evui 3.3.13 → 3.3.16

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.
@@ -144,15 +144,22 @@ const modules = {
144
144
  maxIndex: args.dataIndex,
145
145
  acc: args.acc,
146
146
  } = hitInfo);
147
- }
148
-
149
- if (this.options.selectLabel.use) {
147
+ } else if (this.options.selectLabel.use) {
150
148
  const offset = this.getMousePosition(e);
151
149
  const clickedLabelInfo = this.getLabelInfoByPosition(offset);
152
150
  const selected = this.selectLabel(clickedLabelInfo.labelIndex);
153
- this.renderWithSelectLabel(selected.dataIndex);
151
+ this.renderWithSelected(selected.dataIndex);
152
+
153
+ args.selected = cloneDeep(this.defaultSelectInfo);
154
+ } else if (this.options.selectSeries.use) {
155
+ const offset = this.getMousePosition(e);
156
+ const hitInfo = this.getSeriesIdByPosition(offset);
157
+ if (hitInfo.sId !== null) {
158
+ const selected = this.selectSeries(hitInfo.sId);
159
+ this.renderWithSelected(selected.seriesId);
160
+ }
154
161
 
155
- args.selected = cloneDeep(this.defaultSelectLabelInfo);
162
+ args.selected = cloneDeep(this.defaultSelectInfo);
156
163
  }
157
164
 
158
165
  if (typeof this.listeners.click === 'function') {
@@ -266,12 +273,21 @@ const modules = {
266
273
  yep = aOffsetY;
267
274
  }
268
275
 
269
- dragInfo.xsp = Math.min(xcp, xep);
270
- dragInfo.ysp = type === 'scatter' || type === 'heatMap' ? Math.min(ycp, yep) : aRange.y1;
271
- dragInfo.width = Math.ceil(Math.abs(xep - xcp));
272
- dragInfo.height = type === 'scatter' || type === 'heatMap'
276
+ if (type === 'heatMap') {
277
+ const rangeInfo = { xcp, xep, ycp, yep, range: aRange };
278
+ const { xsp, ysp, width, height } = this.getDragInfoForHeatMap(rangeInfo);
279
+ dragInfo.xsp = xsp;
280
+ dragInfo.ysp = ysp;
281
+ dragInfo.width = width;
282
+ dragInfo.height = height;
283
+ } else {
284
+ dragInfo.xsp = Math.min(xcp, xep);
285
+ dragInfo.ysp = type === 'scatter' ? Math.min(ycp, yep) : aRange.y1;
286
+ dragInfo.width = Math.ceil(Math.abs(xep - xcp));
287
+ dragInfo.height = type === 'scatter'
273
288
  ? Math.ceil(Math.abs(yep - ycp))
274
289
  : aRange.y2 - aRange.y1;
290
+ }
275
291
 
276
292
  this.overlayClear();
277
293
  this.drawSelectionArea(dragInfo);
@@ -289,7 +305,9 @@ const modules = {
289
305
  const args = {
290
306
  e,
291
307
  data: this.findSelectedItems(dragInfo),
292
- range: this.getSelectionRage(dragInfo),
308
+ range: type === 'heatMap'
309
+ ? this.getSelectionRangeForHeatMap(dragInfo)
310
+ : this.getSelectionRage(dragInfo),
293
311
  };
294
312
 
295
313
  this.dragInfoBackup = defaultsDeep({}, dragInfo);
@@ -456,32 +474,51 @@ const modules = {
456
474
  },
457
475
 
458
476
  /**
459
- * render after select label by index list
477
+ * render after selected label or selected series
460
478
  * @param indexList {array} '[0, 1 ...]'
461
479
  */
462
- renderWithSelectLabel(indexList) {
463
- this.defaultSelectLabelInfo.dataIndex = indexList;
464
- this.initSelectedLabelInfo();
480
+ renderWithSelected(list) {
481
+ if (this.options.selectLabel.use) {
482
+ this.defaultSelectInfo.dataIndex = list;
483
+ } else if (this.options.selectSeries.use) {
484
+ this.defaultSelectInfo.seriesId = list;
485
+ }
486
+ this.initSelectedInfo();
465
487
  this.render();
466
488
  },
467
489
 
468
490
  /**
469
- * init defaultSelectLabelInfo object.
470
- * (set each series data and label text)
491
+ * init defaultSelectInfo object.
492
+ * - at selectLabel using: set each series data and label text
493
+ * - at selectSeries using: set series state
471
494
  */
472
- initSelectedLabelInfo() {
473
- const { use, limit } = this.options.selectLabel;
474
-
475
- if (use) {
476
- if (!this.defaultSelectLabelInfo) {
477
- this.defaultSelectLabelInfo = { dataIndex: [] };
495
+ initSelectedInfo() {
496
+ if (this.options.selectLabel.use) {
497
+ const { limit } = this.options.selectLabel;
498
+ if (!this.defaultSelectInfo) {
499
+ this.defaultSelectInfo = { dataIndex: [] };
478
500
  }
479
- const infoObj = this.defaultSelectLabelInfo;
501
+ const infoObj = this.defaultSelectInfo;
480
502
  infoObj.dataIndex.splice(limit);
481
503
  infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
482
504
  const dataEntries = Object.entries(this.data.data);
483
505
  infoObj.data = infoObj.dataIndex.map(labelIdx => Object.fromEntries(
484
506
  dataEntries.map(([sId, data]) => [sId, data[labelIdx]])));
507
+ } else if (this.options.selectSeries.use) {
508
+ if (!this.defaultSelectInfo) {
509
+ this.defaultSelectInfo = { seriesId: [] };
510
+ }
511
+
512
+ const selectedList = this.defaultSelectInfo.seriesId;
513
+ Object.values(this.seriesList).forEach((series) => {
514
+ if (!selectedList.length) {
515
+ series.state = 'normal';
516
+ } else if (selectedList.includes(series.sId)) {
517
+ series.state = 'highlight';
518
+ } else {
519
+ series.state = 'downplay';
520
+ }
521
+ });
485
522
  }
486
523
  },
487
524
 
@@ -492,7 +529,7 @@ const modules = {
492
529
  */
493
530
  selectLabel(labelIndex) {
494
531
  const option = this.options?.selectLabel ?? {};
495
- const before = this.defaultSelectLabelInfo ?? { dataIndex: [] };
532
+ const before = this.defaultSelectInfo ?? { dataIndex: [] };
496
533
  const after = cloneDeep(before);
497
534
 
498
535
  if (before.dataIndex.includes(labelIndex)) {
@@ -512,6 +549,28 @@ const modules = {
512
549
  return after;
513
550
  },
514
551
 
552
+ selectSeries(seriesId) {
553
+ const option = this.options?.selectSeries ?? {};
554
+ const before = this.defaultSelectInfo ?? { seriesId: [] };
555
+ const after = cloneDeep(before);
556
+
557
+ if (before.seriesId.includes(seriesId)) {
558
+ const idx = before.seriesId.indexOf(seriesId);
559
+ after.seriesId.splice(idx, 1);
560
+ } else if (seriesId) {
561
+ after.seriesId.push(seriesId);
562
+ if (option.limit > 0 && option.limit < after.seriesId.length) {
563
+ if (option.useDeselectOverflow) {
564
+ after.seriesId.splice(0, 1);
565
+ } else {
566
+ after.seriesId.pop();
567
+ }
568
+ }
569
+ }
570
+
571
+ return after;
572
+ },
573
+
515
574
  /**
516
575
  * Find items by series within a range
517
576
  * @param {object} range object for find series items
@@ -591,6 +650,30 @@ const modules = {
591
650
 
592
651
  return targetValue / total;
593
652
  },
653
+
654
+ getDragInfoForHeatMap(range) {
655
+ const sId = Object.keys(this.seriesList)[0];
656
+ return this.seriesList[sId].findBlockRange(range);
657
+ },
658
+
659
+ getSelectionRangeForHeatMap(range) {
660
+ const dataRangeX = this.axesSteps.x.length ? this.axesSteps.x[0] : null;
661
+ const dataRangeY = this.axesSteps.y.length ? this.axesSteps.y[0] : null;
662
+
663
+ if (!dataRangeX || !dataRangeY) {
664
+ return null;
665
+ }
666
+
667
+ const sId = Object.keys(this.seriesList)[0];
668
+ const { xMin, xMax, yMin, yMax } = this.seriesList[sId].findSelectionRange(range);
669
+
670
+ return {
671
+ xMin: xMin ?? dataRangeX.graphMin,
672
+ xMax: xMax ?? dataRangeX.graphMax,
673
+ yMin: yMin ?? dataRangeY.graphMin,
674
+ yMax: yMax ?? dataRangeY.graphMax,
675
+ };
676
+ },
594
677
  };
595
678
 
596
679
  export default modules;
@@ -1,3 +1,5 @@
1
+ import Util from '@/components/chart/helpers/helpers.util';
2
+
1
3
  const modules = {
2
4
  /**
3
5
  * Create legend DOM
@@ -80,13 +82,14 @@ const modules = {
80
82
  Object.values(seriesList).forEach((series) => {
81
83
  if (!series.isExistGrp && series.showLegend) {
82
84
  const { colorAxis, valueOpt } = series;
83
- const { max, interval, existError } = valueOpt;
85
+ const { min, max, interval, existError } = valueOpt;
86
+ const endIndex = colorAxis.length - 1;
84
87
  colorAxis.forEach((colorItem, index) => {
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
89
- ? 'error' : `${minValue} - ${maxValue}`;
88
+ const minValue = min + (interval * index);
89
+ const maxValue = index === endIndex
90
+ ? max : minValue + interval;
91
+ const name = existError && index === endIndex ? 'error' : `${minValue} - ${maxValue}`;
92
+
90
93
  this.addLegend({
91
94
  cId: colorItem.id,
92
95
  color: colorItem.value,
@@ -191,15 +194,24 @@ const modules = {
191
194
  }
192
195
  const nameDOM = targetDOM.getElementsByClassName('ev-chart-legend-name')[0];
193
196
  const targetId = nameDOM.series.sId;
197
+ const selectSeriesOption = this.options.selectSeries;
198
+ const selectedList = this.defaultSelectInfo?.seriesId ?? [];
194
199
 
195
200
  Object.values(this.seriesList).forEach((series) => {
196
- series.state = series.sId === targetId ? 'highlight' : 'downplay';
201
+ series.state = series.sId === targetId
202
+ || (selectSeriesOption.use && selectedList.includes(targetId))
203
+ ? 'highlight' : 'downplay';
197
204
  });
198
205
 
206
+ let hitInfo = null;
207
+ if (Util.isPieType(this.options.type)) {
208
+ hitInfo = { sId: targetId, type: this.options.type };
209
+ }
210
+
199
211
  this.update({
200
212
  updateSeries: false,
201
213
  updateSelTip: { update: false, keepDomain: false },
202
- hitInfo: { sId: targetId },
214
+ hitInfo,
203
215
  });
204
216
  };
205
217
 
@@ -209,8 +221,15 @@ const modules = {
209
221
  * @returns {undefined}
210
222
  */
211
223
  this.onLegendBoxLeave = () => {
224
+ const selectSeriesOption = this.options.selectSeries;
225
+ const selectedList = this.defaultSelectInfo?.seriesId ?? [];
212
226
  Object.values(this.seriesList).forEach((series) => {
213
- series.state = 'normal';
227
+ if (selectSeriesOption.use && selectedList.length) {
228
+ series.state = selectedList.includes(series.sId)
229
+ ? 'highlight' : 'downplay';
230
+ } else {
231
+ series.state = 'normal';
232
+ }
214
233
  });
215
234
 
216
235
  this.update({
@@ -408,7 +408,7 @@ const modules = {
408
408
  }
409
409
 
410
410
  // 3. Draw value
411
- let formattedTxt;
411
+ let formattedTxt = itemValue;
412
412
  if (opt.formatter) {
413
413
  formattedTxt = opt.formatter({
414
414
  x: xValue,
@@ -419,8 +419,6 @@ const modules = {
419
419
 
420
420
  if ((!opt.formatter || typeof formattedTxt !== 'string') && itemValue !== 'error') {
421
421
  formattedTxt = numberWithComma(itemValue);
422
- } else {
423
- formattedTxt = itemValue;
424
422
  }
425
423
 
426
424
  ctx.textAlign = 'right';
@@ -164,7 +164,7 @@ class Scale {
164
164
  *
165
165
  * @returns {undefined}
166
166
  */
167
- draw(chartRect, labelOffset, stepInfo, hitInfo) {
167
+ draw(chartRect, labelOffset, stepInfo, hitInfo, selectLabelInfo) {
168
168
  const ctx = this.ctx;
169
169
  const options = this.options;
170
170
  const aPos = {
@@ -239,6 +239,13 @@ class Scale {
239
239
  linePosition = labelCenter + aliasPixel;
240
240
  labelText = this.getLabelFormat(Math.min(axisMax, ticks[ix]));
241
241
 
242
+ const isBlurredLabel = this.options?.selectLabel?.use
243
+ && this.options?.selectLabel?.useLabelOpacity
244
+ && (this.options.horizontal === (this.type === 'y'))
245
+ && selectLabelInfo?.dataIndex?.length
246
+ && !selectLabelInfo?.label
247
+ .map(t => this.getLabelFormat(Math.min(axisMax, t))).includes(labelText);
248
+
242
249
  const labelColor = this.labelStyle.color;
243
250
  let defaultOpacity = 1;
244
251
 
@@ -246,14 +253,17 @@ class Scale {
246
253
  defaultOpacity = Util.getOpacity(labelColor);
247
254
  }
248
255
 
249
- ctx.fillStyle = Util.colorStringToRgba(labelColor, defaultOpacity);
256
+ ctx.fillStyle = Util.colorStringToRgba(labelColor, isBlurredLabel ? 0.1 : defaultOpacity);
250
257
 
251
258
  let labelPoint;
252
259
 
253
260
  if (this.type === 'x') {
254
261
  labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
255
262
  ctx.fillText(labelText, labelCenter, labelPoint);
256
- if (options?.selectItem?.showLabelTip && hitInfo?.label && !this.options?.horizontal) {
263
+ if (!isBlurredLabel
264
+ && options?.selectItem?.showLabelTip
265
+ && hitInfo?.label
266
+ && !this.options?.horizontal) {
257
267
  const selectedLabel = this.getLabelFormat(
258
268
  Math.min(axisMax, hitInfo.label + (0 * stepValue)),
259
269
  );
@@ -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: {
@@ -94,6 +95,11 @@ const DEFAULT_OPTIONS = {
94
95
  useApproximateValue: false,
95
96
  tipBackground: '#000000',
96
97
  },
98
+ selectSeries: {
99
+ use: false,
100
+ limit: 1,
101
+ useDeselectOverflow: false,
102
+ },
97
103
  dragSelection: {
98
104
  use: false,
99
105
  keepDisplay: true,
@@ -108,6 +114,7 @@ const DEFAULT_OPTIONS = {
108
114
  show: false,
109
115
  color: '#FFFFFF',
110
116
  lineWidth: 1,
117
+ opacity: 1,
111
118
  },
112
119
  error: '#FF0000',
113
120
  },
@@ -145,6 +152,7 @@ export const useModel = () => {
145
152
 
146
153
  const selectItemInfo = cloneDeep(props.selectedItem);
147
154
  const selectLabelInfo = cloneDeep(props.selectedLabel);
155
+ const selectSeriesInfo = cloneDeep(props.selectedSeries);
148
156
 
149
157
  const eventListeners = {
150
158
  click: async (e) => {
@@ -152,9 +160,12 @@ export const useModel = () => {
152
160
  if (e.label) {
153
161
  emit('update:selectedItem', { seriesID: e.seriesId, dataIndex: e.dataIndex });
154
162
  }
155
- if (e.selected) {
163
+ if (e.selected?.dataIndex) {
156
164
  emit('update:selectedLabel', { dataIndex: e.selected.dataIndex });
157
165
  }
166
+ if (e.selected?.seriesId) {
167
+ emit('update:selectedSeries', { seriesId: e.selected.seriesId });
168
+ }
158
169
  emit('click', e);
159
170
  },
160
171
  'dbl-click': async (e) => {
@@ -171,6 +182,7 @@ export const useModel = () => {
171
182
  eventListeners,
172
183
  selectItemInfo,
173
184
  selectLabelInfo,
185
+ selectSeriesInfo,
174
186
  getNormalizedData,
175
187
  getNormalizedOptions,
176
188
  };
@@ -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 이벤트를 처리한다.