@limetech/lime-elements 40.19.0 → 40.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/cjs/keyboard-navigation-VyqkMDKy.js +152 -0
- package/dist/cjs/lime-elements.cjs.js +1 -1
- package/dist/cjs/{limel-breadcrumbs_6.cjs.entry.js → limel-badge_7.cjs.entry.js} +33 -0
- package/dist/cjs/limel-chart.cjs.entry.js +51371 -268
- package/dist/cjs/limel-markdown.cjs.entry.js +2 -2
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +1 -1
- package/dist/cjs/limel-tab-bar.cjs.entry.js +6 -149
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{markdown-exporter-BWS2EBxq.js → markdown-exporter-CGNfjGr9.js} +80 -897
- package/dist/cjs/{markdown-parser-toAp9-Eq.js → markdown-parser-C14XF_G3.js} +994 -38
- package/dist/collection/components/chart/chart.css +75 -924
- package/dist/collection/components/chart/chart.js +332 -287
- package/dist/collection/components/chart/options.js +568 -0
- package/dist/collection/components/chart/scale.js +193 -0
- package/dist/collection/components/chart/theme.js +145 -0
- package/dist/collection/components/scroller/scroller.js +1 -1
- package/dist/esm/keyboard-navigation-BF7IKmnG.js +147 -0
- package/dist/esm/{keycodes-Bu6-QXrA.js → keycodes-DQ5DmW_Y.js} +1 -1
- package/dist/esm/lime-elements.js +1 -1
- package/dist/esm/{limel-breadcrumbs_6.entry.js → limel-badge_7.entry.js} +36 -4
- package/dist/esm/limel-chart.entry.js +51372 -269
- package/dist/esm/limel-chip-set.entry.js +1 -1
- package/dist/esm/limel-chip_2.entry.js +1 -1
- package/dist/esm/limel-markdown.entry.js +2 -2
- package/dist/esm/limel-pagination-jump.entry.js +1 -1
- package/dist/esm/limel-picker.entry.js +2 -2
- package/dist/esm/limel-popover_2.entry.js +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +1 -1
- package/dist/esm/limel-resize-handle.entry.js +1 -1
- package/dist/esm/limel-select.entry.js +2 -2
- package/dist/esm/limel-side-panel.entry.js +1 -1
- package/dist/esm/limel-tab-bar.entry.js +2 -145
- package/dist/esm/limel-text-editor-link-menu.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{markdown-exporter-B2vFxSLw.js → markdown-exporter-DcFcD699.js} +80 -897
- package/dist/esm/{markdown-parser-Cw8iW5R9.js → markdown-parser-8aHA9IYo.js} +991 -33
- package/dist/esm/{typeahead-DOlnT3wh.js → typeahead-B4PwrlM3.js} +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-d4702653.entry.js → p-07f3565b.entry.js} +1 -1
- package/dist/lime-elements/p-0887e0df.entry.js +56 -0
- package/dist/lime-elements/{p-0910aefc.entry.js → p-22e9e327.entry.js} +1 -1
- package/dist/lime-elements/{p-7bf3bf8a.entry.js → p-23067836.entry.js} +1 -1
- package/dist/lime-elements/{p-7f0743d6.entry.js → p-56e2fa48.entry.js} +1 -1
- package/dist/lime-elements/{p-af7d07fd.entry.js → p-5e408c27.entry.js} +1 -1
- package/dist/lime-elements/{p-843886fe.entry.js → p-7fcd48c6.entry.js} +1 -1
- package/dist/lime-elements/{p-1d9bc526.entry.js → p-9edd79a8.entry.js} +1 -1
- package/dist/lime-elements/p-C9gctvIB.js +1 -0
- package/dist/lime-elements/{p-fYs7n6yY.js → p-DNYOwOWu.js} +1 -1
- package/dist/lime-elements/{p-Bu6-QXrA.js → p-DQ5DmW_Y.js} +1 -1
- package/dist/lime-elements/p-_1yBt1pG.js +1 -0
- package/dist/lime-elements/p-a807a45f.entry.js +159 -0
- package/dist/lime-elements/{p-c2f993cc.entry.js → p-a891f3e8.entry.js} +1 -1
- package/dist/lime-elements/{p-45572e9d.entry.js → p-c8a34cef.entry.js} +1 -1
- package/dist/lime-elements/{p-4834e7c1.entry.js → p-cd479c23.entry.js} +1 -1
- package/dist/lime-elements/p-cf2d43c7.entry.js +1 -0
- package/dist/lime-elements/{p-94ae27e2.entry.js → p-f3b93ce8.entry.js} +2 -2
- package/dist/lime-elements/p-kiQd8Ntf.js +7 -0
- package/dist/types/components/chart/chart.d.ts +51 -52
- package/dist/types/components/chart/chart.types.d.ts +5 -0
- package/dist/types/components/chart/options.d.ts +88 -0
- package/dist/types/components/chart/scale.d.ts +101 -0
- package/dist/types/components/chart/theme.d.ts +52 -0
- package/dist/types/components.d.ts +7 -38
- package/package.json +4 -3
- package/dist/cjs/limel-badge.cjs.entry.js +0 -37
- package/dist/esm/limel-badge.entry.js +0 -35
- package/dist/lime-elements/p-02aac2c0.entry.js +0 -1
- package/dist/lime-elements/p-38ab193f.entry.js +0 -1
- package/dist/lime-elements/p-3ca188f6.entry.js +0 -159
- package/dist/lime-elements/p-Bd37Vplf.js +0 -7
- package/dist/lime-elements/p-CvHpvp0f.js +0 -1
- package/dist/lime-elements/p-f7a90228.entry.js +0 -1
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import { format } from "echarts/core";
|
|
2
|
+
import { formatValue, getAxisRange, getMaximumValue, getMinimumValue, getScatterRanges, getXValue, getYValue, getShare, getValueSpan, getWholeRange, isPartOfWhole, isRangeItem, } from "./scale";
|
|
3
|
+
const DOT_SIZE = 8;
|
|
4
|
+
const LINE_DOT_SIZE = 6;
|
|
5
|
+
const CONNECTOR_WIDTH = 2;
|
|
6
|
+
const DIMMED_OPACITY = 0.4;
|
|
7
|
+
const AREA_OPACITY = 0.4;
|
|
8
|
+
const PADDING = 8;
|
|
9
|
+
const PERCENT_DECIMALS = 2;
|
|
10
|
+
const NPS_MIN = -100;
|
|
11
|
+
const NPS_MAX = 100;
|
|
12
|
+
const NPS_START_ANGLE = 200;
|
|
13
|
+
const NPS_END_ANGLE = -20;
|
|
14
|
+
const NPS_THRESHOLDS = [0.5, 0.65, 0.85, 1];
|
|
15
|
+
const NPS_ARC_WIDTH = 16;
|
|
16
|
+
const ITEM_TEXT_MIN_WIDTH = 40;
|
|
17
|
+
const ITEM_TEXT_GAP = 4;
|
|
18
|
+
const ITEM_TEXT_LINE_HEIGHT = 14;
|
|
19
|
+
const emphasis = { focus: 'self' };
|
|
20
|
+
const blur = { itemStyle: { opacity: DIMMED_OPACITY } };
|
|
21
|
+
const hidden = { show: false };
|
|
22
|
+
/**
|
|
23
|
+
* Builds the ECharts option for the chart.
|
|
24
|
+
* @param settings - what to draw
|
|
25
|
+
* @param theme - the colors, sizes and font to draw it with
|
|
26
|
+
* @param itemSpace - the distance between two items on the axis, in pixels,
|
|
27
|
+
* when it is known from an earlier drawing
|
|
28
|
+
*/
|
|
29
|
+
export function drawChart(settings, theme, itemSpace) {
|
|
30
|
+
const drawing = drawSeries(settings, theme, itemSpace);
|
|
31
|
+
return Object.assign(Object.assign({}, drawing), { option: Object.assign({ animation: theme.animate, textStyle: { fontFamily: theme.fontFamily, color: theme.textColor }, tooltip: {
|
|
32
|
+
trigger: 'item',
|
|
33
|
+
appendTo: 'body',
|
|
34
|
+
backgroundColor: theme.surfaceColor,
|
|
35
|
+
borderColor: theme.axisLineColor,
|
|
36
|
+
textStyle: { color: theme.textColor },
|
|
37
|
+
formatter: (params) => getTooltip(settings, getItemIndex(drawing, params)),
|
|
38
|
+
} }, drawing.option) });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The index of the item drawn at a position, if an item is drawn there.
|
|
42
|
+
* @param drawing - the drawing of the chart
|
|
43
|
+
* @param location - a position within the drawn series
|
|
44
|
+
*/
|
|
45
|
+
export function getItemIndex(drawing, location) {
|
|
46
|
+
return drawing.itemsAreSeries ? location.seriesIndex : location.dataIndex;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Where an item is drawn, for highlighting it and showing its tooltip.
|
|
50
|
+
* @param drawing - the drawing of the chart
|
|
51
|
+
* @param index - the index of the item
|
|
52
|
+
*/
|
|
53
|
+
export function locateItem(drawing, index) {
|
|
54
|
+
if (drawing.itemsAreSeries) {
|
|
55
|
+
return { seriesIndex: index, dataIndex: 0 };
|
|
56
|
+
}
|
|
57
|
+
return { seriesIndex: drawing.seriesIndex, dataIndex: index };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Shows the text of every item on the axis, cut short to the space of the
|
|
61
|
+
* item, so that no text runs into the next one. When the items are too close
|
|
62
|
+
* together for that, only some of the texts are shown, as many as fit.
|
|
63
|
+
* @param drawing - the drawing of the chart
|
|
64
|
+
* @param itemSpace - the distance between two items on the axis, in pixels
|
|
65
|
+
*/
|
|
66
|
+
export function fitItemTexts(drawing, itemSpace) {
|
|
67
|
+
const axis = drawing.itemTextAxis;
|
|
68
|
+
return {
|
|
69
|
+
[axis]: [{ axisLabel: getItemTextLayout(axis, itemSpace) }],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function getItemTextLayout(axis, itemSpace) {
|
|
73
|
+
if (axis === 'yAxis') {
|
|
74
|
+
const fits = itemSpace >= ITEM_TEXT_LINE_HEIGHT;
|
|
75
|
+
return { interval: fits ? 0 : 'auto' };
|
|
76
|
+
}
|
|
77
|
+
if (itemSpace < ITEM_TEXT_MIN_WIDTH) {
|
|
78
|
+
return { interval: 'auto', overflow: 'none' };
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
interval: 0,
|
|
82
|
+
width: itemSpace - ITEM_TEXT_GAP,
|
|
83
|
+
overflow: 'truncate',
|
|
84
|
+
ellipsis: '…',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The text of an item, with its share of the whole for charts of parts when
|
|
89
|
+
* `displayItemPercentage` is set.
|
|
90
|
+
* @param settings - what the chart draws
|
|
91
|
+
* @param index - the index of the item
|
|
92
|
+
*/
|
|
93
|
+
export function getItemLabel(settings, index) {
|
|
94
|
+
const item = settings.items[index];
|
|
95
|
+
if (!settings.displayItemPercentage || !isPartOfWhole(settings.type)) {
|
|
96
|
+
return item.text;
|
|
97
|
+
}
|
|
98
|
+
const whole = getWholeRange(settings.items, settings.maxValue);
|
|
99
|
+
const share = getShare(item, whole).toFixed(PERCENT_DECIMALS);
|
|
100
|
+
return `${item.text} (${share}%)`;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The tooltip of an item, as HTML: its label and its value.
|
|
104
|
+
* @param settings - what the chart draws
|
|
105
|
+
* @param index - the index of the item
|
|
106
|
+
*/
|
|
107
|
+
export function getTooltip(settings, index) {
|
|
108
|
+
const item = settings.items[index];
|
|
109
|
+
if (!item) {
|
|
110
|
+
return '';
|
|
111
|
+
}
|
|
112
|
+
return [getItemLabel(settings, index), formatValue(item, settings.type)]
|
|
113
|
+
.map((text) => format.encodeHTML(text))
|
|
114
|
+
.join('<br/>');
|
|
115
|
+
}
|
|
116
|
+
function drawSeries(settings, theme, itemSpace) {
|
|
117
|
+
switch (settings.type) {
|
|
118
|
+
case 'pie':
|
|
119
|
+
case 'doughnut': {
|
|
120
|
+
return drawPie(settings, theme);
|
|
121
|
+
}
|
|
122
|
+
case 'stacked-bar': {
|
|
123
|
+
return drawStackedBar(settings, theme);
|
|
124
|
+
}
|
|
125
|
+
case 'ring': {
|
|
126
|
+
return drawRing(settings, theme);
|
|
127
|
+
}
|
|
128
|
+
case 'scatter': {
|
|
129
|
+
return drawScatter(settings, theme);
|
|
130
|
+
}
|
|
131
|
+
case 'nps': {
|
|
132
|
+
return drawNps(settings, theme);
|
|
133
|
+
}
|
|
134
|
+
default: {
|
|
135
|
+
return drawOnAxes(settings, theme, itemSpace);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function drawOnAxes(settings, theme, itemSpace) {
|
|
140
|
+
const { items, orientation } = settings;
|
|
141
|
+
const range = getAxisRange(items, settings.maxValue, settings.axisIncrement);
|
|
142
|
+
const itemTextAxis = getItemTextAxis(settings);
|
|
143
|
+
const categoryAxis = Object.assign(Object.assign(Object.assign({}, getCategoryAxis(settings)), { axisLabel: Object.assign({ show: settings.displayItemText, color: theme.textColor }, (itemTextAxis &&
|
|
144
|
+
itemSpace &&
|
|
145
|
+
getItemTextLayout(itemTextAxis, itemSpace))), axisTick: hidden, axisLine: { lineStyle: { color: theme.axisLineColor } } }), getAxisName(settings, settings.itemsLabel, theme));
|
|
146
|
+
const valueAxis = getValueAxis(range, getAxisName(settings, settings.valuesLabel, theme), theme);
|
|
147
|
+
const { series, seriesIndex } = getAxisSeries(settings, theme);
|
|
148
|
+
const option = {
|
|
149
|
+
grid: getGrid(theme),
|
|
150
|
+
xAxis: orientation === 'landscape' ? categoryAxis : valueAxis,
|
|
151
|
+
yAxis: orientation === 'landscape' ? valueAxis : categoryAxis,
|
|
152
|
+
series: series,
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
seriesIndex: seriesIndex,
|
|
156
|
+
itemsAreSeries: false,
|
|
157
|
+
itemTextAxis: itemTextAxis,
|
|
158
|
+
option: settings.type === 'bar' ? option : withColumns(option, settings),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function getCategoryAxis(settings) {
|
|
162
|
+
return {
|
|
163
|
+
type: 'category',
|
|
164
|
+
data: settings.items.map((item) => item.text),
|
|
165
|
+
inverse: settings.orientation === 'portrait',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function getItemTextAxis(settings) {
|
|
169
|
+
if (!settings.displayItemText || settings.items.length < 2) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
return settings.orientation === 'landscape' ? 'xAxis' : 'yAxis';
|
|
173
|
+
}
|
|
174
|
+
// Dots and lines are small targets, so each item also gets an invisible
|
|
175
|
+
// column across the whole plot that shows its tooltip and takes its clicks.
|
|
176
|
+
// The columns have axes of their own, so they are not laid out next to the
|
|
177
|
+
// bars that draw ranges.
|
|
178
|
+
function withColumns(option, settings) {
|
|
179
|
+
const { items, orientation } = settings;
|
|
180
|
+
const categoryAxis = Object.assign(Object.assign({}, getCategoryAxis(settings)), { show: false });
|
|
181
|
+
const valueAxis = { type: 'value', min: 0, max: 1, show: false };
|
|
182
|
+
const columns = {
|
|
183
|
+
type: 'bar',
|
|
184
|
+
xAxisIndex: 1,
|
|
185
|
+
yAxisIndex: 1,
|
|
186
|
+
barWidth: '100%',
|
|
187
|
+
itemStyle: { color: 'transparent' },
|
|
188
|
+
data: items.map(() => 1),
|
|
189
|
+
cursor: getSeriesCursor(items),
|
|
190
|
+
emphasis: { disabled: true },
|
|
191
|
+
};
|
|
192
|
+
const landscape = orientation === 'landscape';
|
|
193
|
+
return Object.assign(Object.assign({}, option), { xAxis: [option.xAxis, landscape ? categoryAxis : valueAxis], yAxis: [option.yAxis, landscape ? valueAxis : categoryAxis], series: [...option.series, columns] });
|
|
194
|
+
}
|
|
195
|
+
function getAxisSeries(settings, theme) {
|
|
196
|
+
if (settings.type === 'line' || settings.type === 'area') {
|
|
197
|
+
return getLineSeries(settings, theme);
|
|
198
|
+
}
|
|
199
|
+
if (settings.type === 'dot') {
|
|
200
|
+
return getDotSeries(settings, theme);
|
|
201
|
+
}
|
|
202
|
+
return getBarSeries(settings, theme);
|
|
203
|
+
}
|
|
204
|
+
function getBarSeries(settings, theme) {
|
|
205
|
+
const { items } = settings;
|
|
206
|
+
const bars = {
|
|
207
|
+
type: 'bar',
|
|
208
|
+
data: items.map((item) => ({
|
|
209
|
+
value: getValueSpan(item),
|
|
210
|
+
itemStyle: {
|
|
211
|
+
color: item.color,
|
|
212
|
+
borderRadius: theme.itemBorderRadius,
|
|
213
|
+
},
|
|
214
|
+
})),
|
|
215
|
+
label: getValueLabel(settings, theme),
|
|
216
|
+
cursor: getSeriesCursor(items),
|
|
217
|
+
emphasis: emphasis,
|
|
218
|
+
blur: blur,
|
|
219
|
+
};
|
|
220
|
+
if (items.every((item) => !isRangeItem(item))) {
|
|
221
|
+
return { series: [bars], seriesIndex: 0 };
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
series: [
|
|
225
|
+
Object.assign(Object.assign({ type: 'bar' }, rangeBase), { data: getRangeStarts(items) }),
|
|
226
|
+
Object.assign(Object.assign({}, bars), stacked),
|
|
227
|
+
],
|
|
228
|
+
seriesIndex: 1,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function getDotSeries(settings, theme) {
|
|
232
|
+
const { items, orientation } = settings;
|
|
233
|
+
const point = (index, value) => orientation === 'landscape' ? [index, value] : [value, index];
|
|
234
|
+
const ends = {
|
|
235
|
+
type: 'scatter',
|
|
236
|
+
symbolSize: DOT_SIZE,
|
|
237
|
+
data: items.map((item, index) => ({
|
|
238
|
+
value: point(index, getMaximumValue(item)),
|
|
239
|
+
itemStyle: { color: item.color },
|
|
240
|
+
})),
|
|
241
|
+
label: getValueLabel(settings, theme),
|
|
242
|
+
cursor: getSeriesCursor(items),
|
|
243
|
+
emphasis: emphasis,
|
|
244
|
+
blur: blur,
|
|
245
|
+
};
|
|
246
|
+
if (items.every((item) => !isRangeItem(item))) {
|
|
247
|
+
return { series: [ends], seriesIndex: 0 };
|
|
248
|
+
}
|
|
249
|
+
const connectors = Object.assign(Object.assign({ type: 'bar' }, stacked), { silent: true, barWidth: CONNECTOR_WIDTH, data: items.map((item) => ({
|
|
250
|
+
value: isRangeItem(item) ? getValueSpan(item) : null,
|
|
251
|
+
itemStyle: { color: item.color },
|
|
252
|
+
})) });
|
|
253
|
+
const starts = {
|
|
254
|
+
type: 'scatter',
|
|
255
|
+
silent: true,
|
|
256
|
+
symbolSize: DOT_SIZE,
|
|
257
|
+
data: items.map((item, index) => ({
|
|
258
|
+
value: isRangeItem(item)
|
|
259
|
+
? point(index, getMinimumValue(item))
|
|
260
|
+
: [null, null],
|
|
261
|
+
itemStyle: { color: item.color },
|
|
262
|
+
})),
|
|
263
|
+
};
|
|
264
|
+
return {
|
|
265
|
+
series: [
|
|
266
|
+
Object.assign(Object.assign({ type: 'bar' }, rangeBase), { data: getRangeStarts(items) }),
|
|
267
|
+
connectors,
|
|
268
|
+
starts,
|
|
269
|
+
ends,
|
|
270
|
+
],
|
|
271
|
+
seriesIndex: 3,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function getLineSeries(settings, theme) {
|
|
275
|
+
const { items } = settings;
|
|
276
|
+
const color = theme.lineColor;
|
|
277
|
+
const area = settings.type === 'area';
|
|
278
|
+
const line = {
|
|
279
|
+
type: 'line',
|
|
280
|
+
color: color,
|
|
281
|
+
symbol: 'circle',
|
|
282
|
+
symbolSize: LINE_DOT_SIZE,
|
|
283
|
+
data: items.map((item) => ({
|
|
284
|
+
value: getValueSpan(item),
|
|
285
|
+
itemStyle: { color: item.color },
|
|
286
|
+
})),
|
|
287
|
+
areaStyle: area ? { color: color, opacity: AREA_OPACITY } : undefined,
|
|
288
|
+
label: getValueLabel(settings, theme),
|
|
289
|
+
cursor: getSeriesCursor(items),
|
|
290
|
+
emphasis: emphasis,
|
|
291
|
+
blur: blur,
|
|
292
|
+
};
|
|
293
|
+
if (items.every((item) => !isRangeItem(item))) {
|
|
294
|
+
return { series: [line], seriesIndex: 0 };
|
|
295
|
+
}
|
|
296
|
+
const base = Object.assign(Object.assign({ type: 'line' }, rangeBase), { symbol: 'none', color: color, lineStyle: { opacity: area ? 0 : 1 }, data: getRangeStarts(items) });
|
|
297
|
+
return { series: [base, Object.assign(Object.assign({}, line), stacked)], seriesIndex: 1 };
|
|
298
|
+
}
|
|
299
|
+
const stacked = { stack: 'range', stackStrategy: 'all' };
|
|
300
|
+
// A range is drawn as a stack of an invisible part from zero to its start,
|
|
301
|
+
// and a visible part from its start to its end. Items that are not ranges
|
|
302
|
+
// start at zero.
|
|
303
|
+
const rangeBase = Object.assign(Object.assign({}, stacked), { silent: true, tooltip: hidden, emphasis: { disabled: true }, itemStyle: { color: 'transparent' } });
|
|
304
|
+
function getRangeStarts(items) {
|
|
305
|
+
return items.map((item) => (isRangeItem(item) ? getMinimumValue(item) : 0));
|
|
306
|
+
}
|
|
307
|
+
function drawScatter(settings, theme) {
|
|
308
|
+
const { items } = settings;
|
|
309
|
+
const ranges = getScatterRanges(items);
|
|
310
|
+
const landscape = settings.orientation === 'landscape';
|
|
311
|
+
const firstAxis = getValueAxis(ranges.x, getAxisName(settings, settings.itemsLabel, theme), theme);
|
|
312
|
+
const secondAxis = getValueAxis(ranges.y, getAxisName(settings, settings.valuesLabel, theme), theme);
|
|
313
|
+
const scatter = {
|
|
314
|
+
type: 'scatter',
|
|
315
|
+
symbolSize: theme.scatterItemSize,
|
|
316
|
+
data: items.map((item) => {
|
|
317
|
+
const first = getXValue(item);
|
|
318
|
+
const second = getYValue(item);
|
|
319
|
+
return {
|
|
320
|
+
value: landscape ? [first, second] : [second, first],
|
|
321
|
+
itemStyle: { color: item.color },
|
|
322
|
+
};
|
|
323
|
+
}),
|
|
324
|
+
label: Object.assign(Object.assign({ show: settings.displayItemText || settings.displayItemValue, position: 'top' }, getLabelStyle(theme)), { formatter: ({ dataIndex }) => getPointLabel(settings, items[dataIndex]) }),
|
|
325
|
+
cursor: getSeriesCursor(items),
|
|
326
|
+
emphasis: emphasis,
|
|
327
|
+
blur: blur,
|
|
328
|
+
};
|
|
329
|
+
return {
|
|
330
|
+
seriesIndex: 0,
|
|
331
|
+
itemsAreSeries: false,
|
|
332
|
+
option: {
|
|
333
|
+
grid: getGrid(theme),
|
|
334
|
+
xAxis: landscape ? firstAxis : secondAxis,
|
|
335
|
+
yAxis: landscape ? secondAxis : Object.assign(Object.assign({}, firstAxis), { inverse: true }),
|
|
336
|
+
series: [scatter],
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function drawPie(settings, theme) {
|
|
341
|
+
const { items } = settings;
|
|
342
|
+
const whole = getWholeRange(items, settings.maxValue).totalRange;
|
|
343
|
+
const sum = items.reduce((total, item) => total + getValueSpan(item), 0);
|
|
344
|
+
const data = items.map((item) => ({
|
|
345
|
+
value: getValueSpan(item),
|
|
346
|
+
name: item.text,
|
|
347
|
+
itemStyle: { color: item.color },
|
|
348
|
+
}));
|
|
349
|
+
if (whole > sum) {
|
|
350
|
+
data.push({
|
|
351
|
+
value: whole - sum,
|
|
352
|
+
itemStyle: { color: theme.backgroundColor },
|
|
353
|
+
emphasis: { disabled: true },
|
|
354
|
+
cursor: getCursor(false),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const innerRadius = settings.type === 'doughnut' ? '50%' : 0;
|
|
358
|
+
return {
|
|
359
|
+
seriesIndex: 0,
|
|
360
|
+
itemsAreSeries: false,
|
|
361
|
+
option: {
|
|
362
|
+
series: [
|
|
363
|
+
{
|
|
364
|
+
type: 'pie',
|
|
365
|
+
radius: [innerRadius, '90%'],
|
|
366
|
+
startAngle: 90,
|
|
367
|
+
label: hidden,
|
|
368
|
+
labelLine: hidden,
|
|
369
|
+
itemStyle: {
|
|
370
|
+
borderColor: theme.dividerColor,
|
|
371
|
+
borderWidth: 1,
|
|
372
|
+
},
|
|
373
|
+
data: data,
|
|
374
|
+
cursor: getSeriesCursor(items),
|
|
375
|
+
emphasis: Object.assign(Object.assign({}, emphasis), { scale: false }),
|
|
376
|
+
blur: blur,
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function drawStackedBar(settings, theme) {
|
|
383
|
+
const { items } = settings;
|
|
384
|
+
const whole = getWholeRange(items, settings.maxValue).totalRange;
|
|
385
|
+
const valueAxis = {
|
|
386
|
+
type: 'value',
|
|
387
|
+
min: 0,
|
|
388
|
+
max: whole,
|
|
389
|
+
show: false,
|
|
390
|
+
};
|
|
391
|
+
const categoryAxis = { type: 'category', data: [''], show: false };
|
|
392
|
+
const landscape = settings.orientation === 'landscape';
|
|
393
|
+
return {
|
|
394
|
+
seriesIndex: 0,
|
|
395
|
+
itemsAreSeries: true,
|
|
396
|
+
option: {
|
|
397
|
+
backgroundColor: theme.backgroundColor,
|
|
398
|
+
grid: { left: 0, right: 0, top: 0, bottom: 0 },
|
|
399
|
+
xAxis: landscape ? valueAxis : categoryAxis,
|
|
400
|
+
yAxis: landscape ? categoryAxis : valueAxis,
|
|
401
|
+
series: items.map((item) => ({
|
|
402
|
+
type: 'bar',
|
|
403
|
+
stack: 'whole',
|
|
404
|
+
barWidth: '100%',
|
|
405
|
+
cursor: getCursor(item.clickable),
|
|
406
|
+
data: [getValueSpan(item)],
|
|
407
|
+
itemStyle: {
|
|
408
|
+
color: item.color,
|
|
409
|
+
borderRadius: theme.itemBorderRadius,
|
|
410
|
+
borderColor: theme.dividerColor,
|
|
411
|
+
borderWidth: 1,
|
|
412
|
+
},
|
|
413
|
+
emphasis: emphasis,
|
|
414
|
+
blur: blur,
|
|
415
|
+
})),
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
function drawRing(settings, theme) {
|
|
420
|
+
const { items } = settings;
|
|
421
|
+
const whole = getWholeRange(items, settings.maxValue).totalRange;
|
|
422
|
+
return {
|
|
423
|
+
seriesIndex: 0,
|
|
424
|
+
itemsAreSeries: false,
|
|
425
|
+
option: {
|
|
426
|
+
polar: { radius: ['20%', '90%'] },
|
|
427
|
+
angleAxis: {
|
|
428
|
+
type: 'value',
|
|
429
|
+
max: whole,
|
|
430
|
+
startAngle: 90,
|
|
431
|
+
show: false,
|
|
432
|
+
},
|
|
433
|
+
radiusAxis: {
|
|
434
|
+
type: 'category',
|
|
435
|
+
data: items.map((item) => item.text),
|
|
436
|
+
inverse: true,
|
|
437
|
+
show: false,
|
|
438
|
+
},
|
|
439
|
+
series: [
|
|
440
|
+
{
|
|
441
|
+
type: 'bar',
|
|
442
|
+
coordinateSystem: 'polar',
|
|
443
|
+
showBackground: true,
|
|
444
|
+
backgroundStyle: { color: theme.backgroundColor },
|
|
445
|
+
data: items.map((item) => ({
|
|
446
|
+
value: getValueSpan(item),
|
|
447
|
+
itemStyle: { color: item.color },
|
|
448
|
+
})),
|
|
449
|
+
cursor: getSeriesCursor(items),
|
|
450
|
+
emphasis: emphasis,
|
|
451
|
+
blur: blur,
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
},
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function drawNps(settings, theme) {
|
|
458
|
+
const { items } = settings;
|
|
459
|
+
return {
|
|
460
|
+
seriesIndex: 0,
|
|
461
|
+
itemsAreSeries: false,
|
|
462
|
+
option: {
|
|
463
|
+
series: [
|
|
464
|
+
{
|
|
465
|
+
type: 'gauge',
|
|
466
|
+
min: NPS_MIN,
|
|
467
|
+
max: NPS_MAX,
|
|
468
|
+
startAngle: NPS_START_ANGLE,
|
|
469
|
+
endAngle: NPS_END_ANGLE,
|
|
470
|
+
radius: '90%',
|
|
471
|
+
axisLine: {
|
|
472
|
+
lineStyle: {
|
|
473
|
+
width: NPS_ARC_WIDTH,
|
|
474
|
+
color: NPS_THRESHOLDS.map((threshold, index) => [
|
|
475
|
+
threshold,
|
|
476
|
+
theme.npsColors[index],
|
|
477
|
+
]),
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
splitLine: hidden,
|
|
481
|
+
axisTick: hidden,
|
|
482
|
+
axisLabel: hidden,
|
|
483
|
+
pointer: { width: 6, length: '70%' },
|
|
484
|
+
anchor: {
|
|
485
|
+
show: true,
|
|
486
|
+
size: 12,
|
|
487
|
+
itemStyle: { color: theme.textColor },
|
|
488
|
+
},
|
|
489
|
+
title: hidden,
|
|
490
|
+
detail: hidden,
|
|
491
|
+
data: items.map((item) => ({
|
|
492
|
+
value: getMaximumValue(item),
|
|
493
|
+
name: item.text,
|
|
494
|
+
itemStyle: { color: item.color },
|
|
495
|
+
})),
|
|
496
|
+
cursor: getSeriesCursor(items),
|
|
497
|
+
emphasis: emphasis,
|
|
498
|
+
blur: blur,
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
type: 'pie',
|
|
502
|
+
z: 1,
|
|
503
|
+
silent: true,
|
|
504
|
+
radius: [0, '90%'],
|
|
505
|
+
startAngle: NPS_START_ANGLE,
|
|
506
|
+
endAngle: NPS_END_ANGLE,
|
|
507
|
+
label: hidden,
|
|
508
|
+
labelLine: hidden,
|
|
509
|
+
tooltip: hidden,
|
|
510
|
+
data: [
|
|
511
|
+
{
|
|
512
|
+
value: 1,
|
|
513
|
+
itemStyle: { color: theme.backgroundColor },
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
},
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function getGrid(theme) {
|
|
522
|
+
return {
|
|
523
|
+
left: PADDING,
|
|
524
|
+
right: PADDING,
|
|
525
|
+
top: PADDING,
|
|
526
|
+
bottom: PADDING,
|
|
527
|
+
outerBoundsMode: 'same',
|
|
528
|
+
outerBoundsContain: 'all',
|
|
529
|
+
show: true,
|
|
530
|
+
backgroundColor: theme.backgroundColor,
|
|
531
|
+
borderWidth: 0,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function getValueAxis(range, name, theme) {
|
|
535
|
+
return Object.assign({ type: 'value', min: range.minValue, max: range.maxValue, interval: range.increment, axisLabel: { show: true, color: theme.textColor }, axisLine: { lineStyle: { color: theme.axisLineColor } }, splitLine: { lineStyle: { color: theme.axisLineColor } } }, name);
|
|
536
|
+
}
|
|
537
|
+
function getAxisName(settings, name, theme) {
|
|
538
|
+
if (!settings.displayAxisLabels) {
|
|
539
|
+
return {};
|
|
540
|
+
}
|
|
541
|
+
return {
|
|
542
|
+
name: name,
|
|
543
|
+
nameLocation: 'middle',
|
|
544
|
+
nameTextStyle: { color: theme.textColor },
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
function getValueLabel(settings, theme) {
|
|
548
|
+
return Object.assign(Object.assign({ show: settings.displayItemValue, position: settings.orientation === 'landscape' ? 'top' : 'right' }, getLabelStyle(theme)), { formatter: ({ dataIndex }) => formatValue(settings.items[dataIndex], settings.type) });
|
|
549
|
+
}
|
|
550
|
+
function getLabelStyle(theme) {
|
|
551
|
+
return { color: theme.textColor, textBorderWidth: 0 };
|
|
552
|
+
}
|
|
553
|
+
function getPointLabel(settings, item) {
|
|
554
|
+
const parts = [];
|
|
555
|
+
if (settings.displayItemText) {
|
|
556
|
+
parts.push(item.text);
|
|
557
|
+
}
|
|
558
|
+
if (settings.displayItemValue) {
|
|
559
|
+
parts.push(formatValue(item, settings.type));
|
|
560
|
+
}
|
|
561
|
+
return parts.join(' ');
|
|
562
|
+
}
|
|
563
|
+
function getSeriesCursor(items) {
|
|
564
|
+
return getCursor(items.some((item) => item.clickable));
|
|
565
|
+
}
|
|
566
|
+
function getCursor(clickable) {
|
|
567
|
+
return clickable ? 'pointer' : 'default';
|
|
568
|
+
}
|