evui 3.3.13 → 3.3.16
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 +1083 -449
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +1083 -449
- 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 +23 -3
- package/src/components/chart/chart.core.js +11 -10
- package/src/components/chart/element/element.bar.js +8 -1
- package/src/components/chart/element/element.heatmap.js +108 -10
- package/src/components/chart/element/element.line.js +35 -40
- package/src/components/chart/element/element.pie.js +17 -17
- package/src/components/chart/element/element.tip.js +1 -1
- package/src/components/chart/model/model.store.js +105 -2
- package/src/components/chart/plugins/plugins.interaction.js +107 -24
- package/src/components/chart/plugins/plugins.legend.js +28 -9
- package/src/components/chart/plugins/plugins.tooltip.js +1 -3
- package/src/components/chart/scale/scale.js +13 -3
- package/src/components/chart/scale/scale.step.js +25 -10
- package/src/components/chart/uses.js +13 -1
- package/src/components/grid/Grid.vue +7 -4
- package/src/components/grid/grid.summary.vue +36 -6
- package/src/components/grid/uses.js +4 -1
- package/src/components/treeGrid/TreeGrid.vue +5 -1
- package/src/components/treeGrid/uses.js +4 -1
|
@@ -144,15 +144,22 @@ const modules = {
|
|
|
144
144
|
maxIndex: args.dataIndex,
|
|
145
145
|
acc: args.acc,
|
|
146
146
|
} = hitInfo);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (this.options.selectLabel.use) {
|
|
147
|
+
} else if (this.options.selectLabel.use) {
|
|
150
148
|
const offset = this.getMousePosition(e);
|
|
151
149
|
const clickedLabelInfo = this.getLabelInfoByPosition(offset);
|
|
152
150
|
const selected = this.selectLabel(clickedLabelInfo.labelIndex);
|
|
153
|
-
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
|
+
}
|
|
154
161
|
|
|
155
|
-
args.selected = cloneDeep(this.
|
|
162
|
+
args.selected = cloneDeep(this.defaultSelectInfo);
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
if (typeof this.listeners.click === 'function') {
|
|
@@ -266,12 +273,21 @@ const modules = {
|
|
|
266
273
|
yep = aOffsetY;
|
|
267
274
|
}
|
|
268
275
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
276
|
+
if (type === 'heatMap') {
|
|
277
|
+
const rangeInfo = { xcp, xep, ycp, yep, range: aRange };
|
|
278
|
+
const { xsp, ysp, width, height } = this.getDragInfoForHeatMap(rangeInfo);
|
|
279
|
+
dragInfo.xsp = xsp;
|
|
280
|
+
dragInfo.ysp = ysp;
|
|
281
|
+
dragInfo.width = width;
|
|
282
|
+
dragInfo.height = height;
|
|
283
|
+
} else {
|
|
284
|
+
dragInfo.xsp = Math.min(xcp, xep);
|
|
285
|
+
dragInfo.ysp = type === 'scatter' ? Math.min(ycp, yep) : aRange.y1;
|
|
286
|
+
dragInfo.width = Math.ceil(Math.abs(xep - xcp));
|
|
287
|
+
dragInfo.height = type === 'scatter'
|
|
273
288
|
? Math.ceil(Math.abs(yep - ycp))
|
|
274
289
|
: aRange.y2 - aRange.y1;
|
|
290
|
+
}
|
|
275
291
|
|
|
276
292
|
this.overlayClear();
|
|
277
293
|
this.drawSelectionArea(dragInfo);
|
|
@@ -289,7 +305,9 @@ const modules = {
|
|
|
289
305
|
const args = {
|
|
290
306
|
e,
|
|
291
307
|
data: this.findSelectedItems(dragInfo),
|
|
292
|
-
range:
|
|
308
|
+
range: type === 'heatMap'
|
|
309
|
+
? this.getSelectionRangeForHeatMap(dragInfo)
|
|
310
|
+
: this.getSelectionRage(dragInfo),
|
|
293
311
|
};
|
|
294
312
|
|
|
295
313
|
this.dragInfoBackup = defaultsDeep({}, dragInfo);
|
|
@@ -456,32 +474,51 @@ const modules = {
|
|
|
456
474
|
},
|
|
457
475
|
|
|
458
476
|
/**
|
|
459
|
-
* render after
|
|
477
|
+
* render after selected label or selected series
|
|
460
478
|
* @param indexList {array} '[0, 1 ...]'
|
|
461
479
|
*/
|
|
462
|
-
|
|
463
|
-
this.
|
|
464
|
-
|
|
480
|
+
renderWithSelected(list) {
|
|
481
|
+
if (this.options.selectLabel.use) {
|
|
482
|
+
this.defaultSelectInfo.dataIndex = list;
|
|
483
|
+
} else if (this.options.selectSeries.use) {
|
|
484
|
+
this.defaultSelectInfo.seriesId = list;
|
|
485
|
+
}
|
|
486
|
+
this.initSelectedInfo();
|
|
465
487
|
this.render();
|
|
466
488
|
},
|
|
467
489
|
|
|
468
490
|
/**
|
|
469
|
-
* init
|
|
470
|
-
*
|
|
491
|
+
* init defaultSelectInfo object.
|
|
492
|
+
* - at selectLabel using: set each series data and label text
|
|
493
|
+
* - at selectSeries using: set series state
|
|
471
494
|
*/
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
this.defaultSelectLabelInfo = { dataIndex: [] };
|
|
495
|
+
initSelectedInfo() {
|
|
496
|
+
if (this.options.selectLabel.use) {
|
|
497
|
+
const { limit } = this.options.selectLabel;
|
|
498
|
+
if (!this.defaultSelectInfo) {
|
|
499
|
+
this.defaultSelectInfo = { dataIndex: [] };
|
|
478
500
|
}
|
|
479
|
-
const infoObj = this.
|
|
501
|
+
const infoObj = this.defaultSelectInfo;
|
|
480
502
|
infoObj.dataIndex.splice(limit);
|
|
481
503
|
infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
|
|
482
504
|
const dataEntries = Object.entries(this.data.data);
|
|
483
505
|
infoObj.data = infoObj.dataIndex.map(labelIdx => Object.fromEntries(
|
|
484
506
|
dataEntries.map(([sId, data]) => [sId, data[labelIdx]])));
|
|
507
|
+
} else if (this.options.selectSeries.use) {
|
|
508
|
+
if (!this.defaultSelectInfo) {
|
|
509
|
+
this.defaultSelectInfo = { seriesId: [] };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const selectedList = this.defaultSelectInfo.seriesId;
|
|
513
|
+
Object.values(this.seriesList).forEach((series) => {
|
|
514
|
+
if (!selectedList.length) {
|
|
515
|
+
series.state = 'normal';
|
|
516
|
+
} else if (selectedList.includes(series.sId)) {
|
|
517
|
+
series.state = 'highlight';
|
|
518
|
+
} else {
|
|
519
|
+
series.state = 'downplay';
|
|
520
|
+
}
|
|
521
|
+
});
|
|
485
522
|
}
|
|
486
523
|
},
|
|
487
524
|
|
|
@@ -492,7 +529,7 @@ const modules = {
|
|
|
492
529
|
*/
|
|
493
530
|
selectLabel(labelIndex) {
|
|
494
531
|
const option = this.options?.selectLabel ?? {};
|
|
495
|
-
const before = this.
|
|
532
|
+
const before = this.defaultSelectInfo ?? { dataIndex: [] };
|
|
496
533
|
const after = cloneDeep(before);
|
|
497
534
|
|
|
498
535
|
if (before.dataIndex.includes(labelIndex)) {
|
|
@@ -512,6 +549,28 @@ const modules = {
|
|
|
512
549
|
return after;
|
|
513
550
|
},
|
|
514
551
|
|
|
552
|
+
selectSeries(seriesId) {
|
|
553
|
+
const option = this.options?.selectSeries ?? {};
|
|
554
|
+
const before = this.defaultSelectInfo ?? { seriesId: [] };
|
|
555
|
+
const after = cloneDeep(before);
|
|
556
|
+
|
|
557
|
+
if (before.seriesId.includes(seriesId)) {
|
|
558
|
+
const idx = before.seriesId.indexOf(seriesId);
|
|
559
|
+
after.seriesId.splice(idx, 1);
|
|
560
|
+
} else if (seriesId) {
|
|
561
|
+
after.seriesId.push(seriesId);
|
|
562
|
+
if (option.limit > 0 && option.limit < after.seriesId.length) {
|
|
563
|
+
if (option.useDeselectOverflow) {
|
|
564
|
+
after.seriesId.splice(0, 1);
|
|
565
|
+
} else {
|
|
566
|
+
after.seriesId.pop();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return after;
|
|
572
|
+
},
|
|
573
|
+
|
|
515
574
|
/**
|
|
516
575
|
* Find items by series within a range
|
|
517
576
|
* @param {object} range object for find series items
|
|
@@ -591,6 +650,30 @@ const modules = {
|
|
|
591
650
|
|
|
592
651
|
return targetValue / total;
|
|
593
652
|
},
|
|
653
|
+
|
|
654
|
+
getDragInfoForHeatMap(range) {
|
|
655
|
+
const sId = Object.keys(this.seriesList)[0];
|
|
656
|
+
return this.seriesList[sId].findBlockRange(range);
|
|
657
|
+
},
|
|
658
|
+
|
|
659
|
+
getSelectionRangeForHeatMap(range) {
|
|
660
|
+
const dataRangeX = this.axesSteps.x.length ? this.axesSteps.x[0] : null;
|
|
661
|
+
const dataRangeY = this.axesSteps.y.length ? this.axesSteps.y[0] : null;
|
|
662
|
+
|
|
663
|
+
if (!dataRangeX || !dataRangeY) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const sId = Object.keys(this.seriesList)[0];
|
|
668
|
+
const { xMin, xMax, yMin, yMax } = this.seriesList[sId].findSelectionRange(range);
|
|
669
|
+
|
|
670
|
+
return {
|
|
671
|
+
xMin: xMin ?? dataRangeX.graphMin,
|
|
672
|
+
xMax: xMax ?? dataRangeX.graphMax,
|
|
673
|
+
yMin: yMin ?? dataRangeY.graphMin,
|
|
674
|
+
yMax: yMax ?? dataRangeY.graphMax,
|
|
675
|
+
};
|
|
676
|
+
},
|
|
594
677
|
};
|
|
595
678
|
|
|
596
679
|
export default modules;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import Util from '@/components/chart/helpers/helpers.util';
|
|
2
|
+
|
|
1
3
|
const modules = {
|
|
2
4
|
/**
|
|
3
5
|
* Create legend DOM
|
|
@@ -80,13 +82,14 @@ const modules = {
|
|
|
80
82
|
Object.values(seriesList).forEach((series) => {
|
|
81
83
|
if (!series.isExistGrp && series.showLegend) {
|
|
82
84
|
const { colorAxis, valueOpt } = series;
|
|
83
|
-
const { max, interval, existError } = valueOpt;
|
|
85
|
+
const { min, max, interval, existError } = valueOpt;
|
|
86
|
+
const endIndex = colorAxis.length - 1;
|
|
84
87
|
colorAxis.forEach((colorItem, index) => {
|
|
85
|
-
const minValue = interval * index;
|
|
86
|
-
const maxValue = index ===
|
|
87
|
-
? max : minValue + interval
|
|
88
|
-
const name = existError && index ===
|
|
89
|
-
|
|
88
|
+
const minValue = min + (interval * index);
|
|
89
|
+
const maxValue = index === endIndex
|
|
90
|
+
? max : minValue + interval;
|
|
91
|
+
const name = existError && index === endIndex ? 'error' : `${minValue} - ${maxValue}`;
|
|
92
|
+
|
|
90
93
|
this.addLegend({
|
|
91
94
|
cId: colorItem.id,
|
|
92
95
|
color: colorItem.value,
|
|
@@ -191,15 +194,24 @@ const modules = {
|
|
|
191
194
|
}
|
|
192
195
|
const nameDOM = targetDOM.getElementsByClassName('ev-chart-legend-name')[0];
|
|
193
196
|
const targetId = nameDOM.series.sId;
|
|
197
|
+
const selectSeriesOption = this.options.selectSeries;
|
|
198
|
+
const selectedList = this.defaultSelectInfo?.seriesId ?? [];
|
|
194
199
|
|
|
195
200
|
Object.values(this.seriesList).forEach((series) => {
|
|
196
|
-
series.state = series.sId === targetId
|
|
201
|
+
series.state = series.sId === targetId
|
|
202
|
+
|| (selectSeriesOption.use && selectedList.includes(targetId))
|
|
203
|
+
? 'highlight' : 'downplay';
|
|
197
204
|
});
|
|
198
205
|
|
|
206
|
+
let hitInfo = null;
|
|
207
|
+
if (Util.isPieType(this.options.type)) {
|
|
208
|
+
hitInfo = { sId: targetId, type: this.options.type };
|
|
209
|
+
}
|
|
210
|
+
|
|
199
211
|
this.update({
|
|
200
212
|
updateSeries: false,
|
|
201
213
|
updateSelTip: { update: false, keepDomain: false },
|
|
202
|
-
hitInfo
|
|
214
|
+
hitInfo,
|
|
203
215
|
});
|
|
204
216
|
};
|
|
205
217
|
|
|
@@ -209,8 +221,15 @@ const modules = {
|
|
|
209
221
|
* @returns {undefined}
|
|
210
222
|
*/
|
|
211
223
|
this.onLegendBoxLeave = () => {
|
|
224
|
+
const selectSeriesOption = this.options.selectSeries;
|
|
225
|
+
const selectedList = this.defaultSelectInfo?.seriesId ?? [];
|
|
212
226
|
Object.values(this.seriesList).forEach((series) => {
|
|
213
|
-
|
|
227
|
+
if (selectSeriesOption.use && selectedList.length) {
|
|
228
|
+
series.state = selectedList.includes(series.sId)
|
|
229
|
+
? 'highlight' : 'downplay';
|
|
230
|
+
} else {
|
|
231
|
+
series.state = 'normal';
|
|
232
|
+
}
|
|
214
233
|
});
|
|
215
234
|
|
|
216
235
|
this.update({
|
|
@@ -408,7 +408,7 @@ const modules = {
|
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
// 3. Draw value
|
|
411
|
-
let formattedTxt;
|
|
411
|
+
let formattedTxt = itemValue;
|
|
412
412
|
if (opt.formatter) {
|
|
413
413
|
formattedTxt = opt.formatter({
|
|
414
414
|
x: xValue,
|
|
@@ -419,8 +419,6 @@ const modules = {
|
|
|
419
419
|
|
|
420
420
|
if ((!opt.formatter || typeof formattedTxt !== 'string') && itemValue !== 'error') {
|
|
421
421
|
formattedTxt = numberWithComma(itemValue);
|
|
422
|
-
} else {
|
|
423
|
-
formattedTxt = itemValue;
|
|
424
422
|
}
|
|
425
423
|
|
|
426
424
|
ctx.textAlign = 'right';
|
|
@@ -164,7 +164,7 @@ class Scale {
|
|
|
164
164
|
*
|
|
165
165
|
* @returns {undefined}
|
|
166
166
|
*/
|
|
167
|
-
draw(chartRect, labelOffset, stepInfo, hitInfo) {
|
|
167
|
+
draw(chartRect, labelOffset, stepInfo, hitInfo, selectLabelInfo) {
|
|
168
168
|
const ctx = this.ctx;
|
|
169
169
|
const options = this.options;
|
|
170
170
|
const aPos = {
|
|
@@ -239,6 +239,13 @@ class Scale {
|
|
|
239
239
|
linePosition = labelCenter + aliasPixel;
|
|
240
240
|
labelText = this.getLabelFormat(Math.min(axisMax, ticks[ix]));
|
|
241
241
|
|
|
242
|
+
const isBlurredLabel = this.options?.selectLabel?.use
|
|
243
|
+
&& this.options?.selectLabel?.useLabelOpacity
|
|
244
|
+
&& (this.options.horizontal === (this.type === 'y'))
|
|
245
|
+
&& selectLabelInfo?.dataIndex?.length
|
|
246
|
+
&& !selectLabelInfo?.label
|
|
247
|
+
.map(t => this.getLabelFormat(Math.min(axisMax, t))).includes(labelText);
|
|
248
|
+
|
|
242
249
|
const labelColor = this.labelStyle.color;
|
|
243
250
|
let defaultOpacity = 1;
|
|
244
251
|
|
|
@@ -246,14 +253,17 @@ class Scale {
|
|
|
246
253
|
defaultOpacity = Util.getOpacity(labelColor);
|
|
247
254
|
}
|
|
248
255
|
|
|
249
|
-
ctx.fillStyle = Util.colorStringToRgba(labelColor, defaultOpacity);
|
|
256
|
+
ctx.fillStyle = Util.colorStringToRgba(labelColor, isBlurredLabel ? 0.1 : defaultOpacity);
|
|
250
257
|
|
|
251
258
|
let labelPoint;
|
|
252
259
|
|
|
253
260
|
if (this.type === 'x') {
|
|
254
261
|
labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
|
|
255
262
|
ctx.fillText(labelText, labelCenter, labelPoint);
|
|
256
|
-
if (
|
|
263
|
+
if (!isBlurredLabel
|
|
264
|
+
&& options?.selectItem?.showLabelTip
|
|
265
|
+
&& hitInfo?.label
|
|
266
|
+
&& !this.options?.horizontal) {
|
|
257
267
|
const selectedLabel = this.getLabelFormat(
|
|
258
268
|
Math.min(axisMax, hitInfo.label + (0 * stepValue)),
|
|
259
269
|
);
|
|
@@ -7,7 +7,6 @@ class StepScale extends Scale {
|
|
|
7
7
|
constructor(type, opt, ctx, labels, options) {
|
|
8
8
|
super(type, opt, ctx, options);
|
|
9
9
|
this.labels = labels;
|
|
10
|
-
this.rangeMode = opt.rangeMode;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -18,7 +17,8 @@ class StepScale extends Scale {
|
|
|
18
17
|
* @returns {object} min/max value and label
|
|
19
18
|
*/
|
|
20
19
|
calculateScaleRange(minMax, chartRect) {
|
|
21
|
-
const stepMinMax =
|
|
20
|
+
const stepMinMax = this.rangeMode
|
|
21
|
+
? minMax : Util.getStringMinMax(this.labels);
|
|
22
22
|
const maxValue = stepMinMax.max;
|
|
23
23
|
const minValue = stepMinMax.min;
|
|
24
24
|
const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
|
|
@@ -42,9 +42,20 @@ class StepScale extends Scale {
|
|
|
42
42
|
* @returns {object} steps, interval, min/max graph value
|
|
43
43
|
*/
|
|
44
44
|
calculateSteps(range) {
|
|
45
|
+
let numberOfSteps = this.labels.length;
|
|
46
|
+
let interval = 1;
|
|
47
|
+
|
|
48
|
+
if (this.rangeMode) {
|
|
49
|
+
const { maxSteps } = range;
|
|
50
|
+
|
|
51
|
+
while (numberOfSteps > maxSteps * 2) {
|
|
52
|
+
interval *= 2;
|
|
53
|
+
numberOfSteps = Math.round(numberOfSteps / interval);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
45
56
|
return {
|
|
46
|
-
steps:
|
|
47
|
-
interval
|
|
57
|
+
steps: numberOfSteps,
|
|
58
|
+
interval,
|
|
48
59
|
graphMin: range.minValue,
|
|
49
60
|
graphMax: range.maxValue,
|
|
50
61
|
};
|
|
@@ -68,7 +79,9 @@ class StepScale extends Scale {
|
|
|
68
79
|
y2: chartRect.y2 - labelOffset.bottom,
|
|
69
80
|
};
|
|
70
81
|
|
|
82
|
+
const oriSteps = this.labels.length;
|
|
71
83
|
const steps = stepInfo.steps;
|
|
84
|
+
const count = stepInfo.interval;
|
|
72
85
|
|
|
73
86
|
const startPoint = aPos[this.units.rectStart];
|
|
74
87
|
const endPoint = aPos[this.units.rectEnd];
|
|
@@ -116,8 +129,10 @@ class StepScale extends Scale {
|
|
|
116
129
|
|
|
117
130
|
let labelText;
|
|
118
131
|
let labelPoint;
|
|
132
|
+
let index;
|
|
119
133
|
|
|
120
|
-
|
|
134
|
+
for (index = 0; index < oriSteps; index += count) {
|
|
135
|
+
const item = this.labels[index];
|
|
121
136
|
labelCenter = Math.round(startPoint + (labelGap * index));
|
|
122
137
|
linePosition = labelCenter + aliasPixel;
|
|
123
138
|
labelText = this.getLabelFormat(item, maxWidth);
|
|
@@ -143,9 +158,9 @@ class StepScale extends Scale {
|
|
|
143
158
|
ctx.fillText(labelText, xPoint, labelPoint);
|
|
144
159
|
|
|
145
160
|
if (!isBlurredLabel
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
161
|
+
&& this.options?.selectItem?.showLabelTip
|
|
162
|
+
&& hitInfo?.label
|
|
163
|
+
&& !this.options?.horizontal) {
|
|
149
164
|
const selectedLabel = hitInfo.label;
|
|
150
165
|
if (selectedLabel === labelText) {
|
|
151
166
|
const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
|
|
@@ -179,9 +194,9 @@ class StepScale extends Scale {
|
|
|
179
194
|
}
|
|
180
195
|
}
|
|
181
196
|
ctx.stroke();
|
|
182
|
-
}
|
|
197
|
+
}
|
|
183
198
|
|
|
184
|
-
if (this.rangeMode) {
|
|
199
|
+
if (this.rangeMode && (index === this.labels.length)) {
|
|
185
200
|
let labelLastText = +labels[labels.length - 1] + (+labels[1] - +labels[0]);
|
|
186
201
|
if (isNaN(labelLastText)) {
|
|
187
202
|
labelLastText = 'Max';
|
|
@@ -43,6 +43,7 @@ const DEFAULT_OPTIONS = {
|
|
|
43
43
|
width: '100%',
|
|
44
44
|
height: '100%',
|
|
45
45
|
thickness: 1,
|
|
46
|
+
cPadRatio: 0,
|
|
46
47
|
borderRadius: 0,
|
|
47
48
|
combo: false,
|
|
48
49
|
tooltip: {
|
|
@@ -94,6 +95,11 @@ const DEFAULT_OPTIONS = {
|
|
|
94
95
|
useApproximateValue: false,
|
|
95
96
|
tipBackground: '#000000',
|
|
96
97
|
},
|
|
98
|
+
selectSeries: {
|
|
99
|
+
use: false,
|
|
100
|
+
limit: 1,
|
|
101
|
+
useDeselectOverflow: false,
|
|
102
|
+
},
|
|
97
103
|
dragSelection: {
|
|
98
104
|
use: false,
|
|
99
105
|
keepDisplay: true,
|
|
@@ -108,6 +114,7 @@ const DEFAULT_OPTIONS = {
|
|
|
108
114
|
show: false,
|
|
109
115
|
color: '#FFFFFF',
|
|
110
116
|
lineWidth: 1,
|
|
117
|
+
opacity: 1,
|
|
111
118
|
},
|
|
112
119
|
error: '#FF0000',
|
|
113
120
|
},
|
|
@@ -145,6 +152,7 @@ export const useModel = () => {
|
|
|
145
152
|
|
|
146
153
|
const selectItemInfo = cloneDeep(props.selectedItem);
|
|
147
154
|
const selectLabelInfo = cloneDeep(props.selectedLabel);
|
|
155
|
+
const selectSeriesInfo = cloneDeep(props.selectedSeries);
|
|
148
156
|
|
|
149
157
|
const eventListeners = {
|
|
150
158
|
click: async (e) => {
|
|
@@ -152,9 +160,12 @@ export const useModel = () => {
|
|
|
152
160
|
if (e.label) {
|
|
153
161
|
emit('update:selectedItem', { seriesID: e.seriesId, dataIndex: e.dataIndex });
|
|
154
162
|
}
|
|
155
|
-
if (e.selected) {
|
|
163
|
+
if (e.selected?.dataIndex) {
|
|
156
164
|
emit('update:selectedLabel', { dataIndex: e.selected.dataIndex });
|
|
157
165
|
}
|
|
166
|
+
if (e.selected?.seriesId) {
|
|
167
|
+
emit('update:selectedSeries', { seriesId: e.selected.seriesId });
|
|
168
|
+
}
|
|
158
169
|
emit('click', e);
|
|
159
170
|
},
|
|
160
171
|
'dbl-click': async (e) => {
|
|
@@ -171,6 +182,7 @@ export const useModel = () => {
|
|
|
171
182
|
eventListeners,
|
|
172
183
|
selectItemInfo,
|
|
173
184
|
selectLabelInfo,
|
|
185
|
+
selectSeriesInfo,
|
|
174
186
|
getNormalizedData,
|
|
175
187
|
getNormalizedOptions,
|
|
176
188
|
};
|
|
@@ -198,12 +198,12 @@
|
|
|
198
198
|
}"
|
|
199
199
|
>
|
|
200
200
|
<!-- Cell Renderer -->
|
|
201
|
-
<
|
|
201
|
+
<div v-if="!!$slots[column.field]">
|
|
202
202
|
<slot
|
|
203
203
|
:name="column.field"
|
|
204
204
|
:item="{ row, column }"
|
|
205
205
|
/>
|
|
206
|
-
</
|
|
206
|
+
</div>
|
|
207
207
|
<!-- Cell Value -->
|
|
208
208
|
<template v-else>
|
|
209
209
|
<div :title="getConvertValue(column, row[2][column.index])">
|
|
@@ -257,6 +257,7 @@
|
|
|
257
257
|
minWidth,
|
|
258
258
|
rowHeight,
|
|
259
259
|
}"
|
|
260
|
+
:scroll-left="summaryScroll"
|
|
260
261
|
/>
|
|
261
262
|
<!-- Pagination -->
|
|
262
263
|
<grid-pagination
|
|
@@ -271,7 +272,7 @@
|
|
|
271
272
|
</template>
|
|
272
273
|
|
|
273
274
|
<script>
|
|
274
|
-
import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick } from 'vue';
|
|
275
|
+
import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick, ref } from 'vue';
|
|
275
276
|
import Toolbar from './grid.toolbar';
|
|
276
277
|
import FilterWindow from './grid.filter.window';
|
|
277
278
|
import GridPagination from './grid.pagination';
|
|
@@ -474,7 +475,7 @@ export default {
|
|
|
474
475
|
elementInfo,
|
|
475
476
|
clearCheckInfo,
|
|
476
477
|
});
|
|
477
|
-
|
|
478
|
+
const summaryScroll = ref(0);
|
|
478
479
|
const {
|
|
479
480
|
updateVScroll,
|
|
480
481
|
updateHScroll,
|
|
@@ -485,6 +486,7 @@ export default {
|
|
|
485
486
|
elementInfo,
|
|
486
487
|
resizeInfo,
|
|
487
488
|
pageInfo,
|
|
489
|
+
summaryScroll,
|
|
488
490
|
getPagingData,
|
|
489
491
|
updatePagingInfo,
|
|
490
492
|
});
|
|
@@ -751,6 +753,7 @@ export default {
|
|
|
751
753
|
},
|
|
752
754
|
);
|
|
753
755
|
return {
|
|
756
|
+
summaryScroll,
|
|
754
757
|
showHeader,
|
|
755
758
|
stripeStyle,
|
|
756
759
|
borderStyle,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
+
ref="summaryRef"
|
|
3
4
|
:class="{
|
|
4
5
|
'grid-summary': true,
|
|
5
6
|
'non-border': styleInfo.borderStyle === 'none',
|
|
@@ -44,12 +45,18 @@
|
|
|
44
45
|
height: `${styleInfo.rowHeight}px`,
|
|
45
46
|
}"
|
|
46
47
|
>
|
|
47
|
-
<
|
|
48
|
+
<div
|
|
49
|
+
v-if="column.summaryRenderer"
|
|
50
|
+
:title="getSummaryRenderer(column)"
|
|
51
|
+
>
|
|
48
52
|
{{ getSummaryRenderer(column) }}
|
|
49
|
-
</
|
|
50
|
-
<
|
|
53
|
+
</div>
|
|
54
|
+
<div
|
|
55
|
+
v-else
|
|
56
|
+
:title="getSummaryValue(column, column.summaryType)"
|
|
57
|
+
>
|
|
51
58
|
{{ getSummaryValue(column, column.summaryType)}}
|
|
52
|
-
</
|
|
59
|
+
</div>
|
|
53
60
|
</span>
|
|
54
61
|
<span
|
|
55
62
|
v-else
|
|
@@ -62,7 +69,7 @@
|
|
|
62
69
|
</template>
|
|
63
70
|
|
|
64
71
|
<script>
|
|
65
|
-
import { computed } from 'vue';
|
|
72
|
+
import { computed, watch, ref, nextTick } from 'vue';
|
|
66
73
|
import { numberWithComma } from '@/common/utils';
|
|
67
74
|
|
|
68
75
|
export default {
|
|
@@ -88,8 +95,13 @@ export default {
|
|
|
88
95
|
type: Boolean,
|
|
89
96
|
default: false,
|
|
90
97
|
},
|
|
98
|
+
scrollLeft: {
|
|
99
|
+
type: Number,
|
|
100
|
+
default: 0,
|
|
101
|
+
},
|
|
91
102
|
},
|
|
92
103
|
setup(props) {
|
|
104
|
+
const summaryRef = ref();
|
|
93
105
|
const ROW_DATA_INDEX = 2;
|
|
94
106
|
const stores = computed(() => props.stores);
|
|
95
107
|
const columns = computed(() => props.orderedColumns);
|
|
@@ -102,7 +114,8 @@ export default {
|
|
|
102
114
|
convertValue = numberWithComma(value);
|
|
103
115
|
convertValue = convertValue === false ? value : convertValue;
|
|
104
116
|
} else if (column.type === 'float') {
|
|
105
|
-
|
|
117
|
+
const floatValue = convertValue.toFixed(column.decimal ?? 3);
|
|
118
|
+
convertValue = floatValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
106
119
|
}
|
|
107
120
|
|
|
108
121
|
return convertValue;
|
|
@@ -175,10 +188,19 @@ export default {
|
|
|
175
188
|
});
|
|
176
189
|
return result;
|
|
177
190
|
};
|
|
191
|
+
watch(
|
|
192
|
+
() => props.scrollLeft,
|
|
193
|
+
(val) => {
|
|
194
|
+
nextTick(() => {
|
|
195
|
+
summaryRef.value.scrollLeft = val;
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
);
|
|
178
199
|
return {
|
|
179
200
|
columns,
|
|
180
201
|
styleInfo,
|
|
181
202
|
showCheckbox,
|
|
203
|
+
summaryRef,
|
|
182
204
|
getSummaryValue,
|
|
183
205
|
getSummaryRenderer,
|
|
184
206
|
};
|
|
@@ -189,6 +211,9 @@ export default {
|
|
|
189
211
|
<style lang="scss" scoped>
|
|
190
212
|
@import 'style/grid.scss';
|
|
191
213
|
.grid-summary {
|
|
214
|
+
width: 100%;
|
|
215
|
+
overflow: hidden;
|
|
216
|
+
|
|
192
217
|
@include evThemify() {
|
|
193
218
|
border-bottom: 1px solid evThemed('disabled');
|
|
194
219
|
background-color: evThemed('background-lighten');
|
|
@@ -201,6 +226,11 @@ export default {
|
|
|
201
226
|
overflow: hidden;
|
|
202
227
|
text-overflow: ellipsis;
|
|
203
228
|
font-size: 14px;
|
|
229
|
+
> div {
|
|
230
|
+
white-space: nowrap;
|
|
231
|
+
overflow: hidden;
|
|
232
|
+
text-overflow: ellipsis;
|
|
233
|
+
}
|
|
204
234
|
|
|
205
235
|
@include evThemify() {
|
|
206
236
|
color: evThemed('font-color-base');
|
|
@@ -44,7 +44,8 @@ export const commonFunctions = () => {
|
|
|
44
44
|
convertValue = numberWithComma(value);
|
|
45
45
|
convertValue = convertValue === false ? value : convertValue;
|
|
46
46
|
} else if (column.type === 'float') {
|
|
47
|
-
|
|
47
|
+
const floatValue = convertValue.toFixed(column.decimal ?? 3);
|
|
48
|
+
convertValue = floatValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
return convertValue;
|
|
@@ -75,6 +76,7 @@ export const scrollEvent = (params) => {
|
|
|
75
76
|
elementInfo,
|
|
76
77
|
resizeInfo,
|
|
77
78
|
pageInfo,
|
|
79
|
+
summaryScroll,
|
|
78
80
|
getPagingData,
|
|
79
81
|
updatePagingInfo,
|
|
80
82
|
} = params;
|
|
@@ -122,6 +124,7 @@ export const scrollEvent = (params) => {
|
|
|
122
124
|
const bodyEl = elementInfo.body;
|
|
123
125
|
|
|
124
126
|
headerEl.scrollLeft = bodyEl.scrollLeft;
|
|
127
|
+
summaryScroll.value = bodyEl.scrollLeft;
|
|
125
128
|
};
|
|
126
129
|
/**
|
|
127
130
|
* scroll 이벤트를 처리한다.
|