s2-dbi
Version:
effective spreadsheet render core lib
1,501 lines (1,387 loc) • 165 kB
TypeScript
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]: