zmdms-webui 2.6.1 → 2.6.3
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 +63 -21
- 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/modal/interface.d.ts +0 -4
- package/dist/es/modal/modal.js +13 -13
- package/dist/es/modal/useResizable.js +1 -1
- package/dist/es/table/excel.js +1 -1
- package/package.json +1 -1
|
@@ -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,7 @@ import { getTableColumns } from '../table/utils.js';
|
|
|
39
40
|
import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
|
|
40
41
|
|
|
41
42
|
function CanvasTable(props) {
|
|
42
|
-
var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle, mode = props.mode, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _m = props.isIndexMerge, isIndexMerge = _m === void 0 ? true : _m, _o = props.isSelectionMerge, isSelectionMerge = _o === void 0 ? false : _o, _p = props.renderMode, renderMode = _p === void 0 ? "object" : _p, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _q = props.summaryFixed, summaryFixed = _q === void 0 ? false : _q, _r = props.isAutoScrollY, isAutoScrollY = _r === void 0 ? false : _r, _s = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _s === void 0 ? 65 : _s, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _t = props.headerAlign, headerAlign = _t === void 0 ? "center" : _t, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig, _u = props.maxHeight, maxHeight = _u === void 0 ? 3000 : _u;
|
|
43
|
+
var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle, mode = props.mode, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _m = props.isIndexMerge, isIndexMerge = _m === void 0 ? true : _m, _o = props.isSelectionMerge, isSelectionMerge = _o === void 0 ? false : _o, _p = props.renderMode, renderMode = _p === void 0 ? "object" : _p, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _q = props.summaryFixed, summaryFixed = _q === void 0 ? false : _q, _r = props.isAutoScrollY, isAutoScrollY = _r === void 0 ? false : _r, _s = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _s === void 0 ? 65 : _s, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _t = props.headerAlign, headerAlign = _t === void 0 ? "center" : _t, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig, _u = props.maxHeight, maxHeight = _u === void 0 ? 3000 : _u, expandable = props.expandable;
|
|
43
44
|
var actualMode = "mode" in props ? mode : "index";
|
|
44
45
|
var canvasRef = useRef(null);
|
|
45
46
|
var containerRef = useRef(null);
|
|
@@ -94,26 +95,39 @@ function CanvasTable(props) {
|
|
|
94
95
|
onFilterChange: onFilterChange,
|
|
95
96
|
isAutoMerge: isAutoMerge,
|
|
96
97
|
}), state = _y.state, setState = _y.setState, processedDataSource = _y.processedDataSource, handleFilterChange = _y.handleFilterChange, closeFilterPopover = _y.closeFilterPopover, autoGeneratedFilters = _y.autoGeneratedFilters;
|
|
98
|
+
// 树形展开管理
|
|
99
|
+
var _z = useExpandable({
|
|
100
|
+
dataSource: dataSource,
|
|
101
|
+
expandable: expandable,
|
|
102
|
+
rowKey: rowKey,
|
|
103
|
+
}), expandedKeys = _z.expandedKeys, flattenedData = _z.flattenedData, toggleExpand = _z.toggleExpand, expandRow = _z.expandRow, collapseRow = _z.collapseRow, setExpandedRowKeys = _z.setExpandedRowKeys, hasExpandable = _z.hasExpandable;
|
|
97
104
|
var order = useMemo(function () {
|
|
98
105
|
return state.sortOrder && state.sortField
|
|
99
106
|
? { field: state.sortField, order: state.sortOrder }
|
|
100
107
|
: undefined;
|
|
101
108
|
}, [state.sortOrder, state.sortField]);
|
|
102
|
-
var
|
|
109
|
+
var _0 = useAutoMerge(processedDataSource, processedColumnsOld, {
|
|
103
110
|
isAutoMerge: isAutoMerge,
|
|
104
111
|
isDimensionDynamic: isDimensionDynamic,
|
|
105
112
|
order: order,
|
|
106
113
|
dimensionCustomSumKeys: dimensionCustomSumKeys,
|
|
107
|
-
}), newDataSource =
|
|
114
|
+
}), newDataSource = _0[0], processedColumns = _0[1];
|
|
115
|
+
// 如果开启了树形展开,使用扁平化后的数据源
|
|
116
|
+
var expandedDataSource = useMemo(function () {
|
|
117
|
+
if (hasExpandable) {
|
|
118
|
+
return flattenedData.map(function (item) { return item.record; });
|
|
119
|
+
}
|
|
120
|
+
return newDataSource;
|
|
121
|
+
}, [hasExpandable, flattenedData, newDataSource]);
|
|
108
122
|
// 生成合计行和最终数据源
|
|
109
|
-
var
|
|
123
|
+
var _1 = useSummaryRow({
|
|
110
124
|
columns: processedColumns,
|
|
111
|
-
dataSource:
|
|
112
|
-
}), finalDataSource =
|
|
125
|
+
dataSource: expandedDataSource,
|
|
126
|
+
}), finalDataSource = _1.finalDataSource, hasSummaryRow = _1.hasSummaryRow;
|
|
113
127
|
// 用于存储计算后的表头高度(用于自动高度的精确计算)
|
|
114
|
-
var
|
|
128
|
+
var _2 = useState(undefined), preciseHeaderHeight = _2[0], setPreciseHeaderHeight = _2[1];
|
|
115
129
|
// 用于存储是否需要横向滚动条(用于自动高度的精确计算)
|
|
116
|
-
var
|
|
130
|
+
var _3 = useState(false), needHorizontalScrollbar = _3[0], setNeedHorizontalScrollbar = _3[1];
|
|
117
131
|
// 自动高度计算(需要在容器尺寸计算之前)
|
|
118
132
|
var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId, finalDataSource.length, // 数据行数(用于 content 模式)
|
|
119
133
|
headerHeight, // 表头基础高度(用于 content 模式的初始计算)
|
|
@@ -180,7 +194,7 @@ function CanvasTable(props) {
|
|
|
180
194
|
return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
|
|
181
195
|
}, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
|
|
182
196
|
// 计算滚动条指标
|
|
183
|
-
var
|
|
197
|
+
var _4 = useScrollbarMetrics({
|
|
184
198
|
containerWidth: containerWidth,
|
|
185
199
|
containerHeight: containerHeight,
|
|
186
200
|
totalWidth: totalWidth,
|
|
@@ -188,14 +202,14 @@ function CanvasTable(props) {
|
|
|
188
202
|
headerHeight: calculatedHeaderHeight,
|
|
189
203
|
scrollTop: 0,
|
|
190
204
|
scrollLeft: 0,
|
|
191
|
-
}), maxScrollTop =
|
|
205
|
+
}), maxScrollTop = _4.maxScrollTop, maxScrollLeft = _4.maxScrollLeft;
|
|
192
206
|
// 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
|
|
193
|
-
var
|
|
207
|
+
var _5 = useTableScroll({
|
|
194
208
|
containerRef: containerRef,
|
|
195
209
|
maxScrollTop: maxScrollTop,
|
|
196
210
|
maxScrollLeft: maxScrollLeft,
|
|
197
211
|
onScroll: onScroll,
|
|
198
|
-
}), scrollState =
|
|
212
|
+
}), scrollState = _5.scrollState, setScrollState = _5.setScrollState;
|
|
199
213
|
// 使用 ref 保存最新的滚动位置,确保在组件卸载过程中仍能访问
|
|
200
214
|
var scrollPositionRef = useRef({ x: 0, y: 0 });
|
|
201
215
|
useEffect(function () {
|
|
@@ -235,12 +249,12 @@ function CanvasTable(props) {
|
|
|
235
249
|
needHorizontalScrollbar,
|
|
236
250
|
]);
|
|
237
251
|
// 单元格框选
|
|
238
|
-
var
|
|
252
|
+
var _6 = useTableSelection({
|
|
239
253
|
state: state,
|
|
240
254
|
setState: setState,
|
|
241
255
|
}),
|
|
242
256
|
// selectionStartRef,
|
|
243
|
-
startSelection =
|
|
257
|
+
startSelection = _6.startSelection, updateSelection = _6.updateSelection, extendSelection = _6.extendSelection;
|
|
244
258
|
// 处理列宽调整
|
|
245
259
|
var handleColumnResize = useCallback(function (columnKey, newWidth) {
|
|
246
260
|
var _a;
|
|
@@ -295,20 +309,20 @@ function CanvasTable(props) {
|
|
|
295
309
|
onCurrentListChange,
|
|
296
310
|
]);
|
|
297
311
|
// 列宽调整
|
|
298
|
-
var
|
|
312
|
+
var _7 = useColumnResize({
|
|
299
313
|
columnRenderInfos: columnRenderInfos,
|
|
300
314
|
containerWidth: containerWidth,
|
|
301
315
|
headerHeight: calculatedHeaderHeight,
|
|
302
316
|
scrollLeft: scrollState.scrollLeft,
|
|
303
317
|
onColumnResize: handleColumnResize,
|
|
304
|
-
}), resizeState =
|
|
318
|
+
}), resizeState = _7.resizeState, checkResizeHandle = _7.checkResizeHandle, startResize = _7.startResize, updateResize = _7.updateResize, endResize = _7.endResize, setHoverResizeColumn = _7.setHoverResizeColumn, getColumnWidth = _7.getColumnWidth, RESIZE_HANDLE_WIDTH = _7.RESIZE_HANDLE_WIDTH;
|
|
305
319
|
// 复制到剪贴板
|
|
306
|
-
var
|
|
320
|
+
var _8 = useCopyToClipboard({
|
|
307
321
|
cellSelection: state.cellSelection,
|
|
308
322
|
processedDataSource: finalDataSource,
|
|
309
323
|
columns: processedColumns,
|
|
310
324
|
containerRef: containerRef,
|
|
311
|
-
}), getSelectedCellsText =
|
|
325
|
+
}), getSelectedCellsText = _8.getSelectedCellsText, copyToClipboard = _8.copyToClipboard;
|
|
312
326
|
// 处理右键菜单的复制操作
|
|
313
327
|
var handleCopy = useCallback(function () {
|
|
314
328
|
var text = getSelectedCellsText();
|
|
@@ -327,7 +341,7 @@ function CanvasTable(props) {
|
|
|
327
341
|
summaryConfig: (exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.isExportNoSummary) ? undefined : [],
|
|
328
342
|
});
|
|
329
343
|
// 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
|
|
330
|
-
var
|
|
344
|
+
var _9 = useTableInteraction({
|
|
331
345
|
state: state,
|
|
332
346
|
setState: setState,
|
|
333
347
|
scrollState: scrollState,
|
|
@@ -335,6 +349,8 @@ function CanvasTable(props) {
|
|
|
335
349
|
processedDataSource: finalDataSource,
|
|
336
350
|
columnRenderInfos: columnRenderInfos,
|
|
337
351
|
columns: processedColumns,
|
|
352
|
+
expandable: expandable,
|
|
353
|
+
flattenedData: flattenedData,
|
|
338
354
|
rowSelection: rowSelection,
|
|
339
355
|
rowHeight: rowHeight,
|
|
340
356
|
headerHeight: calculatedHeaderHeight,
|
|
@@ -359,6 +375,7 @@ function CanvasTable(props) {
|
|
|
359
375
|
onSortChange: onSortChange,
|
|
360
376
|
onRowClick: onRowClick,
|
|
361
377
|
getRowKey: getRowKey,
|
|
378
|
+
onExpand: toggleExpand,
|
|
362
379
|
startSelection: startSelection,
|
|
363
380
|
updateSelection: updateSelection,
|
|
364
381
|
extendSelection: extendSelection,
|
|
@@ -374,11 +391,11 @@ function CanvasTable(props) {
|
|
|
374
391
|
fixedRowsCount: fixedRowsCount,
|
|
375
392
|
fixedRowsConfig: fixedRowsConfig,
|
|
376
393
|
summaryFixed: summaryFixed,
|
|
377
|
-
}), handleCanvasMouseDown =
|
|
394
|
+
}), handleCanvasMouseDown = _9.handleCanvasMouseDown, handleCanvasMouseMove = _9.handleCanvasMouseMove, handleCanvasMouseUp = _9.handleCanvasMouseUp, handleCanvasMouseLeave = _9.handleCanvasMouseLeave, handleCanvasContextMenu = _9.handleCanvasContextMenu;
|
|
378
395
|
// 渲染表格
|
|
379
396
|
useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
|
|
380
397
|
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 }));
|
|
398
|
+
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
399
|
// 单元格覆盖层
|
|
383
400
|
var cellOverlays = useTableCellOverlay({
|
|
384
401
|
canvasRef: canvasRef,
|
|
@@ -469,6 +486,26 @@ function CanvasTable(props) {
|
|
|
469
486
|
setSelectedRowKeys: function (keys) {
|
|
470
487
|
setState(function (prev) { return (__assign(__assign({}, prev), { selectedRowKeys: keys })); });
|
|
471
488
|
},
|
|
489
|
+
/** 获取展开的keys */
|
|
490
|
+
getExpandedRowKeys: function () {
|
|
491
|
+
return Array.from(expandedKeys);
|
|
492
|
+
},
|
|
493
|
+
/** 设置展开的keys */
|
|
494
|
+
setExpandedRowKeys: function (keys) {
|
|
495
|
+
setExpandedRowKeys(keys);
|
|
496
|
+
},
|
|
497
|
+
/** 展开指定行 */
|
|
498
|
+
expandRow: function (key) {
|
|
499
|
+
expandRow(key);
|
|
500
|
+
},
|
|
501
|
+
/** 收起指定行 */
|
|
502
|
+
collapseRow: function (key) {
|
|
503
|
+
collapseRow(key);
|
|
504
|
+
},
|
|
505
|
+
/** 切换指定行展开状态 */
|
|
506
|
+
toggleExpandRow: function (key) {
|
|
507
|
+
toggleExpand(key);
|
|
508
|
+
},
|
|
472
509
|
/** 滚动到指定位置 */
|
|
473
510
|
scrollTo: function (params) {
|
|
474
511
|
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 +547,11 @@ function CanvasTable(props) {
|
|
|
510
547
|
state.filters,
|
|
511
548
|
setState,
|
|
512
549
|
setScrollState,
|
|
550
|
+
expandedKeys,
|
|
551
|
+
setExpandedRowKeys,
|
|
552
|
+
expandRow,
|
|
553
|
+
collapseRow,
|
|
554
|
+
toggleExpand,
|
|
513
555
|
]);
|
|
514
556
|
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
557
|
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 };
|