e-virt-table 1.2.21 → 1.2.23

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.
@@ -45,12 +45,26 @@ export default class Cell extends BaseCell {
45
45
  drawTextColor: string;
46
46
  drawTextX: number;
47
47
  drawTextY: number;
48
- drawImageX: number;
49
- drawImageY: number;
50
- drawImageWidth: number;
51
- drawImageHeight: number;
52
- drawImageName: string;
53
- drawImageSource?: HTMLImageElement;
48
+ drawTextWidth: number;
49
+ drawTextHeight: number;
50
+ drawTreeImageX: number;
51
+ drawTreeImageY: number;
52
+ drawTreeImageWidth: number;
53
+ drawTreeImageHeight: number;
54
+ drawTreeImageName: string;
55
+ drawTreeImageSource?: HTMLImageElement;
56
+ drawSelectionImageX: number;
57
+ drawSelectionImageY: number;
58
+ drawSelectionImageWidth: number;
59
+ drawSelectionImageHeight: number;
60
+ drawSelectionImageName: string;
61
+ drawSelectionImageSource?: HTMLImageElement;
62
+ drawHoverImageX: number;
63
+ drawHoverImageY: number;
64
+ drawHoverImageWidth: number;
65
+ drawHoverImageHeight: number;
66
+ drawHoverImageName: string;
67
+ drawHoverImageSource?: HTMLImageElement;
54
68
  ellipsis: boolean;
55
69
  rowExpand: boolean;
56
70
  rowHasChildren: boolean;
@@ -73,6 +87,7 @@ export default class Cell extends BaseCell {
73
87
  */
74
88
  updateStyle(): void;
75
89
  private updateTree;
90
+ private drawTreeLine;
76
91
  private updateContainer;
77
92
  private updateSelection;
78
93
  private updateHoverIcon;
package/dist/lib/Cell.js CHANGED
@@ -254,37 +254,124 @@ export default class Cell extends BaseCell {
254
254
  writable: true,
255
255
  value: 0
256
256
  });
257
- Object.defineProperty(this, "drawImageX", {
257
+ Object.defineProperty(this, "drawTextWidth", {
258
258
  enumerable: true,
259
259
  configurable: true,
260
260
  writable: true,
261
261
  value: 0
262
262
  });
263
- Object.defineProperty(this, "drawImageY", {
263
+ Object.defineProperty(this, "drawTextHeight", {
264
264
  enumerable: true,
265
265
  configurable: true,
266
266
  writable: true,
267
267
  value: 0
268
268
  });
269
- Object.defineProperty(this, "drawImageWidth", {
269
+ // 画tree图标
270
+ Object.defineProperty(this, "drawTreeImageX", {
270
271
  enumerable: true,
271
272
  configurable: true,
272
273
  writable: true,
273
274
  value: 0
274
275
  });
275
- Object.defineProperty(this, "drawImageHeight", {
276
+ Object.defineProperty(this, "drawTreeImageY", {
276
277
  enumerable: true,
277
278
  configurable: true,
278
279
  writable: true,
279
280
  value: 0
280
281
  });
281
- Object.defineProperty(this, "drawImageName", {
282
+ Object.defineProperty(this, "drawTreeImageWidth", {
283
+ enumerable: true,
284
+ configurable: true,
285
+ writable: true,
286
+ value: 0
287
+ });
288
+ Object.defineProperty(this, "drawTreeImageHeight", {
289
+ enumerable: true,
290
+ configurable: true,
291
+ writable: true,
292
+ value: 0
293
+ });
294
+ Object.defineProperty(this, "drawTreeImageName", {
295
+ enumerable: true,
296
+ configurable: true,
297
+ writable: true,
298
+ value: ''
299
+ });
300
+ Object.defineProperty(this, "drawTreeImageSource", {
301
+ enumerable: true,
302
+ configurable: true,
303
+ writable: true,
304
+ value: void 0
305
+ });
306
+ // 画selection图标
307
+ Object.defineProperty(this, "drawSelectionImageX", {
308
+ enumerable: true,
309
+ configurable: true,
310
+ writable: true,
311
+ value: 0
312
+ });
313
+ Object.defineProperty(this, "drawSelectionImageY", {
314
+ enumerable: true,
315
+ configurable: true,
316
+ writable: true,
317
+ value: 0
318
+ });
319
+ Object.defineProperty(this, "drawSelectionImageWidth", {
320
+ enumerable: true,
321
+ configurable: true,
322
+ writable: true,
323
+ value: 0
324
+ });
325
+ Object.defineProperty(this, "drawSelectionImageHeight", {
326
+ enumerable: true,
327
+ configurable: true,
328
+ writable: true,
329
+ value: 0
330
+ });
331
+ Object.defineProperty(this, "drawSelectionImageName", {
332
+ enumerable: true,
333
+ configurable: true,
334
+ writable: true,
335
+ value: ''
336
+ });
337
+ Object.defineProperty(this, "drawSelectionImageSource", {
338
+ enumerable: true,
339
+ configurable: true,
340
+ writable: true,
341
+ value: void 0
342
+ });
343
+ // 画hover图标
344
+ Object.defineProperty(this, "drawHoverImageX", {
345
+ enumerable: true,
346
+ configurable: true,
347
+ writable: true,
348
+ value: 0
349
+ });
350
+ Object.defineProperty(this, "drawHoverImageY", {
351
+ enumerable: true,
352
+ configurable: true,
353
+ writable: true,
354
+ value: 0
355
+ });
356
+ Object.defineProperty(this, "drawHoverImageWidth", {
357
+ enumerable: true,
358
+ configurable: true,
359
+ writable: true,
360
+ value: 0
361
+ });
362
+ Object.defineProperty(this, "drawHoverImageHeight", {
363
+ enumerable: true,
364
+ configurable: true,
365
+ writable: true,
366
+ value: 0
367
+ });
368
+ Object.defineProperty(this, "drawHoverImageName", {
282
369
  enumerable: true,
283
370
  configurable: true,
284
371
  writable: true,
285
372
  value: ''
286
373
  });
287
- Object.defineProperty(this, "drawImageSource", {
374
+ Object.defineProperty(this, "drawHoverImageSource", {
288
375
  enumerable: true,
289
376
  configurable: true,
290
377
  writable: true,
@@ -339,11 +426,12 @@ export default class Cell extends BaseCell {
339
426
  this.key = column.key;
340
427
  this.type = column.type || '';
341
428
  this.editorType = column.editorType || 'text';
342
- this.selectorCellValueType = column.selectorCellValueType || this.ctx.config.SELECTOR_CELL_VALUE_TYPE || 'value';
429
+ this.selectorCellValueType =
430
+ column.selectorCellValueType || this.ctx.config.SELECTOR_CELL_VALUE_TYPE || 'value';
343
431
  this.editorProps = column.editorProps || {};
344
432
  this.cellType = cellType;
345
- this.align = column.align || 'center';
346
- this.verticalAlign = column.verticalAlign || 'middle';
433
+ this.align = column.align || this.ctx.config.COLUMNS_ALIGN;
434
+ this.verticalAlign = column.verticalAlign || this.ctx.config.COLUMNS_VERTICAL_ALIGN;
347
435
  this.fixed = column.fixed;
348
436
  this.level = column.level || 0;
349
437
  this.operation = column.operation || false;
@@ -384,6 +472,8 @@ export default class Cell extends BaseCell {
384
472
  this.drawTextY = this.drawY;
385
473
  this.isHasChanged = this.ctx.database.isHasChangedData(this.rowKey, this.key);
386
474
  this.updateSpan();
475
+ this.drawTextWidth = this.visibleWidth;
476
+ this.drawTextHeight = this.visibleHeight;
387
477
  this.updateStyle();
388
478
  this.updateType();
389
479
  this.updateHoverIcon();
@@ -533,43 +623,144 @@ export default class Cell extends BaseCell {
533
623
  let icon = undefined;
534
624
  let iconOffsetX = 0;
535
625
  let iconName = '';
536
- if (this.type === 'tree' && cellType === 'body') {
537
- const row = this.ctx.database.getRowForRowKey(rowKey);
538
- const { expand = false, hasChildren = false, expandLoading = false, level = 0 } = row || {};
539
- this.rowExpand = expand;
540
- this.rowHasChildren = hasChildren;
541
- if (expandLoading) {
542
- const loadingIcon = this.ctx.icons.get('loading');
543
- iconName = 'loading';
544
- icon = loadingIcon;
545
- iconOffsetX = level * 8;
546
- }
547
- else if (hasChildren) {
548
- const expandIcon = this.ctx.icons.get('expand');
549
- const shrinkIcon = this.ctx.icons.get('shrink');
550
- icon = !expand ? expandIcon : shrinkIcon;
551
- iconName = !expand ? 'expand' : 'shrink';
552
- iconOffsetX = level * 8;
553
- }
554
- else {
555
- iconOffsetX = level * 8;
556
- }
557
- let iconWidth = 20;
558
- let iconHeight = 20;
559
- if (icon) {
560
- let iconX = this.drawX + iconOffsetX + CELL_PADDING;
561
- let iconY = this.drawY + (this.visibleHeight - iconHeight) / 2;
562
- this.ctx.paint.drawImage(icon, iconX, iconY, iconWidth, iconHeight);
563
- this.drawImageX = iconX;
564
- this.drawImageY = iconY;
565
- this.drawImageWidth = iconWidth;
566
- this.drawImageHeight = iconHeight;
567
- this.drawImageName = iconName;
568
- this.drawImageSource = icon;
569
- }
570
- // 更改文本距离
626
+ if (!(['tree', 'selection-tree', 'tree-selection'].includes(this.type) && cellType === 'body')) {
627
+ return;
628
+ }
629
+ const row = this.ctx.database.getRowForRowKey(rowKey);
630
+ const { expand = false, hasChildren = false, expandLoading = false, level = 0 } = row || {};
631
+ this.rowExpand = expand;
632
+ this.rowHasChildren = hasChildren;
633
+ // 计算树形图标的偏移量
634
+ const { TREE_INDENT = 16, CHECKBOX_SIZE, TREE_ICON_SIZE } = this.ctx.config;
635
+ iconOffsetX = level * TREE_INDENT;
636
+ if (expandLoading) {
637
+ const loadingIcon = this.ctx.icons.get('loading');
638
+ iconName = 'loading';
639
+ icon = loadingIcon;
640
+ }
641
+ else if (hasChildren) {
642
+ const expandIcon = this.ctx.icons.get('expand');
643
+ const shrinkIcon = this.ctx.icons.get('shrink');
644
+ icon = !expand ? expandIcon : shrinkIcon;
645
+ iconName = !expand ? 'expand' : 'shrink';
646
+ }
647
+ let iconWidth = TREE_ICON_SIZE;
648
+ let iconHeight = TREE_ICON_SIZE;
649
+ let drawX = this.drawX;
650
+ if (this.align === 'center' || this.align === 'right') {
651
+ drawX = this.drawX + (this.visibleWidth - iconWidth - 2 * CELL_PADDING) / 2;
652
+ // 居中对齐,改成左对齐
571
653
  this.align = 'left';
572
- this.drawTextX = iconOffsetX + this.drawX + iconWidth - 0.5;
654
+ }
655
+ let iconX = drawX + iconOffsetX + CELL_PADDING;
656
+ let iconY = this.drawY + (this.visibleHeight - iconHeight) / 2;
657
+ let drawTextX = iconOffsetX + this.drawX + iconWidth - 0.5;
658
+ if (this.type === 'selection-tree') {
659
+ // 树形图标在左侧,checkbox 在树形图标右侧
660
+ iconX = iconOffsetX + this.drawSelectionImageX + this.drawSelectionImageWidth;
661
+ drawTextX = iconX + iconWidth - CELL_PADDING / 2;
662
+ }
663
+ else if (this.type === 'tree-selection') {
664
+ // 树形选择,两个图标宽度,文本已经有CELL_PADDING间距,/2看起来好看些
665
+ drawTextX = iconX + CHECKBOX_SIZE + iconWidth - CELL_PADDING / 2;
666
+ }
667
+ else {
668
+ // 普通tree,文本已经有CELL_PADDING间距,/2看起来好看些
669
+ drawTextX = iconX + iconWidth - CELL_PADDING / 2;
670
+ }
671
+ // 更改文本距离
672
+ this.drawTextX = drawTextX;
673
+ this.drawTextWidth = this.drawX + this.visibleWidth - drawTextX; // 减去树形图标的宽度
674
+ // 判断是否溢出格子
675
+ if (iconX + iconWidth + CELL_PADDING > this.drawX + this.visibleWidth) {
676
+ return;
677
+ }
678
+ if (iconY + iconHeight + CELL_PADDING > this.drawY + this.visibleHeight) {
679
+ return;
680
+ }
681
+ // 不论是否需要绘制图标,都更新图标的“基准位置”,供树线使用
682
+ this.drawTreeImageX = iconX;
683
+ this.drawTreeImageY = iconY;
684
+ this.drawTreeImageWidth = iconWidth;
685
+ this.drawTreeImageHeight = iconHeight;
686
+ if (icon) {
687
+ this.drawTreeImageName = iconName;
688
+ this.drawTreeImageSource = icon;
689
+ }
690
+ else {
691
+ this.drawTreeImageName = '';
692
+ this.drawTreeImageSource = undefined;
693
+ }
694
+ // 树连线仅在绘制阶段调用,避免在 update 阶段被清屏
695
+ }
696
+ drawTreeLine() {
697
+ const { TREE_LINE, TREE_INDENT = 16, TREE_ICON_SIZE = 16, TREE_LINE_COLOR = '#e1e6eb' } = this.ctx.config;
698
+ // 仅 body 且树类型才绘制
699
+ if (!TREE_LINE || this.cellType !== 'body')
700
+ return;
701
+ if (!['tree', 'selection-tree', 'tree-selection'].includes(this.type))
702
+ return;
703
+ if (this.rowspan === 0 || this.colspan === 0)
704
+ return;
705
+ const row = this.ctx.database.getRowForRowKey(this.rowKey) || {};
706
+ const level = row.level ?? 0;
707
+ // 以当前树图标为中心点
708
+ const iconCenterX = this.drawTreeImageX + this.drawTreeImageWidth / 2;
709
+ const iconCenterY = this.drawTreeImageY + this.drawTreeImageHeight / 2;
710
+ // 基于已计算的树图标位置反推基准点:当前图标左侧减去 level * TREE_INDENT
711
+ // 这样无论对齐方式如何(left/center/right),都以实际图标为基准定位所有竖线
712
+ let baseX = this.drawTreeImageX - level * TREE_INDENT;
713
+ // 逐层画竖线(仅当 level > 0 才需要祖先连线)
714
+ const parentRowKeys = Array.isArray(row.parentRowKeys) ? row.parentRowKeys : [];
715
+ if (level > 0) {
716
+ // 祖先层(0..level-2):是否继续取决于该层“下一层链路节点”是否为最后子项
717
+ // 例如当前节点 0-2-1:
718
+ // - 对 i=0(根 0 对应竖线),应看其下一层链路节点 0-2 是否为最后子项。
719
+ // 若 0-2 是最后子项(没有 0-3),则 i=0 的竖线在本行不应出现。
720
+ for (let i = 0; i < level - 1; i += 1) {
721
+ const nextKey = parentRowKeys[i + 1];
722
+ const nextRow = nextKey ? this.ctx.database.getRowForRowKey(nextKey) || {} : {};
723
+ const nextIsLast = !!nextRow.isLastChild;
724
+ if (nextIsLast)
725
+ continue;
726
+ // 以当前树图标 X 为基准向左回推
727
+ const vx = Math.round(this.drawTreeImageX - (level - i) * TREE_INDENT + TREE_ICON_SIZE / 2);
728
+ this.ctx.paint.drawLine([vx, this.drawY, vx, this.drawY + this.visibleHeight], {
729
+ borderColor: TREE_LINE_COLOR,
730
+ borderWidth: 1,
731
+ lineDash: [4, 4],
732
+ lineDashOffset: 0,
733
+ });
734
+ }
735
+ // 父层(level-1):无论父是不是末尾,都需要连接当前节点形成 L 型
736
+ const vxParent = Math.round(this.drawTreeImageX - TREE_INDENT + TREE_ICON_SIZE / 2);
737
+ const toCenter = !!row.isLastChild;
738
+ const y2 = toCenter ? iconCenterY : this.drawY + this.visibleHeight;
739
+ this.ctx.paint.drawLine([vxParent, this.drawY, vxParent, y2], {
740
+ borderColor: TREE_LINE_COLOR,
741
+ borderWidth: 1,
742
+ lineDash: [4, 4],
743
+ lineDashOffset: 0,
744
+ });
745
+ // 当前层的横线:从当前层竖线到图标中心
746
+ const currVX = Math.round(baseX + (level - 1) * TREE_INDENT + TREE_ICON_SIZE / 2);
747
+ this.ctx.paint.drawLine([currVX, iconCenterY, iconCenterX, iconCenterY], {
748
+ borderColor: TREE_LINE_COLOR,
749
+ borderWidth: 1,
750
+ lineDash: [4, 4],
751
+ lineDashOffset: 0,
752
+ });
753
+ }
754
+ // 1) 父节点行:在图标正下画一段短竖线(展开时绘制,符合视觉预期)
755
+ if (row.hasChildren && row.expand) {
756
+ const shortTop = this.drawTreeImageY + this.drawTreeImageHeight;
757
+ const shortBottom = shortTop + Math.min(this.visibleHeight / 2, Math.max(8, TREE_ICON_SIZE / 2));
758
+ this.ctx.paint.drawLine([iconCenterX, shortTop, iconCenterX, shortBottom], {
759
+ borderColor: TREE_LINE_COLOR,
760
+ borderWidth: 1,
761
+ lineDash: [4, 4],
762
+ lineDashOffset: 0,
763
+ });
573
764
  }
574
765
  }
575
766
  updateContainer() {
@@ -679,20 +870,58 @@ export default class Cell extends BaseCell {
679
870
  if (cellType === 'footer') {
680
871
  return;
681
872
  }
682
- // 选中框类型
683
- if (['index-selection', 'selection'].includes(type)) {
873
+ if (!['index-selection', 'selection', 'selection-tree', 'tree-selection'].includes(type)) {
874
+ return;
875
+ }
876
+ const selectable = this.ctx.database.getRowSelectable(rowKey);
877
+ const { CHECKBOX_SIZE = 0, CELL_PADDING } = this.ctx.config;
878
+ let drawX = this.drawX + CELL_PADDING;
879
+ if (this.align === 'center' || this.align === 'right') {
880
+ drawX = this.drawX + (visibleWidth - CHECKBOX_SIZE) / 2;
881
+ }
882
+ let iconX = drawX;
883
+ let iconY = this.drawY + (visibleHeight - CHECKBOX_SIZE) / 2;
884
+ // 对于 selection-tree 类型,checkbox 应该居中显示
885
+ if (type === 'selection-tree') {
886
+ }
887
+ else if (type === 'tree-selection') {
888
+ // 更新选择器的位置
889
+ const { TREE_INDENT = 16, TREE_ICON_SIZE } = this.ctx.config;
890
+ const row = this.ctx.database.getRowForRowKey(rowKey);
891
+ const { level = 0 } = row || {};
892
+ const iconOffsetX = level * TREE_INDENT;
893
+ iconX = drawX + TREE_ICON_SIZE + iconOffsetX; // 树形图标右侧 + 间距
894
+ }
895
+ let checkboxImage = this.ctx.icons.get('checkbox-uncheck');
896
+ let checkboxName = 'checkbox-uncheck';
897
+ if (type === 'selection-tree' || type === 'tree-selection') {
898
+ // 树形选择逻辑
899
+ const treeState = this.ctx.database.getTreeSelectionState(rowKey);
900
+ if (treeState.indeterminate && selectable) {
901
+ checkboxImage = this.ctx.icons.get('checkbox-indeterminate');
902
+ checkboxName = 'checkbox-indeterminate';
903
+ }
904
+ else if (treeState.checked && selectable) {
905
+ checkboxImage = this.ctx.icons.get('checkbox-check');
906
+ checkboxName = 'checkbox-check';
907
+ }
908
+ else if (!treeState.checked && selectable) {
909
+ checkboxImage = this.ctx.icons.get('checkbox-uncheck');
910
+ checkboxName = 'checkbox-uncheck';
911
+ }
912
+ else {
913
+ checkboxImage = this.ctx.icons.get('checkbox-disabled');
914
+ checkboxName = 'checkbox-disabled';
915
+ }
916
+ }
917
+ else {
918
+ // 普通选择逻辑
684
919
  const check = this.ctx.database.getRowSelection(rowKey);
685
- const selectable = this.ctx.database.getRowSelectable(rowKey);
686
- const { CHECKBOX_SIZE = 0 } = this.ctx.config;
687
- const _x = this.drawX + (visibleWidth - CHECKBOX_SIZE) / 2;
688
- const _y = this.drawY + (visibleHeight - CHECKBOX_SIZE) / 2;
689
- let checkboxImage = this.ctx.icons.get('checkbox-uncheck');
690
- let checkboxName = 'checkbox-uncheck';
691
920
  if (check && selectable) {
692
921
  checkboxImage = this.ctx.icons.get('checkbox-check');
693
922
  checkboxName = 'checkbox-check';
694
923
  }
695
- else if (check && selectable) {
924
+ else if (check && !selectable) {
696
925
  checkboxImage = this.ctx.icons.get('checkbox-check-disabled');
697
926
  checkboxName = 'checkbox-check-disabled';
698
927
  }
@@ -704,26 +933,33 @@ export default class Cell extends BaseCell {
704
933
  checkboxImage = this.ctx.icons.get('checkbox-disabled');
705
934
  checkboxName = 'checkbox-disabled';
706
935
  }
707
- if (checkboxImage && type == 'index-selection') {
708
- if ((this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === rowIndex) ||
709
- ['checkbox-disabled', 'checkbox-check'].includes(checkboxName)) {
710
- this.drawImageX = _x;
711
- this.drawImageY = _y;
712
- this.drawImageWidth = CHECKBOX_SIZE;
713
- this.drawImageHeight = CHECKBOX_SIZE;
714
- this.drawImageName = checkboxName;
715
- this.drawImageSource = checkboxImage;
716
- }
717
- }
718
- else if (checkboxImage && 'selection' === type) {
719
- this.drawImageX = _x;
720
- this.drawImageY = _y;
721
- this.drawImageWidth = CHECKBOX_SIZE;
722
- this.drawImageHeight = CHECKBOX_SIZE;
723
- this.drawImageName = checkboxName;
724
- this.drawImageSource = checkboxImage;
936
+ }
937
+ // 判断是否溢出格子
938
+ if (iconX + CHECKBOX_SIZE + CELL_PADDING > this.drawX + this.visibleWidth) {
939
+ return;
940
+ }
941
+ if (iconY + CHECKBOX_SIZE + CELL_PADDING > this.drawY + this.visibleHeight) {
942
+ return;
943
+ }
944
+ if (type === 'index-selection') {
945
+ if ((this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === rowIndex) ||
946
+ ['checkbox-disabled', 'checkbox-check'].includes(checkboxName)) {
947
+ this.drawSelectionImageX = iconX;
948
+ this.drawSelectionImageY = iconY;
949
+ this.drawSelectionImageWidth = CHECKBOX_SIZE;
950
+ this.drawSelectionImageHeight = CHECKBOX_SIZE;
951
+ this.drawSelectionImageName = checkboxName;
952
+ this.drawSelectionImageSource = checkboxImage;
725
953
  }
726
954
  }
955
+ else {
956
+ this.drawSelectionImageX = iconX;
957
+ this.drawSelectionImageY = iconY;
958
+ this.drawSelectionImageWidth = CHECKBOX_SIZE;
959
+ this.drawSelectionImageHeight = CHECKBOX_SIZE;
960
+ this.drawSelectionImageName = checkboxName;
961
+ this.drawSelectionImageSource = checkboxImage;
962
+ }
727
963
  }
728
964
  updateHoverIcon() {
729
965
  const readonly = this.ctx.database.getReadonly(this.rowKey, this.key);
@@ -767,12 +1003,12 @@ export default class Cell extends BaseCell {
767
1003
  }
768
1004
  }
769
1005
  const drawImageSource = this.ctx.icons.get(this.hoverIconName);
770
- this.drawImageX = _x;
771
- this.drawImageY = _y;
772
- this.drawImageWidth = CELL_HOVER_ICON_SIZE;
773
- this.drawImageHeight = CELL_HOVER_ICON_SIZE;
774
- this.drawImageName = this.hoverIconName;
775
- this.drawImageSource = drawImageSource;
1006
+ this.drawHoverImageX = _x;
1007
+ this.drawHoverImageY = _y;
1008
+ this.drawHoverImageWidth = CELL_HOVER_ICON_SIZE;
1009
+ this.drawHoverImageHeight = CELL_HOVER_ICON_SIZE;
1010
+ this.drawHoverImageName = this.hoverIconName;
1011
+ this.drawHoverImageSource = drawImageSource;
776
1012
  }
777
1013
  }
778
1014
  // 过去跨度配置
@@ -807,7 +1043,7 @@ export default class Cell extends BaseCell {
807
1043
  //
808
1044
  if (this.type === 'index-selection' &&
809
1045
  ((this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === this.rowIndex) ||
810
- ['checkbox-disabled', 'checkbox-check'].includes(this.drawImageName))) {
1046
+ ['checkbox-disabled', 'checkbox-check'].includes(this.drawSelectionImageName))) {
811
1047
  return '';
812
1048
  }
813
1049
  if (this.text === null || this.text === undefined) {
@@ -956,7 +1192,9 @@ export default class Cell extends BaseCell {
956
1192
  }
957
1193
  }
958
1194
  draw() {
959
- // 画选中框
1195
+ // 树连线(需在文本之前绘制,避免覆盖图标但不遮挡文本)
1196
+ this.drawTreeLine();
1197
+ // 文字与图标
960
1198
  this.drawText();
961
1199
  this.drawImage();
962
1200
  this.drawSelector();
@@ -980,12 +1218,7 @@ export default class Cell extends BaseCell {
980
1218
  }
981
1219
  drawText() {
982
1220
  const { CELL_PADDING, BODY_FONT, PLACEHOLDER_COLOR } = this.ctx.config;
983
- let visibleWidth = this.visibleWidth;
984
- if (this.type === 'tree') {
985
- const offsetIconX = this.drawTextX - this.drawX;
986
- visibleWidth = this.visibleWidth - offsetIconX; // 减去树形图标的宽度
987
- }
988
- const { ellipsis } = this.ctx.paint.handleEllipsis(this.displayText, visibleWidth, CELL_PADDING, BODY_FONT);
1221
+ const { ellipsis } = this.ctx.paint.handleEllipsis(this.displayText, this.drawTextWidth, CELL_PADDING, BODY_FONT);
989
1222
  this.ellipsis = ellipsis;
990
1223
  const { placeholder } = this.column;
991
1224
  let text = this.displayText;
@@ -1000,7 +1233,7 @@ export default class Cell extends BaseCell {
1000
1233
  text = placeholder;
1001
1234
  color = PLACEHOLDER_COLOR;
1002
1235
  }
1003
- return this.ctx.paint.drawText(text, this.drawTextX, this.drawTextY, visibleWidth, this.visibleHeight, {
1236
+ return this.ctx.paint.drawText(text, this.drawTextX, this.drawTextY, this.drawTextWidth, this.drawTextHeight, {
1004
1237
  font: BODY_FONT,
1005
1238
  padding: CELL_PADDING,
1006
1239
  align: this.align,
@@ -1009,19 +1242,23 @@ export default class Cell extends BaseCell {
1009
1242
  });
1010
1243
  }
1011
1244
  drawImage() {
1012
- if (!this.drawImageSource) {
1013
- return;
1245
+ if (this.drawSelectionImageSource) {
1246
+ this.ctx.paint.drawImage(this.drawSelectionImageSource, this.drawSelectionImageX, this.drawSelectionImageY, this.drawSelectionImageWidth, this.drawSelectionImageHeight);
1247
+ }
1248
+ if (this.drawTreeImageSource) {
1249
+ this.ctx.paint.drawImage(this.drawTreeImageSource, this.drawTreeImageX, this.drawTreeImageY, this.drawTreeImageWidth, this.drawTreeImageHeight);
1014
1250
  }
1015
- if (this.hoverIconName) {
1251
+ if (this.drawHoverImageSource) {
1252
+ // 绘制hover图标背景
1016
1253
  const { CELL_HOVER_ICON_BG_COLOR, CELL_HOVER_ICON_BORDER_COLOR } = this.ctx.config;
1017
- this.ctx.paint.drawRect(this.drawImageX - 2, this.drawImageY - 2, this.drawImageWidth + 4, this.drawImageHeight + 4, {
1254
+ this.ctx.paint.drawRect(this.drawHoverImageX - 2, this.drawHoverImageY - 2, this.drawHoverImageWidth + 4, this.drawHoverImageHeight + 4, {
1018
1255
  borderColor: CELL_HOVER_ICON_BORDER_COLOR,
1019
1256
  radius: 4,
1020
1257
  borderWidth: 1,
1021
1258
  fillColor: CELL_HOVER_ICON_BG_COLOR,
1022
1259
  });
1260
+ this.ctx.paint.drawImage(this.drawHoverImageSource, this.drawHoverImageX, this.drawHoverImageY, this.drawHoverImageWidth, this.drawHoverImageHeight);
1023
1261
  }
1024
- this.ctx.paint.drawImage(this.drawImageSource, this.drawImageX, this.drawImageY, this.drawImageWidth, this.drawImageHeight);
1025
1262
  }
1026
1263
  drawSelector() {
1027
1264
  if (this.cellType === 'footer') {