evui 3.3.20 → 3.3.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.3.20",
3
+ "version": "3.3.21",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -1,4 +1,5 @@
1
1
  import { defaultsDeep } from 'lodash-es';
2
+ import { truthy } from '@/common/utils';
2
3
  import { COLOR, BAR_OPTION } from '../helpers/helpers.constant';
3
4
  import Canvas from '../helpers/helpers.canvas';
4
5
  import Util from '../helpers/helpers.util';
@@ -359,13 +360,11 @@ class Bar {
359
360
  ctx.textAlign = isHorizontal && align !== 'center' ? 'left' : 'center';
360
361
 
361
362
  let value;
362
- const isStacked = !isNaN(data.o);
363
- if (data.o === null) {
364
- value = isHorizontal ? data.x : data.y;
365
- } else if (isStacked) {
363
+ const isStacked = truthy(this.stackIndex);
364
+ if (isStacked) {
366
365
  value = data.o;
367
366
  } else {
368
- value = '';
367
+ value = (isHorizontal ? data.x : data.y) ?? '';
369
368
  }
370
369
 
371
370
  let formattedTxt;
@@ -374,49 +373,73 @@ class Bar {
374
373
  }
375
374
 
376
375
  if (!formatter || typeof formattedTxt !== 'string') {
377
- formattedTxt = Util.labelSignFormat(value, decimalPoint);
376
+ formattedTxt = Util.labelSignFormat(value, decimalPoint) ?? '';
378
377
  }
379
378
 
380
- const vw = Math.round(ctx.measureText(formattedTxt).width);
381
- const vh = fontSize + 4;
379
+ const textWidth = Math.round(ctx.measureText(formattedTxt).width);
380
+ const textHeight = fontSize + 4;
382
381
  const minXPos = x + 10;
383
382
  const minYPos = y - 10;
383
+ const widthFreeSpaceToDraw = w - 10;
384
+ const heightFreeSpaceToDraw = Math.abs(h + 10);
384
385
  const centerX = x + (w / 2) <= minXPos ? minXPos : x + (w / 2);
385
386
  const centerY = y + (h / 2) >= minYPos ? minYPos : y + (h / 2);
386
387
  const centerYHorizontal = isHighlight ? y + (h / 2) : y - (h / 2);
387
388
 
388
389
  switch (align) {
389
- case 'start':
390
+ case 'start': {
390
391
  if (isHorizontal) {
391
- ctx.fillText(formattedTxt, minXPos, centerYHorizontal);
392
- } else {
392
+ if (textWidth < widthFreeSpaceToDraw) {
393
+ ctx.fillText(formattedTxt, minXPos, centerYHorizontal);
394
+ }
395
+ } else if (textHeight < heightFreeSpaceToDraw) {
393
396
  ctx.fillText(formattedTxt, centerX, minYPos);
394
397
  }
398
+
395
399
  break;
396
- case 'center':
400
+ }
401
+
402
+ case 'center': {
397
403
  if (isHorizontal) {
398
- ctx.fillText(formattedTxt, centerX, centerYHorizontal);
399
- } else {
404
+ if (textWidth < widthFreeSpaceToDraw) {
405
+ ctx.fillText(formattedTxt, centerX, centerYHorizontal);
406
+ }
407
+ } else if (textHeight < heightFreeSpaceToDraw) {
400
408
  ctx.fillText(formattedTxt, centerX, centerY);
401
409
  }
410
+
402
411
  break;
403
- case 'out':
412
+ }
413
+
414
+ case 'out': {
415
+ if (isStacked) {
416
+ console.warn('[EVUI][Bar Chart] In case of Stack Bar Chart, \'out\' of \'showValue\'\'s align is not supported.');
417
+ return;
418
+ }
419
+
404
420
  if (isHorizontal) {
405
421
  ctx.fillText(formattedTxt, minXPos + w, centerYHorizontal);
406
422
  } else {
407
- ctx.fillText(formattedTxt, centerX, y + h - (vh / 2));
423
+ ctx.fillText(formattedTxt, centerX, y + h - (textHeight / 2));
408
424
  }
425
+
409
426
  break;
410
- case 'end':
427
+ }
428
+
411
429
  default:
430
+ case 'end': {
412
431
  if (isHorizontal) {
413
- const xPos = x + w - (vw * 2);
414
- ctx.fillText(formattedTxt, xPos <= minXPos ? minXPos : xPos, centerYHorizontal);
415
- } else {
416
- const yPos = y + h + vh;
432
+ if (textWidth < widthFreeSpaceToDraw) {
433
+ const xPos = x + w - (textWidth * 2);
434
+ ctx.fillText(formattedTxt, xPos <= minXPos ? minXPos : xPos, centerYHorizontal);
435
+ }
436
+ } else if (textHeight < heightFreeSpaceToDraw) {
437
+ const yPos = y + h + textHeight;
417
438
  ctx.fillText(formattedTxt, centerX, yPos >= minYPos ? minYPos : yPos);
418
439
  }
440
+
419
441
  break;
442
+ }
420
443
  }
421
444
 
422
445
  ctx.restore();
@@ -15,7 +15,10 @@ class HeatMap {
15
15
 
16
16
  this.sId = sId;
17
17
  this.data = [];
18
- this.labels = {};
18
+ this.labels = {
19
+ x: [],
20
+ y: [],
21
+ };
19
22
  this.valueOpt = {};
20
23
  this.size = {
21
24
  w: 0,
@@ -137,7 +140,7 @@ class HeatMap {
137
140
  ctx.beginPath();
138
141
  if (this.stroke.show) {
139
142
  const { radius } = this.stroke;
140
- if (radius > 0) {
143
+ if (radius > 0 && radius < h && radius < w) {
141
144
  ctx.moveTo(x + radius, y);
142
145
  ctx.arcTo(x + w, y, x + w, y + h, radius);
143
146
  ctx.arcTo(x + w, y + h, x, y + h, radius);
@@ -38,8 +38,10 @@ const modules = {
38
38
  this.createLegendLayout();
39
39
  this.createLegend();
40
40
  }
41
- const series = Object.values(this.seriesList)[0];
42
- this.setLegendStyle(series);
41
+
42
+ Object.values(this.seriesList).forEach((series) => {
43
+ this.setLegendStyle(series);
44
+ });
43
45
  this.initEvent();
44
46
 
45
47
  this.isInitLegend = true;
@@ -76,7 +78,12 @@ const modules = {
76
78
  return;
77
79
  }
78
80
 
79
- const { colorState } = Object.values(this.seriesList)[0];
81
+ const seriesList = Object.values(this.seriesList);
82
+ if (!seriesList.length) {
83
+ return;
84
+ }
85
+
86
+ const { colorState } = seriesList[0];
80
87
  const { start, end } = colorState[0];
81
88
 
82
89
  colorState[0].selectedValue = null;
@@ -102,7 +109,12 @@ const modules = {
102
109
  value = this.isSide ? 100 - value : value;
103
110
  const dir = isStart ? 'start' : 'end';
104
111
 
105
- const { colorState } = Object.values(this.seriesList)[0];
112
+ const seriesList = Object.values(this.seriesList);
113
+ if (!seriesList.length) {
114
+ return;
115
+ }
116
+
117
+ const { colorState } = seriesList[0];
106
118
  const { start, end } = colorState[0];
107
119
  if ((isStart && value > end) || (!isStart && value < start)) {
108
120
  return;
@@ -132,7 +144,12 @@ const modules = {
132
144
  this.onLegendBoxOver = (e) => {
133
145
  const type = e.target.dataset.type;
134
146
 
135
- const { colorState, valueOpt } = Object.values(this.seriesList)[0];
147
+ const seriesList = Object.values(this.seriesList);
148
+ if (!seriesList.length) {
149
+ return;
150
+ }
151
+
152
+ const { colorState, valueOpt } = seriesList[0];
136
153
  const state = colorState[0];
137
154
 
138
155
  let value = this.getSelectedValue(e);
@@ -170,7 +187,12 @@ const modules = {
170
187
  const targetDOM = lineDOM.getElementsByClassName('ev-chart-legend-thumb')[0];
171
188
  this.clearOverlay(targetDOM);
172
189
 
173
- const { colorState } = Object.values(this.seriesList)[0];
190
+ const seriesList = Object.values(this.seriesList);
191
+ if (!seriesList.length) {
192
+ return;
193
+ }
194
+
195
+ const { colorState } = seriesList[0];
174
196
  colorState[0].selectedValue = null;
175
197
 
176
198
  this.update({
@@ -210,8 +232,9 @@ const modules = {
210
232
  this.resetLegend();
211
233
  this.createLegend();
212
234
 
213
- const series = Object.values(this.seriesList)[0];
214
- this.setLegendStyle(series);
235
+ Object.values(this.seriesList).forEach((series) => {
236
+ this.setLegendStyle(series);
237
+ });
215
238
  },
216
239
 
217
240
  /**
@@ -249,6 +272,9 @@ const modules = {
249
272
  this.clearOverlay();
250
273
  const handleSize = this.legendHandleSize;
251
274
  const { min, max } = opt;
275
+ if (min === undefined || max === undefined) {
276
+ return;
277
+ }
252
278
 
253
279
  const targetDOM = this.containerDOM.getElementsByClassName('ev-chart-legend-line')[0];
254
280
 
@@ -326,6 +352,10 @@ const modules = {
326
352
  * @returns {undefined}
327
353
  */
328
354
  createLegend() {
355
+ if (!Object.values(this.seriesList).length) {
356
+ return;
357
+ }
358
+
329
359
  const opt = this.options.legend;
330
360
  this.isSide = !['top', 'bottom'].includes(opt.position);
331
361
  const legendSize = this.isSide ? opt.width : opt.height;
@@ -364,6 +394,7 @@ const modules = {
364
394
  const { valueOpt, colorState } = series;
365
395
 
366
396
  const { min, max, decimalPoint } = valueOpt;
397
+
367
398
  const { start, end } = colorState[0];
368
399
  const startColor = series.getColorForGradient(start);
369
400
  const endColor = series.getColorForGradient(end);
@@ -400,8 +431,10 @@ const modules = {
400
431
  const labelDOM = thumbDOM.getElementsByClassName('ev-chart-legend-label');
401
432
  labelDOM[0].style.cssText = `${labelStyle}0%;`;
402
433
  labelDOM[1].style.cssText = `${labelStyle}100%;`;
403
- labelDOM[0].innerText = this.isSide ? maxText : minText;
404
- labelDOM[1].innerText = this.isSide ? minText : maxText;
434
+ if (min !== undefined && max !== undefined) {
435
+ labelDOM[0].innerText = this.isSide ? maxText : minText;
436
+ labelDOM[1].innerText = this.isSide ? minText : maxText;
437
+ }
405
438
 
406
439
  const handleDOM = this.containerDOM.getElementsByClassName('ev-chart-legend-handle');
407
440
  handleDOM[0].style.cssText = defaultHandleStyle + startStyle;
@@ -524,8 +557,9 @@ const modules = {
524
557
  * @returns {undefined}
525
558
  */
526
559
  updateLegendContainerSize() {
527
- const series = Object.values(this.seriesList)[0];
528
- this.setLegendStyle(series);
560
+ Object.values(this.seriesList).forEach((series) => {
561
+ this.setLegendStyle(series);
562
+ });
529
563
  },
530
564
 
531
565
  /**
@@ -531,6 +531,7 @@ const modules = {
531
531
  const resizeStyle = this.resizeDOM?.style;
532
532
 
533
533
  let chartRect;
534
+ let legendPad;
534
535
  const title = opt?.title?.show ? opt?.title?.height : 0;
535
536
  const positionTop = title + opt?.legend?.height;
536
537
  const { top = 0, bottom = 0, left = 0, right = 0 } = opt?.legend?.padding ?? {};
@@ -545,9 +546,10 @@ const modules = {
545
546
  case 'top':
546
547
  wrapperStyle.padding = `${positionTop}px 0 0 0`;
547
548
  chartRect = this.chartDOM.getBoundingClientRect();
549
+ legendPad = parseInt(legendStyle.paddingTop) + parseInt(legendStyle.paddingBottom);
548
550
 
549
551
  boxStyle.width = '100%';
550
- boxStyle.height = `${opt.legend.height}px`;
552
+ boxStyle.height = `${opt.legend.height - legendPad}px`;
551
553
 
552
554
  legendStyle.top = `${title}px`;
553
555
  legendStyle.right = '';
@@ -555,7 +557,7 @@ const modules = {
555
557
  legendStyle.left = '';
556
558
 
557
559
  legendStyle.width = `${chartRect.width}px`;
558
- legendStyle.height = `${opt.legend.height + 4}px`; // 4 resize bar size
560
+ legendStyle.height = `${opt.legend.height + (resizeStyle ? 4 : 0)}px`; // 4 resize bar size
559
561
 
560
562
  if (resizeStyle) {
561
563
  resizeStyle.top = `${positionTop}px`;
@@ -598,9 +600,10 @@ const modules = {
598
600
  case 'bottom':
599
601
  wrapperStyle.padding = `${title}px 0 ${opt.legend.height}px 0`;
600
602
  chartRect = this.chartDOM.getBoundingClientRect();
603
+ legendPad = parseInt(legendStyle.paddingTop) + parseInt(legendStyle.paddingBottom);
601
604
 
602
605
  boxStyle.width = '100%';
603
- boxStyle.height = `${opt.legend.height}px`;
606
+ boxStyle.height = `${opt.legend.height - legendPad}px`;
604
607
 
605
608
  legendStyle.top = '';
606
609
  legendStyle.right = '';
@@ -608,7 +611,7 @@ const modules = {
608
611
  legendStyle.left = '0px';
609
612
 
610
613
  legendStyle.width = `${chartRect.width}px`;
611
- legendStyle.height = `${opt.legend.height + 4}px`; // 4 resize bar size
614
+ legendStyle.height = `${opt.legend.height + (resizeStyle ? 4 : 0)}px`; // 4 resize bar size
612
615
 
613
616
  if (resizeStyle) {
614
617
  resizeStyle.top = '';
@@ -48,11 +48,16 @@ class StepScale extends Scale {
48
48
  if (this.rangeMode) {
49
49
  const { maxSteps } = range;
50
50
 
51
- while (numberOfSteps > maxSteps * 2) {
52
- interval *= 2;
53
- numberOfSteps = Math.round(numberOfSteps / interval);
51
+ if (maxSteps > 2) {
52
+ while (numberOfSteps > maxSteps * 2) {
53
+ interval *= 2;
54
+ numberOfSteps = Math.round(numberOfSteps / interval);
55
+ }
56
+ } else {
57
+ interval = this.labels.length;
54
58
  }
55
59
  }
60
+
56
61
  return {
57
62
  steps: numberOfSteps,
58
63
  interval,
@@ -118,10 +118,11 @@
118
118
  >
119
119
  <input
120
120
  v-if="filterable"
121
- v-model="filterTextRef"
122
121
  type="text"
123
122
  class="ev-input-query"
124
123
  :placeholder="searchPlaceholder"
124
+ :value="filterTextRef"
125
+ @input="changeFilterText"
125
126
  />
126
127
  <div
127
128
  ref="itemWrapper"
@@ -242,6 +243,7 @@ export default {
242
243
  filteredItems,
243
244
  clickSelectInput,
244
245
  clickOutsideDropbox,
246
+ changeFilterText,
245
247
  changeDropboxPosition,
246
248
  clickItem,
247
249
  selectedItemClass,
@@ -266,6 +268,7 @@ export default {
266
268
  filteredItems,
267
269
  clickSelectInput,
268
270
  clickOutsideDropbox,
271
+ changeFilterText,
269
272
  changeDropboxPosition,
270
273
  clickItem,
271
274
  selectedItemClass,
@@ -127,6 +127,13 @@ export const useDropdown = (param) => {
127
127
  return props.items.filter(v => v.name.toUpperCase().includes(trimText.toUpperCase())) || [];
128
128
  });
129
129
 
130
+ /**
131
+ * filterable 에서 text input 이벤트 핸들러
132
+ */
133
+ const changeFilterText = (e) => {
134
+ filterTextRef.value = e?.target?.value;
135
+ };
136
+
130
137
  /**
131
138
  * dropdown box 위치 변경하는 메소드
132
139
  */
@@ -255,6 +262,7 @@ export const useDropdown = (param) => {
255
262
  filteredItems,
256
263
  clickSelectInput,
257
264
  clickOutsideDropbox,
265
+ changeFilterText,
258
266
  changeDropboxPosition,
259
267
  clickItem,
260
268
  selectedItemClass,