evui 3.3.10 → 3.3.13

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 (30) hide show
  1. package/dist/evui.common.js +2439 -1032
  2. package/dist/evui.common.js.map +1 -1
  3. package/dist/evui.umd.js +2439 -1032
  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.core.js +65 -24
  9. package/src/components/chart/element/element.heatmap.js +195 -51
  10. package/src/components/chart/element/element.line.js +22 -9
  11. package/src/components/chart/element/element.scatter.js +26 -9
  12. package/src/components/chart/element/element.tip.js +103 -83
  13. package/src/components/chart/helpers/helpers.constant.js +13 -11
  14. package/src/components/chart/model/model.series.js +1 -1
  15. package/src/components/chart/model/model.store.js +19 -74
  16. package/src/components/chart/plugins/plugins.interaction.js +15 -4
  17. package/src/components/chart/plugins/plugins.legend.js +6 -3
  18. package/src/components/chart/plugins/plugins.pie.js +17 -0
  19. package/src/components/chart/plugins/plugins.tooltip.js +205 -32
  20. package/src/components/chart/scale/scale.js +10 -11
  21. package/src/components/chart/scale/scale.step.js +38 -3
  22. package/src/components/chart/scale/scale.time.category.js +35 -3
  23. package/src/components/chart/uses.js +12 -0
  24. package/src/components/grid/Grid.vue +109 -36
  25. package/src/components/grid/grid.summary.vue +235 -0
  26. package/src/components/grid/style/grid.scss +0 -14
  27. package/src/components/grid/uses.js +55 -46
  28. package/src/components/treeGrid/TreeGrid.vue +269 -36
  29. package/src/components/treeGrid/TreeGridNode.vue +8 -9
  30. package/src/components/treeGrid/uses.js +152 -37
@@ -51,28 +51,30 @@ const modules = {
51
51
  selArgs.text = numberWithComma(selArgs.value);
52
52
  }
53
53
 
54
- this.drawTextTip({ opt: selTipOpt, tipType: 'sel', isSamePos, ...selArgs });
54
+ this.drawTextTip({ opt: selTipOpt, tipType: 'sel', seriesOpt: seriesInfo, isSamePos, ...selArgs });
55
55
  }
56
56
 
57
57
  if (selTipOpt.showIndicator) {
58
- this.drawFixedIndicator({ opt: selTipOpt, ...selArgs });
58
+ this.drawFixedIndicator({ opt: selTipOpt, seriesOpt: seriesInfo, ...selArgs });
59
59
  }
60
60
  }
61
61
 
62
- if (tipLocationInfo && tipLocationInfo.label !== null) {
62
+ if (tipLocationInfo && tipLocationInfo?.label && tipLocationInfo?.label === 0) {
63
63
  this.lastHitInfo = tipLocationInfo;
64
64
  }
65
65
  }
66
+
66
67
  if (maxTipOpt.use && !isExistSelectedLabel) {
67
68
  const maxSID = this.minMax[isHorizontal ? 'x' : 'y'][0].maxSID;
68
- maxArgs = this.calculateTipInfo(this.seriesList[maxSID], 'max', null);
69
+ const seriesInfo = this.seriesList[maxSID];
70
+ maxArgs = this.calculateTipInfo(seriesInfo, 'max', null);
69
71
 
70
72
  if (maxTipOpt.use && maxArgs) {
71
73
  maxArgs.text = numberWithComma(maxArgs.value);
72
- this.drawTextTip({ opt: maxTipOpt, tipType: 'max', ...maxArgs });
74
+ this.drawTextTip({ opt: maxTipOpt, tipType: 'max', seriesOpt: seriesInfo, ...maxArgs });
73
75
 
74
76
  if (maxTipOpt.showIndicator) {
75
- this.drawFixedIndicator({ opt: maxTipOpt, ...maxArgs });
77
+ this.drawFixedIndicator({ opt: maxTipOpt, seriesOpt: seriesInfo, ...maxArgs });
76
78
  }
77
79
  }
78
80
  }
@@ -175,6 +177,14 @@ const modules = {
175
177
  xArea - size.comboOffset,
176
178
  xsp + (size.comboOffset / 2),
177
179
  );
180
+ } else if (type === 'scatter') {
181
+ dp = Canvas.calculateX(
182
+ ldata,
183
+ graphX.graphMin,
184
+ graphX.graphMax,
185
+ xArea,
186
+ xsp,
187
+ );
178
188
  }
179
189
 
180
190
  const sizeObj = { xArea, yArea, graphX, graphY, xsp, xep, ysp };
@@ -185,8 +195,14 @@ const modules = {
185
195
  drawFixedIndicator(param) {
186
196
  const isHorizontal = !!this.options.horizontal;
187
197
  const ctx = this.bufferCtx;
188
- const { graphX, graphY, xArea, yArea, xsp, ysp, dp, type, value, opt } = param;
189
- const offset = type === 'bar' ? 0 : 3;
198
+ const { graphX, graphY, xArea, yArea, xsp, ysp, dp, type, value, opt, seriesOpt } = param;
199
+ let offset = 0;
200
+
201
+ if (type === 'line') {
202
+ offset += 3;
203
+ } else if (type === 'scatter') {
204
+ offset += seriesOpt?.pointSize ?? 0;
205
+ }
190
206
 
191
207
  let gp;
192
208
 
@@ -234,7 +250,7 @@ const modules = {
234
250
  const opt = this.options;
235
251
  const isHorizontal = !!opt.horizontal;
236
252
  const labelTipOpt = opt.selectLabel;
237
- const { dataIndex, data } = this.defaultSelectLabelInfo;
253
+ const { dataIndex, data, label } = this.defaultSelectLabelInfo;
238
254
  let drawTip = false;
239
255
 
240
256
  if (dataIndex.length) {
@@ -248,86 +264,82 @@ const modules = {
248
264
  y1: chartRect.y1 + labelOffset.top,
249
265
  y2: chartRect.y2 - labelOffset.bottom,
250
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;
251
272
 
252
- const labelAxes = this.options.horizontal ? this.axesY[0] : this.axesX[0];
253
- const labelStartPoint = aPos[labelAxes.units.rectStart];
254
- const labelEndPoint = aPos[labelAxes.units.rectEnd];
255
- const labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
256
-
257
- const valueAxes = this.options.horizontal ? this.axesX[0] : this.axesY[0];
258
- const valueStartPoint = aPos[valueAxes.units.rectStart];
259
-
260
- const offset = this.options.type === 'bar' ? 4 : 6;
261
273
  const chartWidth = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
262
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
+ }
263
304
 
264
- dataIndex.forEach((idx, i) => {
265
- const labelCenter = Math.round(labelStartPoint + (labelGap * idx));
266
- let gp;
267
- const dp = labelCenter + (labelGap / 2);
305
+ data.forEach((selectedData, i) => {
268
306
  if (labelTipOpt.fixedPosTop) {
269
- if (isHorizontal) {
270
- gp = Canvas.calculateX(
271
- this.axesRange.x[0].max,
272
- this.axesRange.x[0].min,
273
- this.axesRange.x[0].max,
274
- chartWidth,
275
- valueStartPoint);
276
- gp += offset;
277
- } else {
278
- gp = Canvas.calculateY(
279
- this.axesRange.y[0].max,
280
- this.axesRange.y[0].min,
281
- this.axesRange.y[0].max,
282
- chartHeight,
283
- valueStartPoint);
284
- gp -= offset;
285
- }
286
- } else if (isHorizontal) {
287
- const seriesList = Object.keys(data[i] ?? {});
288
- const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
289
- const visibleValue = visibleSeries.map(sId => data[i][sId]);
290
- const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
291
-
292
- let maxValue;
293
- if (isExistGrp) {
294
- maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
295
- } else if (visibleValue.length) {
296
- maxValue = Math.max(...visibleValue);
297
- } else {
298
- maxValue = this.axesRange.x[0].max;
299
- }
300
-
301
- gp = Canvas.calculateX(
302
- maxValue,
303
- this.axesRange.x[0].min,
304
- this.axesRange.x[0].max,
305
- chartWidth,
306
- valueStartPoint);
307
- 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);
308
319
  } else {
309
- const seriesList = Object.keys(data[i] ?? {});
310
- const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
311
- const visibleValue = visibleSeries.map(sId => data[i][sId]);
312
- const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
313
-
314
- let maxValue;
315
- if (isExistGrp) {
316
- maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
317
- } else if (visibleValue.length) {
318
- maxValue = Math.max(...visibleValue);
319
- } else {
320
- maxValue = this.axesRange.y[0].max;
321
- }
320
+ value = valueAxesRange.max;
321
+ }
322
+
323
+ if (labelAxes.labels) {
324
+ const labelCenter = Math.round(labelStartPoint + (labelGap * dataIndex[i]));
322
325
 
323
- gp = Canvas.calculateY(
324
- maxValue,
325
- this.axesRange.y[0].min,
326
- this.axesRange.y[0].max,
327
- chartHeight,
328
- valueStartPoint);
329
- gp -= offset;
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
+ );
330
335
  }
336
+ gp = valuePositionCalcFunction(
337
+ value,
338
+ valueAxesRange.min,
339
+ valueAxesRange.max,
340
+ valueSpace,
341
+ valueStartPoint);
342
+ gp += offset;
331
343
 
332
344
  this.showTip({
333
345
  context: this.bufferCtx,
@@ -351,12 +363,20 @@ const modules = {
351
363
  const isHorizontal = !!this.options.horizontal;
352
364
  const ctx = this.bufferCtx;
353
365
  const { graphX, graphY, xArea, yArea, xsp, xep, ysp } = param;
354
- const { dp, value, text, opt, type, tipType, isSamePos } = param;
366
+ const { dp, value, text, opt, type, tipType, isSamePos, seriesOpt } = param;
355
367
 
356
368
  const arrowSize = 4;
357
369
  const maxTipHeight = 20;
358
370
  const borderRadius = 4;
359
- const offset = type === 'bar' ? 4 : 6;
371
+
372
+ let offset = 1;
373
+ if (type === 'line') {
374
+ offset += 6;
375
+ } else if (type === 'scatter') {
376
+ offset += seriesOpt?.pointSize;
377
+ } else if (type === 'bar') {
378
+ offset += 4;
379
+ }
360
380
 
361
381
  let gp;
362
382
  let tdp = dp;
@@ -129,17 +129,19 @@ export const PLOT_BAND_OPTION = {
129
129
  };
130
130
 
131
131
  export const HEAT_MAP_OPTION = {
132
- ...LINE_OPTION,
133
- colorOpt: {
134
- min: '#FFFFFF',
135
- max: '#0052FF',
136
- categoryCnt: 5,
137
- border: '#FFFFFF',
138
- error: '#FF0000',
139
- },
140
- spaces: {
141
- x: 0,
142
- y: 0,
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
 
@@ -54,7 +54,7 @@ const modules = {
54
54
  return new Pie(id, opt, index);
55
55
  } else if (type === 'heatMap') {
56
56
  this.seriesInfo.charts.heatMap.push(id);
57
- return new HeatMap(id, opt, index);
57
+ return new HeatMap(id, opt, this.options.heatMapColor);
58
58
  }
59
59
 
60
60
  return false;
@@ -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.getSeriesMinMaxForHeatMap(series.data, series.spaces);
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(item => ({
308
- x: item.x,
309
- y: item.y,
310
- o: item.value,
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 = targetInterval || 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 = series.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
- const valueInterval = Math.ceil(maxValue / categoryCnt);
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: valueInterval,
447
+ interval: Math.ceil(maxValue / categoryCnt),
503
448
  existError: isExistError,
504
449
  };
505
450
  },
@@ -699,8 +644,8 @@ const modules = {
699
644
  const index = Math.floor(((this.options.horizontal ? y : x) - startPoint) / labelGap);
700
645
  labelIndex = scale.labels.length > index ? index : -1;
701
646
  } else {
702
- hitInfo = this.getItemByPosition(offset, false);
703
- labelIndex = hitInfo.maxIndex;
647
+ hitInfo = this.getItemByPosition(offset, this.options.selectLabel.useApproximateValue);
648
+ labelIndex = hitInfo.maxIndex ?? -1;
704
649
  }
705
650
 
706
651
  return {
@@ -54,7 +54,13 @@ const modules = {
54
54
 
55
55
  if (tooltip.use) {
56
56
  this.setTooltipLayoutPosition(hitInfo, e);
57
- this.drawTooltip(hitInfo, this.tooltipCtx);
57
+ if (type === 'scatter') {
58
+ this.drawTooltipForScatter(hitInfo, this.tooltipCtx);
59
+ } else if (type === 'heatMap') {
60
+ this.drawToolTipForHeatMap(hitInfo, this.tooltipCtx);
61
+ } else {
62
+ this.drawTooltip(hitInfo, this.tooltipCtx);
63
+ }
58
64
  }
59
65
  } else if (tooltip.use) {
60
66
  this.hideTooltipDOM();
@@ -108,7 +114,7 @@ const modules = {
108
114
  this.render(hitInfo);
109
115
  }
110
116
 
111
- ({ label: args.label, value: args.value, sId: args.seriesId } = hitInfo);
117
+ ({ label: args.label, value: args.value, sId: args.seriesId, acc: args.acc } = hitInfo);
112
118
  }
113
119
 
114
120
  if (typeof this.listeners['dbl-click'] === 'function') {
@@ -136,6 +142,7 @@ const modules = {
136
142
  value: args.value,
137
143
  sId: args.seriesId,
138
144
  maxIndex: args.dataIndex,
145
+ acc: args.acc,
139
146
  } = hitInfo);
140
147
  }
141
148
 
@@ -464,8 +471,12 @@ const modules = {
464
471
  */
465
472
  initSelectedLabelInfo() {
466
473
  const { use, limit } = this.options.selectLabel;
467
- const infoObj = this.defaultSelectLabelInfo;
468
- if (use && infoObj?.dataIndex) {
474
+
475
+ if (use) {
476
+ if (!this.defaultSelectLabelInfo) {
477
+ this.defaultSelectLabelInfo = { dataIndex: [] };
478
+ }
479
+ const infoObj = this.defaultSelectLabelInfo;
469
480
  infoObj.dataIndex.splice(limit);
470
481
  infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
471
482
  const dataEntries = Object.entries(this.data.data);
@@ -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 maxValue = valueOpt.interval * (index + 1);
85
- const minValue = maxValue - valueOpt.interval;
86
- const name = valueOpt.existError && index === colorAxis.length - 1
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,
@@ -197,6 +199,7 @@ const modules = {
197
199
  this.update({
198
200
  updateSeries: false,
199
201
  updateSelTip: { update: false, keepDomain: false },
202
+ hitInfo: { sId: targetId },
200
203
  });
201
204
  };
202
205
 
@@ -27,6 +27,11 @@ const modules = {
27
27
 
28
28
  const chartWidth = centerX - (padding.left + padding.right);
29
29
  const chartHeight = centerY - (padding.bottom + padding.top);
30
+ if ((typeof chartWidth === 'number' && chartWidth < 0)
31
+ || (typeof chartHeight === 'number' && chartHeight < 0)) {
32
+ return;
33
+ }
34
+
30
35
  const innerRadius = Math.min(chartWidth, chartHeight) * pieOption.doughnutHoleSize;
31
36
  const outerRadius = Math.min(chartWidth, chartHeight);
32
37
 
@@ -109,8 +114,14 @@ const modules = {
109
114
 
110
115
  const centerX = width / 2;
111
116
  const centerY = height / 2;
117
+
112
118
  const chartWidth = centerX - (padding.left + padding.right);
113
119
  const chartHeight = centerY - (padding.bottom + padding.top);
120
+ if ((typeof chartWidth === 'number' && chartWidth < 0)
121
+ || (typeof chartHeight === 'number' && chartHeight < 0)) {
122
+ return;
123
+ }
124
+
114
125
  const innerRadius = Math.min(chartWidth, chartHeight) * pieOption.doughnutHoleSize;
115
126
  const outerRadius = Math.min(chartWidth, chartHeight);
116
127
 
@@ -190,8 +201,14 @@ const modules = {
190
201
 
191
202
  const centerX = width / 2;
192
203
  const centerY = height / 2;
204
+
193
205
  const chartWidth = centerX - (padding.left + padding.right);
194
206
  const chartHeight = centerY - (padding.bottom + padding.top);
207
+ if ((typeof chartWidth === 'number' && chartWidth < 0)
208
+ || (typeof chartHeight === 'number' && chartHeight < 0)) {
209
+ return;
210
+ }
211
+
195
212
  const radius = Math.min(chartWidth, chartHeight) * pieOption.doughnutHoleSize;
196
213
 
197
214
  ctx.save();