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
@@ -28,18 +28,18 @@ export const commonFunctions = (params) => {
28
28
  /**
29
29
  * 데이터 타입에 따라 변환된 데이터을 반환한다.
30
30
  *
31
- * @param {string} type - 데이터 유형
31
+ * @param {object} column - 컬럼 정보
32
32
  * @param {number|string} value - 데이터
33
33
  * @returns {number|string} 변환된 데이터
34
34
  */
35
- const getConvertValue = (type, value) => {
36
- let convertValue = value;
35
+ const getConvertValue = (column, value) => {
36
+ let convertValue = column.type === 'number' || column.type === 'float' ? Number(value) : value;
37
37
 
38
- if (type === 'number') {
38
+ if (column.type === 'number') {
39
39
  convertValue = numberWithComma(value);
40
40
  convertValue = convertValue === false ? value : convertValue;
41
- } else if (type === 'float') {
42
- convertValue = value.toFixed(3);
41
+ } else if (column.type === 'float') {
42
+ convertValue = convertValue.toFixed(column.decimal ?? 3);
43
43
  }
44
44
 
45
45
  return convertValue;
@@ -81,12 +81,23 @@ export const commonFunctions = (params) => {
81
81
  };
82
82
 
83
83
  export const scrollEvent = (params) => {
84
- const { scrollInfo, stores, elementInfo, resizeInfo } = params;
84
+ const {
85
+ scrollInfo,
86
+ stores,
87
+ elementInfo,
88
+ resizeInfo,
89
+ pageInfo,
90
+ getPagingData,
91
+ updatePagingInfo,
92
+ } = params;
85
93
  /**
86
94
  * 수직 스크롤의 위치 계산 후 적용한다.
87
95
  */
88
- const updateVScroll = () => {
89
- const store = stores.showTreeStore;
96
+ const updateVScroll = (isScroll) => {
97
+ let store = stores.showTreeStore;
98
+ if (pageInfo.isClientPaging) {
99
+ store = getPagingData();
100
+ }
90
101
  const bodyEl = elementInfo.body;
91
102
  if (bodyEl) {
92
103
  const rowHeight = resizeInfo.rowHeight;
@@ -98,7 +109,7 @@ export const scrollEvent = (params) => {
98
109
  firstVisibleIndex = 0;
99
110
  }
100
111
 
101
- const lastVisibleIndex = firstVisibleIndex + rowCount;
112
+ const lastVisibleIndex = firstVisibleIndex + rowCount + 1;
102
113
  const firstIndex = Math.max(firstVisibleIndex, 0);
103
114
  const lastIndex = lastVisibleIndex;
104
115
 
@@ -107,6 +118,12 @@ export const scrollEvent = (params) => {
107
118
  scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
108
119
  scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
109
120
  - scrollInfo.vScrollTopHeight;
121
+ if (isScroll && pageInfo.isInfinite && scrollInfo.vScrollBottomHeight === 0) {
122
+ pageInfo.prevPage = pageInfo.currentPage;
123
+ pageInfo.currentPage = Math.ceil(lastIndex / pageInfo.perPage) + 1;
124
+ pageInfo.startIndex = lastIndex;
125
+ updatePagingInfo({ onScrollEnd: true });
126
+ }
110
127
  }
111
128
  };
112
129
  /**
@@ -131,7 +148,7 @@ export const scrollEvent = (params) => {
131
148
  const isVertical = !(scrollTop === lastTop);
132
149
 
133
150
  if (isVertical && bodyEl.clientHeight) {
134
- updateVScroll();
151
+ updateVScroll(true);
135
152
  }
136
153
 
137
154
  if (isHorizontal) {
@@ -359,16 +376,40 @@ export const clickEvent = (params) => {
359
376
  * @param {object} event - 이벤트 객체
360
377
  * @param {array} row - row 데이터
361
378
  */
379
+ let timer = null;
362
380
  const onRowClick = (event, row) => {
363
381
  if (event.target && event.target.parentElement
364
382
  && event.target.parentElement.classList.contains('row-checkbox-input')) {
365
383
  return false;
366
384
  }
367
- if (selectInfo.useSelect) {
368
- selectInfo.selectedRow = row;
369
- emit('update:selected', row);
370
- emit('click-row', getClickedRowData(event, row));
371
- }
385
+ clearTimeout(timer);
386
+ timer = setTimeout(() => {
387
+ if (selectInfo.useSelect) {
388
+ if (row.selected) {
389
+ row.selected = false;
390
+ if (selectInfo.multiple) {
391
+ if (event.ctrlKey) {
392
+ selectInfo.selectedRow = selectInfo.selectedRow.filter(s => s.index !== row.index);
393
+ } else {
394
+ selectInfo.selectedRow = [row];
395
+ }
396
+ } else {
397
+ selectInfo.selectedRow = [];
398
+ }
399
+ } else {
400
+ row.selected = true;
401
+ if (event.ctrlKey
402
+ && selectInfo.multiple
403
+ && (!selectInfo.limitCount || selectInfo.limitCount > selectInfo.selectedRow.length)) {
404
+ selectInfo.selectedRow.push(row);
405
+ } else {
406
+ selectInfo.selectedRow = [row];
407
+ }
408
+ }
409
+ emit('update:selected', selectInfo.selectedRow);
410
+ emit('click-row', getClickedRowData(event, row));
411
+ }
412
+ }, 100);
372
413
  return true;
373
414
  };
374
415
  /**
@@ -378,15 +419,20 @@ export const clickEvent = (params) => {
378
419
  * @param {array} row - row 데이터
379
420
  */
380
421
  const onRowDblClick = (event, row) => {
381
- selectInfo.selectedRow = row;
382
- emit('update:selected', row);
422
+ clearTimeout(timer);
383
423
  emit('dblclick-row', getClickedRowData(event, row));
384
424
  };
385
425
  return { onRowClick, onRowDblClick };
386
426
  };
387
427
 
388
428
  export const checkEvent = (params) => {
389
- const { checkInfo, stores, checkHeader } = params;
429
+ const {
430
+ checkInfo,
431
+ stores,
432
+ checkHeader,
433
+ pageInfo,
434
+ getPagingData,
435
+ } = params;
390
436
  const { emit } = getCurrentInstance();
391
437
  /**
392
438
  * row에 대한 체크 상태를 해제한다.
@@ -450,7 +496,10 @@ export const checkEvent = (params) => {
450
496
  * @param {array} rowData - row 데이터
451
497
  */
452
498
  const onCheck = (event, rowData) => {
453
- const store = stores.store;
499
+ let store = stores.store;
500
+ if (pageInfo.isClientPaging) {
501
+ store = getPagingData();
502
+ }
454
503
  const isSingleMode = () => checkInfo.useCheckbox.mode === 'single';
455
504
  const unCheckHeader = () => {
456
505
  if (checkInfo.isHeaderChecked) {
@@ -501,7 +550,10 @@ export const checkEvent = (params) => {
501
550
  */
502
551
  const onCheckAll = (event) => {
503
552
  const status = checkInfo.isHeaderChecked;
504
- const store = stores.store;
553
+ let store = stores.store;
554
+ if (pageInfo.isClientPaging) {
555
+ store = getPagingData();
556
+ }
505
557
  store.forEach((row) => {
506
558
  row.checked = status && !row._disabled;
507
559
  if (row.checked) {
@@ -553,21 +605,14 @@ export const contextMenuEvent = (params) => {
553
605
  */
554
606
  const onContextMenu = (event) => {
555
607
  const target = event.target;
556
- const tagName = target.tagName.toLowerCase();
557
- let rowIndex;
558
-
559
- if (tagName === 'td') {
560
- rowIndex = target.parentElement.dataset.index;
561
- } else {
562
- rowIndex = target.parentElement.parentElement.dataset.index;
563
- }
608
+ const rowIndex = target.parentElement.dataset.index;
564
609
 
565
610
  if (rowIndex) {
566
611
  const index = stores.viewStore.findIndex(v => v.index === Number(rowIndex));
567
612
  const rowData = stores.viewStore[index];
568
- selectInfo.selectedRow = rowData;
613
+ selectInfo.selectedRow = [rowData];
569
614
  setContextMenu();
570
- emit('update:selected', rowData);
615
+ emit('update:selected', selectInfo.selectedRow);
571
616
  } else {
572
617
  selectInfo.selectedRow = [];
573
618
  setContextMenu(false);
@@ -603,6 +648,10 @@ export const treeEvent = (params) => {
603
648
  node.checked = false;
604
649
  }
605
650
 
651
+ if (!Object.hasOwnProperty.call(node, 'selected')) {
652
+ node.selected = false;
653
+ }
654
+
606
655
  if (!Object.hasOwnProperty.call(node, 'show')) {
607
656
  node.show = isShow;
608
657
  }
@@ -666,7 +715,16 @@ export const treeEvent = (params) => {
666
715
  };
667
716
 
668
717
  export const filterEvent = (params) => {
669
- const { stores, filterInfo, getConvertValue, onResize, checkHeader } = params;
718
+ const {
719
+ stores,
720
+ filterInfo,
721
+ pageInfo,
722
+ getConvertValue,
723
+ onResize,
724
+ checkHeader,
725
+ getPagingData,
726
+ updatePagingInfo,
727
+ } = params;
670
728
  const makeParentShow = (data) => {
671
729
  if (!data?.parent) {
672
730
  return;
@@ -713,13 +771,10 @@ export const filterEvent = (params) => {
713
771
  for (let ix = 0; ix < stores.orderedColumns.length; ix++) {
714
772
  const column = stores.orderedColumns[ix] || {};
715
773
  let columnValue = row[column.field];
716
- let columnType = column.type;
774
+ column.type = column.type || 'string';
717
775
  if (columnValue) {
718
776
  if (!column.hide && (column?.searchable === undefined || column?.searchable)) {
719
- if (!columnType) {
720
- columnType = 'string';
721
- }
722
- columnValue = getConvertValue(columnType, columnValue).toString();
777
+ columnValue = getConvertValue(column, columnValue).toString();
723
778
  isSameWord = columnValue.toLowerCase()
724
779
  .includes(searchWord.toString().toLowerCase());
725
780
  if (isSameWord) {
@@ -750,9 +805,69 @@ export const filterEvent = (params) => {
750
805
  makeChildShow(row);
751
806
  });
752
807
  }
808
+ if (!searchWord && pageInfo.isClientPaging && pageInfo.prevPage) {
809
+ pageInfo.currentPage = 1;
810
+ stores.pagingStore = getPagingData();
811
+ }
812
+ updatePagingInfo({ onSearch: true });
753
813
  checkHeader(stores.store);
754
814
  onResize();
755
815
  }, 500);
756
816
  };
757
817
  return { onSearch };
758
818
  };
819
+
820
+ export const pagingEvent = (params) => {
821
+ const { emit } = getCurrentInstance();
822
+ const {
823
+ stores,
824
+ pageInfo,
825
+ filterInfo,
826
+ elementInfo,
827
+ clearCheckInfo,
828
+ } = params;
829
+ const getPagingData = () => {
830
+ const start = (pageInfo.currentPage - 1) * pageInfo.perPage;
831
+ const end = parseInt(start, 10) + parseInt(pageInfo.perPage, 10);
832
+ return stores.showTreeStore.slice(start, end);
833
+ };
834
+ const updatePagingInfo = (eventName) => {
835
+ emit('page-change', {
836
+ eventName,
837
+ pageInfo: {
838
+ currentPage: pageInfo.currentPage,
839
+ prevPage: pageInfo.prevPage,
840
+ startIndex: pageInfo.startIndex,
841
+ total: pageInfo.total,
842
+ perPage: pageInfo.perPage,
843
+ },
844
+ searchInfo: {
845
+ searchWord: filterInfo.searchWord,
846
+ searchColumns: stores.orderedColumns
847
+ .filter(c => !c.hide && (c?.searchable === undefined || c?.searchable))
848
+ .map(d => d.field),
849
+ },
850
+ });
851
+ if (pageInfo.isInfinite && (eventName?.onSearch || eventName?.onSort)) {
852
+ pageInfo.currentPage = 1;
853
+ elementInfo.body.scrollTop = 0;
854
+ clearCheckInfo();
855
+ }
856
+ };
857
+ const changePage = (beforeVal) => {
858
+ if (pageInfo.isClientPaging) {
859
+ pageInfo.prevPage = beforeVal;
860
+ if (stores.showTreeStore.length <= pageInfo.perPage) {
861
+ stores.pagingStore = stores.showTreeStore;
862
+ } else {
863
+ const start = (pageInfo.currentPage - 1) * pageInfo.perPage;
864
+ const end = parseInt(start, 10) + parseInt(pageInfo.perPage, 10);
865
+ stores.pagingStore = stores.showTreeStore.slice(start, end);
866
+ elementInfo.body.scrollTop = 0;
867
+ pageInfo.startIndex = start;
868
+ }
869
+ }
870
+ updatePagingInfo({ onChangePage: true });
871
+ };
872
+ return { getPagingData, updatePagingInfo, changePage };
873
+ };