evui 3.3.11 → 3.3.14
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 +1855 -836
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +1855 -836
- 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 +21 -2
- package/src/components/chart/chart.core.js +12 -9
- package/src/components/chart/element/element.heatmap.js +195 -51
- package/src/components/chart/element/element.line.js +20 -9
- package/src/components/chart/element/element.tip.js +69 -73
- package/src/components/chart/helpers/helpers.constant.js +13 -11
- package/src/components/chart/model/model.series.js +1 -1
- package/src/components/chart/model/model.store.js +114 -74
- package/src/components/chart/plugins/plugins.interaction.js +72 -17
- package/src/components/chart/plugins/plugins.legend.js +18 -5
- package/src/components/chart/plugins/plugins.pie.js +17 -0
- package/src/components/chart/plugins/plugins.tooltip.js +30 -14
- package/src/components/chart/scale/scale.js +5 -4
- package/src/components/chart/scale/scale.step.js +29 -2
- package/src/components/chart/scale/scale.time.category.js +27 -3
- package/src/components/chart/uses.js +22 -1
- package/src/components/grid/Grid.vue +19 -7
- package/src/components/grid/grid.summary.vue +20 -6
- package/src/components/grid/uses.js +1 -1
- package/src/components/treeGrid/TreeGrid.vue +269 -36
- package/src/components/treeGrid/TreeGridNode.vue +8 -9
- package/src/components/treeGrid/uses.js +152 -37
|
@@ -250,7 +250,7 @@ const modules = {
|
|
|
250
250
|
const opt = this.options;
|
|
251
251
|
const isHorizontal = !!opt.horizontal;
|
|
252
252
|
const labelTipOpt = opt.selectLabel;
|
|
253
|
-
const { dataIndex, data } = this.
|
|
253
|
+
const { dataIndex, data, label } = this.defaultSelectInfo;
|
|
254
254
|
let drawTip = false;
|
|
255
255
|
|
|
256
256
|
if (dataIndex.length) {
|
|
@@ -264,86 +264,82 @@ const modules = {
|
|
|
264
264
|
y1: chartRect.y1 + labelOffset.top,
|
|
265
265
|
y2: chartRect.y2 - labelOffset.bottom,
|
|
266
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;
|
|
267
272
|
|
|
268
|
-
const labelAxes = this.options.horizontal ? this.axesY[0] : this.axesX[0];
|
|
269
|
-
const labelStartPoint = aPos[labelAxes.units.rectStart];
|
|
270
|
-
const labelEndPoint = aPos[labelAxes.units.rectEnd];
|
|
271
|
-
const labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
|
|
272
|
-
|
|
273
|
-
const valueAxes = this.options.horizontal ? this.axesX[0] : this.axesY[0];
|
|
274
|
-
const valueStartPoint = aPos[valueAxes.units.rectStart];
|
|
275
|
-
|
|
276
|
-
const offset = this.options.type === 'bar' ? 4 : 6;
|
|
277
273
|
const chartWidth = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
|
|
278
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
|
+
}
|
|
279
304
|
|
|
280
|
-
|
|
281
|
-
const labelCenter = Math.round(labelStartPoint + (labelGap * idx));
|
|
282
|
-
let gp;
|
|
283
|
-
const dp = labelCenter + (labelGap / 2);
|
|
305
|
+
data.forEach((selectedData, i) => {
|
|
284
306
|
if (labelTipOpt.fixedPosTop) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
this.axesRange.y[0].max,
|
|
298
|
-
chartHeight,
|
|
299
|
-
valueStartPoint);
|
|
300
|
-
gp -= offset;
|
|
301
|
-
}
|
|
302
|
-
} else if (isHorizontal) {
|
|
303
|
-
const seriesList = Object.keys(data[i] ?? {});
|
|
304
|
-
const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
|
|
305
|
-
const visibleValue = visibleSeries.map(sId => data[i][sId]);
|
|
306
|
-
const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
|
|
307
|
-
|
|
308
|
-
let maxValue;
|
|
309
|
-
if (isExistGrp) {
|
|
310
|
-
maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
|
|
311
|
-
} else if (visibleValue.length) {
|
|
312
|
-
maxValue = Math.max(...visibleValue);
|
|
313
|
-
} else {
|
|
314
|
-
maxValue = this.axesRange.x[0].max;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
gp = Canvas.calculateX(
|
|
318
|
-
maxValue,
|
|
319
|
-
this.axesRange.x[0].min,
|
|
320
|
-
this.axesRange.x[0].max,
|
|
321
|
-
chartWidth,
|
|
322
|
-
valueStartPoint);
|
|
323
|
-
gp += offset;
|
|
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);
|
|
324
319
|
} else {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
let maxValue;
|
|
331
|
-
if (isExistGrp) {
|
|
332
|
-
maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
|
|
333
|
-
} else if (visibleValue.length) {
|
|
334
|
-
maxValue = Math.max(...visibleValue);
|
|
335
|
-
} else {
|
|
336
|
-
maxValue = this.axesRange.y[0].max;
|
|
337
|
-
}
|
|
320
|
+
value = valueAxesRange.max;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (labelAxes.labels) {
|
|
324
|
+
const labelCenter = Math.round(labelStartPoint + (labelGap * dataIndex[i]));
|
|
338
325
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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
|
+
);
|
|
346
335
|
}
|
|
336
|
+
gp = valuePositionCalcFunction(
|
|
337
|
+
value,
|
|
338
|
+
valueAxesRange.min,
|
|
339
|
+
valueAxesRange.max,
|
|
340
|
+
valueSpace,
|
|
341
|
+
valueStartPoint);
|
|
342
|
+
gp += offset;
|
|
347
343
|
|
|
348
344
|
this.showTip({
|
|
349
345
|
context: this.bufferCtx,
|
|
@@ -129,17 +129,19 @@ export const PLOT_BAND_OPTION = {
|
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
export const HEAT_MAP_OPTION = {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
show: true,
|
|
133
|
+
highlight: {
|
|
134
|
+
maxShadowOpacity: 0.4,
|
|
135
|
+
},
|
|
136
|
+
xAxisIndex: 0,
|
|
137
|
+
yAxisIndex: 0,
|
|
138
|
+
showLegend: true,
|
|
139
|
+
showValue: {
|
|
140
|
+
use: false,
|
|
141
|
+
fontSize: 12,
|
|
142
|
+
textColor: '#000000',
|
|
143
|
+
formatter: null,
|
|
144
|
+
decimalPoint: 0,
|
|
143
145
|
},
|
|
144
146
|
};
|
|
145
147
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { reverse } from 'lodash-es';
|
|
2
2
|
import Util from '../helpers/helpers.util';
|
|
3
|
-
import { TIME_INTERVALS } from '../helpers/helpers.constant';
|
|
4
3
|
|
|
5
4
|
const modules = {
|
|
6
5
|
/**
|
|
@@ -37,8 +36,9 @@ const modules = {
|
|
|
37
36
|
const sData = data[seriesID];
|
|
38
37
|
|
|
39
38
|
if (series && sData) {
|
|
39
|
+
series.labels = label;
|
|
40
40
|
series.data = this.addSeriesDSForHeatMap(sData);
|
|
41
|
-
series.minMax = this.
|
|
41
|
+
series.minMax = this.getSeriesMinMax(series.data);
|
|
42
42
|
series.valueOpt = this.getSeriesValueOptForHeatMap(series);
|
|
43
43
|
}
|
|
44
44
|
});
|
|
@@ -301,17 +301,20 @@ const modules = {
|
|
|
301
301
|
/**
|
|
302
302
|
* Take data to create data for each series
|
|
303
303
|
* @param {array} data data array for each series
|
|
304
|
+
* @param {object} label chart label
|
|
305
|
+
*
|
|
304
306
|
* @returns {array} data info added position and etc
|
|
305
307
|
*/
|
|
306
308
|
addSeriesDSForHeatMap(data) {
|
|
307
|
-
return data.map(
|
|
308
|
-
x
|
|
309
|
-
y
|
|
310
|
-
o:
|
|
309
|
+
return data.map(({ x, y, value }) => ({
|
|
310
|
+
x,
|
|
311
|
+
y,
|
|
312
|
+
o: value,
|
|
311
313
|
xp: null,
|
|
312
314
|
yp: null,
|
|
315
|
+
w: null,
|
|
316
|
+
h: null,
|
|
313
317
|
dataColor: null,
|
|
314
|
-
value: item.value,
|
|
315
318
|
cId: null,
|
|
316
319
|
}));
|
|
317
320
|
},
|
|
@@ -414,73 +417,14 @@ const modules = {
|
|
|
414
417
|
return def;
|
|
415
418
|
},
|
|
416
419
|
|
|
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
420
|
getSeriesValueOptForHeatMap(series) {
|
|
476
421
|
const data = series.data;
|
|
477
|
-
const colorOpt =
|
|
478
|
-
const colorAxis = series.colorAxis;
|
|
422
|
+
const colorOpt = this.options.heatMapColor;
|
|
479
423
|
const categoryCnt = colorOpt.categoryCnt;
|
|
480
424
|
|
|
481
425
|
let maxValue = 0;
|
|
482
426
|
let isExistError = false;
|
|
483
|
-
data.forEach(({ value }) => {
|
|
427
|
+
data.forEach(({ o: value }) => {
|
|
484
428
|
if (maxValue < value) {
|
|
485
429
|
maxValue = value;
|
|
486
430
|
}
|
|
@@ -488,18 +432,19 @@ const modules = {
|
|
|
488
432
|
isExistError = true;
|
|
489
433
|
}
|
|
490
434
|
});
|
|
491
|
-
|
|
492
|
-
if (isExistError && colorAxis.length === categoryCnt) {
|
|
493
|
-
colorAxis.push({
|
|
435
|
+
|
|
436
|
+
if (isExistError && series.colorAxis.length === categoryCnt) {
|
|
437
|
+
series.colorAxis.push({
|
|
494
438
|
id: `color#${categoryCnt}`,
|
|
495
439
|
value: colorOpt.error,
|
|
496
440
|
state: 'normal',
|
|
497
441
|
show: true,
|
|
498
442
|
});
|
|
499
443
|
}
|
|
444
|
+
|
|
500
445
|
return {
|
|
501
446
|
max: maxValue,
|
|
502
|
-
interval:
|
|
447
|
+
interval: Math.ceil(maxValue / categoryCnt),
|
|
503
448
|
existError: isExistError,
|
|
504
449
|
};
|
|
505
450
|
},
|
|
@@ -673,6 +618,101 @@ const modules = {
|
|
|
673
618
|
};
|
|
674
619
|
},
|
|
675
620
|
|
|
621
|
+
/**
|
|
622
|
+
* Find seriesId by position x and y
|
|
623
|
+
* @param {array} offset position x and y
|
|
624
|
+
*
|
|
625
|
+
* @returns {object} clicked series id
|
|
626
|
+
*/
|
|
627
|
+
getSeriesIdByPosition(offset) {
|
|
628
|
+
const [clickedX, clickedY] = offset;
|
|
629
|
+
const chartRect = this.chartRect;
|
|
630
|
+
const labelOffset = this.labelOffset;
|
|
631
|
+
const aPos = {
|
|
632
|
+
x1: chartRect.x1 + labelOffset.left,
|
|
633
|
+
x2: chartRect.x2 - labelOffset.right,
|
|
634
|
+
y1: chartRect.y1 + labelOffset.top,
|
|
635
|
+
y2: chartRect.y2 - labelOffset.bottom,
|
|
636
|
+
};
|
|
637
|
+
const valueAxes = this.axesY[0];
|
|
638
|
+
const labelAxes = this.axesX[0];
|
|
639
|
+
const valueStartPoint = aPos[valueAxes.units.rectStart];
|
|
640
|
+
const valueEndPoint = aPos[valueAxes.units.rectEnd];
|
|
641
|
+
const labelStartPoint = aPos[labelAxes.units.rectStart];
|
|
642
|
+
const labelEndPoint = aPos[labelAxes.units.rectEnd];
|
|
643
|
+
|
|
644
|
+
const result = { sId: null };
|
|
645
|
+
|
|
646
|
+
if (clickedY > valueEndPoint && clickedY < valueStartPoint
|
|
647
|
+
&& clickedX < labelEndPoint && clickedX > labelStartPoint) {
|
|
648
|
+
let hitSeries;
|
|
649
|
+
let positionList;
|
|
650
|
+
const hitItem = this.findHitItem(offset);
|
|
651
|
+
const hitSeriesList = Object.keys(hitItem.items);
|
|
652
|
+
|
|
653
|
+
switch (this.options.type) {
|
|
654
|
+
case 'line': {
|
|
655
|
+
const orderedSeriesList = this.seriesInfo.charts.line;
|
|
656
|
+
const isStackChart = Object.values(this.seriesList).some(({ stackIndex }) => stackIndex);
|
|
657
|
+
|
|
658
|
+
if (hitSeriesList.length) { // 클릭한 위치에 data 가 존재하는 경우
|
|
659
|
+
if (isStackChart) {
|
|
660
|
+
positionList = orderedSeriesList.filter(sId => hitSeriesList.includes(sId))
|
|
661
|
+
.map(sId => ({ sId, position: hitItem.items[sId]?.data?.yp }));
|
|
662
|
+
hitSeries = positionList.find(({ position }) => clickedY > position)?.sId;
|
|
663
|
+
} else {
|
|
664
|
+
hitSeries = Object.entries(hitItem.items).find(([, { hit }]) => hit)?.[0];
|
|
665
|
+
}
|
|
666
|
+
} else { // 클릭한 위치에 data 가 존재하지 않는 경우
|
|
667
|
+
const visibleSeriesList = orderedSeriesList.filter(sId => this.seriesList[sId].show);
|
|
668
|
+
positionList = visibleSeriesList.map(sId => ({
|
|
669
|
+
sId,
|
|
670
|
+
position: this.seriesList[sId].data?.map(({ xp, yp }) => [xp, yp]),
|
|
671
|
+
}));
|
|
672
|
+
const dataIndex = positionList[0].position?.findIndex(([xp]) => xp >= clickedX);
|
|
673
|
+
const vectorList = positionList.map(({ sId, position }) => ({
|
|
674
|
+
sId,
|
|
675
|
+
vector: { start: position[dataIndex - 1], end: position[dataIndex] },
|
|
676
|
+
}));
|
|
677
|
+
|
|
678
|
+
// canvas 의 클릭 위치값은 제 4 사분면의 위치이므로 clickedY, y1, y2 의 값은 음수를 취한다.
|
|
679
|
+
if (isStackChart) {
|
|
680
|
+
hitSeries = vectorList.find(({ vector }) => {
|
|
681
|
+
const [x1, y1] = vector.start;
|
|
682
|
+
const [x2, y2] = vector.end;
|
|
683
|
+
const v1 = [x2 - x1, y1 - y2];
|
|
684
|
+
const v2 = [x2 - clickedX, clickedY - y2];
|
|
685
|
+
const xp = v1[0] * v2[1] - v1[1] * v2[0];
|
|
686
|
+
|
|
687
|
+
return vector.start.every(v => typeof v === 'number')
|
|
688
|
+
&& vector.end.every(v => typeof v === 'number')
|
|
689
|
+
&& xp > 0;
|
|
690
|
+
})?.sId;
|
|
691
|
+
} else {
|
|
692
|
+
hitSeries = vectorList.find(({ vector }) => {
|
|
693
|
+
const [x1, y1] = vector.start;
|
|
694
|
+
const [x2, y2] = vector.end;
|
|
695
|
+
const a = (y1 - y2) / (x2 - x1);
|
|
696
|
+
const b = -1;
|
|
697
|
+
const c = -y1 - a * x1;
|
|
698
|
+
const distance = Math.abs(a * clickedX - b * clickedY + c)
|
|
699
|
+
/ Math.sqrt(a ** 2 + b ** 2);
|
|
700
|
+
|
|
701
|
+
return distance < 3;
|
|
702
|
+
})?.sId;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
default:
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
result.sId = hitSeries;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
return result;
|
|
715
|
+
},
|
|
676
716
|
/**
|
|
677
717
|
* Find label info by position x and y
|
|
678
718
|
* @param {array} offset position x and y
|
|
@@ -699,8 +739,8 @@ const modules = {
|
|
|
699
739
|
const index = Math.floor(((this.options.horizontal ? y : x) - startPoint) / labelGap);
|
|
700
740
|
labelIndex = scale.labels.length > index ? index : -1;
|
|
701
741
|
} else {
|
|
702
|
-
hitInfo = this.getItemByPosition(offset,
|
|
703
|
-
labelIndex = hitInfo.maxIndex;
|
|
742
|
+
hitInfo = this.getItemByPosition(offset, this.options.selectLabel.useApproximateValue);
|
|
743
|
+
labelIndex = hitInfo.maxIndex ?? -1;
|
|
704
744
|
}
|
|
705
745
|
|
|
706
746
|
return {
|
|
@@ -56,6 +56,8 @@ const modules = {
|
|
|
56
56
|
this.setTooltipLayoutPosition(hitInfo, e);
|
|
57
57
|
if (type === 'scatter') {
|
|
58
58
|
this.drawTooltipForScatter(hitInfo, this.tooltipCtx);
|
|
59
|
+
} else if (type === 'heatMap') {
|
|
60
|
+
this.drawToolTipForHeatMap(hitInfo, this.tooltipCtx);
|
|
59
61
|
} else {
|
|
60
62
|
this.drawTooltip(hitInfo, this.tooltipCtx);
|
|
61
63
|
}
|
|
@@ -112,7 +114,7 @@ const modules = {
|
|
|
112
114
|
this.render(hitInfo);
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
({ label: args.label, value: args.value, sId: args.seriesId } = hitInfo);
|
|
117
|
+
({ label: args.label, value: args.value, sId: args.seriesId, acc: args.acc } = hitInfo);
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
if (typeof this.listeners['dbl-click'] === 'function') {
|
|
@@ -140,16 +142,24 @@ const modules = {
|
|
|
140
142
|
value: args.value,
|
|
141
143
|
sId: args.seriesId,
|
|
142
144
|
maxIndex: args.dataIndex,
|
|
145
|
+
acc: args.acc,
|
|
143
146
|
} = hitInfo);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (this.options.selectLabel.use) {
|
|
147
|
+
} else if (this.options.selectLabel.use) {
|
|
147
148
|
const offset = this.getMousePosition(e);
|
|
148
149
|
const clickedLabelInfo = this.getLabelInfoByPosition(offset);
|
|
149
150
|
const selected = this.selectLabel(clickedLabelInfo.labelIndex);
|
|
150
|
-
this.
|
|
151
|
+
this.renderWithSelected(selected.dataIndex);
|
|
152
|
+
|
|
153
|
+
args.selected = cloneDeep(this.defaultSelectInfo);
|
|
154
|
+
} else if (this.options.selectSeries.use) {
|
|
155
|
+
const offset = this.getMousePosition(e);
|
|
156
|
+
const hitInfo = this.getSeriesIdByPosition(offset);
|
|
157
|
+
if (hitInfo.sId !== null) {
|
|
158
|
+
const selected = this.selectSeries(hitInfo.sId);
|
|
159
|
+
this.renderWithSelected(selected.seriesId);
|
|
160
|
+
}
|
|
151
161
|
|
|
152
|
-
args.selected = cloneDeep(this.
|
|
162
|
+
args.selected = cloneDeep(this.defaultSelectInfo);
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
if (typeof this.listeners.click === 'function') {
|
|
@@ -453,28 +463,51 @@ const modules = {
|
|
|
453
463
|
},
|
|
454
464
|
|
|
455
465
|
/**
|
|
456
|
-
* render after
|
|
466
|
+
* render after selected label or selected series
|
|
457
467
|
* @param indexList {array} '[0, 1 ...]'
|
|
458
468
|
*/
|
|
459
|
-
|
|
460
|
-
this.
|
|
461
|
-
|
|
469
|
+
renderWithSelected(list) {
|
|
470
|
+
if (this.options.selectLabel.use) {
|
|
471
|
+
this.defaultSelectInfo.dataIndex = list;
|
|
472
|
+
} else if (this.options.selectSeries.use) {
|
|
473
|
+
this.defaultSelectInfo.seriesId = list;
|
|
474
|
+
}
|
|
475
|
+
this.initSelectedInfo();
|
|
462
476
|
this.render();
|
|
463
477
|
},
|
|
464
478
|
|
|
465
479
|
/**
|
|
466
|
-
* init
|
|
467
|
-
*
|
|
480
|
+
* init defaultSelectInfo object.
|
|
481
|
+
* - at selectLabel using: set each series data and label text
|
|
482
|
+
* - at selectSeries using: set series state
|
|
468
483
|
*/
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
484
|
+
initSelectedInfo() {
|
|
485
|
+
if (this.options.selectLabel.use) {
|
|
486
|
+
const { limit } = this.options.selectLabel;
|
|
487
|
+
if (!this.defaultSelectInfo) {
|
|
488
|
+
this.defaultSelectInfo = { dataIndex: [] };
|
|
489
|
+
}
|
|
490
|
+
const infoObj = this.defaultSelectInfo;
|
|
473
491
|
infoObj.dataIndex.splice(limit);
|
|
474
492
|
infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
|
|
475
493
|
const dataEntries = Object.entries(this.data.data);
|
|
476
494
|
infoObj.data = infoObj.dataIndex.map(labelIdx => Object.fromEntries(
|
|
477
495
|
dataEntries.map(([sId, data]) => [sId, data[labelIdx]])));
|
|
496
|
+
} else if (this.options.selectSeries.use) {
|
|
497
|
+
if (!this.defaultSelectInfo) {
|
|
498
|
+
this.defaultSelectInfo = { seriesId: [] };
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const selectedList = this.defaultSelectInfo.seriesId;
|
|
502
|
+
Object.values(this.seriesList).forEach((series) => {
|
|
503
|
+
if (!selectedList.length) {
|
|
504
|
+
series.state = 'normal';
|
|
505
|
+
} else if (selectedList.includes(series.sId)) {
|
|
506
|
+
series.state = 'highlight';
|
|
507
|
+
} else {
|
|
508
|
+
series.state = 'downplay';
|
|
509
|
+
}
|
|
510
|
+
});
|
|
478
511
|
}
|
|
479
512
|
},
|
|
480
513
|
|
|
@@ -485,7 +518,7 @@ const modules = {
|
|
|
485
518
|
*/
|
|
486
519
|
selectLabel(labelIndex) {
|
|
487
520
|
const option = this.options?.selectLabel ?? {};
|
|
488
|
-
const before = this.
|
|
521
|
+
const before = this.defaultSelectInfo ?? { dataIndex: [] };
|
|
489
522
|
const after = cloneDeep(before);
|
|
490
523
|
|
|
491
524
|
if (before.dataIndex.includes(labelIndex)) {
|
|
@@ -505,6 +538,28 @@ const modules = {
|
|
|
505
538
|
return after;
|
|
506
539
|
},
|
|
507
540
|
|
|
541
|
+
selectSeries(seriesId) {
|
|
542
|
+
const option = this.options?.selectSeries ?? {};
|
|
543
|
+
const before = this.defaultSelectInfo ?? { seriesId: [] };
|
|
544
|
+
const after = cloneDeep(before);
|
|
545
|
+
|
|
546
|
+
if (before.seriesId.includes(seriesId)) {
|
|
547
|
+
const idx = before.seriesId.indexOf(seriesId);
|
|
548
|
+
after.seriesId.splice(idx, 1);
|
|
549
|
+
} else if (seriesId) {
|
|
550
|
+
after.seriesId.push(seriesId);
|
|
551
|
+
if (option.limit > 0 && option.limit < after.seriesId.length) {
|
|
552
|
+
if (option.useDeselectOverflow) {
|
|
553
|
+
after.seriesId.splice(0, 1);
|
|
554
|
+
} else {
|
|
555
|
+
after.seriesId.pop();
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return after;
|
|
561
|
+
},
|
|
562
|
+
|
|
508
563
|
/**
|
|
509
564
|
* Find items by series within a range
|
|
510
565
|
* @param {object} range object for find series items
|
|
@@ -80,10 +80,12 @@ const modules = {
|
|
|
80
80
|
Object.values(seriesList).forEach((series) => {
|
|
81
81
|
if (!series.isExistGrp && series.showLegend) {
|
|
82
82
|
const { colorAxis, valueOpt } = series;
|
|
83
|
+
const { max, interval, existError } = valueOpt;
|
|
83
84
|
colorAxis.forEach((colorItem, index) => {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
85
|
+
const minValue = interval * index;
|
|
86
|
+
const maxValue = index === colorAxis.length - 1
|
|
87
|
+
? max : minValue + interval - 1;
|
|
88
|
+
const name = existError && index === colorAxis.length - 1
|
|
87
89
|
? 'error' : `${minValue} - ${maxValue}`;
|
|
88
90
|
this.addLegend({
|
|
89
91
|
cId: colorItem.id,
|
|
@@ -189,9 +191,13 @@ const modules = {
|
|
|
189
191
|
}
|
|
190
192
|
const nameDOM = targetDOM.getElementsByClassName('ev-chart-legend-name')[0];
|
|
191
193
|
const targetId = nameDOM.series.sId;
|
|
194
|
+
const selectSeriesOption = this.options.selectSeries;
|
|
195
|
+
const selectedList = this.defaultSelectInfo?.seriesId ?? [];
|
|
192
196
|
|
|
193
197
|
Object.values(this.seriesList).forEach((series) => {
|
|
194
|
-
series.state = series.sId === targetId
|
|
198
|
+
series.state = series.sId === targetId
|
|
199
|
+
|| (selectSeriesOption.use && selectedList.includes(targetId))
|
|
200
|
+
? 'highlight' : 'downplay';
|
|
195
201
|
});
|
|
196
202
|
|
|
197
203
|
this.update({
|
|
@@ -207,8 +213,15 @@ const modules = {
|
|
|
207
213
|
* @returns {undefined}
|
|
208
214
|
*/
|
|
209
215
|
this.onLegendBoxLeave = () => {
|
|
216
|
+
const selectSeriesOption = this.options.selectSeries;
|
|
217
|
+
const selectedList = this.defaultSelectInfo?.seriesId ?? [];
|
|
210
218
|
Object.values(this.seriesList).forEach((series) => {
|
|
211
|
-
|
|
219
|
+
if (selectSeriesOption.use && selectedList.length) {
|
|
220
|
+
series.state = selectedList.includes(series.sId)
|
|
221
|
+
? 'highlight' : 'downplay';
|
|
222
|
+
} else {
|
|
223
|
+
series.state = 'normal';
|
|
224
|
+
}
|
|
212
225
|
});
|
|
213
226
|
|
|
214
227
|
this.update({
|