UNPKG

@visactor/vtable

Version:

canvas table width high performance

345 lines (331 loc) 24.2 kB
"use strict"; var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) { void 0 === k2 && (k2 = k); var desc = Object.getOwnPropertyDescriptor(m, k); desc && !("get" in desc ? !m.__esModule : desc.writable || desc.configurable) || (desc = { enumerable: !0, get: function() { return m[k]; } }), Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { void 0 === k2 && (k2 = k), o[k2] = m[k]; }), __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: !0, value: v }); } : function(o, v) { o.default = v; }), __importStar = this && this.__importStar || function(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (null != mod) for (var k in mod) "default" !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k); return __setModuleDefault(result, mod), result; }; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.getAdaptiveWidth = exports.computeColWidth = exports.computeColsWidth = void 0; const ts_types_1 = require("../../ts-types"), calc = __importStar(require("../../tools/calc")), padding_1 = require("../utils/padding"), get_prop_1 = require("../utils/get-prop"), factory_1 = require("../../core/factory"), vutils_1 = require("@visactor/vutils"), custom_1 = require("../component/custom"), break_string_1 = require("../utils/break-string"), react_custom_layout_1 = require("../../components/react/react-custom-layout"), helper_1 = require("../../tools/helper"); function computeColsWidth(table, colStart, colEnd, update) { var _a, _b, _c, _d, _e, _f, _g, _h; table.internalProps.columnWidthConfig && table._parseColumnWidthConfig(table.internalProps.columnWidthConfig), table.isPivotTable() && table.internalProps.columnWidthConfigForRowHeader && table._parseColumnWidthConfigForRowHeader(table.internalProps.columnWidthConfigForRowHeader), colStart = null != colStart ? colStart : 0, colEnd = null != colEnd ? colEnd : table.colCount - 1, 0 === colStart && colEnd === table.colCount - 1 && table._clearColRangeWidthsMap(); const layoutMap = table.internalProps.layoutMap; table.isPivotTable() && (layoutMap.enableUseGetBodyCache(), layoutMap.enableUseHeaderPathCache()); const oldColWidths = [], newWidths = []; if (update) for (let col = 0; col < table.colCount; col++) oldColWidths[col] = table.getColWidth(col); for (let col = colStart; col <= colEnd; col++) { let maxWidth; if (table.internalProps.transpose || "only-header" !== (null === (_b = null === (_a = table.internalProps.layoutMap.columnObjects) || void 0 === _a ? void 0 : _a[col]) || void 0 === _b ? void 0 : _b.columnWidthComputeMode) && "only-header" !== table.columnWidthComputeMode || !("showHeader" in table.internalProps.layoutMap)) maxWidth = table.internalProps.transpose || "only-body" !== (null === (_d = null === (_c = table.internalProps.layoutMap.columnObjects) || void 0 === _c ? void 0 : _c[col]) || void 0 === _d ? void 0 : _d.columnWidthComputeMode) && "only-body" !== table.columnWidthComputeMode ? computeColWidth(col, 0, table.rowCount - 1, table) : computeColWidth(col, table.internalProps.layoutMap.getBodyRange().start.row, table.internalProps.layoutMap.getBodyRange().end.row, table); else { const temp = table.internalProps.layoutMap.showHeader; table.internalProps.layoutMap.showHeader = !0, maxWidth = computeColWidth(col, 0, table.internalProps.layoutMap.headerLevelCount - 1, table), table.internalProps.layoutMap.showHeader = temp; } table._setColContentWidth(col, maxWidth); table.getColWidth(col) !== maxWidth && table._clearColRangeWidthsMap(col), update ? newWidths[col] = Math.round(table._adjustColWidth(col, maxWidth)) : table._setColWidth(col, table._adjustColWidth(col, maxWidth), !1, !0); } if ("adaptive" === table.widthMode) { table._clearColRangeWidthsMap(); const canvasWidth = table.tableNoFrameWidth; let actualHeaderWidth = 0, startCol = 0, endCol = table.colCount; if ("only-body" === table.widthAdaptiveMode) { for (let col = 0; col < table.colCount; col++) { const colWidth = update && null !== (_e = newWidths[col]) && void 0 !== _e ? _e : table.getColWidth(col); (col < table.rowHeaderLevelCount || table.isPivotChart() && col >= table.colCount - table.rightFrozenColCount) && (actualHeaderWidth += colWidth); } startCol = table.rowHeaderLevelCount, endCol = table.isPivotChart() ? table.colCount - table.rightFrozenColCount : table.colCount; } getAdaptiveWidth(canvasWidth - actualHeaderWidth, startCol, endCol, update, newWidths, table); } else if (table.autoFillWidth) { table._clearColRangeWidthsMap(); const canvasWidth = table.tableNoFrameWidth; let actualHeaderWidth = 0, actualWidth = 0; for (let col = 0; col < table.colCount; col++) { const colWidth = update && null !== (_f = newWidths[col]) && void 0 !== _f ? _f : table.getColWidth(col); (col < table.rowHeaderLevelCount + table.leftRowSeriesNumberCount || table.isPivotChart() && col >= table.colCount - table.rightFrozenColCount) && (actualHeaderWidth += colWidth), actualWidth += colWidth; } if (actualWidth < canvasWidth && actualWidth > actualHeaderWidth) { getAdaptiveWidth(canvasWidth - actualHeaderWidth, table.rowHeaderLevelCount + table.leftRowSeriesNumberCount, table.isPivotChart() ? table.colCount - table.rightFrozenColCount : table.colCount, update, newWidths, table); } } if (update) { for (let col = 0; col < table.colCount; col++) { const newColWidth = null !== (_h = null !== (_g = newWidths[col]) && void 0 !== _g ? _g : table.getColWidth(col)) && void 0 !== _h ? _h : table.getColWidth(col); newColWidth !== oldColWidths[col] && table._setColWidth(col, newColWidth, !1, !0); } table.stateManager.checkFrozen(); for (let col = 0; col < table.colCount; col++) { const newColWidth = table.getColWidth(col); newColWidth !== oldColWidths[col] && table.scenegraph.updateColWidth(col, newColWidth - oldColWidths[col], !0, !0); } table.scenegraph.updateContainer(!0); } table.isPivotTable() && (layoutMap.disableUseGetBodyCache(), layoutMap.disableUseHeaderPathCache()); } function computeColWidth(col, startRow, endRow, table, forceCompute = !1) { let width = getColWidthDefinedWidthResizedWidth(col, table); return table.internalProps.transpose && "auto" === width && ("only-header" === table.columnWidthComputeMode && col >= table.rowHeaderLevelCount || "only-body" === table.columnWidthComputeMode && col < table.rowHeaderLevelCount) && (width = table.getDefaultColumnWidth(col)), forceCompute && !table.internalProps.transpose ? computeAutoColWidth(width, col, startRow, endRow, forceCompute, table) : "number" == typeof width ? width : "auto" !== width && "string" == typeof width ? table._adjustColWidth(col, table._colWidthDefineToPxWidth(width)) : computeAutoColWidth(width, col, startRow, endRow, forceCompute, table); } function computeAutoColWidth(widthDeifne, col, startRow, endRow, forceCompute, table) { var _a, _b, _c, _d, _e; let maxWidth = 0, deltaRow = 1, prepareDeltaRow = 1; if (endRow - startRow > 5e3 && (prepareDeltaRow = Math.ceil((endRow - startRow) / 5e3)), table.isPivotChart() && col >= table.rowHeaderLevelCount && col < table.colCount - table.rightFrozenColCount) { if (table.internalProps.layoutMap.indicatorsAsCol) return table.defaultColWidth; { const optimunWidth = table.internalProps.layoutMap.getOptimunWidthForChart(col); if (optimunWidth > 0) return optimunWidth; } } for (let row = startRow; row <= endRow; row += deltaRow) { if (table.isPivotChart()) { const layout = table.internalProps.layoutMap, axisConfig = layout.getAxisConfigInPivotChart(col, row); if (axisConfig) { const axisWidth = factory_1.Factory.getFunction("computeAxisComponentWidth")(axisConfig, table); if ("number" == typeof axisWidth) { maxWidth = Math.max(axisWidth, maxWidth); continue; } } else if (layout.isLeftBottomCorner(col, row) || layout.isRightTopCorner(col, row) || layout.isRightBottomCorner(col, row)) continue; } const customWidth = computeCustomRenderWidth(col, row, table); if (customWidth && (maxWidth = Math.max(customWidth.width, maxWidth), !customWidth.renderDefault)) continue; const indicatorWidth = widthDeifne; if ("number" == typeof indicatorWidth && "standard" === table.widthMode && !forceCompute) { maxWidth = Math.max(indicatorWidth, maxWidth); continue; } const cellType = table.isHeader(col, row) ? null === (_a = table._getHeaderLayoutMap(col, row)) || void 0 === _a ? void 0 : _a.headerType : table.getBodyColumnType(col, row); if ((0, vutils_1.isValid)(cellType) && "text" !== cellType && "link" !== cellType && "progressbar" !== cellType && "checkbox" !== cellType && "radio" !== cellType && "switch" !== cellType && "button" !== cellType) { maxWidth = Math.max(maxWidth, table.getColWidthDefinedNumber(col) || 0); continue; } let cellHierarchyIndent = 0; const layoutMap = table.internalProps.layoutMap; if (layoutMap.isHeader(col, row)) { const hd = layoutMap.getHeader(col, row); if ("only-body" === (null === (_b = null == hd ? void 0 : hd.define) || void 0 === _b ? void 0 : _b.columnWidthComputeMode)) continue; (0, vutils_1.isValid)(null == hd ? void 0 : hd.hierarchyLevel) && (cellHierarchyIndent = (null !== (_c = hd.hierarchyLevel) && void 0 !== _c ? _c : 0) * ("tree" === layoutMap.rowHierarchyType && null !== (_d = layoutMap.rowHierarchyIndent) && void 0 !== _d ? _d : 0), layoutMap.rowHierarchyTextStartAlignment && !table.internalProps.headerHelper.getHierarchyIcon(col, row) && (cellHierarchyIndent += table.internalProps.headerHelper.getHierarchyIconWidth())); } else if (table.isListTable()) { deltaRow = prepareDeltaRow; const define = table.getBodyColumnDefine(col, row); if (null == define ? void 0 : define.tree) { const indexArr = table.dataSource.getIndexKey(table.getRecordShowIndexByCell(col, row)); cellHierarchyIndent = Array.isArray(indexArr) && table.getHierarchyState(col, row) !== ts_types_1.HierarchyState.none ? (indexArr.length - 1) * (null !== (_e = layoutMap.hierarchyIndent) && void 0 !== _e ? _e : 0) : 0, layoutMap.hierarchyTextStartAlignment && !table.internalProps.bodyHelper.getHierarchyIcon(col, row) && (cellHierarchyIndent += table.internalProps.headerHelper.getHierarchyIconWidth()); } } const textWidth = computeTextWidth(col, row, cellType, table); maxWidth = Math.max(textWidth + cellHierarchyIndent, maxWidth), deltaRow > 1 && table.bottomFrozenRowCount > 0 && row < table.rowCount - table.bottomFrozenRowCount && row + deltaRow >= table.rowCount - table.bottomFrozenRowCount && (row = table.rowCount - table.bottomFrozenRowCount - deltaRow, deltaRow = 1, prepareDeltaRow = 1); } const colMinWidth = table.getMinColWidth(col), colMaxWidth = table.getMaxColWidth(col); return maxWidth < colMinWidth ? colMinWidth : maxWidth > colMaxWidth ? colMaxWidth : (maxWidth <= 0 && (maxWidth = table.defaultColWidth), maxWidth); } function computeCustomRenderWidth(col, row, table) { var _a, _b, _c, _d, _e, _f, _g; const customRender = table.getCustomRender(col, row); let customLayout = table.getCustomLayout(col, row); if (customRender || customLayout) { let cellRange, spanCol = 1, width = 0, renderDefault = !1, enableCellPadding = !1; (table.isHeader(col, row) || (null === (_a = table.getBodyColumnDefine(col, row)) || void 0 === _a ? void 0 : _a.mergeCell) || table.hasCustomMerge()) && (cellRange = table.getCellRange(col, row), spanCol = cellRange.end.col - cellRange.start.col + 1); const arg = { col: null !== (_b = null == cellRange ? void 0 : cellRange.start.col) && void 0 !== _b ? _b : col, row: null !== (_c = null == cellRange ? void 0 : cellRange.start.row) && void 0 !== _c ? _c : row, dataValue: table.getCellOriginValue(col, row), value: table.getCellValue(col, row) || "", rect: getCellRect(col, row, table), table: table, originCol: col, originRow: row, forComputation: !0 }; if ("react-custom-layout" === customLayout && (customLayout = (null === (_d = table.reactCustomLayout) || void 0 === _d ? void 0 : _d.getCustomLayoutFunc(col, row)) || react_custom_layout_1.emptyCustomLayout), (0, vutils_1.isFunction)(customLayout)) { const customLayoutObj = customLayout(arg); if (customLayoutObj.rootContainer) { customLayoutObj.rootContainer = (0, custom_1.decodeReactDom)(customLayoutObj.rootContainer), (0, custom_1.dealPercentCalc)(customLayoutObj.rootContainer, 0, table.getRowHeight(row)); const setedWidth = customLayoutObj.rootContainer.attribute.width; customLayoutObj.rootContainer.setStage(table.scenegraph.stage), width = setedWidth > 0 ? setedWidth : null !== (_e = customLayoutObj.rootContainer.AABBBounds.width()) && void 0 !== _e ? _e : 0, renderDefault = customLayoutObj.renderDefault, enableCellPadding = customLayoutObj.enableCellPadding; } else width = 0, renderDefault = customLayoutObj.renderDefault, enableCellPadding = customLayoutObj.enableCellPadding; } else if ("function" == typeof customRender) { const customRenderObj = customRender(arg); width = null !== (_f = null == customRenderObj ? void 0 : customRenderObj.expectedWidth) && void 0 !== _f ? _f : 0, renderDefault = null == customRenderObj ? void 0 : customRenderObj.renderDefault; } else width = null !== (_g = null == customRender ? void 0 : customRender.expectedWidth) && void 0 !== _g ? _g : 0, renderDefault = null == customRender ? void 0 : customRender.renderDefault; if (width = Math.ceil(width), enableCellPadding) { const actStyle = table._getCellStyle(col, row), padding = (0, padding_1.getQuadProps)((0, get_prop_1.getProp)("padding", actStyle, col, row, table)); width += padding[1] + padding[3]; } return { width: width / spanCol, renderDefault: renderDefault }; } } function computeIndicatorWidth(col, row, forceCompute, table) { const {layoutMap: layoutMap} = table.internalProps; if (table.isPivotTable() && layoutMap.isColumnIndicatorHeader(col, row)) { const body = layoutMap.getBody(col, row); if (body && body.width && "auto" !== body.width && !forceCompute) { return Math.round(calc.toPx(body.width, table.internalProps.calcWidthContext)); } } } function computeTextWidth(col, row, cellType, table) { var _a, _b, _c, _d; let maxWidth = 0; const cellValue = table.getCellValue(col, row), actStyle = table._getCellStyle(col, row); let iconWidth = 0, mayHaveIcon = !1; if ("body" !== table.getCellLocation(col, row)) mayHaveIcon = !0; else { const define = table.getBodyColumnDefine(col, row); mayHaveIcon = !!(null == define ? void 0 : define.icon) || !!(null == define ? void 0 : define.tree) || (null == define ? void 0 : define.dragOrder); } if (mayHaveIcon) { const icons = table.getCellIcons(col, row); null == icons || icons.forEach((icon => { var _a, _b, _c; icon.positionType !== ts_types_1.IconPosition.absoluteRight && (iconWidth += (null !== (_a = icon.width) && void 0 !== _a ? _a : 0) + (null !== (_b = icon.marginLeft) && void 0 !== _b ? _b : 0) + (null !== (_c = icon.marginRight) && void 0 !== _c ? _c : 0)); })); } let spanCol = 1; if (table.isHeader(col, row) || (null === (_a = table.getBodyColumnDefine(col, row)) || void 0 === _a ? void 0 : _a.mergeCell) || table.hasCustomMerge()) { const cellRange = table.getCellRange(col, row); spanCol = cellRange.end.col - cellRange.start.col + 1; } const padding = (0, padding_1.getQuadProps)((0, get_prop_1.getProp)("padding", actStyle, col, row, table)), paddingWidth = padding[1] + padding[3], fontSize = (0, get_prop_1.getProp)("fontSize", actStyle, col, row, table), fontFamily = (0, get_prop_1.getProp)("fontFamily", actStyle, col, row, table), fontWeight = (0, get_prop_1.getProp)("fontWeight", actStyle, col, row, table); let text; if ("checkbox" === cellType) text = (0, vutils_1.isObject)(cellValue) ? cellValue.text : cellValue; else if ("radio" === cellType) if ((0, vutils_1.isArray)(cellValue)) { text = ""; const define = table.getBodyColumnDefine(col, row), radioDirectionInCell = null !== (_b = null == define ? void 0 : define.radioDirectionInCell) && void 0 !== _b ? _b : "vertical"; "vertical" === radioDirectionInCell ? cellValue.forEach((line => { text += ((0, vutils_1.isObject)(line) ? line.text : line).toString() + "\n"; })) : "horizontal" === radioDirectionInCell && cellValue.forEach((line => { text += ((0, vutils_1.isObject)(line) ? line.text : line).toString(); })); } else text = (0, vutils_1.isObject)(cellValue) ? cellValue.text : cellValue; else if ("button" === cellType) { const define = table.getBodyColumnDefine(col, row), buttonTextValue = (0, helper_1.getOrApply)(define.text, { col: col, row: row, table: table, context: null, value: cellValue, dataValue: table.getCellOriginValue(col, row) }); text = null !== (_c = null != buttonTextValue ? buttonTextValue : cellValue) && void 0 !== _c ? _c : ""; } else text = cellValue; const lines = (0, break_string_1.breakString)(text, table).text; if (lines.length >= 1 && (1 !== lines.length || "" !== lines[0]) ? lines.forEach((line => { const width = table.measureText(line, { fontSize: fontSize, fontFamily: fontFamily, fontWeight: fontWeight }).width; maxWidth = Math.max((width + paddingWidth + 4 + iconWidth) / spanCol, maxWidth); })) : maxWidth = Math.max((paddingWidth + 4 + iconWidth) / spanCol, maxWidth), !1 !== table.internalProps.limitMaxAutoWidth && (maxWidth = Math.min("number" == typeof table.internalProps.limitMaxAutoWidth ? table.internalProps.limitMaxAutoWidth : 450, maxWidth)), "checkbox" === cellType) { const size = (0, get_prop_1.getProp)("size", actStyle, col, row, table); if (maxWidth += size, text) { const spaceBetweenTextAndIcon = (0, get_prop_1.getProp)("spaceBetweenTextAndIcon", actStyle, col, row, table); maxWidth += spaceBetweenTextAndIcon; } } else if ("radio" === cellType) { const size = (0, get_prop_1.getProp)("size", actStyle, col, row, table), outerRadius = (0, get_prop_1.getProp)("outerRadius", actStyle, col, row, table), circleSize = (0, vutils_1.isNumber)(outerRadius) ? 2 * outerRadius : size, spaceBetweenTextAndIcon = (0, get_prop_1.getProp)("spaceBetweenTextAndIcon", actStyle, col, row, table); if ((0, vutils_1.isArray)(cellValue)) { const define = table.getBodyColumnDefine(col, row), spaceBetweenRadio = (0, get_prop_1.getProp)("spaceBetweenRadio", actStyle, col, row, table), radioDirectionInCell = null !== (_d = null == define ? void 0 : define.radioDirectionInCell) && void 0 !== _d ? _d : "vertical"; "vertical" === radioDirectionInCell ? (maxWidth += circleSize, maxWidth += spaceBetweenTextAndIcon) : "horizontal" === radioDirectionInCell && (maxWidth += (circleSize + spaceBetweenTextAndIcon) * cellValue.length, maxWidth += spaceBetweenRadio * (cellValue.length - 1)); } else maxWidth += circleSize, text && (maxWidth += spaceBetweenTextAndIcon); } else if ("switch" === cellType) { const boxWidth = (0, get_prop_1.getProp)("boxWidth", actStyle, col, row, table); maxWidth = boxWidth; } else if ("button" === cellType) { const buttonPadding = (0, get_prop_1.getProp)("buttonPadding", actStyle, col, row, table); maxWidth += 2 * buttonPadding; } return maxWidth; } function getCellRect(col, row, table) { return { left: 0, top: 0, right: table.getColWidth(col), bottom: table.getRowHeight(row), width: null, height: null }; } function getColWidthDefinedWidthResizedWidth(col, table) { const widthDefined = table.getColWidthDefined(col); return table.internalProps._widthResizedColMap.has(col) ? table.getColWidth(col) : widthDefined; } function getAdaptiveWidth(totalDrawWidth, startCol, endColPlus1, update, newWidths, table, fromScenegraph) { var _a, _b, _c, _d; let actualWidth = 0; const adaptiveColumns = [], sparklineColumns = []; let totalSparklineAbleWidth = 0; for (let col = startCol; col < endColPlus1; col++) { const width = update && null !== (_a = newWidths[col]) && void 0 !== _a ? _a : table.getColWidth(col), maxWidth = table.getMaxColWidth(col), minWidth = table.getMinColWidth(col); if (width !== maxWidth && width !== minWidth ? (actualWidth += width, adaptiveColumns.push(col)) : totalDrawWidth -= width, null === (_b = table.options.customConfig) || void 0 === _b ? void 0 : _b.shrinkSparklineFirst) { "sparkline" === table.getBodyColumnType(col, 0) && (sparklineColumns.push({ col: col, width: width }), totalSparklineAbleWidth += width - table.defaultColWidth); } } const factor = totalDrawWidth / actualWidth; if ((null === (_c = table.options.customConfig) || void 0 === _c ? void 0 : _c.shrinkSparklineFirst) && factor < 1 && actualWidth - totalDrawWidth < totalSparklineAbleWidth) for (let i = 0; i < sparklineColumns.length; i++) { const {col: col, width: width} = sparklineColumns[i], deltaWidth = (actualWidth - totalDrawWidth) / sparklineColumns.length, colWidth = Math.floor(width - deltaWidth); update ? newWidths[col] = table._adjustColWidth(col, colWidth) : fromScenegraph ? table.scenegraph.setColWidth(col, table._adjustColWidth(col, colWidth)) : table._setColWidth(col, table._adjustColWidth(col, colWidth), !1, !0); } else for (let i = 0; i < adaptiveColumns.length; i++) { const col = adaptiveColumns[i]; let colWidth; colWidth = i === adaptiveColumns.length - 1 ? totalDrawWidth - adaptiveColumns.reduce(((acr, cur, index) => { var _a; return cur !== col ? acr + (update ? null !== (_a = newWidths[cur]) && void 0 !== _a ? _a : table.getColWidth(col) : table.getColWidth(cur)) : acr; }), 0) : Math.round((update && null !== (_d = newWidths[col]) && void 0 !== _d ? _d : table.getColWidth(col)) * factor), update ? newWidths[col] = table._adjustColWidth(col, colWidth) : fromScenegraph ? table.scenegraph.setColWidth(col, table._adjustColWidth(col, colWidth)) : table._setColWidth(col, table._adjustColWidth(col, colWidth), !1, !0); } } exports.computeColsWidth = computeColsWidth, exports.computeColWidth = computeColWidth, exports.getAdaptiveWidth = getAdaptiveWidth; //# sourceMappingURL=compute-col-width.js.map