diff --git a/packages/s2-core/__tests__/unit/utils/g-mini-charts-spec.ts b/packages/s2-core/__tests__/unit/utils/g-mini-charts-spec.ts index 1175e77ba9..2ef8657d8f 100644 --- a/packages/s2-core/__tests__/unit/utils/g-mini-charts-spec.ts +++ b/packages/s2-core/__tests__/unit/utils/g-mini-charts-spec.ts @@ -16,8 +16,7 @@ import { scale, transformRatioToPercent, } from '@/utils/g-mini-charts'; -import type { IElement } from '@antv/g-lite'; -import { forEach, last, map } from 'lodash'; +import { forEach, map } from 'lodash'; import { data } from 'tests/data/mock-dataset.json'; import { assembleDataCfg, assembleOptions } from 'tests/util'; import { createPivotSheet, getContainer } from 'tests/util/helpers'; @@ -411,7 +410,7 @@ describe('Render Chart Shape Tests', () => { cell, ); - const text = last(cell.getChildren()) as IElement; + const text = cell.children.find((child) => child.style.text); expect(text.attr('text')).toEqual('10.00%'); }); diff --git a/packages/s2-core/package.json b/packages/s2-core/package.json index 29b5f04b86..461591ba63 100644 --- a/packages/s2-core/package.json +++ b/packages/s2-core/package.json @@ -74,9 +74,9 @@ }, "dependencies": { "@antv/event-emitter": "^0.1.3", - "@antv/g": "^6.1.28", - "@antv/g-canvas": "^2.0.48", - "@antv/g-lite": "^2.3.2", + "@antv/g": "^6.3.1", + "@antv/g-canvas": "^2.2.0", + "@antv/g-lite": "^2.7.0", "@antv/vendor": "^1.0.11", "decimal.js": "^10.5.0", "flru": "^1.0.2", @@ -104,7 +104,10 @@ { "path": "./dist/s2.min.js", "import": "{ createComponent }", - "limit": "240 kB" + "ignore": [ + "lodash" + ], + "limit": "230 kB" }, { "path": "./dist/s2.min.css", diff --git a/packages/s2-core/rollup.config.mjs b/packages/s2-core/rollup.config.mjs index a3d1d2046a..e535e897a1 100644 --- a/packages/s2-core/rollup.config.mjs +++ b/packages/s2-core/rollup.config.mjs @@ -79,6 +79,7 @@ if (enableAnalysis) { if (isUmdFormat) { output.globals = { '@antv/s2': 'S2', + lodash: '_', }; output.entryFileNames = '[name].min.js'; plugins.push(terser()); @@ -92,6 +93,7 @@ export default [ }, output, plugins, + external: isUmdFormat ? ['lodash'] : [], }, { input: { @@ -103,6 +105,6 @@ export default [ }, plugins, - external: ['@antv/s2'], + external: isUmdFormat ? ['@antv/s2', 'lodash'] : ['@antv/s2'], }, ]; diff --git a/packages/s2-core/src/cell/base-cell.ts b/packages/s2-core/src/cell/base-cell.ts index bcc609a3c3..66ca86fa2e 100644 --- a/packages/s2-core/src/cell/base-cell.ts +++ b/packages/s2-core/src/cell/base-cell.ts @@ -8,7 +8,7 @@ import type { Text, TextStyleProps, } from '@antv/g'; -import { Group } from '@antv/g'; +import { Group, RectStyleProps } from '@antv/g'; import { each, get, @@ -78,6 +78,7 @@ import { renderText, updateShapeAttr, } from '../utils/g-renders'; +import { batchSetStyle } from '../utils/g-utils'; import { isLinkFieldNode } from '../utils/interaction/link-field'; import { isMobile } from '../utils/is-mobile'; import { @@ -125,6 +126,8 @@ export abstract class BaseCell extends Group { // interactive control shapes, unify read and manipulate operations protected stateShapes = new Map(); + protected borders: Map = new Map(); + /* -------------------------------------------------------------------------- */ /* abstract functions that must be implemented by subtype */ /* -------------------------------------------------------------------------- */ @@ -414,7 +417,13 @@ export abstract class BaseCell extends Group { this.getStyle()?.cell!, ); - renderLine(this, { ...position, ...style }); + const borderStyle = { ...position, ...style }; + + if (this.borders.has(type)) { + batchSetStyle(this.borders.get(type)!, borderStyle); + } else { + this.borders.set(type, renderLine(this, borderStyle)); + } }); } @@ -422,39 +431,56 @@ export abstract class BaseCell extends Group { * 绘制 hover 悬停,刷选的外框 */ protected drawInteractiveBorderShape() { - this.stateShapes.set( + const style = { + ...this.getBBoxByType(CellClipBox.PADDING_BOX), + visibility: 'hidden', + pointerEvents: 'none', + } as RectStyleProps; + + const interactiveBorderShape = this.stateShapes.get( 'interactiveBorderShape', - renderRect(this, { - ...this.getBBoxByType(CellClipBox.PADDING_BOX), - visibility: 'hidden', - pointerEvents: 'none', - }), ); + + if (interactiveBorderShape) { + batchSetStyle(interactiveBorderShape, style); + } else { + this.stateShapes.set('interactiveBorderShape', renderRect(this, style)); + } } /** * 交互使用的背景色 */ protected drawInteractiveBgShape() { - this.stateShapes.set( - 'interactiveBgShape', - renderRect(this, { - ...this.getBBoxByType(), - visibility: 'hidden', - pointerEvents: 'none', - }), - ); + const style = { + ...this.getBBoxByType(), + visibility: 'hidden', + pointerEvents: 'none', + } as RectStyleProps; + + const reuseInteractiveBgShape = this.stateShapes.get('interactiveBgShape'); + + if (reuseInteractiveBgShape) { + batchSetStyle(reuseInteractiveBgShape, style); + } else { + this.stateShapes.set('interactiveBgShape', renderRect(this, style)); + } } protected drawBackgroundShape() { const { backgroundColor, backgroundColorOpacity } = this.getBackgroundColor(); - - this.backgroundShape = renderRect(this, { + const style = { ...this.getBBoxByType(), fill: backgroundColor, fillOpacity: backgroundColorOpacity, - }); + }; + + if (this.backgroundShape) { + batchSetStyle(this.backgroundShape, style); + } else { + this.backgroundShape = renderRect(this, style); + } } public renderTextShape( @@ -464,15 +490,23 @@ export abstract class BaseCell extends Group { const text = getDisplayText(style.text, this.getEmptyPlaceholder()); const shallowRender = options?.shallowRender || this.isShallowRender(); - this.textShape = renderText({ - group: this, - textShape: shallowRender ? undefined : this.textShape, - style: { + if (this.textShape && !shallowRender) { + batchSetStyle(this.textShape, { ...style, // 文本必须为字符串 text: `${text}`, - }, - }); + }); + } else { + this.textShape = renderText({ + group: this, + textShape: shallowRender ? undefined : this.textShape, + style: { + ...style, + // 文本必须为字符串 + text: `${text}`, + }, + }); + } this.addTextShape(this.textShape); @@ -560,8 +594,7 @@ export abstract class BaseCell extends Group { } const { bottom: maxY } = this.textShape.getBBox(); - - this.linkFieldShape = renderLine(this, { + const options = { x1: startX, y1: maxY + 1, // 不用 bbox 的 maxX,因为 g-base 文字宽度预估偏差较大 @@ -569,7 +602,13 @@ export abstract class BaseCell extends Group { y2: maxY + 1, stroke: linkFillColor, lineWidth: 1, - }); + }; + + if (this.linkFieldShape) { + batchSetStyle(this.linkFieldShape, options); + } else { + this.linkFieldShape = renderLine(this, options); + } } this.textShape.style.fill = linkFillColor; @@ -727,13 +766,20 @@ export abstract class BaseCell extends Group { const position = this.getIconPosition(); const { size } = this.getStyle()!.icon!; - this.conditionIconShape = renderIcon(this, { + const iconCfg = { ...position, name: attrs?.name!, width: size, height: size, fill: attrs?.fill, - }); + }; + + if (this.conditionIconShape) { + this.conditionIconShape.reRender(iconCfg); + } else { + this.conditionIconShape = renderIcon(this, iconCfg); + } + this.addConditionIconShape(this.conditionIconShape); } } @@ -890,4 +936,8 @@ export abstract class BaseCell extends Group { (m) => m.field === this.getMetaField(), )?.renderer; } + + public getConditionIntervalShape() { + return this.conditionIntervalShape; + } } diff --git a/packages/s2-core/src/cell/col-cell.ts b/packages/s2-core/src/cell/col-cell.ts index 794b70dbc3..d25515c684 100644 --- a/packages/s2-core/src/cell/col-cell.ts +++ b/packages/s2-core/src/cell/col-cell.ts @@ -32,6 +32,7 @@ import { } from '../utils/cell/cell'; import { adjustTextIconPositionWhileScrolling } from '../utils/cell/text-scrolling'; import { renderIcon, renderLine } from '../utils/g-renders'; +import { batchSetStyle } from '../utils/g-utils'; import { getHiddenColumnContinuousSiblingNodes, isEqualDisplaySiblingNodeId, @@ -46,6 +47,10 @@ import { normalizeTextAlign } from '../utils/normalize'; import { HeaderCell } from './header-cell'; export class ColCell extends HeaderCell { + private verticalResizeArea: CustomRect; + + private horizontalResizeArea: CustomRect; + public get cellType() { return CellType.COL_CELL; } @@ -311,20 +316,28 @@ export class ColCell extends HeaderCell { cell: this, }); - resizeArea.appendChild( - new CustomRect( - { - name: resizeAreaName, - style: { - ...attrs.style, - x: 0, - y: offsetY + height - resizeStyle.size!, - width: resizeAreaWidth, + const style = { + ...attrs.style, + x: 0, + y: offsetY + height - resizeStyle.size!, + width: resizeAreaWidth, + }; + + if (this.horizontalResizeArea) { + this.horizontalResizeArea.name = resizeAreaName; + this.horizontalResizeArea.appendInfo = attrs.appendInfo; + batchSetStyle(this.horizontalResizeArea, style); + } else { + this.horizontalResizeArea = resizeArea.appendChild( + new CustomRect( + { + name: resizeAreaName, + style, }, - }, - attrs.appendInfo, - ), - ); + attrs.appendInfo, + ), + ); + } } private getResizeAreaWidth() { @@ -465,19 +478,26 @@ export class ColCell extends HeaderCell { cell: this, }); - resizeArea.appendChild( - new CustomRect( - { - style: { - ...attrs.style, - x: offsetX + width - resizeStyle.size!, - y: offsetY, - height, + const style = { + ...attrs.style, + x: offsetX + width - resizeStyle.size!, + y: offsetY, + height, + }; + + if (this.verticalResizeArea) { + this.verticalResizeArea.appendInfo = attrs.appendInfo; + batchSetStyle(this.verticalResizeArea, style); + } else { + this.verticalResizeArea = resizeArea.appendChild( + new CustomRect( + { + style, }, - }, - attrs.appendInfo, - ), - ); + attrs.appendInfo, + ), + ); + } } // 绘制热区 @@ -642,4 +662,9 @@ export class ColCell extends HeaderCell { this.spreadsheet.isValueInCols() ); } + + public setHeaderConfig(headerConfig: ColHeaderConfig) { + super.setHeaderConfig(headerConfig); + // this.drawResizeArea(); + } } diff --git a/packages/s2-core/src/cell/header-cell.ts b/packages/s2-core/src/cell/header-cell.ts index 8dbfe67d51..9dce676f34 100644 --- a/packages/s2-core/src/cell/header-cell.ts +++ b/packages/s2-core/src/cell/header-cell.ts @@ -281,7 +281,11 @@ export abstract class HeaderCell< this.appendChild(icon); } - protected drawActionAndConditionIcons() { + protected drawActionAndConditionIcons({ + updatePositionOnly = false, + }: { + updatePositionOnly?: boolean; + } = {}) { if (isEmpty(this.groupedIcons.left) && isEmpty(this.groupedIcons.right)) { return; } @@ -290,6 +294,8 @@ export abstract class HeaderCell< return; } + let updatePositionOnlyIndex = 0; + forEach(this.groupedIcons, (icons, position) => { const { size, margin } = this.getStyle()!.icon!; @@ -302,19 +308,38 @@ export abstract class HeaderCell< const y = iconPosition.y; if (icon.isConditionIcon) { - this.conditionIconShape = renderIcon(this, { + const iconCfg = { x, y, name: icon.name, width: size, height: size, fill: icon.fill, - }); + }; + + if (this.conditionIconShape) { + if (updatePositionOnly) { + this.conditionIconShape.updatePosition({ x, y }); + + return; + } + + this.conditionIconShape.reRender(iconCfg); + } else { + this.conditionIconShape = renderIcon(this, iconCfg); + } + this.addConditionIconShape(this.conditionIconShape); return; } + if (updatePositionOnly) { + this.actionIcons[updatePositionOnlyIndex++]?.updatePosition({ x, y }); + + return; + } + const { onClick, onHover, defaultHide, isSortIcon } = this.actionIconConfig!; @@ -536,4 +561,16 @@ export abstract class HeaderCell< this.meta.belongsCell = null; super.destroy(); } + + public reInitCell(node: Node, headerConfig: T) { + this.setMeta(node); + this.handleRestOptions(headerConfig, undefined); + this.initCell(); + } + + public setHeaderConfig(headerConfig: T) { + this.handleRestOptions(headerConfig, undefined); + this.updateTextPosition(); + this.drawActionAndConditionIcons({ updatePositionOnly: true }); + } } diff --git a/packages/s2-core/src/cell/pool/base.ts b/packages/s2-core/src/cell/pool/base.ts new file mode 100644 index 0000000000..4a0adc4f8f --- /dev/null +++ b/packages/s2-core/src/cell/pool/base.ts @@ -0,0 +1,11 @@ +export class BaseCellPool { + pool: T[] = []; + + acquire(): T | undefined { + return this.pool.pop(); + } + + release(cell: T) { + this.pool.push(cell); + } +} diff --git a/packages/s2-core/src/cell/pool/col-cell.ts b/packages/s2-core/src/cell/pool/col-cell.ts new file mode 100644 index 0000000000..ea886717e2 --- /dev/null +++ b/packages/s2-core/src/cell/pool/col-cell.ts @@ -0,0 +1,33 @@ +import { ColCell } from '../col-cell'; +import { BaseCellPool } from './base'; + +export class ColCellPool extends BaseCellPool { + private readonly cellIdPool = new Set(); + + acquire(): ColCell | undefined { + const cell = super.acquire(); + + if (cell) { + this.cellIdPool.delete(cell.getMeta().id); + } + + return cell; + } + + release(cell: ColCell): void { + if (cell.getRenderer()) { + cell.destroy(); + + return; + } + + const cellId = cell.getMeta().id; + + if (this.cellIdPool.has(cellId)) { + return; + } + + super.release(cell); + this.cellIdPool.add(cellId); + } +} diff --git a/packages/s2-core/src/cell/pool/data-cell.ts b/packages/s2-core/src/cell/pool/data-cell.ts new file mode 100644 index 0000000000..a9a33f55f2 --- /dev/null +++ b/packages/s2-core/src/cell/pool/data-cell.ts @@ -0,0 +1,12 @@ +import { DataCell } from '../data-cell'; +import { BaseCellPool } from './base'; + +export class DataCellPool extends BaseCellPool { + release(cell: DataCell) { + if (!cell.getRenderer()) { + this.pool.push(cell); + } else { + cell.destroy(); + } + } +} diff --git a/packages/s2-core/src/cell/pool/index.ts b/packages/s2-core/src/cell/pool/index.ts new file mode 100644 index 0000000000..129bcd17a8 --- /dev/null +++ b/packages/s2-core/src/cell/pool/index.ts @@ -0,0 +1,4 @@ +export * from './base'; +export * from './col-cell'; +export * from './data-cell'; +export * from './row-cell'; diff --git a/packages/s2-core/src/cell/pool/row-cell.ts b/packages/s2-core/src/cell/pool/row-cell.ts new file mode 100644 index 0000000000..6a5a4e815a --- /dev/null +++ b/packages/s2-core/src/cell/pool/row-cell.ts @@ -0,0 +1,33 @@ +import { RowCell } from '../row-cell'; +import { BaseCellPool } from './base'; + +export class RowCellPool extends BaseCellPool { + private readonly cellIdPool = new Set(); + + acquire(): RowCell | undefined { + const cell = super.acquire(); + + if (cell) { + this.cellIdPool.delete(cell.getMeta().id); + } + + return cell; + } + + release(cell: RowCell): void { + if (cell.getRenderer()) { + cell.destroy(); + + return; + } + + const cellId = cell.getMeta().id; + + if (this.cellIdPool.has(cellId)) { + return; + } + + super.release(cell); + this.cellIdPool.add(cellId); + } +} diff --git a/packages/s2-core/src/cell/row-cell.ts b/packages/s2-core/src/cell/row-cell.ts index 3c2f637bf2..758d53f8d2 100644 --- a/packages/s2-core/src/cell/row-cell.ts +++ b/packages/s2-core/src/cell/row-cell.ts @@ -521,4 +521,8 @@ export class RowCell extends HeaderCell { !this.spreadsheet.isValueInCols() ); } + + public setHeaderConfig(headerConfig: RowHeaderConfig) { + super.setHeaderConfig(headerConfig); + } } diff --git a/packages/s2-core/src/common/icons/gui-icon.ts b/packages/s2-core/src/common/icons/gui-icon.ts index a3bd302476..26f3341c49 100644 --- a/packages/s2-core/src/common/icons/gui-icon.ts +++ b/packages/s2-core/src/common/icons/gui-icon.ts @@ -1,9 +1,10 @@ /** * @description: 请严格要求 svg 的 viewBox,若设计产出的 svg 不是此规格,请叫其修改为 '0 0 1024 1024' */ -import { Group, type ImageStyleProps } from '@antv/g'; +import { Group, PointLike, type ImageStyleProps } from '@antv/g'; import { clone, omit } from 'lodash'; import { CustomImage } from '../../engine'; +import { batchSetStyle } from '../../utils/g-utils'; import { DebuggerUtil } from '../debug'; import { getIcon } from './factory'; @@ -123,6 +124,21 @@ export class GuiIcon extends Group { this.setImageAttrs({ name, fill }); } + public reRender(cfg: GuiIconCfg) { + this.name = cfg.name; + this.cfg = cfg; + const { name, fill } = this.cfg; + const attrs = clone(this.cfg); + + this.iconImageShape.imgType = GuiIcon.type; + batchSetStyle(this.iconImageShape, omit(attrs, 'fill')); + this.setImageAttrs({ name, fill }); + } + + public updatePosition(position: PointLike) { + batchSetStyle(this.iconImageShape, position); + } + public setImageAttrs(attrs: Partial<{ name: string; fill: string | null }>) { let { name, fill } = attrs; const { iconImageShape: image } = this; diff --git a/packages/s2-core/src/common/interface/s2Options.ts b/packages/s2-core/src/common/interface/s2Options.ts index bb4c582270..a0e18198c3 100644 --- a/packages/s2-core/src/common/interface/s2Options.ts +++ b/packages/s2-core/src/common/interface/s2Options.ts @@ -297,6 +297,21 @@ export interface S2BasicOptions< * @see https://s2.antv.antgroup.com/examples/custom/custom-layout/#custom-facet */ facet?: (spreadsheet: SpreadSheet) => BaseFacet; + /** + * Enabling some features for the future. + * + * ! These are some experimental functional features that are currently unstable. + * + * future flag, concept referenced from: + * - https://remix.run/docs/en/main/guides/api-development-strategy#unstable-apis-and-future-flags, + * - https://remix.run/blog/future-flags + */ + future?: { + /** + * 是否复用数据单元格 + */ + experimentalReuseDataCell?: boolean; + }; } // 设备,pc || mobile diff --git a/packages/s2-core/src/extends/pivot-chart/cell/chart-data-cell.ts b/packages/s2-core/src/extends/pivot-chart/cell/chart-data-cell.ts index b43c3648b9..22bb21ee5d 100644 --- a/packages/s2-core/src/extends/pivot-chart/cell/chart-data-cell.ts +++ b/packages/s2-core/src/extends/pivot-chart/cell/chart-data-cell.ts @@ -21,7 +21,9 @@ export class ChartDataCell extends DataCell { return; } - this.chartShape = this.appendChild(new Group({ style: { zIndex: 1 } })); + if (!this.chartShape) { + this.chartShape = this.appendChild(new Group({ style: { zIndex: 1 } })); + } const chartOptions = this.getChartOptions(); diff --git a/packages/s2-core/src/extends/pivot-chart/cell/pivot-chart-data-cell.ts b/packages/s2-core/src/extends/pivot-chart/cell/pivot-chart-data-cell.ts index feee8e4d9b..05b88d4d26 100644 --- a/packages/s2-core/src/extends/pivot-chart/cell/pivot-chart-data-cell.ts +++ b/packages/s2-core/src/extends/pivot-chart/cell/pivot-chart-data-cell.ts @@ -65,7 +65,9 @@ export class PivotChartDataCell extends ChartDataCell { public drawTextShape(): void { const chartOptions = this.getChartOptions(); - this.chartShape = this.appendChild(new Group({ style: { zIndex: 1 } })); + if (!this.chartShape) { + this.chartShape = this.appendChild(new Group({ style: { zIndex: 1 } })); + } waitForCellMounted(() => { if (this.destroyed) { diff --git a/packages/s2-core/src/facet/base-facet.ts b/packages/s2-core/src/facet/base-facet.ts index 1fe97a978d..aa3b0dd60d 100644 --- a/packages/s2-core/src/facet/base-facet.ts +++ b/packages/s2-core/src/facet/base-facet.ts @@ -40,6 +40,7 @@ import { TableSeriesNumberCell, type HeaderCell, } from '../cell'; +import { DataCellPool } from '../cell/pool'; import { BACK_GROUND_GROUP_CONTAINER_Z_INDEX, CellType, @@ -184,6 +185,8 @@ export abstract class BaseFacet { protected textWrapTempColCell: ColCell | TableColCell; + protected dataCellPool: DataCellPool; + public customRowHeightStatusMap: Record; protected abstract getCornerCellInstance( @@ -1611,10 +1614,17 @@ export abstract class BaseFacet { return; } - const cell = this.spreadsheet.options.dataCell?.( - viewMeta, - this.spreadsheet, - )!; + let cell; + + if ( + this.dataCellPool.pool.length > 0 && + this.spreadsheet.options.future?.experimentalReuseDataCell + ) { + cell = this.dataCellPool.acquire()!; + cell.setMeta(viewMeta); + } else { + cell = this.spreadsheet.options.dataCell?.(viewMeta, this.spreadsheet)!; + } if (!cell) { return; @@ -1640,33 +1650,72 @@ export abstract class BaseFacet { diffPanelIndexes(this.preCellIndexes!, indexes); DebuggerUtil.getInstance().debugCallback(DEBUG_VIEW_RENDER, () => { - // add new cell in panelCell - each(willAddDataCells, ([colIndex, rowIndex]) => { - const viewMeta = this.getCellMeta(rowIndex, colIndex); - const cell = this.createDataCell(viewMeta); + if (this.spreadsheet.options.future?.experimentalReuseDataCell) { + const allDataCells = this.getDataCells(); + const maxLength = Math.max( + willRemoveDataCells.length, + willAddDataCells.length, + ); - if (!cell) { - return; - } + // 交替执行删除和添加操作 + for (let i = 0; i < maxLength; i++) { + // 删除单元格 + if (i < willRemoveDataCells.length) { + const [colIndex, rowIndex] = willRemoveDataCells[i]; + const mountedDataCell = find( + allDataCells, + (cell) => cell.name === `${rowIndex}-${colIndex}`, + ); - this.addDataCell(cell); - }); + if (mountedDataCell) { + this.dataCellPool.release(mountedDataCell); + } + } + + // 添加单元格 + if (i < willAddDataCells.length) { + const [colIndex, rowIndex] = willAddDataCells[i]; + const viewMeta = this.getCellMeta(rowIndex, colIndex); + const cell = this.createDataCell(viewMeta); - const allDataCells = this.getDataCells(); + if (cell) { + this.addDataCell(cell); + } + } + } - // remove cell from panelCell - each(willRemoveDataCells, ([colIndex, rowIndex]) => { - const mountedDataCell = find( - allDataCells, - (cell) => cell.name === `${rowIndex}-${colIndex}`, + DebuggerUtil.getInstance().logger( + `Render Cell Panel: ${allDataCells?.length}, Add: ${willAddDataCells?.length}, Remove: ${willRemoveDataCells?.length}`, ); + } else { + // add new cell in panelCell + each(willAddDataCells, ([colIndex, rowIndex]) => { + const viewMeta = this.getCellMeta(rowIndex, colIndex); + const cell = this.createDataCell(viewMeta); - mountedDataCell?.destroy(); - }); + if (!cell) { + return; + } - DebuggerUtil.getInstance().logger( - `Render Cell Panel: ${allDataCells?.length}, Add: ${willAddDataCells?.length}, Remove: ${willRemoveDataCells?.length}`, - ); + this.addDataCell(cell); + }); + + const allDataCells = this.getDataCells(); + + // remove cell from panelCell + each(willRemoveDataCells, ([colIndex, rowIndex]) => { + const mountedDataCell = find( + allDataCells, + (cell) => cell.name === `${rowIndex}-${colIndex}`, + ); + + mountedDataCell?.destroy(); + }); + + DebuggerUtil.getInstance().logger( + `Render Cell Panel: ${allDataCells?.length}, Add: ${willAddDataCells?.length}, Remove: ${willRemoveDataCells?.length}`, + ); + } }); this.preCellIndexes = indexes; @@ -1678,6 +1727,7 @@ export abstract class BaseFacet { }; protected init() { + this.initCellPool(); this.initTextWrapTemp(); this.initGroups(); // layout @@ -2470,4 +2520,8 @@ export abstract class BaseFacet { Math.ceil(this.spreadsheet.measureTextWidth(text, font)) + EXTRA_PIXEL ); } + + protected initCellPool() { + this.dataCellPool = new DataCellPool(); + } } diff --git a/packages/s2-core/src/facet/frozen-facet.ts b/packages/s2-core/src/facet/frozen-facet.ts index 42818ac9a7..71619b78d5 100644 --- a/packages/s2-core/src/facet/frozen-facet.ts +++ b/packages/s2-core/src/facet/frozen-facet.ts @@ -260,8 +260,10 @@ export abstract class FrozenFacet extends BaseFacet { ); if (frozenGroupType === FrozenGroupType.Scroll) { - this.panelScrollGroup.appendChild(cell); - } else { + if (cell.parentElement !== this.panelScrollGroup) { + this.panelScrollGroup.appendChild(cell); + } + } else if (cell.parentElement !== this.frozenGroups[frozenGroupType]) { this.frozenGroups[frozenGroupType].appendChild(cell); } diff --git a/packages/s2-core/src/facet/header/base.ts b/packages/s2-core/src/facet/header/base.ts index e101ce8529..0681b09b2a 100644 --- a/packages/s2-core/src/facet/header/base.ts +++ b/packages/s2-core/src/facet/header/base.ts @@ -1,6 +1,6 @@ import { Group, RectStyleProps } from '@antv/g'; import type { S2CellType } from '../../common'; -import { createOrUpdateRect } from '../../utils'; +import { createOrUpdateRect } from '../../utils/g-utils'; import type { Node } from '../layout/node'; import type { BaseHeaderConfig } from './interface'; diff --git a/packages/s2-core/src/facet/header/col.ts b/packages/s2-core/src/facet/header/col.ts index eb1a68029e..1242f199ad 100644 --- a/packages/s2-core/src/facet/header/col.ts +++ b/packages/s2-core/src/facet/header/col.ts @@ -1,6 +1,7 @@ import { Group } from '@antv/g'; import { each } from 'lodash'; import { ColCell } from '../../cell/col-cell'; +import { ColCellPool } from '../../cell/pool'; import { FRONT_GROUND_GROUP_FROZEN_Z_INDEX, FRONT_GROUND_GROUP_SCROLL_Z_INDEX, @@ -26,6 +27,8 @@ import { * Column Header for SpreadSheet */ export class ColHeader extends BaseHeader { + colCellPool = new ColCellPool(); + protected initGroups(): void { this.scrollGroup = this.appendChild( new Group({ @@ -66,6 +69,17 @@ export class ColHeader extends BaseHeader { } protected getCellInstance(node: Node) { + if ( + this.colCellPool.pool.length > 0 && + this.headerConfig.spreadsheet.options.future?.experimentalReuseDataCell + ) { + const colCell = this.colCellPool.acquire()!; + + colCell.reInitCell(node, this.getHeaderConfig()); + + return colCell; + } + const headerConfig = this.getHeaderConfig(); const { spreadsheet } = this.getHeaderConfig(); @@ -81,11 +95,24 @@ export class ColHeader extends BaseHeader { const { spreadsheet } = this.getHeaderConfig(); const group = this.getCellGroup(node); - const cell = this.getCellInstance(node); + let cell: ColCell; + + if ( + node.belongsCell?.parentNode === group && + node.belongsCell.getMeta() === node + ) { + cell = node.belongsCell as ColCell; + cell.setHeaderConfig(this.headerConfig); + } else { + cell = this.getCellInstance(node); - node.belongsCell = cell; + node.belongsCell = cell; + + if (cell.parentElement !== group) { + group?.appendChild(cell); + } + } - group?.appendChild(cell); spreadsheet.emit(S2Event.COL_CELL_RENDER, cell as ColCell); spreadsheet.emit(S2Event.LAYOUT_CELL_RENDER, cell); } @@ -215,4 +242,22 @@ export class ColHeader extends BaseHeader { position.y, ); } + + public clear() { + if ( + this.headerConfig.spreadsheet.options.future?.experimentalReuseDataCell + ) { + // @ts-ignore + this.scrollGroup.childNodes.forEach((colCell: ColCell) => { + if (!this.isColCellInRect(colCell.getMeta())) { + colCell.getMeta().belongsCell = null; + this.colCellPool.release(colCell); + } + }); + } else { + super.clear(); + } + } + + protected clearResizeAreaGroup() {} } diff --git a/packages/s2-core/src/facet/header/row.ts b/packages/s2-core/src/facet/header/row.ts index 6564b41f59..962dcd549d 100644 --- a/packages/s2-core/src/facet/header/row.ts +++ b/packages/s2-core/src/facet/header/row.ts @@ -1,6 +1,7 @@ import { Group } from '@antv/g'; import { each } from 'lodash'; import { RowCell, SeriesNumberCell } from '../../cell'; +import { RowCellPool } from '../../cell/pool'; import { FRONT_GROUND_GROUP_FROZEN_Z_INDEX, FRONT_GROUND_GROUP_SCROLL_Z_INDEX, @@ -21,6 +22,8 @@ import { getExtraFrozenRowNodes, getFrozenTrailingRowOffset } from './util'; * Row Header for SpreadSheet */ export class RowHeader extends BaseHeader { + rowCellPool = new RowCellPool(); + protected initGroups(): void { this.scrollGroup = this.appendChild( new Group({ @@ -50,6 +53,17 @@ export class RowHeader extends BaseHeader { } public getCellInstance(node: Node): RowCell | SeriesNumberCell { + if ( + this.rowCellPool.pool.length > 0 && + this.headerConfig.spreadsheet.options.future?.experimentalReuseDataCell + ) { + const rowCell = this.rowCellPool.acquire()!; + + rowCell.reInitCell(node, this.headerConfig); + + return rowCell; + } + const headerConfig = this.getHeaderConfig(); const { spreadsheet } = headerConfig; @@ -107,12 +121,24 @@ export class RowHeader extends BaseHeader { const appendNode = (node: Node) => { const group = this.getCellGroup(node); - - const cell = this.getCellInstance(node); - - node.belongsCell = cell; - - group.appendChild(cell); + let cell; + + if ( + node.belongsCell?.parentNode === group && + node.belongsCell.getMeta() === node + ) { + cell = node.belongsCell as RowCell; + cell.setHeaderConfig(this.headerConfig); + cell.updateTextPosition(); + } else { + cell = this.getCellInstance(node); + + node.belongsCell = cell; + + if (cell.parentElement !== group) { + group?.appendChild(cell); + } + } this.emitRenderEvent(cell); }; @@ -205,4 +231,20 @@ export class RowHeader extends BaseHeader { height: frozenTrailingRowGroupHeight, }); } + + public clear() { + if ( + this.headerConfig.spreadsheet.options.future?.experimentalReuseDataCell + ) { + // @ts-ignore + this.scrollGroup.childNodes.forEach((rowCell: RowCell) => { + if (!this.isCellInRect(rowCell.getMeta())) { + rowCell.getMeta().belongsCell = null; + this.rowCellPool.release(rowCell); + } + }); + } else { + super.clear(); + } + } } diff --git a/packages/s2-core/src/utils/g-mini-charts.ts b/packages/s2-core/src/utils/g-mini-charts.ts index 7e99ae0b80..120933a045 100644 --- a/packages/s2-core/src/utils/g-mini-charts.ts +++ b/packages/s2-core/src/utils/g-mini-charts.ts @@ -26,6 +26,7 @@ import { renderPolyline, renderRect, } from '../utils/g-renders'; +import { batchSetStyle } from '../utils/g-utils'; interface FractionDigitsOptions { min: number; @@ -304,13 +305,23 @@ export const drawInterval = (cell: DataCell) => { const fill = attrs.fill ?? barChartFillColor; - return renderRect(cell, { + const style = { x: x + width * zeroScale, y: y + height / 2 - barChartHeight! / 2, width: width * intervalScale, height: barChartHeight!, fill, - }); + }; + + const conditionIntervalShape = cell.getConditionIntervalShape(); + + if (conditionIntervalShape) { + batchSetStyle(conditionIntervalShape, style); + + return conditionIntervalShape; + } + + return renderRect(cell, style); } }; diff --git a/packages/s2-core/src/utils/g-utils.ts b/packages/s2-core/src/utils/g-utils.ts new file mode 100644 index 0000000000..4e37065881 --- /dev/null +++ b/packages/s2-core/src/utils/g-utils.ts @@ -0,0 +1,32 @@ +import { + BaseStyleProps, + DisplayObject, + Rect, + type RectStyleProps, +} from '@antv/g'; +import { get, set } from 'lodash'; + +export function batchSetStyle< + T extends DisplayObject, + S extends BaseStyleProps & { + x?: number | string; + y?: number | string; + }, +>(obj: T, style: S) { + obj.setAttributes(style, { skipDispatchAttrModifiedEvent: true }); +} + +export function createOrUpdateRect( + propertyPath: string, + style: RectStyleProps, +) { + // @ts-ignore + const context = this as any; + const obj = get(context, propertyPath); + + if (!obj) { + set(context, propertyPath, new Rect({ style })); + } else { + batchSetStyle(obj, style); + } +} diff --git a/packages/s2-react/playground/components/BigDataSheet.tsx b/packages/s2-react/playground/components/BigDataSheet.tsx index bf21f49d5b..a51f8eadf7 100644 --- a/packages/s2-react/playground/components/BigDataSheet.tsx +++ b/packages/s2-react/playground/components/BigDataSheet.tsx @@ -16,6 +16,9 @@ const s2Options: SheetComponentOptions = { }, }, showDefaultHeaderActionIcon: false, + future: { + experimentalReuseDataCell: true, + }, }; export function generateRawData( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94e47c8466..d625408433 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -276,14 +276,14 @@ importers: specifier: ^0.1.3 version: 0.1.3 '@antv/g': - specifier: ^6.1.28 - version: 6.1.28 + specifier: ^6.3.1 + version: 6.3.1 '@antv/g-canvas': - specifier: ^2.0.48 - version: 2.0.48 + specifier: ^2.2.0 + version: 2.2.0 '@antv/g-lite': - specifier: ^2.3.2 - version: 2.3.2 + specifier: ^2.7.0 + version: 2.7.0 '@antv/vendor': specifier: ^1.0.11 version: 1.0.11 @@ -863,24 +863,18 @@ packages: '@antv/g-camera-api@2.0.35': resolution: {integrity: sha512-z4WKmB6yN2fFi9EnapjuHbFVF0ilhMrWo2eZCxYXcb0dV5MiflU/WZi/bjs4WqVMJPNtYKx+yZhTyROncEiglw==} - '@antv/g-camera-api@2.0.41': - resolution: {integrity: sha512-dF52/wpzHDKi7ZzPlaHurEjWrF9aBKL2udDwQkEeVtfkJ0DHaavr3BAvhuGhtHoecRYQJvpzP1OkGNDLQJQQlw==} - '@antv/g-canvas@2.0.33': resolution: {integrity: sha512-bqLqB42biy1ov/pu0iuKe7ErY6ASDuCDoChYQjqE9xWHFVAkXC3/sFRV0g/Br4qSJiDX4ewnRj89JH/hqTLMRA==} '@antv/g-canvas@2.0.40': resolution: {integrity: sha512-Starh5g+ydOFKzfK/GpwnLwz+o6UZNHkyWBXdHx2ax/AJWHVXwjyCadt/6kkc2non0ts2ow/hpJaW7X3dgdDxQ==} - '@antv/g-canvas@2.0.48': - resolution: {integrity: sha512-P98cTLRbKbCAcUVgHqMjKcvOany6nR7wvt+g+sazIfKSMUCWgjLTOjlLezux2up3At29mt80StaV2AR3d61YQA==} + '@antv/g-canvas@2.2.0': + resolution: {integrity: sha512-h7zVBBo2aO64DuGKvq9sG+yTU3sCUb9DALCVm7nz8qGPs8hhLuFOkKPEzUDNfNYZGJUGzY8UDtJ3QRGRFcvEQg==} '@antv/g-dom-mutation-observer-api@2.0.32': resolution: {integrity: sha512-50r7en1+doUtR9uXmFJk8YtENQ/+DFcj2g3a4XKu9xp58kmF2qBgtdst9n1deqGcL5s0ufX/Ck9rUhtHwka+Ow==} - '@antv/g-dom-mutation-observer-api@2.0.38': - resolution: {integrity: sha512-xzgbt8GUOiToBeDVv+jmGkDE+HtI9tD6uO8TirJbCya88DKcY/jurQALq0NdWKgMJLn7WPiUKyDwHWimwQcBJw==} - '@antv/g-lite@2.0.5': resolution: {integrity: sha512-IeD7L10MOofNg302Zrru09zjNczCyOAC6mFLjHQlkYCQRtcU04zn32pTxCDy7xRkLHlhAK1mlymBqzeRMkmrRg==} @@ -894,8 +888,8 @@ packages: resolution: {integrity: sha512-Gua5FtIAumkT/bPcIl7twQF5T1RtuaUT9CpbIYKaiEAwMbecrjGLeTbm9kNKoUT5Tub4HcW2gzfQQ4O21zJdzg==} deprecated: This version has been deprecated. Please upgrade to the latest version. - '@antv/g-lite@2.3.2': - resolution: {integrity: sha512-fkIxRoqLOGsNPwsp26bPp58cPWuX3E4wQ9cfkB/DHy5LtLrPpvOwHWB3+MBPgZwzk8jTTjchiXa756ZFOAWyQQ==} + '@antv/g-lite@2.7.0': + resolution: {integrity: sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==} '@antv/g-math@3.0.0': resolution: {integrity: sha512-AkmiNIEL1vgqTPeGY2wtsMdBBqKFwF7SKSgs+D1iOS/rqYMsXdhp/HvtuQ5tx/HdawE/ZzTiicIYopc520ADZw==} @@ -903,6 +897,9 @@ packages: '@antv/g-math@3.0.1': resolution: {integrity: sha512-FvkDBNRpj+HsLINunrL2PW0OlG368MlpHuihbxleuajGim5kra8tgISwCLmAf8Yz2b1CgZ9PvpohqiLzHS7HLg==} + '@antv/g-math@3.1.0': + resolution: {integrity: sha512-DtN1Gj/yI0UiK18nSBsZX8RK0LszGwqfb+cBYWgE+ddyTm8dZnW4tPUhV7QXePsS6/A5hHC+JFpAAK7OEGo5ZQ==} + '@antv/g-plugin-a11y@1.1.15': resolution: {integrity: sha512-1Ip9YXOtMT+yu8rLEmmSBHMxsB+hFpGY0EWy3mYOO+O00WSvHOYQxHvjb2/BtJuwcfyr6HzfLO4RJHSRsGfhMA==} @@ -915,36 +912,24 @@ packages: '@antv/g-plugin-canvas-path-generator@2.1.16': resolution: {integrity: sha512-E3/HUzWRv1/5QyKHLcXIgFJff0JBxDHz4NfHwYp6IOy5P/A1mbISsUjwafSl8JIVqx0J81CzgqpwU7pWHeXlaQ==} - '@antv/g-plugin-canvas-path-generator@2.1.22': - resolution: {integrity: sha512-Z0IawzTGgTppa9IpkNNKsqgoU89oOjUsiU8GZZlkDkUggQTHP0wOxTeLAb43YgClx3aTI3bRs44uMQutNdSVxw==} - '@antv/g-plugin-canvas-picker@2.1.12': resolution: {integrity: sha512-hRoMAeyw32zNhiRDIXYOPJp/IFydOaNkwA6asv4dS5lv/CqfXgeOG9m58YtCBNfIRREVCRh6xuX/L2tiwtzFOg==} '@antv/g-plugin-canvas-picker@2.1.19': resolution: {integrity: sha512-69G0m2v09FimmYSU+hO1wjft1FqM467Cf1jDpjBz6Y3caQ98Hrqpz/7Prko1hMOALCo92MDo65yTTnz/LhBiQA==} - '@antv/g-plugin-canvas-picker@2.1.27': - resolution: {integrity: sha512-DHQ0YLYNXAm6O63pW6nKs/R0fuqlUYfehNs/EtzrmqyUkKASd/Vhs4HLNeHTMUdBMgg41T+x5qay0GGttK4Xdw==} - '@antv/g-plugin-canvas-renderer@2.2.12': resolution: {integrity: sha512-9ydHAXx0IHcvYCgrhIxqA9IFpZ9eeKAqaQJW//43pxeXsMyfbCZlDC5ceCdFzPhhDo1+P98Thl89CMaHUo/Wdg==} '@antv/g-plugin-canvas-renderer@2.2.19': resolution: {integrity: sha512-3Ac0pjU0NAafu0rwTnthwWV/CV5kV9CpTf96v1CCXX0P3iPWtW72SatQNOt/v2aQ2NjYB34YuwYy9i0U1oS8rg==} - '@antv/g-plugin-canvas-renderer@2.3.3': - resolution: {integrity: sha512-d6JkZy1YmLnvI9wsbO8QVpBz7z7tl6JRQkF5hx9XLDtf2fD4n83KINeMq13skiNwaiudS771WWiBtfzUHB73pQ==} - '@antv/g-plugin-dom-interaction@2.1.15': resolution: {integrity: sha512-sxUobdgzst0P4bwSeMf9qiQLMvhtIBsEARAC7viuNNwno2D61TKBaQ/PMEohDlOsqLIbk/xI5Np9XGVwbAnNFQ==} '@antv/g-plugin-dom-interaction@2.1.21': resolution: {integrity: sha512-Vm8yeNjZ2aNgNH3LwDRExRChpuVv0Wv2zOblUGy5rgyRIh2Fkm8R89pKLmd3GlLo4AF1ZqAGWHiY2WOeMHEEIA==} - '@antv/g-plugin-dom-interaction@2.1.27': - resolution: {integrity: sha512-hltVZZH+bj0uXmGSR+6BIwhCFYyHmDIQi3vrj/Wn1Dn6PgufvMCXfjr3DfmkQnY+FFP8ZCpg5N9MaE0BE9OddA==} - '@antv/g-plugin-dragndrop@2.0.32': resolution: {integrity: sha512-0Y9S/jx6Z7O3hEQhqrXGWNIcV1dBoRpokSP9gIMqTxOjCLzVUFYv8pFoI+Uyeow6PAWe+gdBQu+EJgVi223lJQ==} @@ -960,18 +945,12 @@ packages: '@antv/g-plugin-html-renderer@2.1.21': resolution: {integrity: sha512-1PR9rYt4BgSx8LFnVPF+cPlcBYKfI7iWK/xPipEa3jZ4j/xftELQ5EEyZpfPnrTqu2PtKeMurx7oaM/HPsgaiQ==} - '@antv/g-plugin-html-renderer@2.1.27': - resolution: {integrity: sha512-NnI4GxDBb71o/XZzoRdi0xI3xg7GJmthyO5xP5/MiOFmwJ/jW/QDz17vUonmzUVbCt6upikHV5GyYOaogRqdVg==} - '@antv/g-plugin-image-loader@2.1.12': resolution: {integrity: sha512-Jgra9vOcfHO8Xq6yRoIBxl1e5UmI8ZjU5ahta3/C+lg/J+GUfI0FT4dB4Az0gAY5B1o2P/Gkd2K2PKyEcgYmLA==} '@antv/g-plugin-image-loader@2.1.19': resolution: {integrity: sha512-ZjNs08RkzdDMLlEWGabJG1Lu1Q71afStSlhcIRhrDOLB4tH0UdYlq/f72tlzJ6KjtLnril/xQH3D7znPlfAoig==} - '@antv/g-plugin-image-loader@2.1.26': - resolution: {integrity: sha512-AElV0QOX2LAhB3jr9XtvkynntuKhcaU5n7avu5ynM5VoAtMaJRANhCyefA2G3myeJxWcHk4nWDX6u4YMaZnnvw==} - '@antv/g-plugin-rough-canvas-renderer@2.0.33': resolution: {integrity: sha512-3tzcm6evDI51oE4MnqhnmYl3ZB3pPDrRRtlgGPoMRZ1HowPZyjqKL73+Iy2DkgpEfJiSrdWKI0OBSHBebPfj1A==} @@ -981,9 +960,6 @@ packages: '@antv/g-web-animations-api@2.1.21': resolution: {integrity: sha512-EkIjeEH3QzHkDJn3sz1Mk83PqVQXGe5440mJV42QmnxuFuFcxGVJMi9vS8Te7kCUJl4eSb/eqnNi5AWfDMWm+w==} - '@antv/g-web-animations-api@2.1.28': - resolution: {integrity: sha512-V5g8bO2D1hb8fRMMi5hXL/De+1UDRzW3C5EX07oazR0q71GONASP+sVwniZdt9R1HAmJSN5dvW3SqWeU3EEstQ==} - '@antv/g2@5.1.21': resolution: {integrity: sha512-7HRWuiGN7sPK4K8ljl2/x0i3sphWNMymYFuR1BT9qo4wmMqQUgM+K+ISKMb3dXOg55eHmFje0OH80sZ53qhqPg==} @@ -996,8 +972,8 @@ packages: '@antv/g@6.1.21': resolution: {integrity: sha512-3cWmsY1bYwDmVzsFmBeqN1tWVt+3JaWL6Uu54C1oF7qn1VXXa3V3KuXGEYCxuei8E8BMriN3D7fZosY5d+MQqw==} - '@antv/g@6.1.28': - resolution: {integrity: sha512-BwavpbKGR4NEJD3BtVxfBFjCcxy5gsWoUNnBisfG1qfjhGTt7QvUYHFH46+mHJjHMIdYjuFw2T0ZYVtxBddxSg==} + '@antv/g@6.3.1': + resolution: {integrity: sha512-WYEKqy86LHB2PzTmrZXrIsIe+3Epeds2f68zceQ+BJtRoGki7Sy4IhlC8LrUMztgfT1t3d/0L745NWZwITroKA==} '@antv/path-util@3.0.1': resolution: {integrity: sha512-tpvAzMpF9Qm6ik2YSMqICNU5tco5POOW7S4XoxZAI/B0L26adU+Md/SmO0BBo2SpuywKvzPH3hPT3xmoyhr04Q==} @@ -5448,6 +5424,10 @@ packages: resolution: {integrity: sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==} engines: {node: '>= 0.6.0'} + base64-arraybuffer@1.0.2: + resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} + engines: {node: '>= 0.6.0'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -6337,6 +6317,9 @@ packages: css-in-js-utils@3.1.0: resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + css-line-break@2.1.0: + resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} + css-loader@6.7.1: resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==} engines: {node: '>= 12.13.0'} @@ -8778,6 +8761,10 @@ packages: html-whitespace-sensitive-tag-names@2.0.0: resolution: {integrity: sha512-SQdIvTTtnHAx72xGUIUudvVOCjeWvV1U7rvSFnNGxTGRw3ZC7RES4Gw6dm1nMYD60TXvm6zjk/bWqgNc5pjQaw==} + html2canvas@1.4.1: + resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} + engines: {node: '>=8.0.0'} + html2sketch@1.0.2: resolution: {integrity: sha512-/P9NcVH9yBhrOkcnaFkAbWJifDO8Ii+CTIxy9gE6trSQvo2OH++TKQIP5MICEoWvgXpVhZ6botj7P63Krl1/gg==} engines: {node: '>=14.0.0'} @@ -15162,6 +15149,9 @@ packages: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} + text-segmentation@1.0.3: + resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -15787,6 +15777,9 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + utrie@1.0.2: + resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} + uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. @@ -16785,21 +16778,21 @@ snapshots: '@antv/component@2.0.1': dependencies: - '@antv/g': 6.1.28 + '@antv/g': 6.3.1 '@antv/scale': 0.4.16 '@antv/util': 3.3.7 svg-path-parser: 1.1.0 '@antv/component@2.1.2': dependencies: - '@antv/g': 6.1.28 + '@antv/g': 6.3.1 '@antv/scale': 0.4.16 '@antv/util': 3.3.10 svg-path-parser: 1.1.0 '@antv/component@2.1.4': dependencies: - '@antv/g': 6.1.28 + '@antv/g': 6.3.1 '@antv/scale': 0.4.16 '@antv/util': 3.3.10 svg-path-parser: 1.1.0 @@ -16910,14 +16903,6 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 - '@antv/g-camera-api@2.0.41': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - gl-matrix: 3.4.3 - tslib: 2.8.1 - '@antv/g-canvas@2.0.33': dependencies: '@antv/g-lite': 2.2.10 @@ -16944,17 +16929,13 @@ snapshots: '@babel/runtime': 7.27.0 tslib: 2.8.1 - '@antv/g-canvas@2.0.48': + '@antv/g-canvas@2.2.0': dependencies: - '@antv/g-lite': 2.3.2 - '@antv/g-plugin-canvas-path-generator': 2.1.22 - '@antv/g-plugin-canvas-picker': 2.1.27 - '@antv/g-plugin-canvas-renderer': 2.3.3 - '@antv/g-plugin-dom-interaction': 2.1.27 - '@antv/g-plugin-html-renderer': 2.1.27 - '@antv/g-plugin-image-loader': 2.1.26 + '@antv/g-lite': 2.7.0 + '@antv/g-math': 3.1.0 '@antv/util': 3.3.10 '@babel/runtime': 7.27.6 + gl-matrix: 3.4.3 tslib: 2.8.1 '@antv/g-dom-mutation-observer-api@2.0.32': @@ -16962,11 +16943,6 @@ snapshots: '@antv/g-lite': 2.2.16 '@babel/runtime': 7.27.0 - '@antv/g-dom-mutation-observer-api@2.0.38': - dependencies: - '@antv/g-lite': 2.3.2 - '@babel/runtime': 7.27.6 - '@antv/g-lite@2.0.5': dependencies: '@antv/g-math': 3.0.0 @@ -17010,15 +16986,14 @@ snapshots: rbush: 3.0.1 tslib: 2.8.1 - '@antv/g-lite@2.3.2': + '@antv/g-lite@2.7.0': dependencies: - '@antv/g-math': 3.0.1 + '@antv/g-math': 3.1.0 '@antv/util': 3.3.10 '@antv/vendor': 1.0.11 '@babel/runtime': 7.27.6 eventemitter3: 5.0.1 gl-matrix: 3.4.3 - rbush: 3.0.1 tslib: 2.8.1 '@antv/g-math@3.0.0': @@ -17034,6 +17009,13 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 + '@antv/g-math@3.1.0': + dependencies: + '@antv/util': 3.3.10 + '@babel/runtime': 7.27.6 + gl-matrix: 3.4.3 + tslib: 2.8.1 + '@antv/g-plugin-a11y@1.1.15': dependencies: '@antv/g-lite': 2.2.10 @@ -17062,14 +17044,6 @@ snapshots: '@babel/runtime': 7.27.0 tslib: 2.8.1 - '@antv/g-plugin-canvas-path-generator@2.1.22': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/g-math': 3.0.1 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - tslib: 2.8.1 - '@antv/g-plugin-canvas-picker@2.1.12': dependencies: '@antv/g-lite': 2.2.10 @@ -17092,17 +17066,6 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 - '@antv/g-plugin-canvas-picker@2.1.27': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/g-math': 3.0.1 - '@antv/g-plugin-canvas-path-generator': 2.1.22 - '@antv/g-plugin-canvas-renderer': 2.3.3 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - gl-matrix: 3.4.3 - tslib: 2.8.1 - '@antv/g-plugin-canvas-renderer@2.2.12': dependencies: '@antv/g-lite': 2.2.10 @@ -17125,17 +17088,6 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 - '@antv/g-plugin-canvas-renderer@2.3.3': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/g-math': 3.0.1 - '@antv/g-plugin-canvas-path-generator': 2.1.22 - '@antv/g-plugin-image-loader': 2.1.26 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - gl-matrix: 3.4.3 - tslib: 2.8.1 - '@antv/g-plugin-dom-interaction@2.1.15': dependencies: '@antv/g-lite': 2.2.10 @@ -17148,12 +17100,6 @@ snapshots: '@babel/runtime': 7.27.0 tslib: 2.8.1 - '@antv/g-plugin-dom-interaction@2.1.27': - dependencies: - '@antv/g-lite': 2.3.2 - '@babel/runtime': 7.27.6 - tslib: 2.8.1 - '@antv/g-plugin-dragndrop@2.0.32': dependencies: '@antv/g-lite': 2.2.16 @@ -17190,14 +17136,6 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 - '@antv/g-plugin-html-renderer@2.1.27': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - gl-matrix: 3.4.3 - tslib: 2.8.1 - '@antv/g-plugin-image-loader@2.1.12': dependencies: '@antv/g-lite': 2.2.10 @@ -17214,14 +17152,6 @@ snapshots: gl-matrix: 3.4.3 tslib: 2.8.1 - '@antv/g-plugin-image-loader@2.1.26': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - gl-matrix: 3.4.3 - tslib: 2.8.1 - '@antv/g-plugin-rough-canvas-renderer@2.0.33': dependencies: '@antv/g-canvas': 2.0.33 @@ -17247,20 +17177,13 @@ snapshots: '@babel/runtime': 7.27.0 tslib: 2.8.1 - '@antv/g-web-animations-api@2.1.28': - dependencies: - '@antv/g-lite': 2.3.2 - '@antv/util': 3.3.10 - '@babel/runtime': 7.27.6 - tslib: 2.8.1 - '@antv/g2@5.1.21': dependencies: '@antv/component': 2.0.1 '@antv/coord': 0.4.7 '@antv/event-emitter': 0.1.3 - '@antv/g': 6.1.28 - '@antv/g-canvas': 2.0.48 + '@antv/g': 6.3.1 + '@antv/g-canvas': 2.2.0 '@antv/g-plugin-dragndrop': 2.0.5 '@antv/path-util': 3.0.1 '@antv/scale': 0.4.16 @@ -17284,8 +17207,8 @@ snapshots: '@antv/component': 2.1.2 '@antv/coord': 0.4.7 '@antv/event-emitter': 0.1.3 - '@antv/g': 6.1.28 - '@antv/g-canvas': 2.0.48 + '@antv/g': 6.3.1 + '@antv/g-canvas': 2.2.0 '@antv/g-plugin-dragndrop': 2.0.32 '@antv/scale': 0.4.16 '@antv/util': 3.3.10 @@ -17300,8 +17223,8 @@ snapshots: '@antv/coord': 0.4.7 '@antv/event-emitter': 0.1.3 '@antv/expr': 1.0.2 - '@antv/g': 6.1.28 - '@antv/g-canvas': 2.0.48 + '@antv/g': 6.3.1 + '@antv/g-canvas': 2.2.0 '@antv/g-plugin-dragndrop': 2.0.36 '@antv/scale': 0.4.16 '@antv/util': 3.3.10 @@ -17317,13 +17240,13 @@ snapshots: '@antv/g-web-animations-api': 2.1.21 '@babel/runtime': 7.27.0 - '@antv/g@6.1.28': + '@antv/g@6.3.1': dependencies: - '@antv/g-camera-api': 2.0.41 - '@antv/g-dom-mutation-observer-api': 2.0.38 - '@antv/g-lite': 2.3.2 - '@antv/g-web-animations-api': 2.1.28 + '@antv/g-lite': 2.7.0 + '@antv/util': 3.3.10 '@babel/runtime': 7.27.6 + gl-matrix: 3.4.3 + html2canvas: 1.4.1 '@antv/path-util@3.0.1': dependencies: @@ -23104,6 +23027,8 @@ snapshots: base64-arraybuffer@0.1.5: {} + base64-arraybuffer@1.0.2: {} + base64-js@1.5.1: {} base@0.11.2: @@ -24206,6 +24131,10 @@ snapshots: dependencies: hyphenate-style-name: 1.1.0 + css-line-break@2.1.0: + dependencies: + utrie: 1.0.2 + css-loader@6.7.1: dependencies: icss-utils: 5.1.0(postcss@8.5.3) @@ -27545,6 +27474,11 @@ snapshots: html-whitespace-sensitive-tag-names@2.0.0: {} + html2canvas@1.4.1: + dependencies: + css-line-break: 2.1.0 + text-segmentation: 1.0.3 + html2sketch@1.0.2: dependencies: '@sketch-hq/sketch-file-format-ts': 6.5.0 @@ -35881,6 +35815,10 @@ snapshots: text-extensions@2.4.0: {} + text-segmentation@1.0.3: + dependencies: + utrie: 1.0.2 + text-table@0.2.0: {} textextensions@2.6.0: {} @@ -36582,6 +36520,10 @@ snapshots: utils-merge@1.0.1: {} + utrie@1.0.2: + dependencies: + base64-arraybuffer: 1.0.2 + uuid@3.4.0: {} uuid@8.3.2: {}