UNPKG

s2-dbi

Version:

effective spreadsheet render core lib

1,501 lines (1,387 loc) 165 kB
import type { BBox } from '@antv/g-canvas'; import { Canvas } from '@antv/g-canvas'; import type * as CSS_2 from 'csstype'; import { DebouncedFunc } from 'lodash'; import EE from '@antv/event-emitter'; import { Event as GEvent } from '@antv/g-canvas'; import { GM } from '@antv/g-gesture'; import { Group } from '@antv/g-canvas'; import type { IElement } from '@antv/g-canvas'; import { IGroup } from '@antv/g-canvas'; import type { IShape } from '@antv/g-canvas'; import { IShape as IShape_2 } from '@antv/g-base'; import { MemoizedFunction } from 'lodash'; import { Omit as Omit_2 } from 'lodash'; import { Point } from '@antv/g-canvas'; import { Shape } from '@antv/g-canvas'; import { ShapeAttrs } from '@antv/g-canvas'; import type { ShapeCfg } from '@antv/g-canvas'; import type { SimpleBBox } from '@antv/g-canvas'; import { Timer } from 'd3-timer'; import { Wheel } from '@antv/g-gesture'; /** * 根据文字样式计算文字实际绘制起始 * * 以 textAlign=left 为例,g 绘制时取 text 最左侧的坐标值作为基准坐标 * * 计算前: 计算后: * startX = textAreaRange.start = 中心点 startX = 最左侧坐标 * * textAreaRange.start startX * | | * v v * +----------------------------+ +----------------------------+ * | +------------------+ | |+------------------+ | * | | text | icon | | || text | icon | | * | +------------------+ | |+------------------+ | * +----------------------------+ +----------------------------+ * <------------------> * textAndIconSpace * <----------------------------> * textAreaRange.width * * @param textAreaRange 文本&icon 绘制坐标 * @param actualTextWidth 文本实际宽度 * @param actionIconSpace icon 区域实际宽度 * @param textAlign 对齐样式 * @returns 文字绘制起点坐标 */ export declare const adjustColHeaderScrollingTextPosition: (textAreaRange: AreaRange, actualTextWidth: number, actionIconSpace: number, textAlign: TextAlign) => number; /** * 根据单元格文字样式调整 viewport range,使文字在滚动时不会贴边展示 * * 以 textAlign=left 情况为例,由大到小的矩形分别是 viewport、cellContent、cellText * 左图是未调整前,滚动相交判定在 viewport 最左侧,即 colCell 滚动到 viewport 左侧后,文字会贴左边绘制 * 右图是调整后,range.start 提前了 padding.left 个像素,文字与 viewport 有一定间隙更加美观 * * range.start range.start * | | * | range.width | range.width * v<----------------------> v<------------------> * * +-----------------------+ +-----------------------+ * | viewport | | viewport | * +-------------------+ | +-------------------+ | * | +---------+ | | | | +---------+ | | * | | text | | | | | | text | | | * | +---------+ | | | | +---------+ | | * +-------------------+ | +-------------------+ | * +-----------------------+ +-----------------------+ * * <--> * padding.left * * @param viewport 原始 viewport * @param textAlign 文字样式 * @param textPadding 单元格 padding 样式 * @returns viewport range */ export declare const adjustColHeaderScrollingViewport: (viewport: AreaRange, textAlign: TextAlign, textPadding?: Padding) => { start: number; width: number; }; export declare const afterSelectDataCells: OnUpdateCells; export declare enum Aggregation { SUM = "SUM", MIN = "MIN", MAX = "MAX", AVG = "AVG" } export declare interface AreaRange { start: number; width: number; } /** * 自动格式化 * 规则 * 1,小于1w,使用逗号分割,例如 3,459 * 2,大于1w,使用语义化,例如 3.2万,3.4亿 2,234万 * @param v * @param fixed * @param formatter */ export declare const auto: (v: number, fixed?: number, formatter?: (string[] | number[])[]) => string; export declare interface AutoAdjustPositionOptions { position: TooltipPosition; tooltipContainer: HTMLElement; spreadsheet: SpreadSheet; autoAdjustBoundary: TooltipAutoAdjustBoundary; } export declare const BACK_GROUND_GROUP_CONTAINER_Z_INDEX = 0; export declare interface Background { opacity?: number; color?: string; } export declare interface BarTheme { intervalPadding?: number; fill?: string; opacity?: number; } declare abstract class BaseBBox implements BBox { protected spreadsheet: SpreadSheet; protected facet: BaseFacet; protected layoutResult: LayoutResult; x: number; y: number; minX: number; minY: number; maxX: number; maxY: number; width: number; height: number; originalWidth: number; originalHeight: number; viewportHeight: number; viewportWidth: number; constructor(facet: BaseFacet, autoCalculateBBoxWhenCreated?: boolean); abstract calculateBBox(): void; } /** * 刷选基类, dataCell, rowCell, colCell 支持滚动刷选 */ export declare class BaseBrushSelection extends BaseEvent implements BaseEventImplement { displayedCells: S2CellType[]; prepareSelectMaskShape: IShape; startBrushPoint: BrushPoint; endBrushPoint: BrushPoint; brushRangeCells: S2CellType[]; brushSelectionStage: InteractionBrushSelectionStage; brushSelectionMinimumMoveDistance: number; scrollAnimationComplete: boolean; mouseMoveDistanceFromCanvas: number; bindEvents(): void; protected getPrepareSelectMaskTheme(): InteractionStateTheme; protected initPrepareSelectMaskShape(): void; protected setBrushSelectionStage(stage: InteractionBrushSelectionStage): void; protected isPointInCanvas(point: Point): boolean; private setMoveDistanceFromCanvas; formatBrushPointForScroll: (delta: Point, isRowHeader?: boolean) => { x: { value: number; needScroll: boolean; }; y: { value: number; needScroll: boolean; }; }; rectanglesIntersect: (rect1: Rect, rect2: Rect) => boolean; private autoScrollIntervalId; protected autoScrollConfig: BrushAutoScrollConfig; validateYIndex: (yIndex: number) => number; validateXIndex: (xIndex: number) => number; adjustNextColIndexWithFrozen: (colIndex: number, dir: ScrollDirection) => any; adjustNextRowIndexWithFrozen: (rowIndex: number, dir: ScrollDirection) => any; getWillScrollRowIndexDiff: (dir: ScrollDirection) => number; getDefaultWillScrollToRowIndex: (dir: ScrollDirection) => number; protected getWillScrollToRowIndex: (dir: ScrollDirection) => number; private getNextScrollDelta; private onScrollAnimationComplete; private autoScroll; protected handleScroll: DebouncedFunc<(x: number, y: number, isRowHeader?: any) => void>; protected clearAutoScroll: () => void; protected resetDrag(): void; isValidBrushSelection(): boolean; protected setDisplayedCells(): void; protected updatePrepareSelectMask(): void; hidePrepareSelectMaskShape(): void; protected resetScrollDelta(): void; protected getBrushPoint(event: GEvent): BrushPoint; getBrushRange(): BrushRange; protected getBrushRangeCells(): S2CellType[]; protected onUpdateCells: OnUpdateCells; private showPrepareSelectedCells; protected mouseDown(event: GEvent): void; protected addBrushIntercepts(): void; protected bindMouseUp(enableScroll?: boolean): void; protected renderPrepareSelected: (point: Point) => void; autoBrushScroll(point: Point, isRowHeader?: boolean): boolean; emitBrushSelectionEvent(event: S2Event, scrollBrushRangeCells: S2CellType[]): void; getVisibleBrushRangeCells(nodeId: string): S2CellType<ViewMeta>; protected isInBrushRange(meta: ViewMeta | Node_2): boolean; protected bindMouseDown(): void; protected bindMouseMove(): void; protected updateSelectedCells(): void; protected getPrepareSelectMaskPosition(brushRange: BrushRange): Point; } export declare abstract class BaseCell<T extends SimpleBBox> extends Group { protected meta: T; protected spreadsheet: SpreadSheet; protected theme: S2Theme; protected backgroundShape: IShape; protected textShape: IShape; protected textShapes: IShape[]; protected linkFieldShape: IShape; protected actualText: string; protected actualTextWidth: number; protected conditions: Conditions; protected conditionIntervalShape: IShape; protected conditionIconShape: GuiIcon; protected conditionIconShapes: GuiIcon[]; protected stateShapes: Map<StateShapeLayer, IShape>; constructor(meta: T, spreadsheet: SpreadSheet, ...restOptions: unknown[]); getMeta(): T; setMeta(viewMeta: T): void; getIconStyle(): IconTheme; getTextAndIconPosition(iconCount?: number): { text: { x: number; y: number; }; icon: { x: number; y: number; }; }; getActualText(): string; getFieldValue(): string; /** * in case there are more params to be handled * @param options any type's rest params */ protected handleRestOptions(...options: unknown[]): void; /** * Return the type of the cell */ abstract get cellType(): CellTypes; /** * Determine how to render this cell area */ protected abstract initCell(): void; /** * Update cell's selected state */ abstract update(): void; protected abstract getTextStyle(): TextTheme; protected abstract getFormattedFieldValue(): FormatResult; protected abstract getMaxTextWidth(): number; protected abstract getTextPosition(): Point; protected abstract findFieldCondition(conditions: Condition[]): Condition; protected abstract mappingValue(condition: Condition): MappingResult; protected shouldInit(): boolean; getStyle<K extends keyof S2Theme = keyof CellThemes>(name?: K): DefaultCellTheme | S2Theme[K]; protected getResizeAreaStyle(): ResizeArea; protected shouldDrawResizeAreaByType(type: keyof ResizeInteractionOptions, cell: S2CellType): boolean | ((cell: S2CellType<ViewMeta>) => boolean) | ResizeType | ((resizeInfo: ResizeInfo) => boolean); getCellArea(): { x: number; y: number; height: number; width: number; }; getContentArea(): { x: number; y: number; width: number; height: number; }; protected getIconPosition(iconCount?: number): { x: number; y: number; }; protected drawTextShape(): void; protected drawLinkFieldShape(showLinkFieldShape: boolean, linkFillColor: string): void; protected getLinkFieldStyle(): string; protected drawLinkField(meta: Node_2 | ViewMeta): void; updateByState(stateName: InteractionStateName, cell: S2CellType): void; protected getInteractiveBorderShapeStyle<T>(style: T & number): { x: number; y: number; width: number; height: number; }; hideInteractionShape(): void; clearUnselectedState(): void; getTextShape(): IShape; getTextShapes(): IShape[]; addTextShape(textShape: IShape): void; getConditionIconShape(): GuiIcon; getConditionIconShapes(): GuiIcon[]; addConditionIconShape(iconShape: GuiIcon): void; resetTextAndConditionIconShapes(): void; get cellConditions(): Conditions; drawConditionIconShapes(): void; getTextConditionFill(textStyle: TextTheme): string; protected getCrossBackgroundColor(rowIndex: number): { backgroundColorOpacity: number; backgroundColor: string; }; } export declare interface BaseChartData { type: MiniChartTypes; data: Data[]; encode?: { x: keyof Data; y: keyof Data; }; } export declare abstract class BaseDataSet { fields: Fields; meta: Meta[]; originData: DataType[]; totalData: DataType[]; indexesData: DataType[][] | DataType[]; sortParams: SortParams; filterParams: FilterParam[]; protected spreadsheet: SpreadSheet; constructor(spreadsheet: SpreadSheet); protected displayData: DataType[]; /** * 查找字段信息 */ getFieldMeta: ((field: string, meta?: Meta[]) => Meta) & MemoizedFunction; /** * 获得字段名称 * @param field */ getFieldName(field: string): string; /** * 获得字段格式方法 * @param field */ getFieldFormatter(field: string): Formatter; /** * 获得字段描述 * @param field */ getFieldDescription(field: string): string; setDataCfg(dataCfg: S2DataConfig): void; processMeta(meta: Meta[], defaultExtraFieldText: string): Meta[]; getDisplayDataSet(): DataType[]; isEmpty(): boolean; getValueRangeByField(field: string): ValueRange; /** ******************NEED IMPLEMENT BY USER CASE************************ */ /** * Try to process dataConfig in different mode * @param dataCfg */ abstract processDataCfg(dataCfg: S2DataConfig): S2DataConfig; /** * 1、query !== null * province city => field * 辽宁省 * 达州市 * 芜湖市 * field = province * query = {province: '辽宁省'} * => [达州市,芜湖市] * * 2、query = null * query param is not necessary, when just * get some field's all dimension values * * @param field current dimensions * @param query dimension value query */ abstract getDimensionValues(field: string, query?: DataType): string[]; /** * province city type * 辽宁省 * 达州市 A * B * 芜湖市 C * 浙江省 * 杭州市 B * D * 宁波市 E * query = {province: "浙江省"} * field = 'type' * * => [B,D,E] * * @param field current dimensions * @param query dimension value query */ abstract getTotalDimensionValues(field: string, query?: DataType): string[]; /** * In most cases, this function to get the specific * cross data cell data * @param params */ abstract getCellData(params: CellDataParams): DataType; /** * To get a row or column cells data; * if query is empty, return all data * @param query * @param isTotals * @param isRow * @param drillDownFields */ abstract getMultiData(query: DataType, isTotals?: boolean, isRow?: boolean, drillDownFields?: string[]): DataType[]; moreThanOneValue(): boolean; /** * get a row cells data including cell * @param cells */ abstract getRowData(cells: CellMeta): RowData; } export declare abstract class BaseEvent { spreadsheet: SpreadSheet; constructor(spreadsheet: SpreadSheet); getCellAppendInfo<T extends Record<string, any> = CellAppendInfo>(eventTarget: GEvent['target']): T; isLinkFieldText: (eventTarget: GEvent['target']) => boolean; reset(): void; abstract bindEvents(): void; } export declare interface BaseEventImplement { bindEvents: () => void; } declare abstract class BaseFacet { spreadsheet: SpreadSheet; cornerBBox: CornerBBox; panelBBox: PanelBBox; backgroundGroup: IGroup; panelGroup: IGroup; foregroundGroup: IGroup; cfg: SpreadSheetFacetCfg; layoutResult: LayoutResult; viewCellWidths: number[]; viewCellHeights: ViewCellHeights; protected mobileWheel: Wheel; protected timer: Timer; hScrollBar: ScrollBar; hRowScrollBar: ScrollBar; vScrollBar: ScrollBar; rowHeader: RowHeader; columnHeader: ColHeader; cornerHeader: CornerHeader; rowIndexHeader: SeriesNumberHeader; centerFrame: Frame; gridInfo: GridInfo; protected abstract doLayout(): LayoutResult; abstract getContentHeight(): number; abstract getViewCellHeights(layoutResult: LayoutResult): ViewCellHeights; protected scrollFrameId: ReturnType<typeof requestAnimationFrame>; get scrollBarTheme(): ScrollBarTheme; get scrollBarSize(): number; protected preCellIndexes: PanelIndexes; constructor(cfg: SpreadSheetFacetCfg); protected getCellCustomWidth(node: Node_2, width: CellCustomWidth): number; protected getCellDraggedWidth(node: Node_2): number; hideScrollBar: () => void; delayHideScrollBar: DebouncedFunc<() => void>; delayHideScrollbarOnMobile: () => void; showVerticalScrollBar: () => void; showHorizontalScrollBar: () => void; onContainerWheel: () => void; onContainerWheelForPc: () => void; onContainerWheelForMobile: () => void; bindEvents: () => void; /** * Start render, call from outside */ render(): void; /** * 在每次render, 校验scroll offset是否在合法范围中 * 比如在滚动条已经滚动到100%的状态的前提下:( maxAvailableScrollOffsetX = colsHierarchy.width - viewportBBox.width ) * 此时changeSheetSize,sheet从 small width 变为 big width * 导致后者 viewport 区域更大,其结果就是后者的 maxAvailableScrollOffsetX 更小 * 此时就需要重置 scrollOffsetX,否则就会导致滚动过多,出现空白区域 */ protected adjustScrollOffset(): void; getSeriesNumberWidth(): number; getCanvasHW(): { width: number; height: number; }; updateScrollOffset(offsetConfig: OffsetConfig): void; getPaginationScrollY(): number; destroy(): void; setScrollOffset: (scrollOffset: ScrollOffset) => void; getScrollOffset: () => ScrollOffset; emitPaginationEvent: () => void; private unbindEvents; clipPanelGroup: () => void; calculateCellWidthHeight: () => void; /** * The purpose of this rewrite is to take into account that when rowHeader supports scrollbars the panel viewable area must vary with the horizontal distance of the scroll * @param scrollX * @param scrollY * @public */ calculateXYIndexes(scrollX: number, scrollY: number): PanelIndexes; getRealScrollX: (scrollX: number, hRowScroll?: number) => number; protected calculateCornerBBox(): void; protected calculatePanelBBox: () => void; getRealWidth: () => number; getCellRange(): { start: number; end: number; }; getRealHeight: () => number; clearAllGroup: () => void; scrollWithAnimation: (offsetConfig?: OffsetConfig, duration?: number, cb?: () => void) => void; scrollImmediately: (offsetConfig?: OffsetConfig) => void; /** * * @param skipScrollEvent 不触发 S2Event.GLOBAL_SCROLL */ startScroll: (skipScrollEvent?: boolean) => void; getRendererHeight: () => number; private getAdjustedScrollOffset; renderRowScrollBar: (rowHeaderScrollX: number) => void; getValidScrollBarOffset: (offset: number, maxOffset: number) => number; renderHScrollBar: (width: number, realWidth: number, scrollX: number) => void; private getScrollbarPosition; renderVScrollBar: (height: number, realHeight: number, scrollY: number) => void; getScrollBarOffset: (offset: number, scrollbar: ScrollBar) => number; isScrollOverThePanelArea: ({ offsetX, offsetY }: CellScrollOffset) => boolean; isScrollOverTheCornerArea: ({ offsetX, offsetY }: CellScrollOffset) => boolean; updateHorizontalRowScrollOffset: ({ offset, offsetX, offsetY, }: CellScrollOffset) => void; updateHorizontalScrollOffset: ({ offset, offsetX, offsetY, }: CellScrollOffset) => void; isScrollToLeft: ({ deltaX, offsetX, offsetY }: CellScrollOffset) => boolean; isScrollToRight: ({ deltaX, offsetX, offsetY }: CellScrollOffset) => boolean; isScrollToTop: (deltaY: number) => boolean; isScrollToBottom: (deltaY: number) => boolean; isVerticalScrollOverTheViewport: (deltaY: number) => boolean; isHorizontalScrollOverTheViewport: (scrollOffset: CellScrollOffset) => boolean; /** 在当前表格滚动分两种情况: 1. 当前表格无滚动条: 无需阻止外部容器滚动 2. 当前表格有滚动条: - 未滚动到顶部或底部: 当前表格滚动, 阻止外部容器滚动 - 滚动到顶部或底部: 恢复外部容器滚动 */ isScrollOverTheViewport: (scrollOffset: CellScrollOffset) => boolean; cancelScrollFrame: () => boolean; clearScrollFrameIdOnMobile: () => void; /** https://developer.mozilla.org/zh-CN/docs/Web/CSS/overscroll-behavior 阻止外部容器滚动: 表格是虚拟滚动, 这里按照标准模拟浏览器的 [overscroll-behavior] 实现 1. auto => 只有在滚动到表格顶部或底部时才触发外部容器滚动 1. contain => 默认的滚动边界行为不变(“触底”效果或者刷新),但是临近的滚动区域不会被滚动链影响到 2. none => 临近滚动区域不受到滚动链影响,而且默认的滚动到边界的表现也被阻止 所以只要不为 `auto`, 或者表格内, 都需要阻止外部容器滚动 */ private stopScrollChainingIfNeeded; private stopScrollChaining; onWheel: (event: WheelEvent) => void; protected clip(scrollX: number, scrollY: number): void; /** * Translate panelGroup, rowHeader, cornerHeader, columnHeader ect * according to new scroll offset * @param scrollX * @param scrollY * @param hRowScroll * @protected */ protected translateRelatedGroups(scrollX: number, scrollY: number, hRowScroll: number): void; addCell: (cell: S2CellType<ViewMeta>) => void; realCellRender: (scrollX: number, scrollY: number) => void; protected init(): void; protected renderBackground(): void; /** * Render all scrollbars, default horizontal scrollbar only control viewport * area(it means not contains row header) * 1. individual row scrollbar * 2. horizontal scroll bar(can control whether contains row header) * 3. vertical scroll bar */ protected renderScrollBars(): void; /** * Render all headers in {@link #foregroundGroup}, contains: * 1. row header * 2. col header * 3. center frame * 4. corner header * 5. series number header */ protected renderHeaders(): void; protected getRowHeader(): RowHeader; protected getColHeader(): ColHeader; protected getCornerHeader(): CornerHeader; protected getSeriesNumberHeader(): SeriesNumberHeader; protected getCenterFrame(): Frame; protected getGridInfo: () => { cols: number[]; rows: any[]; }; updatePanelScrollGroup(): void; /** * * @param skipScrollEvent: 如true则不触发GLOBAL_SCROLL事件 * During scroll behavior, first call to this method fires immediately and then on interval. * @protected */ protected dynamicRenderCell(skipScrollEvent?: boolean): void; private emitScrollEvent; protected onAfterScroll: DebouncedFunc<() => void>; protected saveInitColumnLeafNodes(columnNodes?: Node_2[]): void; getHiddenColumnsInfo(columnNode: Node_2): HiddenColumnsInfo | null; getCornerNodes(): Node_2[]; } /** * New Base Header for all headers(cornerHeader, rowHeader, colHeader) * NOTE: Do not use this.cfg(which lays in group) to get header config, * use {@see headerConfig} instead */ declare abstract class BaseHeader<T extends BaseHeaderConfig> extends Group { protected headerConfig: T; protected constructor(cfg: T); getConfig(): T; /** * 清空热区,为重绘做准备,防止热区重复渲染 * @param type 当前重绘的header类型 */ protected clearResizeAreaGroup(type: string): void; render(type: string): void; /** * Scroll header group's x,y * @param scrollX hScrollBar horizontal offset * @param scrollY hScrollBar vertical offset * @param type */ onScrollXY(scrollX: number, scrollY: number, type: string): void; /** * Only call when hRowScrollBar scrolls * @param rowHeaderScrollX hRowScrollbar horizontal offset * @param type */ onRowScrollX(rowHeaderScrollX: number, type: string): void; protected abstract layout(): any; protected abstract offset(): any; protected abstract clip(): any; clear(): void; /** * Check whether header cell in viewPort * @param gridPos * @param gridSize * @param viewportPos * @param viewportSize */ protected isHeaderCellInViewport: (gridPos: any, gridSize: any, viewportPos: any, viewportSize: any) => boolean; } /** * Base header config interface */ declare interface BaseHeaderConfig { scrollX?: number; scrollY?: number; width: number; height: number; originalWidth?: number; originalHeight?: number; viewportWidth: number; viewportHeight: number; position: Point; data: Node_2[]; spreadsheet: SpreadSheet; sortParam?: SortParam; } declare interface BaseNodeConfig { id: string; key: string; value: string; label?: string; level?: number; rowIndex?: number; colIndex?: number; parent?: Node_2; isTotals?: boolean; isSubTotals?: boolean; isCollapsed?: boolean; isGrandTotals?: boolean; isTotalRoot?: boolean; hierarchy?: Hierarchy; isPivotMode?: boolean; seriesNumberWidth?: number; field?: string; spreadsheet?: SpreadSheet; query?: Record<string, any>; belongsCell?: S2CellType; isTotalMeasure?: boolean; inCollapseNode?: boolean; isGridCollapsed?: boolean; isLeaf?: boolean; x?: number; y?: number; width?: number; height?: number; padding?: number; children?: Node_2[]; hiddenColumnsInfo?: HiddenColumnsInfo | null; extra?: Record<string, any>; } /** * Base tooltips component */ export declare class BaseTooltip { visible: boolean; spreadsheet: SpreadSheet; container: HTMLElement; options: TooltipShowOptions; position: TooltipPosition; constructor(spreadsheet: SpreadSheet); show<T = Element | string>(showOptions: TooltipShowOptions<T>): void; hide(): void; destroy(): void; renderContent<T = TooltipContentType>(content: T): void; clearContent(): void; disablePointerEvent(): void; private resetPosition; private getContainer; } export declare interface BaseTooltipConfig<T = TooltipContentType, Icon = Element | string, Text = string> { showTooltip?: boolean; content?: TooltipShowOptions<T>['content']; operation?: TooltipOperation<Icon, Text>; autoAdjustBoundary?: TooltipAutoAdjustBoundary; renderTooltip?: (spreadsheet: SpreadSheet) => BaseTooltip; adjustPosition?: (positionInfo: TooltipPositionInfo) => TooltipPosition; getContainer?: () => HTMLElement; className?: string | string[]; style?: CSS_2.Properties; } export declare const BRUSH_AUTO_SCROLL_INITIAL_CONFIG: { x: { value: number; scroll: boolean; }; y: { value: number; scroll: boolean; }; }; export declare interface BrushAutoScrollConfig { x: BrushAutoScrollConfigItem; y: BrushAutoScrollConfigItem; } export declare interface BrushAutoScrollConfigItem { value: number; scroll: boolean; } export declare interface BrushPoint { rowIndex: number; colIndex: number; x: number; y: number; scrollX?: number; scrollY?: number; /** 用于标记 row cell 和 col cell 点的 x, y 坐标 */ headerX?: number; headerY?: number; } export declare interface BrushRange { start: BrushPoint; end: BrushPoint; width: number; height: number; } export declare interface BrushSelection { data?: boolean; row?: boolean; col?: boolean; } export declare interface BrushSelectionInfo { dataBrushSelection: boolean; rowBrushSelection: boolean; colBrushSelection: boolean; } export declare const buildTableHierarchy: (params: TableHeaderParams) => void; export declare interface BulletTheme { progressBar: { widthPercent: number; height: number; innerHeight: number; }; comparativeMeasure: { width: number; height: number; fill?: string; color?: string; opacity?: number; }; rangeColors: RangeColors; backgroundColor: string; } export declare interface BulletValue { type: MiniChartTypes.Bullet; measure: number | string; target: number | string; [key: string]: unknown; } export declare interface CalcTotals { aggregation?: Aggregation; calcFunc?: (query: DataType, arr: DataType[]) => number; } declare type CanvasEventHandler = (event: GEvent) => void; export declare interface CellAppendInfo<T = Node_2> extends Partial<ResizeInfo> { isLinkFieldText?: boolean; cellData?: T; } export declare interface CellAttrs<T extends Record<string, unknown> = Node_2> extends ShapeAttrs { text?: string; appendInfo?: CellAppendInfo<T>; } export declare enum CellBorderPosition { TOP = "TOP", BOTTOM = "BOTTOM", LEFT = "LEFT", RIGHT = "RIGHT" } export declare type CellCallback<T extends BaseHeaderConfig> = (node: Node_2, spreadsheet: SpreadSheet, headerConfig: T) => S2CellType; export declare interface CellCfg { width?: number; height?: number; valuesCfg?: { originalValueField?: string; widthPercent?: number[]; showOriginalValue?: boolean; }; } export declare type CellCustomWidth = number | ((node: Node_2) => number); export declare interface CellDataParams { query: DataType; isTotals?: boolean; rowNode?: Node_2; isRow?: boolean; totalStatus?: TotalStatus; } export declare interface CellMeta { id: string; colIndex: number; rowIndex: number; type: CellTypes; rowQuery?: Record<string, any>; [key: string]: unknown; } export declare interface CellScrollOffset { deltaX?: number; deltaY?: number; offset?: number; offsetX: number; offsetY: number; } export declare type CellScrollPosition = Required<ScrollOffset>; export declare interface CellTheme { crossBackgroundColor?: string; backgroundColor?: string; backgroundColorOpacity?: number; horizontalBorderColor?: string; horizontalBorderColorOpacity?: number; verticalBorderColor?: string; verticalBorderColorOpacity?: number; horizontalBorderWidth?: number; verticalBorderWidth?: number; padding?: Padding; interactionState?: InteractionState; miniBarChartHeight?: number; miniBarChartFillColor?: string; } export declare type CellThemes = { [K in CellTypes]?: DefaultCellTheme; }; export declare enum CellTypes { DATA_CELL = "dataCell", HEADER_CELL = "headerCell", ROW_CELL = "rowCell", COL_CELL = "colCell", CORNER_CELL = "cornerCell", MERGED_CELL = "mergedCell" } export declare interface CheckAccordQueryParams { dimensionValues: string; query: DataType; dimensions: string[]; field: string; } export declare const checkIsLinkField: (linkFields: string[] | ((meta: Node_2 | ViewMeta) => boolean), meta: Node_2 | ViewMeta) => boolean; /** * @desc clear the interaction state information * @param spreadsheet sheet instance */ export declare const clearState: (spreadsheet: SpreadSheet) => boolean; export declare class ColBrushSelection extends BaseBrushSelection { displayedCells: ColCell[]; brushRangeCells: ColCell[]; bindEvents(): void; protected bindMouseDown(): void; protected isPointInCanvas(point: { x: number; y: number; }): boolean; protected bindMouseMove(): void; protected setDisplayedCells(): void; /** * 用户判断 colCell 是否在当前刷选的范围内 * @param meta colCell 位置等属性存储的对象 * @returns boolean */ protected isInBrushRange(meta: ViewMeta | Node_2): boolean; protected updateSelectedCells(): void; protected addBrushIntercepts(): void; protected onUpdateCells: OnUpdateCells; } export declare class ColCell extends HeaderCell { protected headerConfig: ColHeaderConfig; /** 文字绘制起始坐标 */ protected textPosition: Point; get cellType(): CellTypes; protected initCell(): void; protected drawInteractiveBgShape(): void; /** * 绘制hover悬停,刷选的外框 */ protected drawInteractiveBorderShape(): void; protected getMaxTextWidth(): number; protected getIconPosition(): Point; protected isBolderText(): boolean; protected getTextPosition(): Point; protected getActionIconsWidth(): number; protected getColResizeAreaKey(): string; protected getColResizeArea(): IGroup; protected getHorizontalResizeAreaName(): string; protected drawHorizontalResizeArea(): void; protected shouldAddVerticalResizeArea(): boolean; protected getVerticalResizeAreaOffset(): { x: number; y: number; }; protected drawVerticalResizeArea(): void; protected drawResizeArea(): void; protected drawHorizontalBorder(): void; protected drawVerticalBorder(dir: CellBorderPosition): void; protected drawBorders(): void; protected hasHiddenColumnCell(): boolean; protected getExpandIconTheme(): IconTheme; protected addExpandColumnSplitLine(): void; protected addExpandColumnIconShapes(): void; protected addExpandColumnIcons(): void; private addExpandColumnIcon; protected getExpandColumnIconConfig(isLastColumn: boolean): { x: number; y: number; width: number; height: number; }; protected isLastColumn(): boolean; protected isAllDisplaySiblingNodeHidden(): HiddenColumnsInfo; } export declare interface ColCfg { width?: CellCustomWidth; height?: number; widthByFieldValue?: Record<string, number>; heightByField?: Record<string, number>; hideMeasureColumn?: boolean; } /** * Column Header for SpreadSheet */ export declare class ColHeader extends BaseHeader<ColHeaderConfig> { protected scrollGroup: IGroup; protected background: IShape; constructor(cfg: ColHeaderConfig); /** * Make colHeader scroll with hScrollBar * @param scrollX horizontal offset * @param cornerWidth only has real meaning when scroll contains rowCell * @param type */ onColScroll(scrollX: number, type: string): void; protected clip(): void; clear(): void; protected getCellInstance(item: Node_2, spreadsheet: SpreadSheet, headerConfig: ColHeaderConfig): ColCell; protected getCellGroup(node: Node_2): IGroup; protected isColCellInRect(item: Node_2): boolean; protected layout(): void; protected offset(): void; } export declare interface ColHeaderConfig extends BaseHeaderConfig { cornerWidth?: number; scrollContainsRowHeader?: boolean; } export declare type CollapsedRowsType = { collapsedRows: Record<string, boolean> & { [x: number]: any; }; meta?: Node_2; }; export declare interface ColumnNode { key: string; children?: Columns; } export declare type Columns = Array<ColumnNode | string>; /** * One field can hold a condition */ export declare interface Condition { field?: string | RegExp; mapping: MappingFunction; } export declare interface Conditions { text?: Condition[]; background?: Condition[]; interval?: Condition[]; icon?: IconCondition[]; } export declare const convertString: (v: string) => string; export declare type Copyable = CopyableItem | CopyableItem[]; export declare type CopyableItem = { type: CopyMIMEType; content: string; }; /** * Copy data * @param sheetInstance * @param formatOptions 是否格式化数据 * @param split */ export declare const copyData: (sheetInstance: SpreadSheet, split: string, formatOptions?: FormatOptions) => string; export declare enum CopyMIMEType { PLAIN = "text/plain", HTML = "text/html" } export declare const copyToClipboard: (data: Copyable | string, sync?: boolean) => Promise<void>; export declare const copyToClipboardByClipboard: (data: Copyable) => Promise<void>; export declare const copyToClipboardByExecCommand: (data: Copyable) => Promise<void>; export declare enum CopyType { ALL = 0, COL = 1, ROW = 2 } export declare const CORNER_MAX_WIDTH_RATIO = 0.5; declare class CornerBBox extends BaseBBox { calculateBBox(): void; private getCornerBBoxOriginalHeight; private getCornerBBoxHeight; private getCornerBBoxWidth; private adjustCornerBBoxWidth; } export declare class CornerCell extends HeaderCell { protected headerConfig: CornerHeaderConfig; protected isBolderText(): boolean; cornerType: CornerNodeType; get cellType(): CellTypes; protected initCell(): void; /** * @deprecated 已废弃, 请使用 drawTextShape */ protected drawCellText(): void; protected drawTextShape(): void; /** * 绘制折叠展开的icon */ protected drawTreeIcon(): void; /** * Render cell horizontalBorder border * @protected */ protected drawBorderShape(): void; protected isLastRowCornerCell(): boolean; protected getResizeAreaEffect(): ResizeAreaEffect.Field | ResizeAreaEffect.Tree | ResizeAreaEffect.Series; protected drawResizeArea(): void; protected showTreeIcon(): boolean; protected getIconPosition(): Point; protected getTreeIconWidth(): number; protected getTextStyle(): TextTheme; protected getMaxTextWidth(): number; protected getTextPosition(): Point; protected getFormattedFieldValue(): FormatResult; protected getCornerText(): string; } export declare class CornerCellClick extends BaseEvent implements BaseEventImplement { bindEvents(): void; private bindCornerCellClick; private getRowNodesByField; private getRowCells; private showTooltip; } /** * Corner Header for SpreadSheet */ export declare class CornerHeader extends BaseHeader<CornerHeaderConfig> { /** * Get corner Header by config * @param panelBBox * @param cornerBBox * @param seriesNumberWidth * @param cfg * @param layoutResult * @param s2 spreadsheet */ static getCornerHeader(panelBBox: PanelBBox, cornerBBox: CornerBBox, seriesNumberWidth: number, cfg: SpreadSheetFacetCfg, layoutResult: LayoutResult, s2: SpreadSheet): CornerHeader; static getCornerNodes(position: Point, width: number, height: number, rows: string[], columns: string[], rowsHierarchy: Hierarchy, colsHierarchy: Hierarchy, dataSet: BaseDataSet, seriesNumberWidth: number, s2: SpreadSheet): Node_2[]; static getTreeCornerText(s2: SpreadSheet): string; constructor(cfg: CornerHeaderConfig); /** * Make cornerHeader scroll with hScrollBar * @param scrollX */ onCorScroll(scrollX: number, type: string): void; destroy(): void; protected layout(): void; protected renderCells(): void; protected offset(): void; protected clip(): void; getNodes(): Node_2[]; } export declare type CornerHeaderCallback = (parent: S2CellType, spreadsheet: SpreadSheet, ...restOptions: unknown[]) => void; export declare interface CornerHeaderConfig extends BaseHeaderConfig { hierarchyType: S2Options['hierarchyType']; hierarchyCollapse: boolean; rows: string[]; columns: string[]; seriesNumberWidth: number; } export declare enum CornerNodeType { Row = "row", Col = "col", Series = "series" } /** * the label names of rows or columns. * Using the ID_SEPARATOR('[&]') to join two labels * when there are hierarchical relations between them. */ export declare interface CustomHeaderCells { cellLabels: string[]; mode?: 'pick' | 'omit'; } export declare interface CustomInteraction { key: string; interaction: InteractionConstructor; } export declare const customMerge: (...objects: unknown[]) => any; export declare interface CustomSVGIcon { name: string; svg: string; } export declare interface CustomTreeItem { key: string; title: string; collapsed?: boolean; description?: string; children?: CustomTreeItem[]; } export declare class CustomTreePivotDataSet extends PivotDataSet { getCellData(params: CellDataParams): DataType; setDataCfg(dataCfg: S2DataConfig): void; processDataCfg(dataCfg: S2DataConfig): S2DataConfig; } export declare type Data = Record<string, DataItem>; /** * DataCell for panelGroup area * ---------------------------- * | | | * |interval text| icon | * | | | * ---------------------------- * There are four conditions({@see BaseCell.conditions}) to determine how to render * 1、background color * 2、icon align in right with size {@link ICON_SIZE} * 3、left rect area is interval(in left) and text(in right) */ export declare class DataCell extends BaseCell<ViewMeta> { get cellType(): CellTypes; get valueRangeByField(): ValueRange; protected handleByStateName(cells: CellMeta[], stateName: InteractionStateName): void; protected handleSearchResult(cells: CellMeta[]): void; protected handleSelect(cells: CellMeta[]): void; protected handleHover(cells: CellMeta[]): void; update(): void; setMeta(viewMeta: ViewMeta): void; protected drawTextShape(): void; protected initCell(): void; /** * 获取默认字体颜色:根据字段标记背景颜色,设置字体颜色 * @param textStyle * @private */ private getDefaultTextFill; protected getTextStyle(): TextTheme; getIconStyle(): IconCfg | undefined; protected drawConditionIntervalShape(): void; protected shouldHideRowSubtotalData(): boolean; protected getFormattedFieldValue(): FormatResult; protected getMaxTextWidth(): number; protected getTextPosition(): Point; getBackgroundColor(): { backgroundColor: string; backgroundColorOpacity: number; intelligentReverseTextColor?: undefined; } | { backgroundColor: string; backgroundColorOpacity: number; intelligentReverseTextColor: boolean; }; /** * Draw cell background */ protected drawBackgroundShape(): void; /** * 绘制hover悬停,刷选的外框 */ protected drawInteractiveBorderShape(): void; /** * Draw interactive color */ protected drawInteractiveBgShape(): void; protected changeRowColSelectState(indexType: ViewMetaIndexType): void; /** * Render cell border controlled by verticalBorder & horizontalBorder * @protected */ protected drawBorderShape(): void; /** * Find current field related condition * @param conditions */ findFieldCondition(conditions: Condition[]): Condition; /** * Mapping value to get condition related attrs * @param condition */ mappingValue(condition: Condition): MappingResult; updateByState(stateName: InteractionStateName): void; clearUnselectedState(): void; private toggleConditionIntervalShapeOpacity; protected drawLeftBorder(): void; } export declare class DataCellBrushSelection extends BaseBrushSelection { displayedCells: DataCell[]; brushRangeCells: DataCell[]; protected bindMouseDown(): void; protected bindMouseMove(): void; protected isInBrushRange(meta: ViewMeta): boolean; getSelectedCellMetas: (brushRange: BrushRange) => CellMeta[]; protected updateSelectedCells(): void; /** * @name 获取刷选 (含滚动后不再可视范围内) 的单元格 * @description DataCell 存在滚动刷选, 由于按需加载的特性, 非可视范围内的单元格已被注销 * 如果在可视范围, 直接返回 DataCell, 非可视范围, 由于实例已被销毁, 构造实例后返回 */ private getScrollBrushRangeCells; protected bindMouseUp(): void; protected getPrepareSelectMaskPosition(brushRange: BrushRange): Point; } export declare type DataCellCallback = (viewMeta: ViewMeta) => S2CellType; export declare class DataCellClick extends BaseEvent implements BaseEventImplement { bindEvents(): void; private bindDataCellClick; private getTooltipOperator; private showTooltip; private emitLinkFieldClickEvent; } export declare class DataCellMultiSelection extends BaseEvent implements BaseEventImplement { private isMultiSelection; bindEvents(): void; reset(): void; private bindKeyboardDown; private bindKeyboardUp; private bindMouseMove; private getSelectedCells; private bindDataCellClick; } export declare type DataItem = SimpleDataItem | MultiData; export declare type DataPathParams = { rowDimensionValues: string[]; colDimensionValues: string[]; isFirstCreate?: boolean; onFirstCreate?: (params: { isRow: boolean; dimension: string; dimensionPath: string[]; }) => void; careUndefined?: boolean; rowFields?: string[]; colFields?: string[]; rowPivotMeta?: PivotMeta; colPivotMeta?: PivotMeta; }; export declare type DataType = Record<string, any>; export declare const DEBUG_HEADER_LAYOUT = "Header Layout"; export declare const DEBUG_TRANSFORM_DATA = "Transform Data"; export declare const DEBUG_VIEW_RENDER = "Data Cell Render"; export declare class DebuggerUtil { private static instance; private debug; static getInstance(): DebuggerUtil; setDebug(debug: boolean): void; debugCallback: (info: string, callback: () => void) => void; logger: (info: string, ...params: unknown[]) => void; } export declare const DEFAULT_DATA_CONFIG: Readonly<S2DataConfig>; export declare const DEFAULT_FONT_COLOR = "#000000"; export declare const DEFAULT_OPTIONS: Readonly<S2Options>; export declare const DEFAULT_PAGE_INDEX = 1; export declare const DEFAULT_STYLE: Readonly<Style>; export declare const DEFAULT_TREE_ROW_WIDTH = 120; export declare const DEFAULT_VALUE_RANGES: {}; export declare interface DefaultCellTheme extends GridAnalysisCellTheme { bolderText?: TextTheme; text?: TextTheme; seriesText?: TextTheme; measureText?: TextTheme; cell?: CellTheme; icon?: IconTheme; miniChart?: MiniChartTheme; seriesNumberWidth?: number; } /** * 对比两个TempMergedCell,返回 mainTempMergedCells 中存在的,但是 otherTempMergedCells 中不存在的的 TempMergedCell * @param mainTempMergedCells * @param compareTempMergedCells */ export declare const differenceTempMergedCells: (mainTempMergedCells: TempMergedCell[], compareTempMergedCells: TempMergedCell[]) => TempMergedCell[]; export declare const download: (str: string, fileName: string) => void; /** * 绘制单元格内的 mini 柱状图 */ export declare const drawBar: (chartData: BaseChartData, cell: S2CellType) => void; /** * 绘制单元格内的 mini子弹图 */ export declare const drawBullet: (value: BulletValue, cell: S2CellType) => void; /** * 绘制单元格内的 条件格式 柱图 */ export declare const drawInterval: (cell: DataCell) => IShape_2; /** * 绘制单元格内的 mini 折线图 */ export declare const drawLine: (chartData: BaseChartData, cell: S2CellType) => void; /** * @desc draw text shape of object * @param cell * @multiData 自定义文本内容 * @useCondition 是否使用条件格式 */ export declare const drawObjectText: (cell: S2CellType, multiData?: MultiData, useCondition?: boolean) => void; export declare const ELLIPSIS_SYMBOL = "..."; export declare interface EmitterType { /** ================ Global ================ */ [S2Event.GLOBAL_ACTION_ICON_CLICK]: CanvasEventHandler; [S2Event.GLOBAL_ACTION_ICON_HOVER]: CanvasEventHandler; [S2Event.GLOBAL_ACTION_ICON_HOVER_OFF]: CanvasEventHandler; [S2Event.GLOBAL_COPIED]: (data: string) => void; [S2Event.GLOBAL_KEYBOARD_DOWN]: KeyboardEventHandler; [S2Event.GLOBAL_KEYBOARD_UP]: KeyboardEventHandler; [S2Event.GLOBAL_MOUSE_UP]: MouseEventHandler; [S2Event.GLOBAL_MOUSE_MOVE]: MouseEventHandler; [S2Event.LAYOUT_RESIZE_MOUSE_DOWN]: CanvasEventHandler; [S2Event.LAYOUT_RESIZE_MOUSE_UP]: CanvasEventHandler; [S2Event.LAYOUT_RESIZE_MOUSE_MOVE]: CanvasEventHandler; [S2Event.GLOBAL_CONTEXT_MENU]: CanvasEventHandler; [S2Event.GLOBAL_CLICK]: CanvasEventHandler; [S2Event.GLOBAL_DOUBLE_CLICK]: CanvasEventHandler; [S2Event.GLOBAL_RESET]: EventHandler_2; [S2Event.GLOBAL_HOVER]: CanvasEventHandler; [S2Event.GLOBAL_SELECTED]: SelectedHandler; [S2Event.GLOBAL_SCROLL]: (position: CellScrollPosition) => void; /** ================ Sort ================ */ [S2Event.RANGE_SORT]: (info: SortParams) => void; [S2Event.RANGE_SORTED]: SortedHandler | CanvasEventHandler; /** ================ Filter ================ */ [S2Event.RANGE_FILTER]: (info: FilterParam) => void; [S2Event.RANGE_FILTERED]: (data: Data[]) => any; /** ================ Cell ================ */ [S2Event.GLOBAL_LINK_FIELD_JUMP]: (data: { key: string; cellData: Node_2; record: Data; }) => void; /** ================ Date Cell ================ */ [S2Event.DATA_CELL_MOUSE_DOWN]: CanvasEventHandler; [S2Event.DATA_CELL_MOUSE_UP]: CanvasEventHandler; [S2Event.DATA_CELL_MOUSE_MOVE]: CanvasEventHandler; [S2Event.DATA_CELL_HOVER]: CanvasEventHandler; [S2Event.DATA_CELL_CLICK]: