zmdms-webui 2.6.2 → 2.6.4
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/dist/es/canvastable/canvasTable.js +75 -27
- package/dist/es/canvastable/hooks/renderers/BadgeRenderer.js +58 -0
- package/dist/es/canvastable/hooks/renderers/BorderRenderer.js +229 -0
- package/dist/es/canvastable/hooks/renderers/DataRowRenderer.js +358 -0
- package/dist/es/canvastable/hooks/renderers/ExpandIconRenderer.js +97 -0
- package/dist/es/canvastable/hooks/renderers/FixedColumnRenderer.js +71 -0
- package/dist/es/canvastable/hooks/renderers/FixedRowRenderer.js +192 -0
- package/dist/es/canvastable/hooks/renderers/HeaderRenderer.js +395 -0
- package/dist/es/canvastable/hooks/renderers/ScrollbarRenderer.js +85 -0
- package/dist/es/canvastable/hooks/renderers/SelectionRenderer.js +181 -0
- package/dist/es/canvastable/hooks/useExpandable.js +185 -0
- package/dist/es/canvastable/hooks/useTableInteraction.js +37 -1
- package/dist/es/canvastable/hooks/useTableRender.js +172 -1464
- package/dist/es/canvastable/interface.d.ts +71 -1
- package/dist/es/canvastable/utils/renderHelpers.js +118 -0
- package/dist/es/table/excel.js +62 -9
- package/dist/es/table/table.js +17 -15
- package/package.json +3 -2
|
@@ -13,6 +13,7 @@ import HeaderOverlay from './components/HeaderOverlay.js';
|
|
|
13
13
|
import { useContextMenu as Fe } from '../node_modules/react-contexify/dist/index.js';
|
|
14
14
|
import { useTableState } from './hooks/useTableState.js';
|
|
15
15
|
import { useTableSelection } from './hooks/useTableSelection.js';
|
|
16
|
+
import { useExpandable } from './hooks/useExpandable.js';
|
|
16
17
|
import { useTableRender } from './hooks/useTableRender.js';
|
|
17
18
|
import { useTableInteraction } from './hooks/useTableInteraction.js';
|
|
18
19
|
import { useScrollbarMetrics, useTableScroll, useScrollReset } from './hooks/useScroll.js';
|
|
@@ -39,7 +40,8 @@ import { getTableColumns } from '../table/utils.js';
|
|
|
39
40
|
import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
|
|
40
41
|
|
|
41
42
|
function CanvasTable(props) {
|
|
42
|
-
var _a
|
|
43
|
+
var _a;
|
|
44
|
+
var _b = props.dataSource, dataSource = _b === void 0 ? [] : _b, _c = props.columns, columns = _c === void 0 ? [] : _c, _d = props.rowKey, rowKey = _d === void 0 ? "id" : _d, _e = props.height, height = _e === void 0 ? 600 : _e, width = props.width, _f = props.rowHeight, rowHeight = _f === void 0 ? 36 : _f, _g = props.headerHeight, headerHeight = _g === void 0 ? 36 : _g, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _h = props.bordered, bordered = _h === void 0 ? true : _h, _j = props.striped, striped = _j === void 0 ? false : _j, _k = props.emptyText, emptyText = _k === void 0 ? "暂无数据" : _k, style = props.style, className = props.className, _l = props.loading, loading = _l === void 0 ? false : _l, _m = props.isContextMenu, isContextMenu = _m === void 0 ? true : _m, isFullscreenHandle = props.isFullscreenHandle, mode = props.mode, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _o = props.isIndexMerge, isIndexMerge = _o === void 0 ? true : _o, _p = props.isSelectionMerge, isSelectionMerge = _p === void 0 ? false : _p, _q = props.renderMode, renderMode = _q === void 0 ? "object" : _q, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _r = props.summaryFixed, summaryFixed = _r === void 0 ? false : _r, _s = props.isAutoScrollY, isAutoScrollY = _s === void 0 ? false : _s, _t = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _t === void 0 ? 65 : _t, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _u = props.headerAlign, headerAlign = _u === void 0 ? "center" : _u, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig, _v = props.maxHeight, maxHeight = _v === void 0 ? 3000 : _v, expandable = props.expandable;
|
|
43
45
|
var actualMode = "mode" in props ? mode : "index";
|
|
44
46
|
var canvasRef = useRef(null);
|
|
45
47
|
var containerRef = useRef(null);
|
|
@@ -62,17 +64,17 @@ function CanvasTable(props) {
|
|
|
62
64
|
return String((_a = record[rowKey]) !== null && _a !== void 0 ? _a : index);
|
|
63
65
|
}, [rowKey]);
|
|
64
66
|
// 动态列配置
|
|
65
|
-
var
|
|
67
|
+
var _w = useDynamicListByColumns(columns, {
|
|
66
68
|
dynamicKey: dynamicKey,
|
|
67
69
|
dynamicVersion: dynamicVersion,
|
|
68
70
|
customDynamicListHandle: customDynamicListHandle,
|
|
69
|
-
}), defaultDynamicList =
|
|
71
|
+
}), defaultDynamicList = _w.defaultDynamicList, currentDynamicList = _w.currentDynamicList, onCurrentListChange = _w.onCurrentListChange, dynamicSettingRef = _w.dynamicSettingRef;
|
|
70
72
|
// 根据动态列配置处理columns
|
|
71
73
|
var dynamicColumns = useMemo(function () { return getTableColumns(columns, currentDynamicList); }, [columns, currentDynamicList]).columns;
|
|
72
74
|
// 内部列宽状态(未开启动态配置时使用)
|
|
73
|
-
var
|
|
75
|
+
var _x = useState({}), internalColumnWidths = _x[0], setInternalColumnWidths = _x[1];
|
|
74
76
|
// 跟踪用户手动调整过宽度的列(用于排除自动宽度分配)
|
|
75
|
-
var
|
|
77
|
+
var _y = useState(new Set()), manuallyResizedColumnKeys = _y[0], setManuallyResizedColumnKeys = _y[1];
|
|
76
78
|
// 处理选中框列、序号列等
|
|
77
79
|
var processedColumnsOld = useProcessedColumns({
|
|
78
80
|
columns: columns,
|
|
@@ -87,33 +89,46 @@ function CanvasTable(props) {
|
|
|
87
89
|
headerAlign: headerAlign,
|
|
88
90
|
});
|
|
89
91
|
// 表格状态管理
|
|
90
|
-
var
|
|
92
|
+
var _z = useTableState({
|
|
91
93
|
dataSource: dataSource,
|
|
92
94
|
columns: processedColumnsOld,
|
|
93
95
|
rowSelection: rowSelection,
|
|
94
96
|
onFilterChange: onFilterChange,
|
|
95
97
|
isAutoMerge: isAutoMerge,
|
|
96
|
-
}), state =
|
|
98
|
+
}), state = _z.state, setState = _z.setState, processedDataSource = _z.processedDataSource, handleFilterChange = _z.handleFilterChange, closeFilterPopover = _z.closeFilterPopover, autoGeneratedFilters = _z.autoGeneratedFilters;
|
|
99
|
+
// 树形展开管理
|
|
100
|
+
var _0 = useExpandable({
|
|
101
|
+
dataSource: dataSource,
|
|
102
|
+
expandable: expandable,
|
|
103
|
+
rowKey: rowKey,
|
|
104
|
+
}), expandedKeys = _0.expandedKeys, flattenedData = _0.flattenedData, toggleExpand = _0.toggleExpand, expandRow = _0.expandRow, collapseRow = _0.collapseRow, setExpandedRowKeys = _0.setExpandedRowKeys, hasExpandable = _0.hasExpandable;
|
|
97
105
|
var order = useMemo(function () {
|
|
98
106
|
return state.sortOrder && state.sortField
|
|
99
107
|
? { field: state.sortField, order: state.sortOrder }
|
|
100
108
|
: undefined;
|
|
101
109
|
}, [state.sortOrder, state.sortField]);
|
|
102
|
-
var
|
|
110
|
+
var _1 = useAutoMerge(processedDataSource, processedColumnsOld, {
|
|
103
111
|
isAutoMerge: isAutoMerge,
|
|
104
112
|
isDimensionDynamic: isDimensionDynamic,
|
|
105
113
|
order: order,
|
|
106
114
|
dimensionCustomSumKeys: dimensionCustomSumKeys,
|
|
107
|
-
}), newDataSource =
|
|
115
|
+
}), newDataSource = _1[0], processedColumns = _1[1];
|
|
116
|
+
// 如果开启了树形展开,使用扁平化后的数据源
|
|
117
|
+
var expandedDataSource = useMemo(function () {
|
|
118
|
+
if (hasExpandable) {
|
|
119
|
+
return flattenedData.map(function (item) { return item.record; });
|
|
120
|
+
}
|
|
121
|
+
return newDataSource;
|
|
122
|
+
}, [hasExpandable, flattenedData, newDataSource]);
|
|
108
123
|
// 生成合计行和最终数据源
|
|
109
|
-
var
|
|
124
|
+
var _2 = useSummaryRow({
|
|
110
125
|
columns: processedColumns,
|
|
111
|
-
dataSource:
|
|
112
|
-
}), finalDataSource =
|
|
126
|
+
dataSource: expandedDataSource,
|
|
127
|
+
}), finalDataSource = _2.finalDataSource, hasSummaryRow = _2.hasSummaryRow;
|
|
113
128
|
// 用于存储计算后的表头高度(用于自动高度的精确计算)
|
|
114
|
-
var
|
|
129
|
+
var _3 = useState(undefined), preciseHeaderHeight = _3[0], setPreciseHeaderHeight = _3[1];
|
|
115
130
|
// 用于存储是否需要横向滚动条(用于自动高度的精确计算)
|
|
116
|
-
var
|
|
131
|
+
var _4 = useState(false), needHorizontalScrollbar = _4[0], setNeedHorizontalScrollbar = _4[1];
|
|
117
132
|
// 自动高度计算(需要在容器尺寸计算之前)
|
|
118
133
|
var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId, finalDataSource.length, // 数据行数(用于 content 模式)
|
|
119
134
|
headerHeight, // 表头基础高度(用于 content 模式的初始计算)
|
|
@@ -180,7 +195,7 @@ function CanvasTable(props) {
|
|
|
180
195
|
return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
|
|
181
196
|
}, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
|
|
182
197
|
// 计算滚动条指标
|
|
183
|
-
var
|
|
198
|
+
var _5 = useScrollbarMetrics({
|
|
184
199
|
containerWidth: containerWidth,
|
|
185
200
|
containerHeight: containerHeight,
|
|
186
201
|
totalWidth: totalWidth,
|
|
@@ -188,14 +203,14 @@ function CanvasTable(props) {
|
|
|
188
203
|
headerHeight: calculatedHeaderHeight,
|
|
189
204
|
scrollTop: 0,
|
|
190
205
|
scrollLeft: 0,
|
|
191
|
-
}), maxScrollTop =
|
|
206
|
+
}), maxScrollTop = _5.maxScrollTop, maxScrollLeft = _5.maxScrollLeft;
|
|
192
207
|
// 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
|
|
193
|
-
var
|
|
208
|
+
var _6 = useTableScroll({
|
|
194
209
|
containerRef: containerRef,
|
|
195
210
|
maxScrollTop: maxScrollTop,
|
|
196
211
|
maxScrollLeft: maxScrollLeft,
|
|
197
212
|
onScroll: onScroll,
|
|
198
|
-
}), scrollState =
|
|
213
|
+
}), scrollState = _6.scrollState, setScrollState = _6.setScrollState;
|
|
199
214
|
// 使用 ref 保存最新的滚动位置,确保在组件卸载过程中仍能访问
|
|
200
215
|
var scrollPositionRef = useRef({ x: 0, y: 0 });
|
|
201
216
|
useEffect(function () {
|
|
@@ -213,6 +228,10 @@ function CanvasTable(props) {
|
|
|
213
228
|
sortOrder: state.sortOrder,
|
|
214
229
|
setScrollState: setScrollState,
|
|
215
230
|
});
|
|
231
|
+
// 容器尺寸变化时重置滚动位置
|
|
232
|
+
useEffect(function () {
|
|
233
|
+
setScrollState(function (prev) { return (__assign(__assign({}, prev), { scrollLeft: 0, scrollTop: 0 })); });
|
|
234
|
+
}, [containerWidth, containerHeight, setScrollState]);
|
|
216
235
|
// 使用实际滚动位置重新计算滚动条的显示位置
|
|
217
236
|
var scrollbarMetrics = useScrollbarMetrics({
|
|
218
237
|
containerWidth: containerWidth,
|
|
@@ -235,12 +254,12 @@ function CanvasTable(props) {
|
|
|
235
254
|
needHorizontalScrollbar,
|
|
236
255
|
]);
|
|
237
256
|
// 单元格框选
|
|
238
|
-
var
|
|
257
|
+
var _7 = useTableSelection({
|
|
239
258
|
state: state,
|
|
240
259
|
setState: setState,
|
|
241
260
|
}),
|
|
242
261
|
// selectionStartRef,
|
|
243
|
-
startSelection =
|
|
262
|
+
startSelection = _7.startSelection, updateSelection = _7.updateSelection, extendSelection = _7.extendSelection;
|
|
244
263
|
// 处理列宽调整
|
|
245
264
|
var handleColumnResize = useCallback(function (columnKey, newWidth) {
|
|
246
265
|
var _a;
|
|
@@ -295,20 +314,20 @@ function CanvasTable(props) {
|
|
|
295
314
|
onCurrentListChange,
|
|
296
315
|
]);
|
|
297
316
|
// 列宽调整
|
|
298
|
-
var
|
|
317
|
+
var _8 = useColumnResize({
|
|
299
318
|
columnRenderInfos: columnRenderInfos,
|
|
300
319
|
containerWidth: containerWidth,
|
|
301
320
|
headerHeight: calculatedHeaderHeight,
|
|
302
321
|
scrollLeft: scrollState.scrollLeft,
|
|
303
322
|
onColumnResize: handleColumnResize,
|
|
304
|
-
}), resizeState =
|
|
323
|
+
}), resizeState = _8.resizeState, checkResizeHandle = _8.checkResizeHandle, startResize = _8.startResize, updateResize = _8.updateResize, endResize = _8.endResize, setHoverResizeColumn = _8.setHoverResizeColumn, getColumnWidth = _8.getColumnWidth, RESIZE_HANDLE_WIDTH = _8.RESIZE_HANDLE_WIDTH;
|
|
305
324
|
// 复制到剪贴板
|
|
306
|
-
var
|
|
325
|
+
var _9 = useCopyToClipboard({
|
|
307
326
|
cellSelection: state.cellSelection,
|
|
308
327
|
processedDataSource: finalDataSource,
|
|
309
328
|
columns: processedColumns,
|
|
310
329
|
containerRef: containerRef,
|
|
311
|
-
}), getSelectedCellsText =
|
|
330
|
+
}), getSelectedCellsText = _9.getSelectedCellsText, copyToClipboard = _9.copyToClipboard;
|
|
312
331
|
// 处理右键菜单的复制操作
|
|
313
332
|
var handleCopy = useCallback(function () {
|
|
314
333
|
var text = getSelectedCellsText();
|
|
@@ -325,9 +344,10 @@ function CanvasTable(props) {
|
|
|
325
344
|
columns: exportColumns,
|
|
326
345
|
isAutoMerge: isAutoMerge,
|
|
327
346
|
summaryConfig: (exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.isExportNoSummary) ? undefined : [],
|
|
347
|
+
childrenColumnName: (_a = props.expandable) === null || _a === void 0 ? void 0 : _a.childrenColumnName,
|
|
328
348
|
});
|
|
329
349
|
// 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
|
|
330
|
-
var
|
|
350
|
+
var _10 = useTableInteraction({
|
|
331
351
|
state: state,
|
|
332
352
|
setState: setState,
|
|
333
353
|
scrollState: scrollState,
|
|
@@ -335,6 +355,8 @@ function CanvasTable(props) {
|
|
|
335
355
|
processedDataSource: finalDataSource,
|
|
336
356
|
columnRenderInfos: columnRenderInfos,
|
|
337
357
|
columns: processedColumns,
|
|
358
|
+
expandable: expandable,
|
|
359
|
+
flattenedData: flattenedData,
|
|
338
360
|
rowSelection: rowSelection,
|
|
339
361
|
rowHeight: rowHeight,
|
|
340
362
|
headerHeight: calculatedHeaderHeight,
|
|
@@ -359,6 +381,7 @@ function CanvasTable(props) {
|
|
|
359
381
|
onSortChange: onSortChange,
|
|
360
382
|
onRowClick: onRowClick,
|
|
361
383
|
getRowKey: getRowKey,
|
|
384
|
+
onExpand: toggleExpand,
|
|
362
385
|
startSelection: startSelection,
|
|
363
386
|
updateSelection: updateSelection,
|
|
364
387
|
extendSelection: extendSelection,
|
|
@@ -374,11 +397,11 @@ function CanvasTable(props) {
|
|
|
374
397
|
fixedRowsCount: fixedRowsCount,
|
|
375
398
|
fixedRowsConfig: fixedRowsConfig,
|
|
376
399
|
summaryFixed: summaryFixed,
|
|
377
|
-
}), handleCanvasMouseDown =
|
|
400
|
+
}), handleCanvasMouseDown = _10.handleCanvasMouseDown, handleCanvasMouseMove = _10.handleCanvasMouseMove, handleCanvasMouseUp = _10.handleCanvasMouseUp, handleCanvasMouseLeave = _10.handleCanvasMouseLeave, handleCanvasContextMenu = _10.handleCanvasContextMenu;
|
|
378
401
|
// 渲染表格
|
|
379
402
|
useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
|
|
380
403
|
state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, baseHeaderHeight: headerHeight, // 传入原始基础高度用于计算每层高度
|
|
381
|
-
rowHeight: rowHeight, bordered: bordered, striped: striped, headerAlign: headerAlign }, scrollbarMetrics), { getRowKey: getRowKey, resizeState: resizeState, getColumnWidth: getColumnWidth, RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH, mergeCellMap: mergeCellMap, hasSummaryRow: hasSummaryRow, fixedRowsCount: fixedRowsCount, fixedRowsConfig: fixedRowsConfig, summaryFixed: summaryFixed }));
|
|
404
|
+
rowHeight: rowHeight, bordered: bordered, striped: striped, headerAlign: headerAlign }, scrollbarMetrics), { getRowKey: getRowKey, resizeState: resizeState, getColumnWidth: getColumnWidth, RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH, mergeCellMap: mergeCellMap, hasSummaryRow: hasSummaryRow, fixedRowsCount: fixedRowsCount, fixedRowsConfig: fixedRowsConfig, summaryFixed: summaryFixed, expandable: expandable, flattenedData: flattenedData }));
|
|
382
405
|
// 单元格覆盖层
|
|
383
406
|
var cellOverlays = useTableCellOverlay({
|
|
384
407
|
canvasRef: canvasRef,
|
|
@@ -469,6 +492,26 @@ function CanvasTable(props) {
|
|
|
469
492
|
setSelectedRowKeys: function (keys) {
|
|
470
493
|
setState(function (prev) { return (__assign(__assign({}, prev), { selectedRowKeys: keys })); });
|
|
471
494
|
},
|
|
495
|
+
/** 获取展开的keys */
|
|
496
|
+
getExpandedRowKeys: function () {
|
|
497
|
+
return Array.from(expandedKeys);
|
|
498
|
+
},
|
|
499
|
+
/** 设置展开的keys */
|
|
500
|
+
setExpandedRowKeys: function (keys) {
|
|
501
|
+
setExpandedRowKeys(keys);
|
|
502
|
+
},
|
|
503
|
+
/** 展开指定行 */
|
|
504
|
+
expandRow: function (key) {
|
|
505
|
+
expandRow(key);
|
|
506
|
+
},
|
|
507
|
+
/** 收起指定行 */
|
|
508
|
+
collapseRow: function (key) {
|
|
509
|
+
collapseRow(key);
|
|
510
|
+
},
|
|
511
|
+
/** 切换指定行展开状态 */
|
|
512
|
+
toggleExpandRow: function (key) {
|
|
513
|
+
toggleExpand(key);
|
|
514
|
+
},
|
|
472
515
|
/** 滚动到指定位置 */
|
|
473
516
|
scrollTo: function (params) {
|
|
474
517
|
setScrollState(function (prev) { return (__assign(__assign({}, prev), { scrollLeft: params.x !== undefined ? params.x : prev.scrollLeft, scrollTop: params.y !== undefined ? params.y : prev.scrollTop })); });
|
|
@@ -510,6 +553,11 @@ function CanvasTable(props) {
|
|
|
510
553
|
state.filters,
|
|
511
554
|
setState,
|
|
512
555
|
setScrollState,
|
|
556
|
+
expandedKeys,
|
|
557
|
+
setExpandedRowKeys,
|
|
558
|
+
expandRow,
|
|
559
|
+
collapseRow,
|
|
560
|
+
toggleExpand,
|
|
513
561
|
]);
|
|
514
562
|
return (jsx(Spin, __assign({ spinning: loading }, { children: jsxs("div", __assign({ ref: containerRef, id: canvasTableId, className: "canvas-table-container ".concat(className || ""), tabIndex: 0, style: __assign(__assign({}, style), { position: "relative", width: width || "100%", height: containerHeight, overflow: "hidden", touchAction: "none", outline: "none" }) }, { children: [jsx("canvas", { ref: canvasRef, onMouseDown: handleCanvasMouseDown, onMouseMove: handleCanvasMouseMove, onMouseUp: handleCanvasMouseUp, onMouseLeave: handleCanvasMouseLeave, onContextMenu: handleCanvasContextMenu, style: {
|
|
515
563
|
display: "block",
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Badge 渲染�?
|
|
3
|
+
* 负责绘制单元格角标(三角形标记,类似Excel批注�?
|
|
4
|
+
*/
|
|
5
|
+
var BadgeRenderer = /** @class */ (function () {
|
|
6
|
+
function BadgeRenderer() {
|
|
7
|
+
this.context = null;
|
|
8
|
+
}
|
|
9
|
+
BadgeRenderer.prototype.setContext = function (context) {
|
|
10
|
+
this.context = context;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 绘制角标
|
|
14
|
+
*/
|
|
15
|
+
BadgeRenderer.prototype.render = function (badge, cellX, cellY, cellWidth, cellHeight) {
|
|
16
|
+
if (!this.context) {
|
|
17
|
+
throw new Error("BadgeRenderer: Context not set");
|
|
18
|
+
}
|
|
19
|
+
var ctx = this.context.ctx;
|
|
20
|
+
var triangleSize = 12; // 三角形边�?
|
|
21
|
+
var position = badge.position || "top-right";
|
|
22
|
+
var color = badge.color || "#ff4d4f";
|
|
23
|
+
ctx.fillStyle = color;
|
|
24
|
+
ctx.beginPath();
|
|
25
|
+
// 根据位置绘制不同方向的三角形
|
|
26
|
+
switch (position) {
|
|
27
|
+
case "top-left":
|
|
28
|
+
// 左上角三角形
|
|
29
|
+
ctx.moveTo(cellX, cellY);
|
|
30
|
+
ctx.lineTo(cellX + triangleSize, cellY);
|
|
31
|
+
ctx.lineTo(cellX, cellY + triangleSize);
|
|
32
|
+
break;
|
|
33
|
+
case "top-right":
|
|
34
|
+
// 右上角三角形(默认)
|
|
35
|
+
ctx.moveTo(cellX + cellWidth, cellY);
|
|
36
|
+
ctx.lineTo(cellX + cellWidth - triangleSize, cellY);
|
|
37
|
+
ctx.lineTo(cellX + cellWidth, cellY + triangleSize);
|
|
38
|
+
break;
|
|
39
|
+
case "bottom-left":
|
|
40
|
+
// 左下角三角形
|
|
41
|
+
ctx.moveTo(cellX, cellY + cellHeight);
|
|
42
|
+
ctx.lineTo(cellX, cellY + cellHeight - triangleSize);
|
|
43
|
+
ctx.lineTo(cellX + triangleSize, cellY + cellHeight);
|
|
44
|
+
break;
|
|
45
|
+
case "bottom-right":
|
|
46
|
+
// 右下角三角形
|
|
47
|
+
ctx.moveTo(cellX + cellWidth, cellY + cellHeight);
|
|
48
|
+
ctx.lineTo(cellX + cellWidth, cellY + cellHeight - triangleSize);
|
|
49
|
+
ctx.lineTo(cellX + cellWidth - triangleSize, cellY + cellHeight);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
ctx.closePath();
|
|
53
|
+
ctx.fill();
|
|
54
|
+
};
|
|
55
|
+
return BadgeRenderer;
|
|
56
|
+
}());
|
|
57
|
+
|
|
58
|
+
export { BadgeRenderer };
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { COLORS, SCROLLBAR_SIZE } from '../../utils/constants.js';
|
|
2
|
+
import 'zmdms-utils';
|
|
3
|
+
import 'dayjs';
|
|
4
|
+
import '../../../_virtual/_tslib.js';
|
|
5
|
+
import { calculateFixedColumnsRightEdge } from '../../utils/renderHelpers.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 边框渲染�?
|
|
9
|
+
* 负责渲染表格的所有边框(数据行、固定行、表头)
|
|
10
|
+
*/
|
|
11
|
+
var BorderRenderer = /** @class */ (function () {
|
|
12
|
+
function BorderRenderer() {
|
|
13
|
+
this.context = null;
|
|
14
|
+
}
|
|
15
|
+
BorderRenderer.prototype.setContext = function (context) {
|
|
16
|
+
this.context = context;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* 渲染数据行边�?
|
|
20
|
+
*/
|
|
21
|
+
BorderRenderer.prototype.renderDataBorders = function (startRow, endRow, onlyFixed) {
|
|
22
|
+
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
23
|
+
if (!this.context || !this.context.bordered)
|
|
24
|
+
return;
|
|
25
|
+
var _a = this.context, ctx = _a.ctx, processedDataSource = _a.processedDataSource, headerHeight = _a.headerHeight, rowHeight = _a.rowHeight, scrollState = _a.scrollState, displayWidth = _a.displayWidth, displayHeight = _a.displayHeight, needHorizontalScrollbar = _a.needHorizontalScrollbar, fixedRowsCount = _a.fixedRowsCount, fixedRowsConfig = _a.fixedRowsConfig, summaryFixed = _a.summaryFixed, hasSummaryRow = _a.hasSummaryRow, columnRenderInfos = _a.columnRenderInfos, getColumnWidth = _a.getColumnWidth, mergeCellMap = _a.mergeCellMap;
|
|
26
|
+
ctx.strokeStyle = COLORS.border;
|
|
27
|
+
ctx.lineWidth = 1;
|
|
28
|
+
var dataRowCount = processedDataSource.length;
|
|
29
|
+
// 计算固定行占用的高度
|
|
30
|
+
var fixedTopRowsCount = fixedRowsCount || (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.topCount) || 0;
|
|
31
|
+
var fixedBottomRowsCount = (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.bottomCount) || 0;
|
|
32
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
33
|
+
var fixedBottomHeight = fixedBottomRowsCount * rowHeight;
|
|
34
|
+
// 计算可滚动数据行的数�?
|
|
35
|
+
var scrollableDataRowCount = dataRowCount -
|
|
36
|
+
fixedTopRowsCount -
|
|
37
|
+
fixedBottomRowsCount -
|
|
38
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
39
|
+
// 计算实际数据区域的底部位�?
|
|
40
|
+
var dataBottomY = Math.min(headerHeight +
|
|
41
|
+
fixedTopRowsCount * rowHeight +
|
|
42
|
+
scrollableDataRowCount * rowHeight -
|
|
43
|
+
scrollState.scrollTop, displayHeight -
|
|
44
|
+
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
45
|
+
fixedBottomHeight -
|
|
46
|
+
fixedSummaryHeight);
|
|
47
|
+
// 绘制垂直边框
|
|
48
|
+
columnRenderInfos.forEach(function (info, colIndex) {
|
|
49
|
+
var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
|
|
50
|
+
if (onlyFixed && !fixed)
|
|
51
|
+
return;
|
|
52
|
+
if (!onlyFixed && fixed)
|
|
53
|
+
return;
|
|
54
|
+
var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
|
|
55
|
+
var drawX = fixed
|
|
56
|
+
? fixedLeft + actualWidth
|
|
57
|
+
: x + actualWidth - scrollState.scrollLeft;
|
|
58
|
+
if (drawX >= 0 && drawX <= displayWidth) {
|
|
59
|
+
ctx.beginPath();
|
|
60
|
+
ctx.moveTo(drawX, headerHeight);
|
|
61
|
+
ctx.lineTo(drawX, dataBottomY);
|
|
62
|
+
ctx.stroke();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// 绘制水平边框
|
|
66
|
+
var maxRow = Math.min(endRow, dataRowCount, fixedTopRowsCount + scrollableDataRowCount);
|
|
67
|
+
var _loop_1 = function (i) {
|
|
68
|
+
var y = headerHeight +
|
|
69
|
+
fixedTopRowsCount * rowHeight +
|
|
70
|
+
(i - fixedTopRowsCount) * rowHeight -
|
|
71
|
+
scrollState.scrollTop;
|
|
72
|
+
if (y >= headerHeight + fixedTopRowsCount * rowHeight &&
|
|
73
|
+
y <= dataBottomY) {
|
|
74
|
+
// 分段绘制,只绘制当前范围的边�?
|
|
75
|
+
columnRenderInfos.forEach(function (info, colIndex) {
|
|
76
|
+
if (onlyFixed && !info.fixed)
|
|
77
|
+
return;
|
|
78
|
+
if (!onlyFixed && info.fixed)
|
|
79
|
+
return;
|
|
80
|
+
var mergeCellKey = "".concat(i, "-").concat(colIndex);
|
|
81
|
+
var mergeInfo = mergeCellMap === null || mergeCellMap === void 0 ? void 0 : mergeCellMap.get(mergeCellKey);
|
|
82
|
+
// 只有被合并的单元格(skip=true)才跳过绘制上边�?
|
|
83
|
+
if (mergeInfo && mergeInfo.skip) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
|
|
87
|
+
var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
|
|
88
|
+
var drawX = fixed ? fixedLeft : x - scrollState.scrollLeft;
|
|
89
|
+
if (!fixed && (drawX + actualWidth < 0 || drawX > displayWidth)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
ctx.beginPath();
|
|
93
|
+
ctx.moveTo(Math.max(drawX, 0), y);
|
|
94
|
+
ctx.lineTo(Math.min(drawX + actualWidth, displayWidth), y);
|
|
95
|
+
ctx.stroke();
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
for (var i = startRow; i <= maxRow; i++) {
|
|
100
|
+
_loop_1(i);
|
|
101
|
+
}
|
|
102
|
+
// 为合并单元格绘制底部边框
|
|
103
|
+
if (mergeCellMap && mergeCellMap.size > 0) {
|
|
104
|
+
mergeCellMap.forEach(function (mergeInfo) {
|
|
105
|
+
if (!mergeInfo.skip && mergeInfo.rowSpan > 1) {
|
|
106
|
+
var rowIndex = mergeInfo.rowIndex, colIndex = mergeInfo.colIndex, rowSpan = mergeInfo.rowSpan;
|
|
107
|
+
if (rowIndex >= startRow && rowIndex <= maxRow) {
|
|
108
|
+
var columnInfo = columnRenderInfos[colIndex];
|
|
109
|
+
if (!columnInfo)
|
|
110
|
+
return;
|
|
111
|
+
if (onlyFixed && !columnInfo.fixed)
|
|
112
|
+
return;
|
|
113
|
+
if (!onlyFixed && columnInfo.fixed)
|
|
114
|
+
return;
|
|
115
|
+
var x = columnInfo.x, width = columnInfo.width, fixed = columnInfo.fixed, fixedLeft = columnInfo.fixedLeft;
|
|
116
|
+
var actualWidth = getColumnWidth
|
|
117
|
+
? getColumnWidth(colIndex)
|
|
118
|
+
: width;
|
|
119
|
+
var drawX = fixed ? fixedLeft : x - scrollState.scrollLeft;
|
|
120
|
+
var bottomY = headerHeight +
|
|
121
|
+
fixedTopRowsCount * rowHeight +
|
|
122
|
+
(rowIndex + rowSpan - fixedTopRowsCount) * rowHeight -
|
|
123
|
+
scrollState.scrollTop;
|
|
124
|
+
if (bottomY >= headerHeight + fixedTopRowsCount * rowHeight &&
|
|
125
|
+
bottomY <= dataBottomY) {
|
|
126
|
+
ctx.beginPath();
|
|
127
|
+
ctx.moveTo(drawX, bottomY);
|
|
128
|
+
ctx.lineTo(drawX + actualWidth, bottomY);
|
|
129
|
+
ctx.stroke();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* 渲染固定行边框(通用�?
|
|
138
|
+
*/
|
|
139
|
+
BorderRenderer.prototype.renderFixedRowBorders = function (rowCount, startYCalculator, onlyFixed, borderType) {
|
|
140
|
+
var _this = this;
|
|
141
|
+
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
142
|
+
if (borderType === void 0) { borderType = "normal"; }
|
|
143
|
+
if (!this.context || !this.context.bordered)
|
|
144
|
+
return;
|
|
145
|
+
var _a = this.context, ctx = _a.ctx, columnRenderInfos = _a.columnRenderInfos, scrollState = _a.scrollState, displayWidth = _a.displayWidth, getColumnWidth = _a.getColumnWidth;
|
|
146
|
+
ctx.save();
|
|
147
|
+
ctx.strokeStyle = COLORS.border;
|
|
148
|
+
ctx.lineWidth = borderType === "summary" ? 2 : 1;
|
|
149
|
+
var startY = startYCalculator();
|
|
150
|
+
// 计算固定列的右边�?
|
|
151
|
+
var fixedColumnsRightEdge = 0;
|
|
152
|
+
if (onlyFixed) {
|
|
153
|
+
fixedColumnsRightEdge = calculateFixedColumnsRightEdge(columnRenderInfos, getColumnWidth);
|
|
154
|
+
}
|
|
155
|
+
// 绘制水平边框
|
|
156
|
+
for (var i = 0; i <= rowCount; i++) {
|
|
157
|
+
var y = startY + i * this.context.rowHeight;
|
|
158
|
+
ctx.beginPath();
|
|
159
|
+
if (onlyFixed) {
|
|
160
|
+
ctx.moveTo(0, y);
|
|
161
|
+
ctx.lineTo(fixedColumnsRightEdge, y);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
ctx.moveTo(0, y);
|
|
165
|
+
ctx.lineTo(displayWidth, y);
|
|
166
|
+
}
|
|
167
|
+
ctx.stroke();
|
|
168
|
+
}
|
|
169
|
+
// 绘制垂直边框
|
|
170
|
+
ctx.lineWidth = 1;
|
|
171
|
+
columnRenderInfos.forEach(function (info, colIndex) {
|
|
172
|
+
var _a;
|
|
173
|
+
var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
|
|
174
|
+
if (onlyFixed && !fixed)
|
|
175
|
+
return;
|
|
176
|
+
if (!onlyFixed && fixed)
|
|
177
|
+
return;
|
|
178
|
+
var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
|
|
179
|
+
var drawX = fixed
|
|
180
|
+
? fixedLeft + actualWidth
|
|
181
|
+
: x + actualWidth - scrollState.scrollLeft;
|
|
182
|
+
if (drawX >= 0 && drawX <= displayWidth) {
|
|
183
|
+
ctx.beginPath();
|
|
184
|
+
ctx.moveTo(drawX, startY);
|
|
185
|
+
ctx.lineTo(drawX, startY + rowCount * (((_a = _this.context) === null || _a === void 0 ? void 0 : _a.rowHeight) || 0));
|
|
186
|
+
ctx.stroke();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
ctx.restore();
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* 渲染固定顶部行边�?
|
|
193
|
+
*/
|
|
194
|
+
BorderRenderer.prototype.renderFixedTopBorders = function (rowCount, onlyFixed) {
|
|
195
|
+
var _this = this;
|
|
196
|
+
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
197
|
+
if (!this.context)
|
|
198
|
+
return;
|
|
199
|
+
this.renderFixedRowBorders(rowCount, function () { return _this.context.headerHeight; }, onlyFixed, "normal");
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* 渲染固定底部行边�?
|
|
203
|
+
*/
|
|
204
|
+
BorderRenderer.prototype.renderFixedBottomBorders = function (rowCount, onlyFixed) {
|
|
205
|
+
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
206
|
+
if (!this.context)
|
|
207
|
+
return;
|
|
208
|
+
var _a = this.context, displayHeight = _a.displayHeight, needHorizontalScrollbar = _a.needHorizontalScrollbar, summaryFixed = _a.summaryFixed, hasSummaryRow = _a.hasSummaryRow, rowHeight = _a.rowHeight;
|
|
209
|
+
this.renderFixedRowBorders(rowCount, function () {
|
|
210
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
211
|
+
return (displayHeight -
|
|
212
|
+
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
213
|
+
fixedSummaryHeight -
|
|
214
|
+
rowCount * rowHeight);
|
|
215
|
+
}, onlyFixed, "normal");
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* 渲染固定合计行边�?
|
|
219
|
+
*/
|
|
220
|
+
BorderRenderer.prototype.renderFixedSummaryBorder = function (fixedY, onlyFixed) {
|
|
221
|
+
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
222
|
+
if (!this.context)
|
|
223
|
+
return;
|
|
224
|
+
this.renderFixedRowBorders(1, function () { return fixedY; }, onlyFixed, "summary");
|
|
225
|
+
};
|
|
226
|
+
return BorderRenderer;
|
|
227
|
+
}());
|
|
228
|
+
|
|
229
|
+
export { BorderRenderer };
|