evui 3.3.50 → 3.3.52

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.
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div
3
- v-if="zoomOptions.toolbar.show && !injectIsChartGroup"
3
+ v-if="zoomOptions.toolbar?.show && !injectIsChartGroup"
4
4
  ref="evChartToolbarRef"
5
5
  >
6
6
  <ev-chart-toolbar
@@ -79,6 +79,7 @@
79
79
  const injectBrushSeries = inject('brushSeries', { list: [], chartIdx: null });
80
80
  const injectGroupSelectedLabel = inject('groupSelectedLabel', null);
81
81
  const injectBrushIdx = inject('brushIdx', { start: 0, end: -1 });
82
+ const injectEvChartPropsInGroup = inject('evChartPropsInGroup', []);
82
83
 
83
84
  const {
84
85
  eventListeners,
@@ -110,10 +111,11 @@
110
111
  setDataForUseZoom,
111
112
  controlZoomIdx,
112
113
  onClickToolbar,
113
- } = useZoomModel(
114
+ } = injectIsChartGroup ? {} : useZoomModel(
114
115
  normalizedOptions,
115
116
  { wrapper, evChartGroupRef: null },
116
117
  props.selectedLabel ? selectedLabel : selectedItem,
118
+ injectEvChartPropsInGroup,
117
119
  );
118
120
 
119
121
  const createChart = () => {
@@ -209,14 +211,14 @@
209
211
  }, { deep: true, flush: 'post' });
210
212
 
211
213
  watch(() => (injectGroupSelectedLabel?.value ?? selectedLabel.value), (newValue) => {
212
- if (newValue.dataIndex) {
213
- evChart.renderWithSelected(newValue.dataIndex);
214
+ if (newValue?.dataIndex) {
215
+ evChart.selectLabelByData(newValue.dataIndex, newValue?.targetAxis);
214
216
  }
215
217
  }, { deep: true, flush: 'post' });
216
218
 
217
219
  watch(() => props.selectedSeries, (newValue) => {
218
220
  if (newValue.seriesId) {
219
- evChart.renderWithSelected(newValue.seriesId);
221
+ evChart.selectSeriesByData(newValue.seriesId);
220
222
  }
221
223
  }, { deep: true, flush: 'post' });
222
224
 
@@ -227,6 +229,10 @@
227
229
  }
228
230
 
229
231
  onMounted(async () => {
232
+ if (injectEvChartPropsInGroup?.value) {
233
+ injectEvChartPropsInGroup.value.push(props);
234
+ }
235
+
230
236
  await createChart();
231
237
  await drawChart();
232
238
  });
@@ -235,6 +241,10 @@
235
241
  if (evChart && 'destroy' in evChart) {
236
242
  evChart.destroy();
237
243
  }
244
+
245
+ if (injectEvChartPropsInGroup?.value?.length) {
246
+ injectEvChartPropsInGroup.value.length = 0;
247
+ }
238
248
  });
239
249
 
240
250
  onDeactivated(() => {
@@ -268,7 +278,7 @@
268
278
  injectIsChartGroup,
269
279
  onClickToolbar,
270
280
  normalizedOptions,
271
- zoomOptions: toRef(evChartZoomOptions, 'zoom'),
281
+ zoomOptions: toRef(evChartZoomOptions ?? { zoom: {} }, 'zoom'),
272
282
  };
273
283
  },
274
284
  };
@@ -100,7 +100,7 @@ class EvChart {
100
100
  const { series, data, labels, groups } = this.data;
101
101
  const { type, axesX, axesY, tooltip, horizontal } = this.options;
102
102
 
103
- this.createSeriesSet(series, type, horizontal);
103
+ this.createSeriesSet(series, type, horizontal, groups);
104
104
  if (groups.length) {
105
105
  this.addGroupInfo(groups);
106
106
  }
@@ -116,7 +116,7 @@ class EvChart {
116
116
  this.axesRange = this.getAxesRange();
117
117
  this.labelOffset = this.getLabelOffset();
118
118
 
119
- this.initSelectedInfo?.();
119
+ this.initDefaultSelectInfo();
120
120
 
121
121
  this.drawChart();
122
122
 
@@ -161,7 +161,7 @@ class EvChart {
161
161
 
162
162
  /**
163
163
  * To draw canvas chart, it processes several sequential jobs
164
- * @param {any} [hitInfo=undefined] from mousemove callback (object or undefined)
164
+ * @param {any} [hitInfo=undefined] from mousemove callback (object or object[] of undefined)
165
165
  *
166
166
  * @returns {undefined}
167
167
  */
@@ -186,7 +186,14 @@ class EvChart {
186
186
  * @returns {undefined}
187
187
  */
188
188
  drawSeries(hitInfo) {
189
- const { maxTip, selectLabel, selectItem, selectSeries, brush, displayOverflow } = this.options;
189
+ const {
190
+ maxTip,
191
+ selectLabel,
192
+ selectItem,
193
+ selectSeries,
194
+ brush,
195
+ displayOverflow,
196
+ } = this.options;
190
197
 
191
198
  const opt = {
192
199
  ctx: this.bufferCtx,
@@ -196,6 +203,7 @@ class EvChart {
196
203
  maxTipOpt: { background: maxTip.background, color: maxTip.color },
197
204
  selectLabel: { option: selectLabel, selected: this.defaultSelectInfo },
198
205
  selectSeries: { option: selectSeries, selected: this.defaultSelectInfo },
206
+ selectItem: { option: selectItem, selected: this.defaultSelectItemInfo },
199
207
  overlayCtx: this.overlayCtx,
200
208
  isBrush: !!brush,
201
209
  displayOverflow,
@@ -231,21 +239,8 @@ class EvChart {
231
239
  case 'heatMap': {
232
240
  const legendHitInfo = hitInfo?.legend;
233
241
 
234
- let selectInfo;
235
- const defaultSelectInfo = this.defaultSelectItemInfo;
236
- if (defaultSelectInfo?.dataIndex || defaultSelectInfo?.dataIndex === 0) {
237
- selectInfo = { ...defaultSelectInfo };
238
- } else {
239
- selectInfo = null;
240
- }
241
-
242
242
  series.draw({
243
243
  legendHitInfo,
244
- selectInfo,
245
- selectItem: {
246
- option: selectItem,
247
- selected: selectInfo,
248
- },
249
244
  ...opt,
250
245
  });
251
246
  break;
@@ -702,7 +697,7 @@ class EvChart {
702
697
  this.seriesList = {};
703
698
  this.lastTip = { pos: null, value: null };
704
699
 
705
- this.createSeriesSet(series, options.type, options.horizontal);
700
+ this.createSeriesSet(series, options.type, options.horizontal, groups);
706
701
 
707
702
  if (this.legendDOM) {
708
703
  this.updateLegend();
@@ -766,7 +761,7 @@ class EvChart {
766
761
  this.axesRange = this.getAxesRange();
767
762
  this.labelOffset = this.getLabelOffset();
768
763
 
769
- this.initSelectedInfo?.();
764
+ this.initDefaultSelectInfo();
770
765
 
771
766
  this.render(updateInfo?.hitInfo);
772
767
 
@@ -930,6 +925,32 @@ class EvChart {
930
925
  this.tooltipDOM.style.display = 'none';
931
926
  }
932
927
  }
928
+
929
+ /**
930
+ * init defaultSelectInfo (for selectLabel, selectSeries options)
931
+ */
932
+ initDefaultSelectInfo() {
933
+ const {
934
+ type: chartType,
935
+ selectLabel,
936
+ selectSeries,
937
+ } = this.options;
938
+
939
+ if (selectLabel.use) {
940
+ let targetAxis = null;
941
+ if (chartType === 'heatMap' && selectLabel?.useBothAxis) {
942
+ targetAxis = this.defaultSelectInfo?.targetAxis;
943
+ }
944
+
945
+ this.defaultSelectInfo = !this.defaultSelectInfo?.dataIndex
946
+ ? { dataIndex: [], label: [], data: [] }
947
+ : this.getSelectedLabelInfoWithLabelData(this.defaultSelectInfo.dataIndex, targetAxis);
948
+ }
949
+
950
+ if (selectSeries.use && !this.defaultSelectInfo) {
951
+ this.defaultSelectInfo = { seriesId: [] };
952
+ }
953
+ }
933
954
  }
934
955
 
935
956
  export default EvChart;
@@ -1,7 +1,7 @@
1
1
  import { merge } from 'lodash-es';
2
+ import { convertToPercent, truthy } from '@/common/utils';
2
3
  import Util from '../helpers/helpers.util';
3
4
  import { HEAT_MAP_OPTION } from '../helpers/helpers.constant';
4
- import { convertToPercent } from '../../../common/utils';
5
5
 
6
6
  class HeatMap {
7
7
  constructor(sId, opt, colorOpt, isHorizontal, isGradient) {
@@ -229,18 +229,28 @@ class HeatMap {
229
229
  this.size.h = yArea / this.labels.y.length;
230
230
 
231
231
  const getOpacity = (item, opacity, index) => {
232
- const selectLabelOption = selectLabel?.option;
233
- const useSelectLabel = selectLabelOption?.use && selectLabelOption?.useSeriesOpacity;
234
- const selectItemOption = selectItem?.option;
235
- const useSelectItem = selectItemOption?.use && selectItemOption?.useSeriesOpacity;
236
232
  if (!legendHitInfo) {
237
- let isDownplay = false;
238
- if (useSelectItem) {
239
- isDownplay = selectItem?.selected && index !== selectItem?.selected?.dataIndex;
240
- } else if (useSelectLabel) {
241
- const selectedLabelList = selectLabel?.selected?.label;
242
- isDownplay = selectedLabelList.length
243
- && !selectedLabelList.includes(this.isHorizontal ? item.y : item.x);
233
+ let isDownplay;
234
+ const {
235
+ option: selectedItemOpt,
236
+ selected: selectedItem,
237
+ } = selectItem;
238
+
239
+ const {
240
+ option: selectedLabelOpt,
241
+ selected: selectedLabel,
242
+ } = selectLabel;
243
+
244
+ const isSelectedItem = truthy(selectedItem?.dataIndex) && selectedItem?.dataIndex > -1;
245
+ const isSelectedLabel = selectedLabel?.label?.length > 0;
246
+ if (isSelectedItem) {
247
+ isDownplay = selectedItemOpt.useSeriesOpacity
248
+ ? index !== selectedItem?.dataIndex
249
+ : false;
250
+ } else if (isSelectedLabel) {
251
+ isDownplay = selectedLabelOpt.useSeriesOpacity
252
+ ? !selectedLabel?.label?.includes(this.getItemLabel(selectLabel, item))
253
+ : false;
244
254
  }
245
255
  return isDownplay ? 0.1 : 1;
246
256
  }
@@ -608,6 +618,20 @@ class HeatMap {
608
618
 
609
619
  return selectionRange;
610
620
  }
621
+
622
+ getItemLabel(selectLabel, item) {
623
+ const {
624
+ option: selectedLabelOpt,
625
+ selected: selectedLabel,
626
+ } = selectLabel;
627
+
628
+ let targetLabel = this.isHorizontal ? item.y : item.x;
629
+ if (selectedLabelOpt?.useBothAxis && selectedLabel?.targetAxis) {
630
+ targetLabel = selectedLabel?.targetAxis === 'yAxis' ? item.y : item.x;
631
+ }
632
+
633
+ return targetLabel;
634
+ }
611
635
  }
612
636
 
613
637
  export default HeatMap;
@@ -292,7 +292,8 @@ const modules = {
292
292
 
293
293
  const seriesList = Object.keys(this.seriesList ?? {});
294
294
  const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
295
- const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
295
+ const isExistGrp = seriesList
296
+ .some(sId => this.seriesList[sId].isExistGrp && !this.seriesList[sId].isOverlapping);
296
297
  const groups = this.data.groups?.[0] ?? [];
297
298
 
298
299
  let gp;
@@ -11,11 +11,18 @@ const modules = {
11
11
  * @param {object} series chart series info
12
12
  * @param {string} defaultType default series type in options
13
13
  * @param {boolean} isHorizontal determines if a horizontal option's value
14
+ * @param {object} groups group info
14
15
  *
15
16
  * @returns {undefined}
16
17
  */
17
- createSeriesSet(series, defaultType, isHorizontal) {
18
- Object.keys(series).forEach((key, index) => {
18
+ createSeriesSet(series, defaultType, isHorizontal, groups) {
19
+ let seriesKeys = Object.keys(series);
20
+
21
+ if (this.options.overlapping.use) {
22
+ seriesKeys = this.getOverlappingSeriesKeys(series, defaultType, groups);
23
+ }
24
+
25
+ seriesKeys.forEach((key, index) => {
19
26
  const type = series[key].type || defaultType;
20
27
  this.seriesList[key] = this.addSeries({
21
28
  type,
@@ -27,6 +34,30 @@ const modules = {
27
34
  });
28
35
  },
29
36
 
37
+ getOverlappingSeriesKeys(series, defaultType, groups) {
38
+ const barSeries = [];
39
+ const otherSeries = [];
40
+ const allGroups = groups.flat();
41
+
42
+ Object.keys(series).forEach((key) => {
43
+ const type = series[key].type || defaultType;
44
+ const isOverlappingBar = type === 'bar' && allGroups.length;
45
+
46
+ if (isOverlappingBar) {
47
+ const overlappingIdx = allGroups.findIndex(group => group === key);
48
+ barSeries.push({ key, overlappingIdx });
49
+ } else {
50
+ otherSeries.push({ key });
51
+ }
52
+ });
53
+
54
+ // 큰 값을 가지는 series가 먼저 그려지도록 groups에서 지정한 순서의 역순으로 정렬
55
+ barSeries.sort((a, b) => b.overlappingIdx - a.overlappingIdx);
56
+
57
+ return [...barSeries, ...otherSeries]
58
+ .map(({ key }) => key);
59
+ },
60
+
30
61
  /**
31
62
  * Takes series information to create series list.
32
63
  * @param {object} param series info
@@ -79,6 +110,7 @@ const modules = {
79
110
  series.isExistGrp = true;
80
111
  series.bsId = prev;
81
112
  series.bsIds = group.filter((item, idx) => item !== curr && sIdx > idx);
113
+ series.isOverlapping = this.options.overlapping.use;
82
114
 
83
115
  if (!series.show) {
84
116
  interpolation--;
@@ -48,7 +48,7 @@ const modules = {
48
48
  const sData = data[seriesID];
49
49
 
50
50
  if (series && sData) {
51
- if (series.isExistGrp && series.stackIndex) {
51
+ if (series.isExistGrp && series.stackIndex && !series.isOverlapping) {
52
52
  series.data = this.addSeriesStackDS(sData, label, series.bsIds, series.stackIndex);
53
53
  } else {
54
54
  series.data = this.addSeriesDS(sData, label);
@@ -569,7 +569,7 @@ const modules = {
569
569
  }
570
570
  }
571
571
 
572
- itemPosition = dataIndex.map((idx) => {
572
+ itemPosition = dataIndex?.map((idx) => {
573
573
  const dataInfo = this.getDataByValues(firShowSeriesID, idx);
574
574
 
575
575
  if (!dataInfo) {
@@ -700,7 +700,7 @@ const modules = {
700
700
  *
701
701
  * @returns {object} clicked series id
702
702
  */
703
- getSeriesIdByPosition(offset) {
703
+ getSeriesInfoByPosition(offset) {
704
704
  const [clickedX, clickedY] = offset;
705
705
  const chartRect = this.chartRect;
706
706
  const labelOffset = this.labelOffset;
@@ -802,10 +802,11 @@ const modules = {
802
802
  /**
803
803
  * Find label info by position x and y
804
804
  * @param {array} offset position x and y
805
+ * @param {string | null} targetAxis target Axis Location ('xAxis', 'yAxis' , null)
805
806
  *
806
807
  * @returns {object} clicked label information
807
808
  */
808
- getLabelInfoByPosition(offset) {
809
+ getLabelInfoByPosition(offset, targetAxis) {
809
810
  const [x, y] = offset;
810
811
  const aPos = {
811
812
  x1: this.chartRect.x1 + this.labelOffset.left,
@@ -814,12 +815,21 @@ const modules = {
814
815
  y2: this.chartRect.y2 - this.labelOffset.bottom,
815
816
  };
816
817
 
817
- const seiresList = this.data.series;
818
- const pointSize = Object.values(seiresList).sort(
818
+ const seriesList = this.data.series;
819
+ const pointSize = Object.values(seriesList).sort(
819
820
  (a, b) => b.pointSize ?? 0 - a.pointSize ?? 0,
820
821
  )[0]?.pointSize ?? 3; // default pointSize 3
821
822
  const { horizontal, selectLabel } = this.options;
822
- const scale = horizontal ? this.axesY[0] : this.axesX[0];
823
+
824
+ let scale;
825
+ if (targetAxis === 'xAxis') {
826
+ scale = this.axesX[0];
827
+ } else if (targetAxis === 'yAxis') {
828
+ scale = this.axesY[0];
829
+ } else {
830
+ scale = horizontal ? this.axesY[0] : this.axesX[0];
831
+ }
832
+
823
833
  const startPoint = aPos[scale.units.rectStart];
824
834
  const endPoint = aPos[scale.units.rectEnd];
825
835
 
@@ -827,7 +837,8 @@ const modules = {
827
837
  let hitInfo;
828
838
  if (scale?.labels?.length) {
829
839
  const labelGap = (endPoint - startPoint) / scale.labels.length;
830
- const index = Math.floor(((horizontal ? y : x) - startPoint) / labelGap);
840
+ const isYAxis = targetAxis === 'yAxis' || horizontal;
841
+ const index = Math.floor(((isYAxis ? y : x) - startPoint) / labelGap);
831
842
  labelIndex = scale.labels.length > index ? index : -1;
832
843
  } else {
833
844
  let offsetX;