evui 3.4.33 → 3.4.35

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,9 +1,12 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.4.33",
3
+ "version": "3.4.35",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
7
+ "engines": {
8
+ "node": "<=12.0.0"
9
+ },
7
10
  "scripts": {
8
11
  "serve": "vue-cli-service serve",
9
12
  "build": "vue-cli-service build",
@@ -737,6 +737,7 @@ const modules = {
737
737
  items[sId] = item;
738
738
 
739
739
  const formattedTxt = this.getFormattedTooltipValue({
740
+ seriesId: sId,
740
741
  seriesName: sName,
741
742
  value: gdata,
742
743
  itemData: item.data,
@@ -774,12 +775,13 @@ const modules = {
774
775
 
775
776
  /**
776
777
  * get formatted value for tooltip
778
+ * @param seriesId
777
779
  * @param seriesName
778
780
  * @param value
779
781
  * @param itemData
780
782
  * @returns {string}
781
783
  */
782
- getFormattedTooltipValue({ seriesName, value, itemData }) {
784
+ getFormattedTooltipValue({ seriesId, seriesName, value, itemData }) {
783
785
  const opt = this.options;
784
786
  const isHorizontal = !!opt.horizontal;
785
787
  const tooltipOpt = opt.tooltip;
@@ -794,18 +796,21 @@ const modules = {
794
796
  value,
795
797
  name: seriesName,
796
798
  percentage: itemData?.percentage,
799
+ seriesId,
797
800
  });
798
801
  } else if (opt.type === 'heatMap') {
799
802
  formattedTxt = tooltipValueFormatter({
800
803
  x: itemData?.x,
801
804
  y: itemData?.y,
802
805
  value: value > -1 ? value : 'error',
806
+ seriesId,
803
807
  });
804
808
  } else {
805
809
  formattedTxt = tooltipValueFormatter({
806
810
  x: isHorizontal ? value : itemData?.x,
807
811
  y: isHorizontal ? itemData?.y : value,
808
812
  name: seriesName,
813
+ seriesId,
809
814
  });
810
815
  }
811
816
  }
@@ -848,6 +853,7 @@ const modules = {
848
853
  );
849
854
 
850
855
  const formattedValue = this.getFormattedTooltipValue({
856
+ seriesId: sId,
851
857
  seriesName: series.name,
852
858
  value: hasData?.o,
853
859
  itemData: hasData,
@@ -6,6 +6,7 @@ import Util from '../helpers/helpers.util';
6
6
  const LINE_SPACING = 8;
7
7
  const VALUE_MARGIN = 50;
8
8
  const SCROLL_WIDTH = 17;
9
+ const BODY_PADDING = 8;
9
10
 
10
11
  const modules = {
11
12
  /**
@@ -73,7 +74,7 @@ const modules = {
73
74
  const {
74
75
  top = 0,
75
76
  right = 20,
76
- bottom = 8,
77
+ bottom = 3,
77
78
  left = 16,
78
79
  } = this.options?.tooltip?.rowPadding ?? {};
79
80
 
@@ -104,6 +105,30 @@ const modules = {
104
105
  const opt = this.options.tooltip;
105
106
  const seriesColorMarginRight = this.getColorMargin();
106
107
 
108
+ // Draw hidden tooltip header DOM to calculate height
109
+ const sId = hitInfo.hitId;
110
+ const hitItem = items[sId].data;
111
+ const hitAxis = items[sId].axis;
112
+ const titleFormatter = opt.formatter?.title;
113
+
114
+ if (this.axesX.length && this.axesY.length && opt.showHeader) {
115
+ if (titleFormatter) {
116
+ this.tooltipHeaderDOM.textContent = titleFormatter({
117
+ x: hitItem.x,
118
+ y: hitItem.y,
119
+ });
120
+ } else {
121
+ this.tooltipHeaderDOM.textContent = this.options.horizontal
122
+ ? this.axesY[hitAxis.y].getLabelFormat(hitItem.y)
123
+ : this.axesX[hitAxis.x].getLabelFormat(hitItem.x);
124
+ }
125
+ }
126
+
127
+ if (opt.textOverflow) {
128
+ this.tooltipHeaderDOM.classList.add(`ev-chart-tooltip-header--${opt.textOverflow}`);
129
+ }
130
+
131
+ this.tooltipHeaderDOM.style.visibility = 'hidden';
107
132
 
108
133
  // calculate and decide width of canvas El(contentsWidth)
109
134
  ctx.save();
@@ -173,19 +198,20 @@ const modules = {
173
198
  this.tooltipHeaderDOM.style.height = 'auto';
174
199
  this.tooltipDOM.style.height = 'auto';
175
200
  this.tooltipBodyDOM.style.height = `${contentsHeight + 6}px`;
176
-
201
+ this.tooltipDOM.style.display = 'block';
177
202
 
178
203
  // set tooltipDOM's positions
179
204
  const bodyWidth = document.body.clientWidth;
180
205
  const bodyHeight = document.body.clientHeight;
181
206
  const distanceMouseAndTooltip = 20;
182
- const tooltipDOMSize = this.tooltipDOM?.getBoundingClientRect();
207
+ const tooltipDOMHeight = this.tooltipDOM?.offsetHeight
208
+ || this.tooltipHeaderDOM?.offsetHeight + contentsHeight + BODY_PADDING;
183
209
  const maximumPosX = bodyWidth - contentsWidth - distanceMouseAndTooltip;
184
- const maximumPosY = bodyHeight - tooltipDOMSize.height - distanceMouseAndTooltip;
210
+ const maximumPosY = bodyHeight - tooltipDOMHeight - distanceMouseAndTooltip;
185
211
  const expectedPosX = mouseX + distanceMouseAndTooltip;
186
212
  const expectedPosY = mouseY + distanceMouseAndTooltip;
187
213
  const reversedPosX = mouseX - contentsWidth - distanceMouseAndTooltip;
188
- const reversedPosY = mouseY - tooltipDOMSize.height - distanceMouseAndTooltip;
214
+ const reversedPosY = mouseY - tooltipDOMHeight - distanceMouseAndTooltip;
189
215
  this.tooltipDOM.style.left = expectedPosX > maximumPosX
190
216
  ? `${reversedPosX}px`
191
217
  : `${expectedPosX}px`;
@@ -225,39 +251,21 @@ const modules = {
225
251
  drawTooltip(hitInfo, context) {
226
252
  const ctx = context;
227
253
  const items = hitInfo.items;
228
- const sId = hitInfo.hitId;
229
- const hitItem = items[sId].data;
230
- const hitAxis = items[sId].axis;
231
254
  const [, maxValue] = hitInfo.maxTip;
232
255
  const seriesKeys = this.alignSeriesList(Object.keys(items));
233
256
  const boxPadding = this.getBoxPadding();
234
257
  const isHorizontal = this.options.horizontal;
235
258
  const opt = this.options.tooltip;
236
- const titleFormatter = opt.formatter?.title;
237
259
  const textHeight = this.getTextHeight();
238
260
  const seriesColorMarginRight = this.getColorMargin();
239
261
 
240
- // draw tooltip Title(axis label) and add style class for wrap line about too much long label.
241
- if (this.axesX.length && this.axesY.length) {
242
- if (titleFormatter) {
243
- this.tooltipHeaderDOM.textContent = titleFormatter({
244
- x: hitItem.x,
245
- y: hitItem.y,
246
- });
247
- } else {
248
- this.tooltipHeaderDOM.textContent = this.options.horizontal
249
- ? this.axesY[hitAxis.y].getLabelFormat(hitItem.y)
250
- : this.axesX[hitAxis.x].getLabelFormat(hitItem.x);
251
- }
262
+ // draw Tooltip header DOM
263
+ if (this.axesX.length && this.axesY.length && opt.showHeader) {
264
+ this.tooltipHeaderDOM.style.visibility = 'visible';
252
265
  } else {
253
- // Pie Chart
254
266
  this.tooltipHeaderDOM.style.display = 'none';
255
267
  }
256
268
 
257
- if (opt.textOverflow) {
258
- this.tooltipHeaderDOM.classList.add(`ev-chart-tooltip-header--${opt.textOverflow}`);
259
- }
260
-
261
269
  // draw tooltip contents (series, value combination)
262
270
  let x = 2;
263
271
  let y = 2;
@@ -399,7 +407,6 @@ const modules = {
399
407
  const boxPadding = this.getBoxPadding();
400
408
  const isHorizontal = this.options.horizontal;
401
409
  const opt = this.options.tooltip;
402
- const titleFormatter = opt.formatter?.title;
403
410
  const series = Object.values(this.seriesList)[0];
404
411
  const textHeight = this.getTextHeight();
405
412
  const seriesColorMarginRight = this.getColorMargin();
@@ -423,20 +430,11 @@ const modules = {
423
430
  return;
424
431
  }
425
432
 
426
- // draw tooltip Title(axis label) and add style class for wrap line about too much long label.
427
- if (this.axesX.length) {
428
- if (titleFormatter) {
429
- this.tooltipHeaderDOM.textContent = titleFormatter({
430
- x: hitItem.x,
431
- y: hitItem.y,
432
- });
433
- } else {
434
- this.tooltipHeaderDOM.textContent = this.axesX[hitAxis.x].getLabelFormat(hitItem.x);
435
- }
436
- }
437
-
438
- if (opt.textOverflow) {
439
- this.tooltipHeaderDOM.classList.add(`ev-chart-tooltip-header--${opt.textOverflow}`);
433
+ // draw Tooltip header DOM
434
+ if (this.axesX.length && this.axesY.length && opt.showHeader) {
435
+ this.tooltipHeaderDOM.style.visibility = 'visible';
436
+ } else {
437
+ this.tooltipHeaderDOM.style.display = 'none';
440
438
  }
441
439
 
442
440
  this.setTooltipDOMStyle(opt);
@@ -501,6 +499,13 @@ const modules = {
501
499
  const textHeight = this.getTextHeight();
502
500
  const seriesColorMarginRight = this.getColorMargin();
503
501
 
502
+ // draw Tooltip header DOM
503
+ if (this.axesX.length && this.axesY.length && opt.showHeader) {
504
+ this.tooltipHeaderDOM.style.visibility = 'visible';
505
+ } else {
506
+ this.tooltipHeaderDOM.style.display = 'none';
507
+ }
508
+
504
509
  let x = 2;
505
510
  let y = 2;
506
511
 
@@ -747,30 +752,30 @@ const modules = {
747
752
  };
748
753
  const mouseXIp = 1; // mouseInterpolation
749
754
  const mouseYIp = 10;
755
+ const options = this.options;
750
756
 
751
757
  if (offsetX >= (graphPos.x1 - mouseXIp) && offsetX <= (graphPos.x2 + mouseXIp)
752
758
  && offsetY >= (graphPos.y1 - mouseYIp) && offsetY <= (graphPos.y2 + mouseYIp)) {
753
- if (this.options.horizontal) {
754
- ctx.beginPath();
755
- ctx.save();
756
- ctx.strokeStyle = color;
757
- ctx.lineWidth = 1;
759
+ ctx.beginPath();
760
+ ctx.save();
761
+ ctx.strokeStyle = color;
762
+ ctx.lineWidth = 1;
763
+
764
+ if (options.indicator?.segments) {
765
+ ctx.setLineDash(options.indicator.segments);
766
+ }
767
+
768
+ if (options.horizontal) {
758
769
  ctx.moveTo(graphPos.x1, offsetY + 0.5);
759
770
  ctx.lineTo(graphPos.x2, offsetY + 0.5);
760
- ctx.stroke();
761
- ctx.restore();
762
- ctx.closePath();
763
771
  } else {
764
- ctx.beginPath();
765
- ctx.save();
766
- ctx.strokeStyle = color;
767
- ctx.lineWidth = 1;
768
772
  ctx.moveTo(offsetX + 0.5, graphPos.y1);
769
773
  ctx.lineTo(offsetX + 0.5, graphPos.y2);
770
- ctx.stroke();
771
- ctx.restore();
772
- ctx.closePath();
773
774
  }
775
+
776
+ ctx.stroke();
777
+ ctx.restore();
778
+ ctx.closePath();
774
779
  }
775
780
  },
776
781
 
@@ -107,14 +107,16 @@ const DEFAULT_OPTIONS = {
107
107
  },
108
108
  rowPadding: {
109
109
  top: 0,
110
- bottom: 8,
110
+ bottom: 3,
111
111
  right: 20,
112
112
  left: 16,
113
113
  },
114
+ showHeader: true,
114
115
  },
115
116
  indicator: {
116
117
  use: true,
117
118
  color: '#EE7F44',
119
+ segments: null,
118
120
  },
119
121
  maxTip: {
120
122
  use: false,
@@ -7,7 +7,7 @@
7
7
  class="ev-menu-li"
8
8
  :class="{ disabled: item.disabled }"
9
9
  @click="handleItemClick(item)"
10
- @mouseenter="!item.disabled ? mouseenterLi($event, item.children) : (() => {})()"
10
+ @mouseenter="mouseenterLi($event, item)"
11
11
  >
12
12
  <i
13
13
  v-if="!!item.iconClass"
@@ -190,14 +190,14 @@ export const useMenuList = () => {
190
190
  /**
191
191
  * 항목에 마우스엔터 시 발생하는 이벤트
192
192
  * @param e - 마우스 이벤트 (showChild에 넘김)
193
- * @param children - 자식 리스트
193
+ * @param item - 마우스오버된 메뉴
194
194
  * @returns null
195
195
  */
196
- const mouseenterLi = async (e, children) => {
197
- if (!children || !Array.isArray(children)) {
196
+ const mouseenterLi = async (e, item) => {
197
+ if (!item.children || !Array.isArray(item.children) || item.disabled) {
198
198
  hideChild();
199
199
  } else {
200
- await showChild(e, children);
200
+ await showChild(e, item.children);
201
201
  }
202
202
  };
203
203
 
@@ -495,7 +495,7 @@
495
495
  :item="{ row }"
496
496
  />
497
497
  </tr>
498
- </template>
498
+ </template>
499
499
  <tr v-if="!viewStore.length">
500
500
  <td class="is-empty">No records</td>
501
501
  </tr>
@@ -672,6 +672,7 @@ export default {
672
672
  'sort-column': null,
673
673
  'expand-row': null,
674
674
  'update:expanded': null,
675
+ 'resize:column': column => column,
675
676
  },
676
677
  setup(props) {
677
678
  // const ROW_INDEX = 0;
@@ -176,7 +176,7 @@ export const scrollEvent = (params) => {
176
176
  };
177
177
 
178
178
  export const resizeEvent = (params) => {
179
- const { props } = getCurrentInstance();
179
+ const { props, emit } = getCurrentInstance();
180
180
  const {
181
181
  resizeInfo,
182
182
  elementInfo,
@@ -344,6 +344,7 @@ export const resizeEvent = (params) => {
344
344
  resizeInfo.showResizeLine = false;
345
345
  document.removeEventListener('mousemove', handleMouseMove);
346
346
  onResize();
347
+ emit('resize:column', stores.orderedColumns[columnIndex]);
347
348
  };
348
349
 
349
350
  document.addEventListener('mousemove', handleMouseMove);
@@ -14,7 +14,7 @@
14
14
  @show-context-menu="getContextMenuFlag"
15
15
  @contextmenu.prevent="showContextMenu"
16
16
  />
17
- <div v-if="!treeNodeData.length">{{ emptyText }}</div>
17
+ <div v-if="isShowEmptyText">{{ emptyText }}</div>
18
18
  <ev-context-menu
19
19
  v-if="contextMenuItems.length"
20
20
  ref="contextMenu"
@@ -24,7 +24,7 @@
24
24
  </template>
25
25
 
26
26
  <script>
27
- import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
27
+ import { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';
28
28
  import TreeNode from './TreeNode';
29
29
 
30
30
  export default {
@@ -278,6 +278,9 @@ export default {
278
278
  });
279
279
  }
280
280
 
281
+ const isShowEmptyText = computed(() => !treeNodeData.value.length
282
+ || treeNodeData.value.every(node => !node.visible));
283
+
281
284
  watch(() => props.data, (newData) => {
282
285
  treeNodeData.value = newData;
283
286
  allNodeInfo = getAllNodeInfo();
@@ -320,6 +323,7 @@ export default {
320
323
  treeNodeData,
321
324
  contextMenu,
322
325
  component,
326
+ isShowEmptyText,
323
327
  updateCheckedInfo,
324
328
  clickContent,
325
329
  dblClickContent,