evui 3.3.14 → 3.3.17

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.
@@ -7,7 +7,6 @@ class StepScale extends Scale {
7
7
  constructor(type, opt, ctx, labels, options) {
8
8
  super(type, opt, ctx, options);
9
9
  this.labels = labels;
10
- this.rangeMode = opt.rangeMode;
11
10
  }
12
11
 
13
12
  /**
@@ -18,7 +17,8 @@ class StepScale extends Scale {
18
17
  * @returns {object} min/max value and label
19
18
  */
20
19
  calculateScaleRange(minMax, chartRect) {
21
- const stepMinMax = Util.getStringMinMax(this.labels);
20
+ const stepMinMax = this.rangeMode
21
+ ? minMax : Util.getStringMinMax(this.labels);
22
22
  const maxValue = stepMinMax.max;
23
23
  const minValue = stepMinMax.min;
24
24
  const maxWidth = chartRect.chartWidth / (this.labels.length + 2);
@@ -42,9 +42,20 @@ class StepScale extends Scale {
42
42
  * @returns {object} steps, interval, min/max graph value
43
43
  */
44
44
  calculateSteps(range) {
45
+ let numberOfSteps = this.labels.length;
46
+ let interval = 1;
47
+
48
+ if (this.rangeMode) {
49
+ const { maxSteps } = range;
50
+
51
+ while (numberOfSteps > maxSteps * 2) {
52
+ interval *= 2;
53
+ numberOfSteps = Math.round(numberOfSteps / interval);
54
+ }
55
+ }
45
56
  return {
46
- steps: this.labels.length,
47
- interval: 1,
57
+ steps: numberOfSteps,
58
+ interval,
48
59
  graphMin: range.minValue,
49
60
  graphMax: range.maxValue,
50
61
  };
@@ -68,7 +79,9 @@ class StepScale extends Scale {
68
79
  y2: chartRect.y2 - labelOffset.bottom,
69
80
  };
70
81
 
82
+ const oriSteps = this.labels.length;
71
83
  const steps = stepInfo.steps;
84
+ const count = stepInfo.interval;
72
85
 
73
86
  const startPoint = aPos[this.units.rectStart];
74
87
  const endPoint = aPos[this.units.rectEnd];
@@ -116,8 +129,10 @@ class StepScale extends Scale {
116
129
 
117
130
  let labelText;
118
131
  let labelPoint;
132
+ let index;
119
133
 
120
- labels.forEach((item, index) => {
134
+ for (index = 0; index < oriSteps; index += count) {
135
+ const item = this.labels[index];
121
136
  labelCenter = Math.round(startPoint + (labelGap * index));
122
137
  linePosition = labelCenter + aliasPixel;
123
138
  labelText = this.getLabelFormat(item, maxWidth);
@@ -143,9 +158,9 @@ class StepScale extends Scale {
143
158
  ctx.fillText(labelText, xPoint, labelPoint);
144
159
 
145
160
  if (!isBlurredLabel
146
- && this.options?.selectItem?.showLabelTip
147
- && hitInfo?.label
148
- && !this.options?.horizontal) {
161
+ && this.options?.selectItem?.showLabelTip
162
+ && hitInfo?.label
163
+ && !this.options?.horizontal) {
149
164
  const selectedLabel = hitInfo.label;
150
165
  if (selectedLabel === labelText) {
151
166
  const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
@@ -179,9 +194,9 @@ class StepScale extends Scale {
179
194
  }
180
195
  }
181
196
  ctx.stroke();
182
- });
197
+ }
183
198
 
184
- if (this.rangeMode) {
199
+ if (this.rangeMode && (index === this.labels.length)) {
185
200
  let labelLastText = +labels[labels.length - 1] + (+labels[1] - +labels[0]);
186
201
  if (isNaN(labelLastText)) {
187
202
  labelLastText = 'Max';
@@ -43,6 +43,7 @@ const DEFAULT_OPTIONS = {
43
43
  width: '100%',
44
44
  height: '100%',
45
45
  thickness: 1,
46
+ cPadRatio: 0,
46
47
  borderRadius: 0,
47
48
  combo: false,
48
49
  tooltip: {
@@ -113,8 +114,10 @@ const DEFAULT_OPTIONS = {
113
114
  show: false,
114
115
  color: '#FFFFFF',
115
116
  lineWidth: 1,
117
+ opacity: 1,
116
118
  },
117
119
  error: '#FF0000',
120
+ decimalPoint: 0,
118
121
  },
119
122
  };
120
123
 
@@ -198,12 +198,12 @@
198
198
  }"
199
199
  >
200
200
  <!-- Cell Renderer -->
201
- <template v-if="!!$slots[column.field]">
201
+ <div v-if="!!$slots[column.field]">
202
202
  <slot
203
203
  :name="column.field"
204
204
  :item="{ row, column }"
205
205
  />
206
- </template>
206
+ </div>
207
207
  <!-- Cell Value -->
208
208
  <template v-else>
209
209
  <div :title="getConvertValue(column, row[2][column.index])">
@@ -257,6 +257,7 @@
257
257
  minWidth,
258
258
  rowHeight,
259
259
  }"
260
+ :scroll-left="summaryScroll"
260
261
  />
261
262
  <!-- Pagination -->
262
263
  <grid-pagination
@@ -271,7 +272,7 @@
271
272
  </template>
272
273
 
273
274
  <script>
274
- import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick } from 'vue';
275
+ import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick, ref } from 'vue';
275
276
  import Toolbar from './grid.toolbar';
276
277
  import FilterWindow from './grid.filter.window';
277
278
  import GridPagination from './grid.pagination';
@@ -474,7 +475,7 @@ export default {
474
475
  elementInfo,
475
476
  clearCheckInfo,
476
477
  });
477
-
478
+ const summaryScroll = ref(0);
478
479
  const {
479
480
  updateVScroll,
480
481
  updateHScroll,
@@ -485,6 +486,7 @@ export default {
485
486
  elementInfo,
486
487
  resizeInfo,
487
488
  pageInfo,
489
+ summaryScroll,
488
490
  getPagingData,
489
491
  updatePagingInfo,
490
492
  });
@@ -751,6 +753,7 @@ export default {
751
753
  },
752
754
  );
753
755
  return {
756
+ summaryScroll,
754
757
  showHeader,
755
758
  stripeStyle,
756
759
  borderStyle,
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div
3
+ ref="summaryRef"
3
4
  :class="{
4
5
  'grid-summary': true,
5
6
  'non-border': styleInfo.borderStyle === 'none',
@@ -44,12 +45,18 @@
44
45
  height: `${styleInfo.rowHeight}px`,
45
46
  }"
46
47
  >
47
- <template v-if="column.summaryRenderer">
48
+ <div
49
+ v-if="column.summaryRenderer"
50
+ :title="getSummaryRenderer(column)"
51
+ >
48
52
  {{ getSummaryRenderer(column) }}
49
- </template>
50
- <template v-else>
53
+ </div>
54
+ <div
55
+ v-else
56
+ :title="getSummaryValue(column, column.summaryType)"
57
+ >
51
58
  {{ getSummaryValue(column, column.summaryType)}}
52
- </template>
59
+ </div>
53
60
  </span>
54
61
  <span
55
62
  v-else
@@ -62,7 +69,7 @@
62
69
  </template>
63
70
 
64
71
  <script>
65
- import { computed } from 'vue';
72
+ import { computed, watch, ref, nextTick } from 'vue';
66
73
  import { numberWithComma } from '@/common/utils';
67
74
 
68
75
  export default {
@@ -88,8 +95,13 @@ export default {
88
95
  type: Boolean,
89
96
  default: false,
90
97
  },
98
+ scrollLeft: {
99
+ type: Number,
100
+ default: 0,
101
+ },
91
102
  },
92
103
  setup(props) {
104
+ const summaryRef = ref();
93
105
  const ROW_DATA_INDEX = 2;
94
106
  const stores = computed(() => props.stores);
95
107
  const columns = computed(() => props.orderedColumns);
@@ -102,7 +114,8 @@ export default {
102
114
  convertValue = numberWithComma(value);
103
115
  convertValue = convertValue === false ? value : convertValue;
104
116
  } else if (column.type === 'float') {
105
- convertValue = convertValue.toFixed(column.decimal ?? 3);
117
+ const floatValue = convertValue.toFixed(column.decimal ?? 3);
118
+ convertValue = floatValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
106
119
  }
107
120
 
108
121
  return convertValue;
@@ -175,10 +188,19 @@ export default {
175
188
  });
176
189
  return result;
177
190
  };
191
+ watch(
192
+ () => props.scrollLeft,
193
+ (val) => {
194
+ nextTick(() => {
195
+ summaryRef.value.scrollLeft = val;
196
+ });
197
+ },
198
+ );
178
199
  return {
179
200
  columns,
180
201
  styleInfo,
181
202
  showCheckbox,
203
+ summaryRef,
182
204
  getSummaryValue,
183
205
  getSummaryRenderer,
184
206
  };
@@ -189,6 +211,9 @@ export default {
189
211
  <style lang="scss" scoped>
190
212
  @import 'style/grid.scss';
191
213
  .grid-summary {
214
+ width: 100%;
215
+ overflow: hidden;
216
+
192
217
  @include evThemify() {
193
218
  border-bottom: 1px solid evThemed('disabled');
194
219
  background-color: evThemed('background-lighten');
@@ -201,6 +226,11 @@ export default {
201
226
  overflow: hidden;
202
227
  text-overflow: ellipsis;
203
228
  font-size: 14px;
229
+ > div {
230
+ white-space: nowrap;
231
+ overflow: hidden;
232
+ text-overflow: ellipsis;
233
+ }
204
234
 
205
235
  @include evThemify() {
206
236
  color: evThemed('font-color-base');
@@ -44,7 +44,8 @@ export const commonFunctions = () => {
44
44
  convertValue = numberWithComma(value);
45
45
  convertValue = convertValue === false ? value : convertValue;
46
46
  } else if (column.type === 'float') {
47
- convertValue = convertValue.toFixed(column.decimal ?? 3);
47
+ const floatValue = convertValue.toFixed(column.decimal ?? 3);
48
+ convertValue = floatValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
48
49
  }
49
50
 
50
51
  return convertValue;
@@ -75,6 +76,7 @@ export const scrollEvent = (params) => {
75
76
  elementInfo,
76
77
  resizeInfo,
77
78
  pageInfo,
79
+ summaryScroll,
78
80
  getPagingData,
79
81
  updatePagingInfo,
80
82
  } = params;
@@ -122,6 +124,7 @@ export const scrollEvent = (params) => {
122
124
  const bodyEl = elementInfo.body;
123
125
 
124
126
  headerEl.scrollLeft = bodyEl.scrollLeft;
127
+ summaryScroll.value = bodyEl.scrollLeft;
125
128
  };
126
129
  /**
127
130
  * scroll 이벤트를 처리한다.
@@ -871,12 +874,14 @@ export const contextMenuEvent = (params) => {
871
874
  } else {
872
875
  rowIndex = target.parentElement.parentElement.dataset.index;
873
876
  }
874
-
877
+ let clickedRow;
875
878
  if (rowIndex) {
876
- const rowData = stores.viewStore[+rowIndex][ROW_DATA_INDEX];
877
- selectInfo.selectedRow = rowData;
879
+ clickedRow = stores.viewStore.find(row => row[ROW_INDEX] === +rowIndex)?.[ROW_DATA_INDEX];
880
+ }
881
+ if (clickedRow) {
882
+ selectInfo.selectedRow = clickedRow;
878
883
  setContextMenu();
879
- emit('update:selected', rowData);
884
+ emit('update:selected', clickedRow);
880
885
  } else {
881
886
  selectInfo.selectedRow = [];
882
887
  setContextMenu(false);
@@ -6,6 +6,7 @@
6
6
  :item="menu"
7
7
  :selected-item="modelValue"
8
8
  :expandable="expandable"
9
+ :disabled="disabled"
9
10
  :comp="component"
10
11
  @click="clickMenu"
11
12
  />
@@ -34,14 +35,21 @@ export default {
34
35
  type: Boolean,
35
36
  default: true,
36
37
  },
38
+ disabled: {
39
+ type: Boolean,
40
+ default: false,
41
+ },
37
42
  },
38
43
  emits: ['update:modelValue', 'change'],
39
44
  setup(props, { emit }) {
40
45
  const prevMenuItem = ref(props.items.filter(item => props.modelValue === item.value));
41
- const clickMenu = (newMenuItem) => {
42
- emit('update:modelValue', newMenuItem.value);
43
- emit('change', newMenuItem, prevMenuItem.value);
44
- prevMenuItem.value = newMenuItem;
46
+ const clickMenu = (params) => {
47
+ if (!params.disabled) {
48
+ const newMenuItem = params.item;
49
+ emit('update:modelValue', newMenuItem.value);
50
+ emit('change', newMenuItem, prevMenuItem.value);
51
+ prevMenuItem.value = newMenuItem;
52
+ }
45
53
  };
46
54
  const component = MenuItem;
47
55
  return {
@@ -4,14 +4,17 @@
4
4
  :class="[
5
5
  'ev-menu-item',
6
6
  `depth${depth}`,
7
- { active: item.value === selectedItem },
7
+ { active: !item.disabled && item.value === selectedItem },
8
8
  ]">
9
9
  <div
10
10
  :class="[
11
11
  'ev-menu-title',
12
- { 'expandable': hasChild && expandable },
12
+ {
13
+ 'expandable': hasChild && expandable,
14
+ 'disabled': item.disabled,
15
+ },
13
16
  ]"
14
- @click="clickMenu(item, depth)"
17
+ @click="clickMenu({item, depth, disabled: item.disabled})"
15
18
  >
16
19
  <i
17
20
  v-if="!!item.iconClass"
@@ -43,6 +46,7 @@
43
46
  :item="menu"
44
47
  :selected-item="selectedItem"
45
48
  :expandable="expandable"
49
+ :disabled="disabled"
46
50
  :comp="comp"
47
51
  @click="clickMenu"
48
52
  />
@@ -77,6 +81,9 @@ export default {
77
81
  } else if (obj.hidden !== undefined && typeof obj.hidden !== 'boolean') {
78
82
  console.warn('[EVUI][Menu] hidden attribute must be \'Boolean\' type.');
79
83
  return false;
84
+ } else if (obj.disabled !== undefined && typeof obj.disabled !== 'boolean') {
85
+ console.warn('[EVUI][Menu] disabled attribute must be \'Boolean\' type.');
86
+ return false;
80
87
  }
81
88
  return true;
82
89
  },
@@ -93,6 +100,10 @@ export default {
93
100
  type: Object,
94
101
  default: () => {},
95
102
  },
103
+ disabled: {
104
+ type: Boolean,
105
+ default: false,
106
+ },
96
107
  },
97
108
  emits: ['click'],
98
109
  setup(props, { emit }) {
@@ -100,13 +111,13 @@ export default {
100
111
  const isExpand = ref(defaultExpand);
101
112
  const hasChild = computed(() => !!props.item.children && !!props.item.children.length);
102
113
 
103
- const clickMenu = (menuItem, depth) => {
104
- if (hasChild.value && depth === props.depth) {
114
+ const clickMenu = (params) => {
115
+ if (hasChild.value && params.depth === props.depth) {
105
116
  if (props.expandable) {
106
117
  isExpand.value = !isExpand.value;
107
118
  }
108
119
  } else {
109
- emit('click', menuItem, props.depth);
120
+ emit('click', params);
110
121
  }
111
122
  };
112
123
 
@@ -149,6 +160,13 @@ export default {
149
160
  &.expandable {
150
161
  padding-right: 27px;
151
162
  }
163
+ &.disabled {
164
+ color: #848484 !important;
165
+ &:hover {
166
+ cursor: not-allowed;
167
+ color: #848484 !important;
168
+ }
169
+ }
152
170
  .list-expend-icon {
153
171
  position: absolute;
154
172
  top: 50%;
@@ -7,7 +7,6 @@
7
7
  }"
8
8
  v-bind="$attrs"
9
9
  :aria-current="page.isCurrent"
10
- @click.prevent="page.click"
11
10
  >
12
11
  <slot>{{ page.number }}</slot>
13
12
  </span>
@@ -172,6 +172,7 @@
172
172
  minWidth,
173
173
  rowHeight,
174
174
  }"
175
+ :scroll-left="summaryScroll"
175
176
  />
176
177
  <!-- Pagination -->
177
178
  <grid-pagination
@@ -186,7 +187,7 @@
186
187
  </template>
187
188
 
188
189
  <script>
189
- import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick } from 'vue';
190
+ import { reactive, toRefs, computed, watch, onMounted, onActivated, nextTick, ref } from 'vue';
190
191
  import treeGridNode from './TreeGridNode';
191
192
  import Toolbar from './treeGrid.toolbar';
192
193
  import GridPagination from '../grid/grid.pagination';
@@ -380,6 +381,7 @@ export default {
380
381
  elementInfo,
381
382
  clearCheckInfo,
382
383
  });
384
+ const summaryScroll = ref(0);
383
385
  const {
384
386
  updateVScroll,
385
387
  updateHScroll,
@@ -390,6 +392,7 @@ export default {
390
392
  elementInfo,
391
393
  resizeInfo,
392
394
  pageInfo,
395
+ summaryScroll,
393
396
  getPagingData,
394
397
  updatePagingInfo,
395
398
  });
@@ -689,6 +692,7 @@ export default {
689
692
  const getSlotName = column => `${column}Node`;
690
693
 
691
694
  return {
695
+ summaryScroll,
692
696
  gridStyle,
693
697
  gridClass,
694
698
  headerClass,
@@ -39,7 +39,8 @@ export const commonFunctions = (params) => {
39
39
  convertValue = numberWithComma(value);
40
40
  convertValue = convertValue === false ? value : convertValue;
41
41
  } else if (column.type === 'float') {
42
- convertValue = convertValue.toFixed(column.decimal ?? 3);
42
+ const floatValue = convertValue.toFixed(column.decimal ?? 3);
43
+ convertValue = floatValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
43
44
  }
44
45
 
45
46
  return convertValue;
@@ -87,6 +88,7 @@ export const scrollEvent = (params) => {
87
88
  elementInfo,
88
89
  resizeInfo,
89
90
  pageInfo,
91
+ summaryScroll,
90
92
  getPagingData,
91
93
  updatePagingInfo,
92
94
  } = params;
@@ -134,6 +136,7 @@ export const scrollEvent = (params) => {
134
136
  const bodyEl = elementInfo.body;
135
137
 
136
138
  headerEl.scrollLeft = bodyEl.scrollLeft;
139
+ summaryScroll.value = bodyEl.scrollLeft;
137
140
  };
138
141
  /**
139
142
  * scroll 이벤트를 처리한다.