evui 3.3.9 → 3.3.12
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/dist/evui.common.js +3546 -973
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +3546 -973
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/chart/Chart.vue +15 -6
- package/src/components/chart/chart.core.js +86 -31
- package/src/components/chart/element/element.bar.js +7 -1
- package/src/components/chart/element/element.heatmap.js +213 -0
- package/src/components/chart/element/element.line.js +20 -9
- package/src/components/chart/element/element.pie.js +13 -5
- package/src/components/chart/element/element.scatter.js +26 -9
- package/src/components/chart/element/element.tip.js +154 -13
- package/src/components/chart/helpers/helpers.constant.js +15 -0
- package/src/components/chart/model/model.series.js +4 -0
- package/src/components/chart/model/model.store.js +160 -2
- package/src/components/chart/plugins/plugins.interaction.js +82 -10
- package/src/components/chart/plugins/plugins.legend.js +213 -42
- package/src/components/chart/plugins/plugins.tooltip.js +249 -6
- package/src/components/chart/scale/scale.js +9 -0
- package/src/components/chart/scale/scale.step.js +20 -5
- package/src/components/chart/scale/scale.time.category.js +20 -2
- package/src/components/chart/uses.js +20 -3
- package/src/components/grid/Grid.vue +276 -132
- package/src/components/grid/grid.filter.window.vue +1 -0
- package/src/components/grid/grid.pagination.vue +75 -0
- package/src/components/grid/grid.summary.vue +235 -0
- package/src/components/grid/style/grid.scss +0 -14
- package/src/components/grid/uses.js +158 -79
- package/src/components/pagination/Pagination.vue +20 -17
- package/src/components/treeGrid/TreeGrid.vue +253 -34
- package/src/components/treeGrid/TreeGridNode.vue +8 -9
- package/src/components/treeGrid/uses.js +152 -37
|
@@ -14,9 +14,15 @@ const modules = {
|
|
|
14
14
|
const isHorizontal = !!opt.horizontal;
|
|
15
15
|
const maxTipOpt = opt.maxTip;
|
|
16
16
|
const selTipOpt = opt.selectItem;
|
|
17
|
+
const labelTipOpt = opt.selectLabel;
|
|
17
18
|
let maxArgs;
|
|
19
|
+
let isExistSelectedLabel;
|
|
18
20
|
|
|
19
|
-
if (
|
|
21
|
+
if (labelTipOpt.use && labelTipOpt.showTip) {
|
|
22
|
+
isExistSelectedLabel = this.drawLabelTip();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (selTipOpt.use && tipLocationInfo && !isExistSelectedLabel) {
|
|
20
26
|
const seriesInfo = this.seriesList[tipLocationInfo?.sId];
|
|
21
27
|
|
|
22
28
|
if (!seriesInfo?.show) {
|
|
@@ -45,29 +51,30 @@ const modules = {
|
|
|
45
51
|
selArgs.text = numberWithComma(selArgs.value);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
this.drawTextTip({ opt: selTipOpt, tipType: 'sel', isSamePos, ...selArgs });
|
|
54
|
+
this.drawTextTip({ opt: selTipOpt, tipType: 'sel', seriesOpt: seriesInfo, isSamePos, ...selArgs });
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
if (selTipOpt.showIndicator) {
|
|
52
|
-
this.drawFixedIndicator({ opt: selTipOpt, ...selArgs });
|
|
58
|
+
this.drawFixedIndicator({ opt: selTipOpt, seriesOpt: seriesInfo, ...selArgs });
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
if (tipLocationInfo && tipLocationInfo
|
|
62
|
+
if (tipLocationInfo && tipLocationInfo?.label && tipLocationInfo?.label === 0) {
|
|
57
63
|
this.lastHitInfo = tipLocationInfo;
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
|
|
61
|
-
if (maxTipOpt.use) {
|
|
67
|
+
if (maxTipOpt.use && !isExistSelectedLabel) {
|
|
62
68
|
const maxSID = this.minMax[isHorizontal ? 'x' : 'y'][0].maxSID;
|
|
63
|
-
|
|
69
|
+
const seriesInfo = this.seriesList[maxSID];
|
|
70
|
+
maxArgs = this.calculateTipInfo(seriesInfo, 'max', null);
|
|
64
71
|
|
|
65
72
|
if (maxTipOpt.use && maxArgs) {
|
|
66
73
|
maxArgs.text = numberWithComma(maxArgs.value);
|
|
67
|
-
this.drawTextTip({ opt: maxTipOpt, tipType: 'max', ...maxArgs });
|
|
74
|
+
this.drawTextTip({ opt: maxTipOpt, tipType: 'max', seriesOpt: seriesInfo, ...maxArgs });
|
|
68
75
|
|
|
69
76
|
if (maxTipOpt.showIndicator) {
|
|
70
|
-
this.drawFixedIndicator({ opt: maxTipOpt, ...maxArgs });
|
|
77
|
+
this.drawFixedIndicator({ opt: maxTipOpt, seriesOpt: seriesInfo, ...maxArgs });
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
}
|
|
@@ -76,7 +83,8 @@ const modules = {
|
|
|
76
83
|
/**
|
|
77
84
|
* Calculate tip size and contents
|
|
78
85
|
* @param {object} series series information (max series or selected series)
|
|
79
|
-
* @param {string} tipType tip type
|
|
86
|
+
* @param {string} tipType tip type
|
|
87
|
+
* [sel = user select series, label = user select label, max = max value]
|
|
80
88
|
* @param {object} hitInfo mouse hit information
|
|
81
89
|
*
|
|
82
90
|
* @returns {object} size and tip contents
|
|
@@ -169,6 +177,14 @@ const modules = {
|
|
|
169
177
|
xArea - size.comboOffset,
|
|
170
178
|
xsp + (size.comboOffset / 2),
|
|
171
179
|
);
|
|
180
|
+
} else if (type === 'scatter') {
|
|
181
|
+
dp = Canvas.calculateX(
|
|
182
|
+
ldata,
|
|
183
|
+
graphX.graphMin,
|
|
184
|
+
graphX.graphMax,
|
|
185
|
+
xArea,
|
|
186
|
+
xsp,
|
|
187
|
+
);
|
|
172
188
|
}
|
|
173
189
|
|
|
174
190
|
const sizeObj = { xArea, yArea, graphX, graphY, xsp, xep, ysp };
|
|
@@ -179,8 +195,14 @@ const modules = {
|
|
|
179
195
|
drawFixedIndicator(param) {
|
|
180
196
|
const isHorizontal = !!this.options.horizontal;
|
|
181
197
|
const ctx = this.bufferCtx;
|
|
182
|
-
const { graphX, graphY, xArea, yArea, xsp, ysp, dp, type, value, opt } = param;
|
|
183
|
-
|
|
198
|
+
const { graphX, graphY, xArea, yArea, xsp, ysp, dp, type, value, opt, seriesOpt } = param;
|
|
199
|
+
let offset = 0;
|
|
200
|
+
|
|
201
|
+
if (type === 'line') {
|
|
202
|
+
offset += 3;
|
|
203
|
+
} else if (type === 'scatter') {
|
|
204
|
+
offset += seriesOpt?.pointSize ?? 0;
|
|
205
|
+
}
|
|
184
206
|
|
|
185
207
|
let gp;
|
|
186
208
|
|
|
@@ -220,6 +242,117 @@ const modules = {
|
|
|
220
242
|
ctx.closePath();
|
|
221
243
|
},
|
|
222
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Draw Selected Label Tip
|
|
247
|
+
* @returns {boolean} Whether drew at least one tip
|
|
248
|
+
*/
|
|
249
|
+
drawLabelTip() {
|
|
250
|
+
const opt = this.options;
|
|
251
|
+
const isHorizontal = !!opt.horizontal;
|
|
252
|
+
const labelTipOpt = opt.selectLabel;
|
|
253
|
+
const { dataIndex, data, label } = this.defaultSelectLabelInfo;
|
|
254
|
+
let drawTip = false;
|
|
255
|
+
|
|
256
|
+
if (dataIndex.length) {
|
|
257
|
+
drawTip = true;
|
|
258
|
+
|
|
259
|
+
const chartRect = this.chartRect;
|
|
260
|
+
const labelOffset = this.labelOffset;
|
|
261
|
+
const aPos = {
|
|
262
|
+
x1: chartRect.x1 + labelOffset.left,
|
|
263
|
+
x2: chartRect.x2 - labelOffset.right,
|
|
264
|
+
y1: chartRect.y1 + labelOffset.top,
|
|
265
|
+
y2: chartRect.y2 - labelOffset.bottom,
|
|
266
|
+
};
|
|
267
|
+
const labelAxes = isHorizontal ? this.axesY[0] : this.axesX[0];
|
|
268
|
+
const valueAxes = isHorizontal ? this.axesX[0] : this.axesY[0];
|
|
269
|
+
const valueAxesRange = isHorizontal ? this.axesRange.x[0] : this.axesRange.y[0];
|
|
270
|
+
const valuePositionCalcFunction = isHorizontal ? Canvas.calculateX : Canvas.calculateY;
|
|
271
|
+
const labelPositionCalcFunction = isHorizontal ? Canvas.calculateY : Canvas.calculateX;
|
|
272
|
+
|
|
273
|
+
const chartWidth = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
|
|
274
|
+
const chartHeight = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
|
|
275
|
+
const valueSpace = isHorizontal ? chartWidth : chartHeight;
|
|
276
|
+
const valueStartPoint = aPos[valueAxes.units.rectStart];
|
|
277
|
+
let offset = this.options.type === 'bar' ? 4 : 6;
|
|
278
|
+
offset *= isHorizontal ? 1 : -1;
|
|
279
|
+
|
|
280
|
+
const seriesList = Object.keys(this.seriesList ?? {});
|
|
281
|
+
const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
|
|
282
|
+
const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
|
|
283
|
+
const groups = this.data.groups?.[0] ?? [];
|
|
284
|
+
|
|
285
|
+
let gp;
|
|
286
|
+
let dp;
|
|
287
|
+
let value;
|
|
288
|
+
let labelStartPoint;
|
|
289
|
+
let labelEndPoint;
|
|
290
|
+
let labelGap;
|
|
291
|
+
let graphX;
|
|
292
|
+
let lineSeries;
|
|
293
|
+
let sizeObj;
|
|
294
|
+
|
|
295
|
+
if (labelAxes.labels) {
|
|
296
|
+
labelStartPoint = aPos[labelAxes.units.rectStart];
|
|
297
|
+
labelEndPoint = aPos[labelAxes.units.rectEnd];
|
|
298
|
+
labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
|
|
299
|
+
} else {
|
|
300
|
+
graphX = this.axesSteps.x[0];
|
|
301
|
+
lineSeries = seriesList.find(sId => this.seriesList[sId]?.type === 'line');
|
|
302
|
+
sizeObj = this.seriesList[lineSeries].size;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
data.forEach((selectedData, i) => {
|
|
306
|
+
if (labelTipOpt.fixedPosTop) {
|
|
307
|
+
value = valueAxesRange.max;
|
|
308
|
+
} else if (isExistGrp) {
|
|
309
|
+
const sumValue = visibleSeries.reduce((ac, sId) => (
|
|
310
|
+
groups.includes(sId) ? ac + (selectedData[sId]?.value ?? selectedData[sId]) : ac), 0);
|
|
311
|
+
const nonGroupValues = visibleSeries
|
|
312
|
+
.filter(sId => !groups.includes(sId))
|
|
313
|
+
.map(sId => selectedData[sId]?.value ?? selectedData[sId]);
|
|
314
|
+
value = Math.max(...nonGroupValues, sumValue);
|
|
315
|
+
} else if (visibleSeries.length) {
|
|
316
|
+
const visibleValue = visibleSeries
|
|
317
|
+
.map(sId => selectedData[sId]?.value ?? selectedData[sId]);
|
|
318
|
+
value = Math.max(...visibleValue);
|
|
319
|
+
} else {
|
|
320
|
+
value = valueAxesRange.max;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (labelAxes.labels) {
|
|
324
|
+
const labelCenter = Math.round(labelStartPoint + (labelGap * dataIndex[i]));
|
|
325
|
+
|
|
326
|
+
dp = labelCenter + (labelGap / 2);
|
|
327
|
+
} else {
|
|
328
|
+
dp = labelPositionCalcFunction(
|
|
329
|
+
label[i],
|
|
330
|
+
graphX.graphMin,
|
|
331
|
+
graphX.graphMax,
|
|
332
|
+
chartWidth - sizeObj.comboOffset,
|
|
333
|
+
aPos.x1 + (sizeObj.comboOffset / 2),
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
gp = valuePositionCalcFunction(
|
|
337
|
+
value,
|
|
338
|
+
valueAxesRange.min,
|
|
339
|
+
valueAxesRange.max,
|
|
340
|
+
valueSpace,
|
|
341
|
+
valueStartPoint);
|
|
342
|
+
gp += offset;
|
|
343
|
+
|
|
344
|
+
this.showTip({
|
|
345
|
+
context: this.bufferCtx,
|
|
346
|
+
x: isHorizontal ? gp : dp,
|
|
347
|
+
y: isHorizontal ? dp : gp,
|
|
348
|
+
opt: labelTipOpt,
|
|
349
|
+
isSamePos: false,
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return drawTip;
|
|
355
|
+
},
|
|
223
356
|
/**
|
|
224
357
|
* Calculate x, y position to draw text tip
|
|
225
358
|
* @param {object} param object for drawing text tip
|
|
@@ -230,12 +363,20 @@ const modules = {
|
|
|
230
363
|
const isHorizontal = !!this.options.horizontal;
|
|
231
364
|
const ctx = this.bufferCtx;
|
|
232
365
|
const { graphX, graphY, xArea, yArea, xsp, xep, ysp } = param;
|
|
233
|
-
const { dp, value, text, opt, type, tipType, isSamePos } = param;
|
|
366
|
+
const { dp, value, text, opt, type, tipType, isSamePos, seriesOpt } = param;
|
|
234
367
|
|
|
235
368
|
const arrowSize = 4;
|
|
236
369
|
const maxTipHeight = 20;
|
|
237
370
|
const borderRadius = 4;
|
|
238
|
-
|
|
371
|
+
|
|
372
|
+
let offset = 1;
|
|
373
|
+
if (type === 'line') {
|
|
374
|
+
offset += 6;
|
|
375
|
+
} else if (type === 'scatter') {
|
|
376
|
+
offset += seriesOpt?.pointSize;
|
|
377
|
+
} else if (type === 'bar') {
|
|
378
|
+
offset += 4;
|
|
379
|
+
}
|
|
239
380
|
|
|
240
381
|
let gp;
|
|
241
382
|
let tdp = dp;
|
|
@@ -128,6 +128,21 @@ export const PLOT_BAND_OPTION = {
|
|
|
128
128
|
color: '#FAE59D',
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
+
export const HEAT_MAP_OPTION = {
|
|
132
|
+
...LINE_OPTION,
|
|
133
|
+
colorOpt: {
|
|
134
|
+
min: '#FFFFFF',
|
|
135
|
+
max: '#0052FF',
|
|
136
|
+
categoryCnt: 5,
|
|
137
|
+
border: '#FFFFFF',
|
|
138
|
+
error: '#FF0000',
|
|
139
|
+
},
|
|
140
|
+
spaces: {
|
|
141
|
+
x: 0,
|
|
142
|
+
y: 0,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
131
146
|
|
|
132
147
|
export const TIME_INTERVALS = {
|
|
133
148
|
millisecond: {
|
|
@@ -3,6 +3,7 @@ import Scatter from '../element/element.scatter';
|
|
|
3
3
|
import Bar from '../element/element.bar';
|
|
4
4
|
import TimeBar from '../element/element.bar.time';
|
|
5
5
|
import Pie from '../element/element.pie';
|
|
6
|
+
import HeatMap from '../element/element.heatmap';
|
|
6
7
|
|
|
7
8
|
const modules = {
|
|
8
9
|
/**
|
|
@@ -51,6 +52,9 @@ const modules = {
|
|
|
51
52
|
} else if (type === 'pie') {
|
|
52
53
|
this.seriesInfo.charts.pie.push(id);
|
|
53
54
|
return new Pie(id, opt, index);
|
|
55
|
+
} else if (type === 'heatMap') {
|
|
56
|
+
this.seriesInfo.charts.heatMap.push(id);
|
|
57
|
+
return new HeatMap(id, opt, index);
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
return false;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { reverse } from 'lodash-es';
|
|
2
2
|
import Util from '../helpers/helpers.util';
|
|
3
|
+
import { TIME_INTERVALS } from '../helpers/helpers.constant';
|
|
3
4
|
|
|
4
5
|
const modules = {
|
|
5
6
|
/**
|
|
@@ -30,6 +31,17 @@ const modules = {
|
|
|
30
31
|
series.minMax = this.getSeriesMinMax(series.data);
|
|
31
32
|
}
|
|
32
33
|
});
|
|
34
|
+
} else if (typeKey === 'heatMap') {
|
|
35
|
+
seriesIDs.forEach((seriesID) => {
|
|
36
|
+
const series = this.seriesList[seriesID];
|
|
37
|
+
const sData = data[seriesID];
|
|
38
|
+
|
|
39
|
+
if (series && sData) {
|
|
40
|
+
series.data = this.addSeriesDSForHeatMap(sData);
|
|
41
|
+
series.minMax = this.getSeriesMinMaxForHeatMap(series.data, series.spaces);
|
|
42
|
+
series.valueOpt = this.getSeriesValueOptForHeatMap(series);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
33
45
|
} else {
|
|
34
46
|
seriesIDs.forEach((seriesID) => {
|
|
35
47
|
const series = this.seriesList[seriesID];
|
|
@@ -286,6 +298,24 @@ const modules = {
|
|
|
286
298
|
});
|
|
287
299
|
},
|
|
288
300
|
|
|
301
|
+
/**
|
|
302
|
+
* Take data to create data for each series
|
|
303
|
+
* @param {array} data data array for each series
|
|
304
|
+
* @returns {array} data info added position and etc
|
|
305
|
+
*/
|
|
306
|
+
addSeriesDSForHeatMap(data) {
|
|
307
|
+
return data.map(item => ({
|
|
308
|
+
x: item.x,
|
|
309
|
+
y: item.y,
|
|
310
|
+
o: item.value,
|
|
311
|
+
xp: null,
|
|
312
|
+
yp: null,
|
|
313
|
+
dataColor: null,
|
|
314
|
+
value: item.value,
|
|
315
|
+
cId: null,
|
|
316
|
+
}));
|
|
317
|
+
},
|
|
318
|
+
|
|
289
319
|
/**
|
|
290
320
|
* Take data to create data object for graph
|
|
291
321
|
* @param {object} gdata graph data (y-axis value for vertical chart)
|
|
@@ -384,6 +414,96 @@ const modules = {
|
|
|
384
414
|
return def;
|
|
385
415
|
},
|
|
386
416
|
|
|
417
|
+
adjustMinMax(max, min, opt, space) {
|
|
418
|
+
if ((opt.type === 'time' && opt.categoryMode) || opt.type === 'step') {
|
|
419
|
+
return {
|
|
420
|
+
max,
|
|
421
|
+
min,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
let targetMax = max;
|
|
426
|
+
let targetMin = min;
|
|
427
|
+
if (targetMax > 0 && opt.interval && space) {
|
|
428
|
+
if (targetMax < (opt.interval * space)) {
|
|
429
|
+
targetMax += opt.interval;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
let targetInterval = opt.interval;
|
|
434
|
+
if (opt.type === 'time') {
|
|
435
|
+
if (typeof targetInterval === 'string') {
|
|
436
|
+
targetInterval = TIME_INTERVALS[targetInterval].size;
|
|
437
|
+
} else if (typeof targetInterval === 'object') {
|
|
438
|
+
targetInterval = targetInterval.time * TIME_INTERVALS[targetInterval.unit].size;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (!opt.startToZero || targetMin > 0) {
|
|
443
|
+
const targetSpace = space ? (space - 1) : (targetMax - targetMin);
|
|
444
|
+
const targetStep = Math.ceil((max - targetMin) / targetSpace);
|
|
445
|
+
targetMin = targetMin < targetStep ? 0 : targetMin - targetStep;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return {
|
|
449
|
+
max: targetMax,
|
|
450
|
+
min: targetMin,
|
|
451
|
+
};
|
|
452
|
+
},
|
|
453
|
+
/**
|
|
454
|
+
* Take series data to create min/max info for each series
|
|
455
|
+
* @param data
|
|
456
|
+
* @param spaces
|
|
457
|
+
* @returns {*|{maxDomain: null, minY: null, minX: null, maxY: null, maxX: null}}
|
|
458
|
+
*/
|
|
459
|
+
getSeriesMinMaxForHeatMap(data, spaces) {
|
|
460
|
+
const axesXOption = this.options.axesX[0];
|
|
461
|
+
const axesYOption = this.options.axesY[0];
|
|
462
|
+
const seriesMinMax = this.getSeriesMinMax(data);
|
|
463
|
+
|
|
464
|
+
const adjustX = this.adjustMinMax(seriesMinMax.maxX, seriesMinMax.minX, axesXOption, spaces.x);
|
|
465
|
+
seriesMinMax.maxX = adjustX.max;
|
|
466
|
+
seriesMinMax.minX = adjustX.min;
|
|
467
|
+
|
|
468
|
+
const adjustY = this.adjustMinMax(seriesMinMax.maxY, seriesMinMax.minY, axesYOption, spaces.y);
|
|
469
|
+
seriesMinMax.maxY = adjustY.max;
|
|
470
|
+
seriesMinMax.minY = adjustY.min;
|
|
471
|
+
|
|
472
|
+
return seriesMinMax;
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
getSeriesValueOptForHeatMap(series) {
|
|
476
|
+
const data = series.data;
|
|
477
|
+
const colorOpt = series.colorOpt;
|
|
478
|
+
const colorAxis = series.colorAxis;
|
|
479
|
+
const categoryCnt = colorOpt.categoryCnt;
|
|
480
|
+
|
|
481
|
+
let maxValue = 0;
|
|
482
|
+
let isExistError = false;
|
|
483
|
+
data.forEach(({ value }) => {
|
|
484
|
+
if (maxValue < value) {
|
|
485
|
+
maxValue = value;
|
|
486
|
+
}
|
|
487
|
+
if (value < 0) {
|
|
488
|
+
isExistError = true;
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
const valueInterval = Math.ceil(maxValue / categoryCnt);
|
|
492
|
+
if (isExistError && colorAxis.length === categoryCnt) {
|
|
493
|
+
colorAxis.push({
|
|
494
|
+
id: `color#${categoryCnt}`,
|
|
495
|
+
value: colorOpt.error,
|
|
496
|
+
state: 'normal',
|
|
497
|
+
show: true,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
max: maxValue,
|
|
502
|
+
interval: valueInterval,
|
|
503
|
+
existError: isExistError,
|
|
504
|
+
};
|
|
505
|
+
},
|
|
506
|
+
|
|
387
507
|
/**
|
|
388
508
|
* Get graph items for each series by label index
|
|
389
509
|
* @param {number} labelIndex label index
|
|
@@ -553,6 +673,42 @@ const modules = {
|
|
|
553
673
|
};
|
|
554
674
|
},
|
|
555
675
|
|
|
676
|
+
/**
|
|
677
|
+
* Find label info by position x and y
|
|
678
|
+
* @param {array} offset position x and y
|
|
679
|
+
*
|
|
680
|
+
* @returns {object} clicked label information
|
|
681
|
+
*/
|
|
682
|
+
getLabelInfoByPosition(offset) {
|
|
683
|
+
const [x, y] = offset;
|
|
684
|
+
const aPos = {
|
|
685
|
+
x1: this.chartRect.x1 + this.labelOffset.left,
|
|
686
|
+
x2: this.chartRect.x2 - this.labelOffset.right,
|
|
687
|
+
y1: this.chartRect.y1 + this.labelOffset.top,
|
|
688
|
+
y2: this.chartRect.y2 - this.labelOffset.bottom,
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
const scale = this.options.horizontal ? this.axesY[0] : this.axesX[0];
|
|
692
|
+
const startPoint = aPos[scale.units.rectStart];
|
|
693
|
+
const endPoint = aPos[scale.units.rectEnd];
|
|
694
|
+
|
|
695
|
+
let labelIndex;
|
|
696
|
+
let hitInfo;
|
|
697
|
+
if (scale.labels) {
|
|
698
|
+
const labelGap = (endPoint - startPoint) / scale.labels.length;
|
|
699
|
+
const index = Math.floor(((this.options.horizontal ? y : x) - startPoint) / labelGap);
|
|
700
|
+
labelIndex = scale.labels.length > index ? index : -1;
|
|
701
|
+
} else {
|
|
702
|
+
hitInfo = this.getItemByPosition(offset, this.options.selectLabel.useApproximateValue);
|
|
703
|
+
labelIndex = hitInfo.maxIndex ?? -1;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return {
|
|
707
|
+
labelIndex,
|
|
708
|
+
hitInfo,
|
|
709
|
+
};
|
|
710
|
+
},
|
|
711
|
+
|
|
556
712
|
/**
|
|
557
713
|
* Create min/max information for all of data
|
|
558
714
|
* @property seriesList
|
|
@@ -584,7 +740,8 @@ const modules = {
|
|
|
584
740
|
|
|
585
741
|
if (smm && series.show) {
|
|
586
742
|
if (!isHorizontal) {
|
|
587
|
-
if (smm.minX
|
|
743
|
+
if (smm.minX !== null
|
|
744
|
+
&& ((minmax.x[axisX].min === null || (smm.minX < minmax.x[axisX].min)))) {
|
|
588
745
|
minmax.x[axisX].min = smm.minX;
|
|
589
746
|
}
|
|
590
747
|
if (minmax.y[axisY].min === null || (smm.minY < minmax.y[axisY].min)) {
|
|
@@ -594,7 +751,8 @@ const modules = {
|
|
|
594
751
|
if (minmax.x[axisX].min === null || (smm.minX < minmax.x[axisX].min)) {
|
|
595
752
|
minmax.x[axisX].min = smm.minX;
|
|
596
753
|
}
|
|
597
|
-
if (smm.minY
|
|
754
|
+
if (smm.minY !== null
|
|
755
|
+
&& (minmax.y[axisY].min === null || (smm.minY < minmax.y[axisY].min))) {
|
|
598
756
|
minmax.y[axisY].min = smm.minY;
|
|
599
757
|
}
|
|
600
758
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { numberWithComma } from '@/common/utils';
|
|
2
|
-
import { defaultsDeep } from 'lodash-es';
|
|
2
|
+
import { cloneDeep, defaultsDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
const modules = {
|
|
5
5
|
/**
|
|
@@ -48,13 +48,17 @@ const modules = {
|
|
|
48
48
|
this.overlayClear();
|
|
49
49
|
|
|
50
50
|
if (Object.keys(hitInfo.items).length) {
|
|
51
|
-
if (
|
|
51
|
+
if ((type !== 'scatter' && type !== 'heatMap') || tooltip.use) {
|
|
52
52
|
this.drawItemsHighlight(hitInfo, ctx);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (tooltip.use) {
|
|
56
56
|
this.setTooltipLayoutPosition(hitInfo, e);
|
|
57
|
-
|
|
57
|
+
if (type === 'scatter') {
|
|
58
|
+
this.drawTooltipForScatter(hitInfo, this.tooltipCtx);
|
|
59
|
+
} else {
|
|
60
|
+
this.drawTooltip(hitInfo, this.tooltipCtx);
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
} else if (tooltip.use) {
|
|
60
64
|
this.hideTooltipDOM();
|
|
@@ -64,7 +68,7 @@ const modules = {
|
|
|
64
68
|
this.drawSelectionArea(this.dragInfoBackup);
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
if (indicator.use && type !== 'pie' && type !== 'scatter') {
|
|
71
|
+
if (indicator.use && type !== 'pie' && type !== 'scatter' && type !== 'heatMap') {
|
|
68
72
|
this.drawIndicator(offset, indicator.color);
|
|
69
73
|
}
|
|
70
74
|
};
|
|
@@ -139,6 +143,15 @@ const modules = {
|
|
|
139
143
|
} = hitInfo);
|
|
140
144
|
}
|
|
141
145
|
|
|
146
|
+
if (this.options.selectLabel.use) {
|
|
147
|
+
const offset = this.getMousePosition(e);
|
|
148
|
+
const clickedLabelInfo = this.getLabelInfoByPosition(offset);
|
|
149
|
+
const selected = this.selectLabel(clickedLabelInfo.labelIndex);
|
|
150
|
+
this.renderWithSelectLabel(selected.dataIndex);
|
|
151
|
+
|
|
152
|
+
args.selected = cloneDeep(this.defaultSelectLabelInfo);
|
|
153
|
+
}
|
|
154
|
+
|
|
142
155
|
if (typeof this.listeners.click === 'function') {
|
|
143
156
|
if (!this.dragInfoBackup) {
|
|
144
157
|
this.listeners.click(args);
|
|
@@ -154,7 +167,7 @@ const modules = {
|
|
|
154
167
|
this.onMouseDown = (e) => {
|
|
155
168
|
const { dragSelection, type } = this.options;
|
|
156
169
|
|
|
157
|
-
if (dragSelection.use && (type === 'scatter' || type === 'line')) {
|
|
170
|
+
if (dragSelection.use && (type === 'scatter' || type === 'line' || type === 'heatMap')) {
|
|
158
171
|
this.removeSelectionArea();
|
|
159
172
|
this.dragStart(e, type);
|
|
160
173
|
}
|
|
@@ -251,9 +264,11 @@ const modules = {
|
|
|
251
264
|
}
|
|
252
265
|
|
|
253
266
|
dragInfo.xsp = Math.min(xcp, xep);
|
|
254
|
-
dragInfo.ysp = type === 'scatter' ? Math.min(ycp, yep) : aRange.y1;
|
|
267
|
+
dragInfo.ysp = type === 'scatter' || type === 'heatMap' ? Math.min(ycp, yep) : aRange.y1;
|
|
255
268
|
dragInfo.width = Math.ceil(Math.abs(xep - xcp));
|
|
256
|
-
dragInfo.height = type === 'scatter'
|
|
269
|
+
dragInfo.height = type === 'scatter' || type === 'heatMap'
|
|
270
|
+
? Math.ceil(Math.abs(yep - ycp))
|
|
271
|
+
: aRange.y2 - aRange.y1;
|
|
257
272
|
|
|
258
273
|
this.overlayClear();
|
|
259
274
|
this.drawSelectionArea(dragInfo);
|
|
@@ -367,7 +382,7 @@ const modules = {
|
|
|
367
382
|
}
|
|
368
383
|
|
|
369
384
|
if (gdata !== null && gdata !== undefined) {
|
|
370
|
-
const sName =
|
|
385
|
+
const sName = series.name;
|
|
371
386
|
const sw = ctx ? ctx.measureText(sName).width : 1;
|
|
372
387
|
|
|
373
388
|
item.name = sName;
|
|
@@ -412,7 +427,7 @@ const modules = {
|
|
|
412
427
|
* @returns {boolean}
|
|
413
428
|
*/
|
|
414
429
|
selectItemByData(targetInfo, chartType) {
|
|
415
|
-
this.
|
|
430
|
+
this.defaultSelectItemInfo = targetInfo;
|
|
416
431
|
|
|
417
432
|
let foundInfo;
|
|
418
433
|
if (chartType === 'pie') {
|
|
@@ -437,9 +452,66 @@ const modules = {
|
|
|
437
452
|
return true;
|
|
438
453
|
},
|
|
439
454
|
|
|
455
|
+
/**
|
|
456
|
+
* render after select label by index list
|
|
457
|
+
* @param indexList {array} '[0, 1 ...]'
|
|
458
|
+
*/
|
|
459
|
+
renderWithSelectLabel(indexList) {
|
|
460
|
+
this.defaultSelectLabelInfo.dataIndex = indexList;
|
|
461
|
+
this.initSelectedLabelInfo();
|
|
462
|
+
this.render();
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* init defaultSelectLabelInfo object.
|
|
467
|
+
* (set each series data and label text)
|
|
468
|
+
*/
|
|
469
|
+
initSelectedLabelInfo() {
|
|
470
|
+
const { use, limit } = this.options.selectLabel;
|
|
471
|
+
|
|
472
|
+
if (use) {
|
|
473
|
+
if (!this.defaultSelectLabelInfo) {
|
|
474
|
+
this.defaultSelectLabelInfo = { dataIndex: [] };
|
|
475
|
+
}
|
|
476
|
+
const infoObj = this.defaultSelectLabelInfo;
|
|
477
|
+
infoObj.dataIndex.splice(limit);
|
|
478
|
+
infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
|
|
479
|
+
const dataEntries = Object.entries(this.data.data);
|
|
480
|
+
infoObj.data = infoObj.dataIndex.map(labelIdx => Object.fromEntries(
|
|
481
|
+
dataEntries.map(([sId, data]) => [sId, data[labelIdx]])));
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Add or delete selected label index, according to policy and option
|
|
487
|
+
* (set each series data and label text)
|
|
488
|
+
* @param labelIndex {array} '[0, 1 ...]'
|
|
489
|
+
*/
|
|
490
|
+
selectLabel(labelIndex) {
|
|
491
|
+
const option = this.options?.selectLabel ?? {};
|
|
492
|
+
const before = this.defaultSelectLabelInfo ?? { dataIndex: [] };
|
|
493
|
+
const after = cloneDeep(before);
|
|
494
|
+
|
|
495
|
+
if (before.dataIndex.includes(labelIndex)) {
|
|
496
|
+
const idx = before.dataIndex.indexOf(labelIndex);
|
|
497
|
+
after.dataIndex.splice(idx, 1);
|
|
498
|
+
} else if (labelIndex > -1) {
|
|
499
|
+
after.dataIndex.push(labelIndex);
|
|
500
|
+
if (option.limit > 0 && option.limit < after.dataIndex.length) {
|
|
501
|
+
if (option.useDeselectOverflow) {
|
|
502
|
+
after.dataIndex.splice(0, 1);
|
|
503
|
+
} else {
|
|
504
|
+
after.dataIndex.pop();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return after;
|
|
510
|
+
},
|
|
511
|
+
|
|
440
512
|
/**
|
|
441
513
|
* Find items by series within a range
|
|
442
|
-
* @param {object}
|
|
514
|
+
* @param {object} range object for find series items
|
|
443
515
|
*
|
|
444
516
|
* @returns {object}
|
|
445
517
|
*/
|