evui 3.3.39 → 3.3.41

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.
Files changed (31) hide show
  1. package/dist/evui.common.js +2477 -197
  2. package/dist/evui.common.js.map +1 -1
  3. package/dist/evui.umd.js +2477 -197
  4. package/dist/evui.umd.js.map +1 -1
  5. package/dist/evui.umd.min.js +1 -1
  6. package/dist/evui.umd.min.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/components/chart/Chart.vue +95 -5
  9. package/src/components/chart/ChartToolbar.vue +52 -0
  10. package/src/components/chart/chart.core.js +71 -27
  11. package/src/components/chart/chartZoom.core.js +479 -0
  12. package/src/components/chart/element/element.line.js +2 -1
  13. package/src/components/chart/element/element.scatter.js +8 -2
  14. package/src/components/chart/element/element.tip.js +41 -33
  15. package/src/components/chart/model/model.store.js +34 -5
  16. package/src/components/chart/plugins/plugins.interaction.js +28 -4
  17. package/src/components/chart/plugins/plugins.legend.js +11 -1
  18. package/src/components/chart/plugins/plugins.title.js +13 -8
  19. package/src/components/chart/scale/scale.js +8 -3
  20. package/src/components/chart/style/chart.scss +14 -0
  21. package/src/components/chart/uses.js +329 -6
  22. package/src/components/chartBrush/ChartBrush.vue +298 -0
  23. package/src/components/chartBrush/chartBrush.core.js +458 -0
  24. package/src/components/chartBrush/index.js +9 -0
  25. package/src/components/chartBrush/uses.js +22 -0
  26. package/src/components/chartGroup/ChartGroup.vue +125 -0
  27. package/src/components/chartGroup/index.js +9 -0
  28. package/src/components/chartGroup/style/chartGroup.scss +5 -0
  29. package/src/components/chartGroup/uses.js +48 -0
  30. package/src/components/pagination/pageButton.vue +1 -0
  31. package/src/main.js +4 -0
@@ -63,6 +63,7 @@ const modules = {
63
63
  *
64
64
  * @returns {undefined}
65
65
  */
66
+
66
67
  this.onMouseLeave = () => {
67
68
  const { tooltip, dragSelection } = this.options;
68
69
 
@@ -111,6 +112,10 @@ const modules = {
111
112
  * @returns {undefined}
112
113
  */
113
114
  this.onClick = (e) => {
115
+ if (this.isMouseMove) {
116
+ this.isMouseMove = false;
117
+ return;
118
+ }
114
119
  const args = { e };
115
120
  if (this.options.selectItem.use && this.options.selectItem.useClick) {
116
121
  const offset = this.getMousePosition(e);
@@ -239,6 +244,7 @@ const modules = {
239
244
  let yep;
240
245
 
241
246
  dragInfo.isMove = true;
247
+ this.isMouseMove = true;
242
248
 
243
249
  if (aOffsetX < aRange.x1) {
244
250
  xep = aRange.x1;
@@ -295,13 +301,31 @@ const modules = {
295
301
 
296
302
  this.dragInfoBackup = defaultsDeep({}, dragInfo);
297
303
 
298
- if (typeof this.listeners['drag-select'] === 'function') {
304
+ if (typeof this.listeners['drag-select'] === 'function' && !this.options?.zoom?.use) {
299
305
  this.listeners['drag-select'](args);
306
+ } else {
307
+ const {
308
+ xsp,
309
+ range: chartRange,
310
+ width: dragWidth,
311
+ } = dragInfo;
312
+ const dragXsp = xsp - chartRange.x1;
313
+
314
+ args.range.dragSelectionInfo = {
315
+ dragXsp,
316
+ dragXep: dragXsp + dragWidth,
317
+ exceptAxesYChartWidth: chartRange.x2 - chartRange.x1,
318
+ exceptAxesXChartHeight: chartRange.y2 - chartRange.y1,
319
+ chartRange,
320
+ chartTitle: this.options.title.text,
321
+ };
322
+
323
+ this.options.zoom.getRangeInfo(args);
300
324
  }
301
- }
302
325
 
303
- if (!this.options.dragSelection.keepDisplay) {
304
- this.removeSelectionArea();
326
+ if (!this.options.dragSelection.keepDisplay) {
327
+ this.removeSelectionArea();
328
+ }
305
329
  }
306
330
 
307
331
  this.dragInfo = null;
@@ -176,6 +176,7 @@ const modules = {
176
176
  cId: colorItem.id,
177
177
  color: colorItem.color,
178
178
  name,
179
+ show: true,
179
180
  });
180
181
  }
181
182
  }
@@ -230,7 +231,8 @@ const modules = {
230
231
  * @returns {undefined}
231
232
  */
232
233
  this.onLegendBoxClick = (e) => {
233
- const opt = this.options.legend;
234
+ const { legend: opt } = this.options;
235
+ const { chartIdx } = this.data;
234
236
 
235
237
  const targetDOM = this.getContainerDOM(e);
236
238
  if (!targetDOM) {
@@ -290,6 +292,14 @@ const modules = {
290
292
  series.show = !series.show;
291
293
  targetDOM.classList.toggle('inactive');
292
294
 
295
+ if (this.brushSeries) {
296
+ const seriesList = [...this.brushSeries.list];
297
+ seriesList[chartIdx] = this.seriesList;
298
+
299
+ this.brushSeries.list = seriesList;
300
+ this.brushSeries.chartIdx = chartIdx;
301
+ }
302
+
293
303
  this.update({
294
304
  updateSeries: false,
295
305
  updateSelTip: { update: true, keepDomain: true },
@@ -20,14 +20,7 @@ const modules = {
20
20
  this.createTitle();
21
21
  }
22
22
 
23
- const opt = this.options.title;
24
- Object.keys(opt.style).forEach((key) => {
25
- this.titleDOM.style[key] = opt.style[key];
26
- });
27
-
28
- this.titleDOM.textContent = opt.text;
29
- this.titleDOM.style.height = `${opt.height}px`;
30
- this.titleDOM.style.lineHeight = `${opt.height}px`;
23
+ this.updateTitle();
31
24
 
32
25
  this.isInitTitle = true;
33
26
  },
@@ -51,6 +44,18 @@ const modules = {
51
44
  this.titleDOM.style.display = 'none';
52
45
  this.wrapperDOM.style.paddingTop = '0px';
53
46
  },
47
+
48
+ updateTitle() {
49
+ const opt = this.options.title;
50
+
51
+ Object.keys(opt.style).forEach((key) => {
52
+ this.titleDOM.style[key] = opt.style[key];
53
+ });
54
+
55
+ this.titleDOM.textContent = opt.text;
56
+ this.titleDOM.style.height = `${opt.height}px`;
57
+ this.titleDOM.style.lineHeight = `${opt.height}px`;
58
+ },
54
59
  };
55
60
 
56
61
  export default modules;
@@ -311,7 +311,10 @@ class Scale {
311
311
 
312
312
  if (this.type === 'x') {
313
313
  labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
314
- ctx.fillText(labelText, labelCenter, labelPoint);
314
+ if (options?.brush?.showLabel || !options.brush) {
315
+ ctx.fillText(labelText, labelCenter, labelPoint);
316
+ }
317
+
315
318
  if (!isBlurredLabel
316
319
  && options?.selectItem?.showLabelTip
317
320
  && hitInfo?.label
@@ -341,10 +344,12 @@ class Scale {
341
344
  }
342
345
  } else {
343
346
  labelPoint = this.position === 'left' ? offsetPoint - 10 : offsetPoint + 10;
344
- ctx.fillText(labelText, labelPoint, labelCenter);
347
+ if (options?.brush?.showLabel || !options.brush) {
348
+ ctx.fillText(labelText, labelPoint, labelCenter);
349
+ }
345
350
 
346
351
  if (ix === steps) {
347
- linePosition += 1;
352
+ linePosition -= 1;
348
353
  }
349
354
 
350
355
  if (ix !== 0 && this.showGrid) {
@@ -7,6 +7,13 @@
7
7
  height: 100%;
8
8
  }
9
9
 
10
+ .ev-chart-brush-wrapper {
11
+ display: block;
12
+ position: relative;
13
+ width: 100%;
14
+ height: 100%;
15
+ }
16
+
10
17
  .ev-chart-container {
11
18
  position: relative;
12
19
  overflow: hidden;
@@ -14,6 +21,13 @@
14
21
  height: 100%;
15
22
  }
16
23
 
24
+ .ev-chart-brush-container {
25
+ position: relative;
26
+ overflow: hidden;
27
+ width: 100%;
28
+ height: 100%;
29
+ }
30
+
17
31
  .ev-chart-title {
18
32
  position: absolute;
19
33
  top: 0;
@@ -1,6 +1,7 @@
1
- import { ref, computed, getCurrentInstance, nextTick } from 'vue';
2
- import { cloneDeep, defaultsDeep } from 'lodash-es';
1
+ import { ref, computed, getCurrentInstance, nextTick, reactive, onUpdated, watch } from 'vue';
2
+ import { cloneDeep, defaultsDeep, isEqual } from 'lodash-es';
3
3
  import { getQuantity } from '@/common/utils';
4
+ import EvChartZoom from '@/components/chart/chartZoom.core';
4
5
 
5
6
  const DEFAULT_OPTIONS = {
6
7
  padding: {
@@ -130,6 +131,7 @@ const DEFAULT_OPTIONS = {
130
131
  selectLabel: {
131
132
  use: false,
132
133
  useClick: true,
134
+ tipText: 'value',
133
135
  limit: 1,
134
136
  useDeselectOverflow: false,
135
137
  showTip: false,
@@ -138,6 +140,17 @@ const DEFAULT_OPTIONS = {
138
140
  fixedPosTop: false,
139
141
  useApproximateValue: false,
140
142
  tipBackground: '#000000',
143
+ indicatorColor: '#000000',
144
+ tipStyle: {
145
+ height: 20,
146
+ background: '#000000',
147
+ textColor: '#FFFFFF',
148
+ fontSize: 14,
149
+ fontFamily: 'Roboto',
150
+ fontWeight: 400,
151
+ },
152
+ showTextTip: false,
153
+ showIndicator: false,
141
154
  },
142
155
  selectSeries: {
143
156
  use: false,
@@ -151,6 +164,34 @@ const DEFAULT_OPTIONS = {
151
164
  fillColor: '#38ACEC',
152
165
  opacity: 0.65,
153
166
  },
167
+ zoom: {
168
+ bufferMemoryCnt: 100,
169
+ toolbar: {
170
+ show: false,
171
+ items: {
172
+ previous: {
173
+ icon: 'ev-icon-allow2-left',
174
+ size: 'medium',
175
+ title: 'Previous',
176
+ },
177
+ latest: {
178
+ icon: 'ev-icon-allow2-right',
179
+ size: 'medium',
180
+ title: 'Latest',
181
+ },
182
+ reset: {
183
+ icon: 'ev-icon-redo',
184
+ size: 'medium',
185
+ title: 'Reset',
186
+ },
187
+ dragZoom: {
188
+ icon: 'ev-icon-zoomin',
189
+ size: 'medium',
190
+ title: 'Drag Zoom',
191
+ },
192
+ },
193
+ },
194
+ },
154
195
  heatMapColor: {
155
196
  min: '#FFFFFF',
156
197
  max: '#0052FF',
@@ -174,7 +215,7 @@ const DEFAULT_DATA = {
174
215
  data: {},
175
216
  };
176
217
 
177
- export const useModel = () => {
218
+ export const useModel = (selectedLabel) => {
178
219
  const { props, emit } = getCurrentInstance();
179
220
 
180
221
  const getNormalizedOptions = (options) => {
@@ -191,14 +232,14 @@ export const useModel = () => {
191
232
  left: 2,
192
233
  bottom: 4,
193
234
  };
194
- }
235
+ }
195
236
 
196
237
  return normalizedOptions;
197
238
  };
198
239
  const getNormalizedData = data => defaultsDeep(data, DEFAULT_DATA);
199
240
 
200
241
  const selectItemInfo = cloneDeep(props.selectedItem);
201
- const selectLabelInfo = cloneDeep(props.selectedLabel);
242
+ const selectLabelInfo = cloneDeep(props.selectedLabel ?? selectedLabel?.value);
202
243
  const selectSeriesInfo = cloneDeep(props.selectedSeries);
203
244
 
204
245
  const eventListeners = {
@@ -208,7 +249,11 @@ export const useModel = () => {
208
249
  emit('update:selectedItem', { seriesID: e.seriesId, dataIndex: e.dataIndex });
209
250
  }
210
251
  if (e.selected?.dataIndex) {
211
- emit('update:selectedLabel', { dataIndex: e.selected.dataIndex });
252
+ if (selectedLabel?.value) {
253
+ selectedLabel.value.dataIndex = e.selected.dataIndex;
254
+ } else {
255
+ emit('update:selectedLabel', { dataIndex: e.selected.dataIndex });
256
+ }
212
257
  }
213
258
  if (e.selected?.seriesId) {
214
259
  emit('update:selectedSeries', { seriesId: e.selected.seriesId });
@@ -262,3 +307,281 @@ export const useWrapper = (options) => {
262
307
  wrapperStyle,
263
308
  };
264
309
  };
310
+
311
+ export const useZoomModel = (
312
+ evChartNormalizedOptions,
313
+ { wrapper: evChartWrapper, evChartGroupRef },
314
+ selectedLabelOrItem,
315
+ ) => {
316
+ const { props, slots, emit } = getCurrentInstance();
317
+
318
+ const isExecuteZoom = ref(false);
319
+ const isUseZoomMode = ref(false);
320
+ const evChartToolbarRef = ref();
321
+
322
+ const evChartZoomOptions = reactive({ zoom: evChartNormalizedOptions.zoom });
323
+ const brushIdx = reactive({
324
+ start: 0,
325
+ end: -1,
326
+ isUseButton: false,
327
+ isUseScroll: false,
328
+ });
329
+
330
+ let evChartZoom = null;
331
+ const evChartInfo = reactive({
332
+ dom: [],
333
+ props: {
334
+ data: [],
335
+ options: [],
336
+ },
337
+ });
338
+ const evChartClone = reactive({ data: null, options: null });
339
+ const brushChartIdx = ref([]);
340
+
341
+ const getRangeInfo = (zoomInfo) => {
342
+ if (zoomInfo.data.length && zoomInfo.range && isUseZoomMode.value) {
343
+ evChartZoom.dragZoom(zoomInfo);
344
+ }
345
+ };
346
+
347
+ const setEvChartOptions = () => {
348
+ evChartInfo.props.options.forEach((option, idx) => {
349
+ option.zoom = {
350
+ ...option.zoom,
351
+ use: isUseZoomMode.value,
352
+ getRangeInfo,
353
+ };
354
+
355
+ if (isUseZoomMode.value) {
356
+ option.dragSelection = {
357
+ ...option.dragSelection,
358
+ use: true,
359
+ keepDisplay: false,
360
+ };
361
+ } else {
362
+ const {
363
+ use: originUseOption,
364
+ keepDisplay: originKeepDisplayOption,
365
+ } = evChartClone.options[idx].dragSelection ?? {};
366
+
367
+ option.dragSelection = {
368
+ use: !!originUseOption,
369
+ keepDisplay: !!originKeepDisplayOption,
370
+ };
371
+ }
372
+ });
373
+ };
374
+
375
+ const createEvChartZoom = () => {
376
+ if (evChartGroupRef) {
377
+ evChartInfo.dom = evChartGroupRef.value.querySelectorAll('.ev-chart-container');
378
+
379
+ let chartIdx = 0;
380
+ if (evChartInfo.dom.length) {
381
+ slots.default(evChartInfo.dom).forEach(({ type, props: evChartProps }) => {
382
+ if (type?.name === 'EvChart') {
383
+ const { options, data } = evChartProps;
384
+
385
+ data.chartIdx = chartIdx;
386
+ chartIdx++;
387
+
388
+ evChartInfo.props.data.push(data);
389
+ evChartInfo.props.options.push(options);
390
+ } else if (type?.name === 'EvChartBrush') {
391
+ brushChartIdx.value.push(evChartProps?.options?.chartIdx ?? 0);
392
+ }
393
+ });
394
+ }
395
+ } else {
396
+ evChartInfo.dom = [evChartWrapper.value.querySelector('.ev-chart-container')];
397
+ evChartInfo.props.data.push(props.data);
398
+ evChartInfo.props.options.push(props.options);
399
+ }
400
+
401
+ if (evChartInfo.props.data.length) {
402
+ evChartClone.data = cloneDeep(evChartInfo.props.data);
403
+ evChartClone.options = cloneDeep(evChartInfo.props.options);
404
+
405
+ const emitFunc = {
406
+ updateZoomStartIdx: startIdx => emit('update:zoomStartIdx', startIdx),
407
+ updateZoomEndIdx: endIdx => emit('update:zoomEndIdx', endIdx),
408
+ };
409
+
410
+ evChartZoom = new EvChartZoom(
411
+ evChartInfo,
412
+ evChartClone,
413
+ evChartZoomOptions,
414
+ evChartToolbarRef.value,
415
+ isExecuteZoom,
416
+ brushIdx,
417
+ emitFunc,
418
+ );
419
+ }
420
+ };
421
+
422
+ const toggleUseZoom = (target) => {
423
+ if (evChartClone.data[0].labels.length <= 1) {
424
+ return;
425
+ }
426
+
427
+ isUseZoomMode.value = !isUseZoomMode.value;
428
+
429
+ if (target) {
430
+ target.classList.toggle('active');
431
+ } else {
432
+ const dragZoomIcon = evChartToolbarRef.value.querySelector('.dragZoom');
433
+
434
+ dragZoomIcon.classList.toggle('active');
435
+ }
436
+
437
+ setEvChartOptions();
438
+
439
+ evChartZoom.setIconStyle(isUseZoomMode.value);
440
+ evChartZoom.setEventListener(isUseZoomMode.value);
441
+ };
442
+
443
+ const onClickToolbar = (e, iconType) => {
444
+ if (!evChartZoom.isAnimationFinish) {
445
+ return;
446
+ }
447
+
448
+ switch (iconType) {
449
+ case 'dragZoom':
450
+ toggleUseZoom(e.target);
451
+ break;
452
+ case 'reset':
453
+ evChartZoom.initZoom();
454
+ break;
455
+ case 'previous':
456
+ case 'latest':
457
+ evChartZoom.clickMoveZoomArea(iconType);
458
+ break;
459
+ default:
460
+ break;
461
+ }
462
+ };
463
+
464
+ onUpdated(() => {
465
+ if (evChartToolbarRef.value) {
466
+ evChartZoom.setIcon(evChartToolbarRef.value);
467
+ }
468
+ });
469
+
470
+ const setOptionsForUseZoom = (newOpt) => {
471
+ const isUpdateZoomOptions = !isEqual(newOpt.zoom, evChartZoomOptions.zoom);
472
+
473
+ if (isUpdateZoomOptions) {
474
+ evChartZoomOptions.zoom = newOpt.zoom;
475
+
476
+ if (evChartZoom) {
477
+ if (!evChartZoomOptions.zoom.toolbar.show && isUseZoomMode.value) {
478
+ toggleUseZoom();
479
+ }
480
+
481
+ evChartZoom.setEvChartZoomOptions(evChartZoomOptions);
482
+ } else if (evChartZoomOptions.zoom.toolbar.show && !evChartGroupRef) {
483
+ createEvChartZoom();
484
+ }
485
+ }
486
+ };
487
+
488
+ const setDataForUseZoom = (newData) => {
489
+ if (!isExecuteZoom.value) {
490
+ evChartClone.data = evChartGroupRef ? cloneDeep(newData) : [cloneDeep(newData)];
491
+ isUseZoomMode.value = false;
492
+
493
+ setEvChartOptions();
494
+
495
+ brushIdx.end = -1;
496
+ for (let i = 0; i < brushChartIdx.value.length; i++) {
497
+ const data = evChartClone.data[brushChartIdx.value[i]];
498
+
499
+ if (data.labels.length) {
500
+ brushIdx.start = 0;
501
+ brushIdx.end = data.labels.length - 1;
502
+ }
503
+ }
504
+
505
+ if (evChartZoom) {
506
+ evChartZoom.updateEvChartCloneData(evChartClone, isUseZoomMode.value);
507
+ }
508
+ }
509
+
510
+ isExecuteZoom.value = false;
511
+ };
512
+
513
+ const controlZoomIdx = (zoomStartIdx, zoomEndIdx) => {
514
+ if (evChartZoom.isUseToolbar) {
515
+ evChartZoom.isUseToolbar = false;
516
+ return;
517
+ }
518
+
519
+ if (isUseZoomMode.value) {
520
+ evChartZoom.executeZoom(zoomStartIdx, zoomEndIdx);
521
+ evChartZoom.setZoomAreaMemory(zoomStartIdx, zoomEndIdx);
522
+ }
523
+ };
524
+
525
+ watch(() => [
526
+ brushIdx.start,
527
+ brushIdx.end,
528
+ ], ([
529
+ curBrushStartIdx,
530
+ curBrushEndIdx,
531
+ ], [
532
+ prevBrushStartIdx,
533
+ ]) => {
534
+ if (selectedLabelOrItem?.value) {
535
+ if (typeof selectedLabelOrItem.value.dataIndex === 'number') {
536
+ if (curBrushStartIdx >= (prevBrushStartIdx ?? 0)) {
537
+ selectedLabelOrItem.value.dataIndex -= curBrushStartIdx - (prevBrushStartIdx ?? 0);
538
+ } else {
539
+ selectedLabelOrItem.value.dataIndex += prevBrushStartIdx - curBrushStartIdx;
540
+ }
541
+ } else {
542
+ for (let idx = 0; idx < selectedLabelOrItem.value.dataIndex.length; idx++) {
543
+ if (curBrushStartIdx >= (prevBrushStartIdx ?? 0)) {
544
+ selectedLabelOrItem.value.dataIndex[idx] -= curBrushStartIdx - (prevBrushStartIdx ?? 0);
545
+ } else {
546
+ selectedLabelOrItem.value.dataIndex[idx] += prevBrushStartIdx - curBrushStartIdx;
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ if (brushIdx.isUseButton || brushIdx.isUseScroll) {
553
+ evChartZoom.executeZoom(curBrushStartIdx, curBrushEndIdx);
554
+ }
555
+ });
556
+
557
+ watch(() => [
558
+ brushIdx.isUseButton,
559
+ brushIdx.isUseScroll,
560
+ ], ([
561
+ curIsUseButton,
562
+ curIsUseScroll,
563
+ ], [
564
+ prevIsUseButton,
565
+ prevIsUseScroll,
566
+ ]) => {
567
+ if (prevIsUseButton && !curIsUseButton) {
568
+ evChartZoom.setZoomAreaMemory(brushIdx.start, brushIdx.end);
569
+ } else if (prevIsUseScroll && !curIsUseScroll) {
570
+ evChartZoom.zoomAreaMemory.current[0] = [brushIdx.start, brushIdx.end];
571
+ }
572
+ });
573
+
574
+ return {
575
+ evChartZoomOptions,
576
+ evChartInfo,
577
+ evChartToolbarRef,
578
+ evChartClone,
579
+ brushIdx,
580
+
581
+ createEvChartZoom,
582
+ setOptionsForUseZoom,
583
+ setDataForUseZoom,
584
+ controlZoomIdx,
585
+ onClickToolbar,
586
+ };
587
+ };