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.
Files changed (35) hide show
  1. package/dist/evui.common.js +3546 -973
  2. package/dist/evui.common.js.map +1 -1
  3. package/dist/evui.umd.js +3546 -973
  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 +15 -6
  9. package/src/components/chart/chart.core.js +86 -31
  10. package/src/components/chart/element/element.bar.js +7 -1
  11. package/src/components/chart/element/element.heatmap.js +213 -0
  12. package/src/components/chart/element/element.line.js +20 -9
  13. package/src/components/chart/element/element.pie.js +13 -5
  14. package/src/components/chart/element/element.scatter.js +26 -9
  15. package/src/components/chart/element/element.tip.js +154 -13
  16. package/src/components/chart/helpers/helpers.constant.js +15 -0
  17. package/src/components/chart/model/model.series.js +4 -0
  18. package/src/components/chart/model/model.store.js +160 -2
  19. package/src/components/chart/plugins/plugins.interaction.js +82 -10
  20. package/src/components/chart/plugins/plugins.legend.js +213 -42
  21. package/src/components/chart/plugins/plugins.tooltip.js +249 -6
  22. package/src/components/chart/scale/scale.js +9 -0
  23. package/src/components/chart/scale/scale.step.js +20 -5
  24. package/src/components/chart/scale/scale.time.category.js +20 -2
  25. package/src/components/chart/uses.js +20 -3
  26. package/src/components/grid/Grid.vue +276 -132
  27. package/src/components/grid/grid.filter.window.vue +1 -0
  28. package/src/components/grid/grid.pagination.vue +75 -0
  29. package/src/components/grid/grid.summary.vue +235 -0
  30. package/src/components/grid/style/grid.scss +0 -14
  31. package/src/components/grid/uses.js +158 -79
  32. package/src/components/pagination/Pagination.vue +20 -17
  33. package/src/components/treeGrid/TreeGrid.vue +253 -34
  34. package/src/components/treeGrid/TreeGridNode.vue +8 -9
  35. package/src/components/treeGrid/uses.js +152 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.3.9",
3
+ "version": "3.3.12",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -20,6 +20,10 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
20
20
  type: Object,
21
21
  default: null,
22
22
  },
23
+ selectedLabel: {
24
+ type: Object,
25
+ default: null,
26
+ },
23
27
  options: {
24
28
  type: Object,
25
29
  default: () => ({}),
@@ -38,6 +42,7 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
38
42
  'dbl-click',
39
43
  'drag-select',
40
44
  'update:selectedItem',
45
+ 'update:selectedLabel',
41
46
  ],
42
47
  setup(props) {
43
48
  let evChart = {};
@@ -45,7 +50,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
45
50
 
46
51
  const {
47
52
  eventListeners,
48
- selectInfo,
53
+ selectItemInfo,
54
+ selectLabelInfo,
49
55
  getNormalizedData,
50
56
  getNormalizedOptions,
51
57
  } = useModel();
@@ -66,7 +72,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
66
72
  normalizedData,
67
73
  normalizedOptions,
68
74
  eventListeners,
69
- selectInfo,
75
+ selectItemInfo,
76
+ selectLabelInfo,
70
77
  );
71
78
  };
72
79
 
@@ -102,13 +109,15 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
102
109
  }, { deep: true });
103
110
 
104
111
  await watch(() => props.selectedItem, (newValue) => {
105
- if (!newValue?.seriesID) {
106
- return;
107
- }
108
-
109
112
  const chartType = props.options?.type;
110
113
  evChart.selectItemByData(newValue, chartType);
111
114
  }, { deep: true });
115
+
116
+ await watch(() => props.selectedLabel, (newValue) => {
117
+ if (newValue.dataIndex) {
118
+ evChart.renderWithSelectLabel(newValue.dataIndex);
119
+ }
120
+ }, { deep: true });
112
121
  });
113
122
 
114
123
  onBeforeUnmount(() => {
@@ -14,7 +14,7 @@ import Pie from './plugins/plugins.pie';
14
14
  import Tip from './element/element.tip';
15
15
 
16
16
  class EvChart {
17
- constructor(target, data, options, listeners, defaultSelectInfo) {
17
+ constructor(target, data, options, listeners, defaultSelectItemInfo, defaultSelectLabelInfo) {
18
18
  Object.keys(Model).forEach(key => Object.assign(this, Model[key]));
19
19
  Object.assign(this, Title);
20
20
  Object.assign(this, Legend);
@@ -61,11 +61,12 @@ class EvChart {
61
61
  this.seriesList = {};
62
62
  this.lastTip = { pos: null, value: null };
63
63
  this.seriesInfo = {
64
- charts: { pie: [], bar: [], line: [], scatter: [] },
64
+ charts: { pie: [], bar: [], line: [], scatter: [], heatMap: [] },
65
65
  count: 0,
66
66
  };
67
67
 
68
- this.defaultSelectInfo = defaultSelectInfo;
68
+ this.defaultSelectItemInfo = defaultSelectItemInfo;
69
+ this.defaultSelectLabelInfo = defaultSelectLabelInfo;
69
70
  }
70
71
 
71
72
  /**
@@ -92,6 +93,7 @@ class EvChart {
92
93
 
93
94
  this.axesRange = this.getAxesRange();
94
95
  this.labelOffset = this.getLabelOffset();
96
+ this.initSelectedLabelInfo();
95
97
 
96
98
  this.drawChart();
97
99
 
@@ -146,11 +148,12 @@ class EvChart {
146
148
 
147
149
  /**
148
150
  * Draw each series
151
+ * @param {any} [hitInfo=undefined] from mousemove callback (object or undefined)
149
152
  *
150
153
  * @returns {undefined}
151
154
  */
152
155
  drawSeries(hitInfo) {
153
- const maxTip = this.options.maxTip;
156
+ const { maxTip, selectLabel, selectItem } = this.options;
154
157
 
155
158
  const opt = {
156
159
  ctx: this.bufferCtx,
@@ -158,6 +161,7 @@ class EvChart {
158
161
  labelOffset: this.labelOffset,
159
162
  axesSteps: this.axesSteps,
160
163
  maxTipOpt: { background: maxTip.background, color: maxTip.color },
164
+ selectLabel: { option: selectLabel, selected: this.defaultSelectLabelInfo },
161
165
  };
162
166
 
163
167
  let showIndex = 0;
@@ -177,37 +181,76 @@ class EvChart {
177
181
  for (let jx = 0; jx < chartTypeSet.length; jx++) {
178
182
  const series = this.seriesList[chartTypeSet[jx]];
179
183
 
180
- if (chartType === 'line' || chartType === 'scatter') {
181
- series.draw(opt);
182
- } else if (chartType === 'bar') {
183
- const { thickness, borderRadius } = this.options;
184
- series.draw({ thickness, borderRadius, showSeriesCount, showIndex, ...opt });
185
-
186
- if (series.show) {
187
- showIndex++;
184
+ switch (chartType) {
185
+ case 'line':
186
+ case 'heatMap': {
187
+ series.draw(opt);
188
+ break;
188
189
  }
189
- } else {
190
- const selectInfo = hitInfo
191
- ?? this.lastHitInfo
192
- ?? { sId: this.defaultSelectInfo?.seriesID };
193
-
194
- if (this.options.sunburst) {
195
- this.drawSunburst(selectInfo);
196
- } else {
197
- this.drawPie(selectInfo);
190
+ case 'bar': {
191
+ const { thickness, borderRadius } = this.options;
192
+ series.draw({ thickness, borderRadius, showSeriesCount, showIndex, ...opt });
193
+ if (series.show) {
194
+ showIndex++;
195
+ }
196
+ break;
198
197
  }
199
-
200
- if (this.options.doughnutHoleSize > 0) {
201
- this.drawDoughnutHole();
198
+ case 'pie': {
199
+ const selectInfo = hitInfo
200
+ ?? this.lastHitInfo
201
+ ?? { sId: this.defaultSelectItemInfo?.seriesID };
202
+
203
+ if (this.options.sunburst) {
204
+ this.drawSunburst(selectInfo);
205
+ } else {
206
+ this.drawPie(selectInfo);
207
+ }
208
+
209
+ if (this.options.doughnutHoleSize > 0) {
210
+ this.drawDoughnutHole();
211
+ }
212
+ break;
213
+ }
214
+ case 'scatter': {
215
+ if (selectItem.use && selectItem.useSeriesOpacity) {
216
+ if (hitInfo) {
217
+ if (hitInfo?.maxIndex || hitInfo?.maxIndex === 0) {
218
+ opt.selectInfo = {
219
+ seriesID: hitInfo.sId,
220
+ dataIndex: hitInfo.maxIndex,
221
+ };
222
+ } else {
223
+ opt.selectInfo = null;
224
+ }
225
+ } else if (this.lastHitInfo?.maxIndex || this.lastHitInfo?.maxIndex === 0) {
226
+ opt.selectInfo = {
227
+ seriesID: this.lastHitInfo.sId,
228
+ dataIndex: this.lastHitInfo.maxIndex,
229
+ };
230
+ } else if (this.defaultSelectItemInfo?.dataIndex
231
+ || this.defaultSelectItemInfo?.dataIndex === 0) {
232
+ opt.selectInfo = {
233
+ seriesID: this.defaultSelectItemInfo.seriesID,
234
+ dataIndex: this.defaultSelectItemInfo.dataIndex,
235
+ };
236
+ } else {
237
+ opt.selectInfo = null;
238
+ }
239
+ }
240
+
241
+ series.draw(opt);
242
+ break;
243
+ }
244
+ default: {
245
+ break;
202
246
  }
203
- break;
204
247
  }
205
248
  }
206
249
  }
207
250
  }
208
251
 
209
252
  /**
210
- * Draw Tip with hitInfo and defaultSelectInfo
253
+ * Draw Tip with hitInfo and defaultSelectItemInfo
211
254
  * @param hitInfo
212
255
  */
213
256
  drawTip(hitInfo) {
@@ -221,8 +264,8 @@ class EvChart {
221
264
  tipLocationInfo = hitInfo;
222
265
  } else if (this.lastHitInfo) {
223
266
  tipLocationInfo = this.lastHitInfo;
224
- } else if (this.defaultSelectInfo) {
225
- tipLocationInfo = this.getItem(this.defaultSelectInfo, false);
267
+ } else if (this.defaultSelectItemInfo) {
268
+ tipLocationInfo = this.getItem(this.defaultSelectItemInfo, false);
226
269
  } else {
227
270
  tipLocationInfo = null;
228
271
  }
@@ -281,11 +324,21 @@ class EvChart {
281
324
  */
282
325
  drawAxis(hitInfo) {
283
326
  this.axesX.forEach((axis, index) => {
284
- axis.draw(this.chartRect, this.labelOffset, this.axesSteps.x[index], hitInfo);
327
+ axis.draw(
328
+ this.chartRect,
329
+ this.labelOffset,
330
+ this.axesSteps.x[index],
331
+ hitInfo,
332
+ this.defaultSelectLabelInfo);
285
333
  });
286
334
 
287
335
  this.axesY.forEach((axis, index) => {
288
- axis.draw(this.chartRect, this.labelOffset, this.axesSteps.y[index]);
336
+ axis.draw(
337
+ this.chartRect,
338
+ this.labelOffset,
339
+ this.axesSteps.y[index],
340
+ hitInfo,
341
+ this.defaultSelectLabelInfo);
289
342
  });
290
343
  }
291
344
 
@@ -545,6 +598,7 @@ class EvChart {
545
598
  bar: [],
546
599
  line: [],
547
600
  scatter: [],
601
+ heatMap: [],
548
602
  },
549
603
  count: 0,
550
604
  };
@@ -604,8 +658,9 @@ class EvChart {
604
658
  this.axesY = this.createAxes('y', options.axesY);
605
659
  this.axesRange = this.getAxesRange();
606
660
  this.labelOffset = this.getLabelOffset();
661
+ this.initSelectedLabelInfo();
607
662
 
608
- this.render();
663
+ this.render(updateInfo?.hitInfo);
609
664
 
610
665
  const isDragMove = this.dragInfo && this.drawSelectionArea;
611
666
  if (isDragMove) {
@@ -131,7 +131,13 @@ class Bar {
131
131
  }
132
132
 
133
133
  const barColor = item.dataColor || this.color;
134
- const isDownplay = this.state === 'downplay';
134
+
135
+ const selectLabelOption = param.selectLabel.option;
136
+ const selectedLabel = param.selectLabel.selected ?? { dataIndex: [] };
137
+
138
+ const isDownplay = selectLabelOption.use && selectLabelOption.useSeriesOpacity
139
+ ? selectedLabel.dataIndex.length && !selectedLabel.dataIndex.includes(index)
140
+ : this.state === 'downplay';
135
141
 
136
142
  if (typeof barColor !== 'string') {
137
143
  ctx.fillStyle = Canvas.createGradient(
@@ -0,0 +1,213 @@
1
+ import { merge } from 'lodash-es';
2
+ import Canvas from '../helpers/helpers.canvas';
3
+ import Util from '../helpers/helpers.util';
4
+ import { COLOR, HEAT_MAP_OPTION } from '../helpers/helpers.constant';
5
+
6
+ class HeatMap {
7
+ constructor(sId, opt, sIdx) {
8
+ const merged = merge({}, HEAT_MAP_OPTION, opt);
9
+ Object.keys(merged).forEach((key) => {
10
+ this[key] = merged[key];
11
+ });
12
+
13
+ ['color', 'pointFill', 'fillColor'].forEach((colorProp) => {
14
+ if (this[colorProp] === undefined) {
15
+ this[colorProp] = COLOR[sIdx];
16
+ }
17
+ });
18
+
19
+ this.colorAxis = this.createColorAxis(opt.colorOpt);
20
+ this.errorColor = opt.colorOpt.error;
21
+ this.borderColor = opt.colorOpt.border;
22
+
23
+ this.sId = sId;
24
+ this.data = [];
25
+ this.spaces = opt.spaces || { x: null, y: null };
26
+ this.size = {
27
+ w: 0,
28
+ h: 0,
29
+ };
30
+ this.valueOpt = {
31
+ max: 0,
32
+ interval: 0,
33
+ };
34
+ this.type = 'heatMap';
35
+ }
36
+
37
+ /**
38
+ * create series color axis
39
+ * @param colorOpt
40
+ * @returns {*[]}
41
+ */
42
+ createColorAxis(colorOpt) {
43
+ const colorAxis = [];
44
+ const { min, max, categoryCnt } = colorOpt;
45
+
46
+ const minColor = min.includes('#') ? Util.hexToRgb(min) : min;
47
+ const maxColor = max.includes('#') ? Util.hexToRgb(max) : max;
48
+
49
+ const [minR, minG, minB] = minColor.split(',');
50
+ const [maxR, maxG, maxB] = maxColor.split(',');
51
+
52
+ const unitR = Math.floor((minR - maxR) / (categoryCnt - 1));
53
+ const unitG = Math.floor((minG - maxG) / (categoryCnt - 1));
54
+ const unitB = Math.floor((minB - maxB) / (categoryCnt - 1));
55
+
56
+ for (let ix = 0; ix < categoryCnt; ix++) {
57
+ const r = +minR - (unitR * ix);
58
+ const g = +minG - (unitG * ix);
59
+ const b = +minB - (unitB * ix);
60
+
61
+ colorAxis.push({
62
+ id: `color#${ix}`,
63
+ value: `rgb(${r},${g},${b})`,
64
+ state: 'normal',
65
+ show: true,
66
+ });
67
+ }
68
+
69
+ return colorAxis;
70
+ }
71
+
72
+ getColorIndex(value) {
73
+ const existError = this.valueOpt.existError;
74
+ const maxIndex = this.colorAxis.length;
75
+ if (value < 0) {
76
+ return maxIndex - 1;
77
+ }
78
+
79
+ const colorIndex = Math.floor(value / this.valueOpt.interval);
80
+ if (colorIndex >= maxIndex) {
81
+ return existError ? maxIndex - 2 : maxIndex - 1;
82
+ }
83
+
84
+ return colorIndex;
85
+ }
86
+
87
+ drawItem(ctx, xp, yp) {
88
+ ctx.beginPath();
89
+ ctx.strokeRect(xp - this.size.w, yp + Math.SQRT2, this.size.w, this.size.h);
90
+ ctx.fillRect(xp - this.size.w, yp + Math.SQRT2, this.size.w, this.size.h);
91
+ ctx.closePath();
92
+ ctx.stroke();
93
+ }
94
+
95
+ draw(param) {
96
+ if (!this.show) {
97
+ return;
98
+ }
99
+
100
+ const { ctx, chartRect, labelOffset, axesSteps } = param;
101
+
102
+ const minmaxX = axesSteps.x[this.xAxisIndex];
103
+ const minmaxY = axesSteps.y[this.yAxisIndex];
104
+
105
+ const xArea = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
106
+ const yArea = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
107
+
108
+ const xsp = chartRect.x1 + labelOffset.left;
109
+ const ysp = chartRect.y2 - labelOffset.bottom;
110
+
111
+ this.size.w = Math.floor(xArea / (this.spaces.x || (minmaxX.graphMax - minmaxX.graphMin)));
112
+ this.size.h = Math.floor(yArea / (this.spaces.y || (minmaxY.graphMax - minmaxY.graphMin)));
113
+
114
+ this.data.forEach((item) => {
115
+ item.xp = Canvas.calculateX(item.x, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp);
116
+ item.yp = Canvas.calculateY(item.y, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp);
117
+
118
+ const { xp, yp, o: value } = item;
119
+
120
+ if (xp !== null && yp !== null) {
121
+ const colorIndex = this.getColorIndex(value);
122
+ const opacity = this.colorAxis[colorIndex].state === 'downplay' ? 0.1 : 1;
123
+ item.dataColor = value < 0 ? this.errorColor : this.colorAxis[colorIndex].value;
124
+ item.cId = this.colorAxis[colorIndex].id;
125
+ if (this.colorAxis[colorIndex].show) {
126
+ ctx.strokeStyle = Util.colorStringToRgba(this.borderColor, opacity);
127
+ ctx.fillStyle = Util.colorStringToRgba(item.dataColor, opacity);
128
+ this.drawItem(ctx, xp, yp);
129
+ }
130
+ }
131
+ });
132
+ }
133
+
134
+ /**
135
+ *Returns items in range
136
+ * @param {object} params range values
137
+ *
138
+ * @returns {array}
139
+ */
140
+ findItems({ xsp, ysp, width, height }) {
141
+ const gdata = this.data;
142
+ const xep = xsp + width;
143
+ const yep = ysp + height;
144
+ return gdata.filter(seriesData =>
145
+ (xsp - 1 <= seriesData.xp && seriesData.xp <= xep + 1
146
+ && ysp - 1 <= seriesData.yp && seriesData.yp <= yep + 1));
147
+ }
148
+
149
+ /**
150
+ * Draw item highlight
151
+ * @param {object} item object for drawing series data
152
+ * @param {object} context canvas context
153
+ *
154
+ * @returns {undefined}
155
+ */
156
+ itemHighlight(item, context) {
157
+ const gdata = item.data;
158
+ const ctx = context;
159
+
160
+ const x = gdata.xp;
161
+ const y = gdata.yp;
162
+
163
+ ctx.save();
164
+ if (x !== null && y !== null) {
165
+ const color = gdata.dataColor;
166
+ ctx.strokeStyle = Util.colorStringToRgba(color, 1);
167
+ ctx.fillStyle = Util.colorStringToRgba(color, this.highlight.maxShadowOpacity);
168
+ this.drawItem(ctx, x, y);
169
+ }
170
+
171
+ ctx.restore();
172
+ }
173
+
174
+ /**
175
+ * Find graph item for tooltip
176
+ * @param {array} offset mouse position
177
+ *
178
+ * @returns {object} graph item
179
+ */
180
+ findGraphData(offset) {
181
+ const xp = offset[0];
182
+ const yp = offset[1];
183
+ const item = {
184
+ data: null,
185
+ hit: false,
186
+ color: null,
187
+ name: null,
188
+ };
189
+ const wSize = this.size.w;
190
+ const hSize = this.size.h;
191
+ const gdata = this.data;
192
+
193
+ const foundItem = gdata.find((data) => {
194
+ const x = data.xp;
195
+ const y = data.yp;
196
+
197
+ return (x - wSize <= xp)
198
+ && (xp <= x)
199
+ && (y <= yp)
200
+ && (yp <= y + hSize);
201
+ });
202
+
203
+ if (foundItem) {
204
+ item.data = foundItem;
205
+ item.color = foundItem.dataColor;
206
+ item.hit = true;
207
+ }
208
+
209
+ return item;
210
+ }
211
+ }
212
+
213
+ export default HeatMap;
@@ -44,15 +44,22 @@ class Line {
44
44
  return;
45
45
  }
46
46
 
47
- const { ctx, chartRect, labelOffset, axesSteps } = param;
47
+ const { ctx, chartRect, labelOffset, axesSteps, selectLabel } = param;
48
48
  const extent = this.extent[this.state];
49
-
50
- const fillOpacity = this.fillOpacity * extent.opacity;
49
+ const selectLabelOption = selectLabel.option;
50
+ const selectedLabel = selectLabel.selected;
51
+ const isExistSelectedLabel = selectLabelOption.use
52
+ && selectLabelOption.useSeriesOpacity
53
+ && selectedLabel.dataIndex?.length > 0;
54
+ const downplayOpacity = this.extent.downplay.opacity;
55
+
56
+ const fillOpacity = isExistSelectedLabel
57
+ ? this.fillOpacity * downplayOpacity : this.fillOpacity * extent.opacity;
51
58
  const lineWidth = this.lineWidth * extent.lineWidth;
52
59
 
53
60
  const getOpacity = (colorStr) => {
54
61
  const noneDownplayOpacity = colorStr.includes('rgba') ? Util.getOpacity(colorStr) : 1;
55
- return this.state === 'downplay' ? 0.1 : noneDownplayOpacity;
62
+ return this.state === 'downplay' || isExistSelectedLabel ? 0.1 : noneDownplayOpacity;
56
63
  };
57
64
 
58
65
  const mainColor = this.color;
@@ -165,14 +172,18 @@ class Line {
165
172
 
166
173
  ctx.fill();
167
174
  }
168
-
169
- if (this.point) {
175
+ if (this.point || isExistSelectedLabel) {
170
176
  ctx.strokeStyle = Util.colorStringToRgba(mainColor, mainColorOpacity);
171
- ctx.fillStyle = Util.colorStringToRgba(pointFillColor, pointFillColorOpacity);
177
+ const focusStyle = Util.colorStringToRgba(pointFillColor, 1);
178
+ const blurStyle = Util.colorStringToRgba(pointFillColor, pointFillColorOpacity);
172
179
 
173
- this.data.forEach((curr) => {
180
+ this.data.forEach((curr, i) => {
174
181
  if (curr.xp !== null && curr.yp !== null) {
175
- Canvas.drawPoint(ctx, this.pointStyle, this.pointSize, curr.xp, curr.yp);
182
+ ctx.fillStyle = isExistSelectedLabel && selectedLabel.dataIndex.includes(i)
183
+ ? focusStyle : blurStyle;
184
+ if (this.point || selectedLabel.dataIndex.includes(i)) {
185
+ Canvas.drawPoint(ctx, this.pointStyle, this.pointSize, curr.xp, curr.yp);
186
+ }
176
187
  }
177
188
  });
178
189
  }
@@ -27,7 +27,6 @@ class Pie {
27
27
  this.doughnutHoleSize = 0;
28
28
  this.startAngle = 0;
29
29
  this.endAngle = 0;
30
- this.slice = null;
31
30
  this.state = null;
32
31
  this.ctx = null;
33
32
  this.isSelect = false;
@@ -71,8 +70,6 @@ class Pie {
71
70
  }
72
71
 
73
72
  ctx.closePath();
74
-
75
- this.slice = slice;
76
73
  this.ctx = ctx;
77
74
  }
78
75
 
@@ -84,8 +81,19 @@ class Pie {
84
81
  */
85
82
  findGraphData([offsetX, offsetY]) {
86
83
  const item = { data: null, hit: false, color: null, index: -1 };
87
-
88
- if (this.show && this.ctx?.isPointInPath(this.slice, offsetX, offsetY)) {
84
+ const {
85
+ radius,
86
+ startAngle,
87
+ endAngle,
88
+ centerX,
89
+ centerY,
90
+ } = this;
91
+
92
+ const distance = Math.sqrt((offsetX - centerX) ** 2 + (offsetY - centerY) ** 2);
93
+ const radian = (2.5 * Math.PI) - Math.atan2((offsetX - centerX), (offsetY - centerY));
94
+ const isPointInPath = radius > distance && radian >= startAngle && radian <= endAngle;
95
+
96
+ if (this.show && isPointInPath) {
89
97
  item.type = this.type;
90
98
  item.data = this.data;
91
99
  item.hit = true;
@@ -69,18 +69,34 @@ class Scatter {
69
69
  return item;
70
70
  }, this.data[0]);
71
71
 
72
- const getOpacity = (colorStr) => {
72
+ const getOpacity = (colorStr, dataIndex) => {
73
73
  const noneDownplayOpacity = colorStr.includes('rgba') ? Util.getOpacity(colorStr) : 1;
74
- return this.state === 'downplay' ? 0.1 : noneDownplayOpacity;
74
+ let resultOpacity = noneDownplayOpacity;
75
+
76
+ const { selectInfo } = param;
77
+ if (selectInfo) {
78
+ const isSelectedData = selectInfo?.seriesID === this.sId
79
+ && selectInfo?.dataIndex === dataIndex;
80
+
81
+ if (isSelectedData) {
82
+ resultOpacity = noneDownplayOpacity;
83
+ } else {
84
+ resultOpacity = 0.1;
85
+ }
86
+ } else {
87
+ resultOpacity = this.state === 'downplay' ? 0.1 : noneDownplayOpacity;
88
+ }
89
+
90
+ return resultOpacity;
75
91
  };
76
92
 
77
- this.data.forEach((curr) => {
93
+ this.data.forEach((curr, idx) => {
78
94
  if (curr.xp !== null && curr.yp !== null) {
79
95
  const color = curr.dataColor || this.color;
80
- ctx.strokeStyle = Util.colorStringToRgba(color, getOpacity(color));
96
+ ctx.strokeStyle = Util.colorStringToRgba(color, getOpacity(color, idx));
81
97
 
82
98
  const pointFillColor = curr.dataColor || this.pointFill;
83
- ctx.fillStyle = Util.colorStringToRgba(pointFillColor, getOpacity(pointFillColor));
99
+ ctx.fillStyle = Util.colorStringToRgba(pointFillColor, getOpacity(pointFillColor, idx));
84
100
 
85
101
  Canvas.drawPoint(ctx, this.pointStyle, this.pointSize, curr.xp, curr.yp);
86
102
  }
@@ -148,11 +164,11 @@ class Scatter {
148
164
  findGraphData(offset) {
149
165
  const xp = offset[0];
150
166
  const yp = offset[1];
151
- const item = { data: null, hit: false, color: this.color };
167
+ const item = { data: null, hit: false, color: this.color, index: null };
152
168
  const pointSize = this.pointSize;
153
169
  const gdata = this.data;
154
170
 
155
- const foundItem = gdata.find((data) => {
171
+ const targetIndex = gdata.findIndex((data) => {
156
172
  const x = data.xp;
157
173
  const y = data.yp;
158
174
 
@@ -162,8 +178,9 @@ class Scatter {
162
178
  && (yp <= y + pointSize);
163
179
  });
164
180
 
165
- if (foundItem) {
166
- item.data = foundItem;
181
+ if (targetIndex > -1) {
182
+ item.data = gdata[targetIndex];
183
+ item.index = targetIndex;
167
184
  item.hit = true;
168
185
  }
169
186