evui 3.2.0 → 3.3.0

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.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -48,7 +48,9 @@ const modules = {
48
48
  this.overlayClear();
49
49
 
50
50
  if (Object.keys(hitInfo.items).length) {
51
- this.drawItemsHighlight(hitInfo, ctx);
51
+ if (this.options.type !== 'scatter' || tooltip.use) {
52
+ this.drawItemsHighlight(hitInfo, ctx);
53
+ }
52
54
 
53
55
  if (tooltip.use) {
54
56
  this.setTooltipLayoutPosition(hitInfo, e);
@@ -95,7 +97,7 @@ const modules = {
95
97
  */
96
98
  this.onDblClick = (e) => {
97
99
  const selectItem = this.options.selectItem;
98
- const args = {};
100
+ const args = { e };
99
101
 
100
102
  if (selectItem.use) {
101
103
  const offset = this.getMousePosition(e);
@@ -120,8 +122,7 @@ const modules = {
120
122
  * @returns {undefined}
121
123
  */
122
124
  this.onClick = (e) => {
123
- const args = {};
124
-
125
+ const args = { e };
125
126
  if (this.options.selectItem.use) {
126
127
  const offset = this.getMousePosition(e);
127
128
  const hitInfo = this.findClickedData(offset);
@@ -134,7 +135,9 @@ const modules = {
134
135
  }
135
136
 
136
137
  if (typeof this.listeners.click === 'function') {
137
- this.listeners.click(args);
138
+ if (!this.dragInfoBackup) {
139
+ this.listeners.click(args);
140
+ }
138
141
  }
139
142
  };
140
143
 
@@ -254,11 +257,12 @@ const modules = {
254
257
  *
255
258
  * @returns {undefined}
256
259
  */
257
- const dragEnd = () => {
260
+ const dragEnd = (e) => {
258
261
  const dragInfo = this.dragInfo;
259
262
 
260
- if (dragInfo?.isMove) {
263
+ if (dragInfo?.isMove && dragInfo?.width > 1 && dragInfo?.height > 1) {
261
264
  const args = {
265
+ e,
262
266
  data: this.findSelectedItems(dragInfo),
263
267
  range: this.getSelectionRage(dragInfo),
264
268
  };
@@ -577,10 +581,10 @@ const modules = {
577
581
  const yMax = dataRangeY.graphMin + graphHeight * (1 - yMaxRatio);
578
582
 
579
583
  return {
580
- xMin: +parseFloat(xMin).toFixed(3),
581
- xMax: +parseFloat(xMax).toFixed(3),
582
- yMin: +parseFloat(yMin).toFixed(3),
583
- yMax: +parseFloat(yMax).toFixed(3),
584
+ xMin: Math.max(+parseFloat(xMin).toFixed(3), dataRangeX.graphMin),
585
+ xMax: Math.min(+parseFloat(xMax).toFixed(3), dataRangeX.graphMax),
586
+ yMin: Math.max(+parseFloat(yMin).toFixed(3), dataRangeY.graphMin),
587
+ yMax: Math.min(+parseFloat(yMax).toFixed(3), dataRangeY.graphMax),
584
588
  };
585
589
  },
586
590
 
@@ -9,12 +9,15 @@ const modules = {
9
9
  this.legendDOM.className = 'ev-chart-legend';
10
10
  this.legendBoxDOM = document.createElement('div');
11
11
  this.legendBoxDOM.className = 'ev-chart-legend-box';
12
- this.resizeDOM = document.createElement('div');
13
- this.resizeDOM.className = 'ev-chart-resize-bar';
14
- this.ghostDOM = document.createElement('div');
15
- this.ghostDOM.className = 'ev-chart-resize-ghost';
16
12
 
17
- this.wrapperDOM.appendChild(this.resizeDOM);
13
+ if (this.options?.legend?.allowResize) {
14
+ this.resizeDOM = document.createElement('div');
15
+ this.resizeDOM.className = 'ev-chart-resize-bar';
16
+ this.ghostDOM = document.createElement('div');
17
+ this.ghostDOM.className = 'ev-chart-resize-ghost';
18
+ this.wrapperDOM.appendChild(this.resizeDOM);
19
+ }
20
+
18
21
  this.legendDOM.appendChild(this.legendBoxDOM);
19
22
  this.wrapperDOM.appendChild(this.legendDOM);
20
23
  },
@@ -212,10 +215,12 @@ const modules = {
212
215
  this.legendBoxDOM.addEventListener('click', this.onLegendBoxClick);
213
216
  this.legendBoxDOM.addEventListener('mouseover', this.onLegendBoxOver);
214
217
  this.legendBoxDOM.addEventListener('mouseleave', this.onLegendBoxLeave);
215
- this.resizeDOM.addEventListener('mousedown', this.onResizeMouseDown);
216
218
 
217
- this.mouseMove = this.onMouseMove.bind(this); // resizing function
218
- this.mouseUp = this.onMouseUp.bind(this); // resizing function
219
+ if (this.resizeDOM) {
220
+ this.resizeDOM.addEventListener('mousedown', this.onResizeMouseDown);
221
+ this.mouseMove = this.onMouseMove.bind(this); // resizing function
222
+ this.mouseUp = this.onMouseUp.bind(this); // resizing function
223
+ }
219
224
  },
220
225
 
221
226
  /**
@@ -338,14 +343,16 @@ const modules = {
338
343
  legendStyle.width = `${chartRect.width}px`;
339
344
  legendStyle.height = `${opt.legend.height + 4}px`; // 4 resize bar size
340
345
 
341
- resizeStyle.top = `${positionTop}px`;
342
- resizeStyle.right = '';
343
- resizeStyle.bottom = '';
344
- resizeStyle.left = '';
346
+ if (resizeStyle) {
347
+ resizeStyle.top = `${positionTop}px`;
348
+ resizeStyle.right = '';
349
+ resizeStyle.bottom = '';
350
+ resizeStyle.left = '';
345
351
 
346
- resizeStyle.width = `${chartRect.width}px`;
347
- resizeStyle.height = '4px';
348
- resizeStyle.cursor = 'row-resize';
352
+ resizeStyle.width = `${chartRect.width}px`;
353
+ resizeStyle.height = '4px';
354
+ resizeStyle.cursor = 'row-resize';
355
+ }
349
356
  break;
350
357
  case 'right':
351
358
  wrapperStyle.padding = `${title}px ${opt.legend.width}px 0 0`;
@@ -363,14 +370,16 @@ const modules = {
363
370
  legendStyle.width = `${opt.legend.width}px`;
364
371
  legendStyle.height = `${chartRect.height}px`;
365
372
 
366
- resizeStyle.top = `${title}px`;
367
- resizeStyle.right = `${opt.legend.width}px`;
368
- resizeStyle.bottom = '';
369
- resizeStyle.left = '';
373
+ if (resizeStyle) {
374
+ resizeStyle.top = `${title}px`;
375
+ resizeStyle.right = `${opt.legend.width}px`;
376
+ resizeStyle.bottom = '';
377
+ resizeStyle.left = '';
370
378
 
371
- resizeStyle.width = '4px';
372
- resizeStyle.height = `${chartRect.height}px`;
373
- resizeStyle.cursor = 'col-resize';
379
+ resizeStyle.width = '4px';
380
+ resizeStyle.height = `${chartRect.height}px`;
381
+ resizeStyle.cursor = 'col-resize';
382
+ }
374
383
  break;
375
384
  case 'bottom':
376
385
  wrapperStyle.padding = `${title}px 0 ${opt.legend.height}px 0`;
@@ -387,14 +396,16 @@ const modules = {
387
396
  legendStyle.width = `${chartRect.width}px`;
388
397
  legendStyle.height = `${opt.legend.height + 4}px`; // 4 resize bar size
389
398
 
390
- resizeStyle.top = '';
391
- resizeStyle.right = '';
392
- resizeStyle.bottom = `${opt.legend.height}px`;
393
- resizeStyle.left = '';
399
+ if (resizeStyle) {
400
+ resizeStyle.top = '';
401
+ resizeStyle.right = '';
402
+ resizeStyle.bottom = `${opt.legend.height}px`;
403
+ resizeStyle.left = '';
394
404
 
395
- resizeStyle.width = `${chartRect.width}px`;
396
- resizeStyle.height = '4px';
397
- resizeStyle.cursor = 'row-resize';
405
+ resizeStyle.width = `${chartRect.width}px`;
406
+ resizeStyle.height = '4px';
407
+ resizeStyle.cursor = 'row-resize';
408
+ }
398
409
  break;
399
410
  case 'left':
400
411
  wrapperStyle.padding = `${title}px 0 0 ${opt.legend.width}px`;
@@ -413,14 +424,16 @@ const modules = {
413
424
  legendStyle.width = `${opt.legend.width}px`;
414
425
  legendStyle.height = `${chartRect.height}px`;
415
426
 
416
- resizeStyle.top = `${title}px`;
417
- resizeStyle.right = '';
418
- resizeStyle.bottom = '';
419
- resizeStyle.left = `${opt.legend.width}px`;
427
+ if (resizeStyle) {
428
+ resizeStyle.top = `${title}px`;
429
+ resizeStyle.right = '';
430
+ resizeStyle.bottom = '';
431
+ resizeStyle.left = `${opt.legend.width}px`;
420
432
 
421
- resizeStyle.width = '4px';
422
- resizeStyle.height = `${chartRect.height}px`;
423
- resizeStyle.cursor = 'col-resize';
433
+ resizeStyle.width = '4px';
434
+ resizeStyle.height = `${chartRect.height}px`;
435
+ resizeStyle.cursor = 'col-resize';
436
+ }
424
437
  break;
425
438
  default:
426
439
  break;
@@ -599,12 +612,13 @@ const modules = {
599
612
  * @returns {undefined}
600
613
  */
601
614
  showLegend() {
602
- if (!this.resizeDOM || !this.legendDOM) {
603
- return;
615
+ if (this.resizeDOM) {
616
+ this.resizeDOM.style.display = 'block';
604
617
  }
605
618
 
606
- this.resizeDOM.style.display = 'block';
607
- this.legendDOM.style.display = 'block';
619
+ if (this.legendDOM) {
620
+ this.legendDOM.style.display = 'block';
621
+ }
608
622
  },
609
623
 
610
624
  /**
@@ -619,13 +633,15 @@ const modules = {
619
633
  const legendStyle = this.legendDOM?.style;
620
634
  const title = opt?.title?.show ? opt?.title?.height : 0;
621
635
 
622
- if (!resizeStyle || !legendStyle || !wrapperStyle) {
636
+ if (!legendStyle || !wrapperStyle) {
623
637
  return;
624
638
  }
625
639
 
626
- resizeStyle.display = 'none';
627
- legendStyle.display = 'none';
640
+ if (resizeStyle) {
641
+ resizeStyle.display = 'none';
642
+ }
628
643
 
644
+ legendStyle.display = 'none';
629
645
  legendStyle.width = '0';
630
646
  legendStyle.height = '0';
631
647
  wrapperStyle.padding = `${title}px 0 0 0`;
@@ -27,6 +27,7 @@ const DEFAULT_OPTIONS = {
27
27
  inactive: '#aaa',
28
28
  width: 140,
29
29
  height: 24,
30
+ allowResize: false,
30
31
  },
31
32
  itemHighlight: true,
32
33
  seriesHighlight: true,
@@ -99,11 +100,13 @@ export const useModel = () => {
99
100
  const { emit } = getCurrentInstance();
100
101
 
101
102
  const getNormalizedOptions = (options) => {
102
- if (options.type === 'scatter') {
103
- DEFAULT_OPTIONS.tooltip.use = false;
103
+ const normalizedOptions = defaultsDeep({}, options, DEFAULT_OPTIONS);
104
+
105
+ if (options.type === 'scatter' && !options?.tooltip) {
106
+ normalizedOptions.tooltip.use = false;
104
107
  }
105
108
 
106
- return defaultsDeep({}, options, DEFAULT_OPTIONS);
109
+ return normalizedOptions;
107
110
  };
108
111
  const getNormalizedData = data => defaultsDeep(data, DEFAULT_DATA);
109
112
 
@@ -251,7 +251,7 @@
251
251
  </template>
252
252
 
253
253
  <script>
254
- import { reactive, toRefs, computed, watch, onMounted } from 'vue';
254
+ import { reactive, toRefs, computed, watch, onMounted, onActivated } from 'vue';
255
255
  import FilterWindow from './grid.filter.window';
256
256
  import Toolbar from './grid.toolbar';
257
257
  import {
@@ -334,13 +334,14 @@ export default {
334
334
  filterList: {},
335
335
  isFiltering: computed(() =>
336
336
  (props.option.useFilter === undefined ? true : props.option.useFilter)),
337
- isSearch: false,
338
337
  setFiltering: false,
339
338
  showFilterWindow: false,
340
339
  currentFilter: {
341
340
  column: {},
342
341
  items: [],
343
342
  },
343
+ isSearch: false,
344
+ searchValue: computed(() => (props.option.searchValue || '')),
344
345
  });
345
346
  const stores = reactive({
346
347
  viewStore: [],
@@ -428,7 +429,15 @@ export default {
428
429
  onCloseFilterWindow,
429
430
  onApplyFilter,
430
431
  setFilter,
431
- } = filterEvent({ filterInfo, stores, getColumnIndex });
432
+ onSearch,
433
+ } = filterEvent({
434
+ filterInfo,
435
+ stores,
436
+ checkInfo,
437
+ getColumnIndex,
438
+ getConvertValue,
439
+ updateVScroll,
440
+ });
432
441
 
433
442
  const {
434
443
  setStore,
@@ -461,9 +470,17 @@ export default {
461
470
  calculatedColumn();
462
471
  setStore(props.rows);
463
472
  });
473
+ onActivated(() => {
474
+ updateVScroll();
475
+ });
464
476
  const ROW_INDEX = 0;
465
477
  const ROW_CHECK_INDEX = 1;
466
478
  const ROW_DATA_INDEX = 2;
479
+ const clearCheckInfo = () => {
480
+ checkInfo.checkedRows = [];
481
+ checkInfo.checkedIndex.clear();
482
+ checkInfo.isHeaderChecked = false;
483
+ };
467
484
  watch(
468
485
  () => props.columns,
469
486
  () => {
@@ -494,24 +511,28 @@ export default {
494
511
  () => props.rows,
495
512
  (value) => {
496
513
  setStore(value);
514
+ if (filterInfo.isSearch) {
515
+ onSearch(filterInfo.searchValue);
516
+ }
497
517
  },
498
518
  );
499
519
  watch(
500
520
  () => props.checked,
501
- (value) => {
502
- checkInfo.checkedRows = value;
521
+ (checkedList) => {
522
+ checkInfo.checkedRows = checkedList;
503
523
  checkInfo.isHeaderChecked = false;
504
- let store = stores.originStore;
505
- if (filterInfo.isSearch && stores.searchStore) {
506
- store = stores.searchStore;
507
- }
508
- store.forEach((row) => {
509
- row[ROW_CHECK_INDEX] = checkInfo.checkedRows.includes(row[ROW_DATA_INDEX]);
510
- });
511
- if (checkInfo.checkedRows.length
512
- && store.length === checkInfo.checkedRows.length) {
513
- checkInfo.isHeaderChecked = true;
524
+ checkInfo.checkedIndex.clear();
525
+ const store = stores.store;
526
+ if (store.length) {
527
+ store.forEach((row) => {
528
+ row[ROW_CHECK_INDEX] = checkedList.includes(row[ROW_DATA_INDEX]);
529
+ if (row[ROW_CHECK_INDEX]) {
530
+ checkInfo.checkedIndex.add(row[ROW_INDEX]);
531
+ }
532
+ });
533
+ checkInfo.isHeaderChecked = checkedList.length === store.length;
514
534
  }
535
+ updateVScroll();
515
536
  },
516
537
  );
517
538
  watch(
@@ -523,8 +544,15 @@ export default {
523
544
  watch(
524
545
  () => checkInfo.useCheckbox.mode,
525
546
  () => {
526
- checkInfo.checkedRows = [];
527
- checkInfo.isHeaderChecked = false;
547
+ clearCheckInfo();
548
+ },
549
+ );
550
+ watch(
551
+ () => props.checked.length,
552
+ (checkedSize) => {
553
+ if (!checkedSize) {
554
+ clearCheckInfo();
555
+ }
528
556
  },
529
557
  );
530
558
  watch(
@@ -553,64 +581,12 @@ export default {
553
581
  setStore([], false);
554
582
  },
555
583
  );
556
- let timer = null;
557
- const onSearch = (searchWord) => {
558
- if (timer) {
559
- clearTimeout(timer);
560
- }
561
- timer = setTimeout(() => {
562
- filterInfo.isSearch = false;
563
- if (searchWord) {
564
- const filterStores = stores.store.filter((row) => {
565
- let isShow = false;
566
- for (let ix = 0; ix < stores.orderedColumns.length; ix++) {
567
- const column = stores.orderedColumns[ix] || {};
568
- let columnValue = row[ROW_DATA_INDEX][ix];
569
- let columnType = column.type;
570
- if (columnValue) {
571
- if (typeof columnValue === 'object') {
572
- columnValue = columnValue[column.field];
573
- }
574
- if (!column.hide && (column?.searchable === undefined || column?.searchable)) {
575
- if (!columnType) {
576
- columnType = 'string';
577
- }
578
- columnValue = getConvertValue(columnType, columnValue).toString();
579
- isShow = columnValue.toLowerCase().includes(searchWord.toString().toLowerCase());
580
- if (isShow) {
581
- break;
582
- }
583
- }
584
- }
585
- }
586
- return isShow;
587
- });
588
- filterInfo.isSearch = true;
589
- stores.searchStore = JSON.parse(JSON.stringify(filterStores));
590
- } else {
591
- filterInfo.isSearch = false;
592
- }
593
- let store = stores.originStore;
594
- let checkSize = checkInfo.checkedRows.length;
595
- for (let ix = 0; ix < store.length; ix++) {
596
- if (checkInfo.checkedIndex.has(store[ix][ROW_INDEX])) {
597
- store[ix][ROW_CHECK_INDEX] = true;
598
- } else {
599
- store[ix][ROW_CHECK_INDEX] = false;
600
- }
601
- }
602
- if (filterInfo.isSearch && stores.searchStore) {
603
- store = stores.searchStore;
604
- checkSize = checkInfo.checkedIndex.size;
605
- }
606
- if (store.length && checkSize >= store.length) {
607
- checkInfo.isHeaderChecked = true;
608
- } else {
609
- checkInfo.isHeaderChecked = false;
610
- }
611
- setStore([], false);
612
- }, 500);
613
- };
584
+ watch(
585
+ () => filterInfo.searchValue,
586
+ (value) => {
587
+ onSearch(value?.value ?? value);
588
+ }, { immediate: true },
589
+ );
614
590
  const isFilterButton = field => filterInfo.isFiltering && field !== 'db-icon' && field !== 'user-icon';
615
591
  return {
616
592
  showHeader,