Skip to content

Commit

Permalink
refactor(cell): unify cell functions (#136)
Browse files Browse the repository at this point in the history
* refactor: fix updateShapeAttr type define

* refactor: refine getCellType to getter

* refactor: add header cell class

* refactor: rename detail row cell to detail data cell

* refactor: refine function declaration in data cell

* refactor: refine merge cell constructor

* refactor: unify stateShapes

* refactor: refactor render util function

* refactor: unify interaction state

* refactor: extract link text variable to theme config

* refactor: rename interactive shape

* chore: close loop for test:live

* fix: remove blue color, add link field color into brand colors
  • Loading branch information
wjgogogo committed Aug 23, 2021
1 parent 61ecd17 commit 08745f3
Show file tree
Hide file tree
Showing 30 changed files with 443 additions and 450 deletions.
1 change: 1 addition & 0 deletions packages/s2-core/scripts/test-live.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async function main() {
type: 'rawlist',
message: '📢 请选择测试文件 (输入序号可快速选择)',
name: 'path',
loop: false,
choices: paths,
default: () => defaultSelectedIndex,
},
Expand Down
62 changes: 34 additions & 28 deletions packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import {
SHAPE_ATTRS_MAP,
SHAPE_STYLE_MAP,
} from '@/common/constant';
import { InteractionStateTheme, SpreadSheetTheme } from '@/common/interface';
import { SpreadSheetTheme } from '@/common/interface';
import { Group, IShape } from '@antv/g-canvas';
import { each, findKey, get, includes } from 'lodash';
import { SpreadSheet } from '../sheet-type';
import { updateShapeAttr } from '../utils/g-renders';
import { StateShapeLayer } from './../common/interface/interaction';

export abstract class BaseCell<T> extends Group {
// used to determine the cell type
public cellType: CellTypes;

// cell's data meta info
protected meta: T;

Expand All @@ -23,19 +21,14 @@ export abstract class BaseCell<T> extends Group {
// spreadsheet's theme
protected theme: SpreadSheetTheme;

// background control by icon condition
// background control shape
protected backgroundShape: IShape;

// text control shape
protected textShape: IShape;

// render interactive background,
protected interactiveBgShape: IShape;

// 需要根据state改变样式的shape集合
// 需要这个属性的原因是在state clear时知道具体哪些shape要hide。不然只能手动改,比较麻烦
protected stateShapes: IShape[] = [];

// protected actionIcons: GuiIcon[];
// interactive control shapes, unify read and manipulate operations
protected stateShapes = new Map<StateShapeLayer, IShape>();

public constructor(
meta: T,
Expand All @@ -50,11 +43,6 @@ export abstract class BaseCell<T> extends Group {
this.initCell();
}

/**
* Update cell's selected state
*/
public abstract update(): void;

public getMeta(): T {
return this.meta;
}
Expand All @@ -67,31 +55,49 @@ export abstract class BaseCell<T> extends Group {
* in case there are more params to be handled
* @param options any type's rest params
*/
protected handleRestOptions(...options: any) {
protected handleRestOptions(...options: unknown[]) {
// default do nothing
}

/**
* Return the type of the cell
*/
public abstract get cellType(): CellTypes;

/**
* Determine how to render this cell area
*/
protected abstract initCell(): void;

/**
* Return the type of the cell
* Update cell's selected state
*/
protected abstract getCellType(): CellTypes;
public abstract update(): void;

/* -------------------------------------------------------------------------- */
/* common functions that will be used in subtype */
/* -------------------------------------------------------------------------- */

// 根据当前state来更新cell的样式
public updateByState(stateName: InteractionStateName) {
const stateStyles = get(this.theme, `${this.cellType}.cell.${stateName}`);
const stateStyles = get(
this.theme,
`${this.cellType}.cell.interactionState.${stateName}`,
);
each(stateStyles, (style, styleKey) => {
if (styleKey) {
const currentShape = findKey(SHAPE_ATTRS_MAP, (attrs) =>
includes(attrs, styleKey),
);
if (!currentShape) return;
updateShapeAttr(this[currentShape], SHAPE_STYLE_MAP[styleKey], style);
const currentShape = findKey(SHAPE_ATTRS_MAP, (attrs) =>
includes(attrs, styleKey),
) as StateShapeLayer | undefined;

if (!currentShape || !this.stateShapes.has(currentShape)) {
return;
}

updateShapeAttr(
this.stateShapes.get(currentShape),
SHAPE_STYLE_MAP[styleKey],
style,
);
});
}

Expand Down
110 changes: 45 additions & 65 deletions packages/s2-core/src/cell/col-cell.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,32 @@
import { BaseCell } from '@/cell/base-cell';
import {
CellTypes,
COLOR_DEFAULT_RESIZER,
KEY_GROUP_COL_RESIZER,
InteractionStateName,
} from '@/common/constant';
import { GuiIcon } from '@/common/icons';
import { TextAlign } from '@/common/interface';
import { HIT_AREA } from '@/facet/header/base';
import { ColHeaderConfig } from '@/facet/header/col';
import { ResizeInfo } from '@/facet/header/interface';
import { Node } from '@/index';
import { renderRect } from '@/utils/g-renders';
import { renderLine, renderRect, renderText } from '@/utils/g-renders';
import {
getEllipsisText,
getTextPosition,
measureTextWidth,
} from '@/utils/text';
import { IGroup } from '@antv/g-canvas';
import _ from 'lodash';
import { get, isEqual } from 'lodash';
import { HeaderCell } from './header-cell';

export class ColCell extends BaseCell<Node> {
export class ColCell extends HeaderCell {
protected headerConfig: ColHeaderConfig;

public update() {
const stateName = this.spreadsheet.interaction.getCurrentStateName();
const cells = this.spreadsheet.interaction.getActiveCells();
const currentCell = _.first(cells);
if (
!currentCell ||
(stateName !== InteractionStateName.HOVER &&
stateName !== InteractionStateName.HOVER_FOCUS)
) {
return;
}
if (currentCell?.cellType === CellTypes.DATA_CELL || cells.includes(this)) {
this.updateByState(InteractionStateName.HOVER);
}
}

protected handleRestOptions(...options: ColHeaderConfig[]) {
this.headerConfig = options[0];
public get cellType() {
return CellTypes.COL_CELL;
}

protected initCell() {
this.cellType = this.getCellType();
// draw rect background
// 1、draw rect background
this.drawRectBackground();
// interactive background shape
this.drawInteractiveBgShape();
Expand All @@ -57,14 +38,9 @@ export class ColCell extends BaseCell<Node> {
this.drawRightBorder();
// draw hot-spot rect
this.drawHotSpot();
// update the interaction state
this.update();
}

protected getCellType() {
return CellTypes.COL_CELL;
}

protected getColHotSpotKey() {
return this.meta.key;
}
Expand All @@ -82,12 +58,8 @@ export class ColCell extends BaseCell<Node> {
}

protected drawCellText() {
const {
offset,
width,
scrollContainsRowHeader,
cornerWidth,
} = this.headerConfig;
const { offset, width, scrollContainsRowHeader, cornerWidth } =
this.headerConfig;
const {
label,
x,
Expand All @@ -114,7 +86,7 @@ export class ColCell extends BaseCell<Node> {
? iconCfg.size + iconCfg.margin.right
: 0;
const textStyle = isLeaf && !isTotals ? textCfg : bolderTextCfg;
const padding = _.get(this, 'theme.colCell.cell.padding');
const padding = get(this, 'theme.colCell.cell.padding');
const text = getEllipsisText(
content,
cellWidth - sortIconPadding - padding?.left - padding?.right,
Expand All @@ -126,8 +98,8 @@ export class ColCell extends BaseCell<Node> {
let textAlign: TextAlign;
if (isLeaf) {
// 最后一个层级的维值,与 dataCell 对齐方式保持一致
textAlign = _.get(this, 'theme.dataCell.text.textAlign');
const textBaseline = _.get(this, 'theme.dataCell.text.textBaseline');
textAlign = this.theme.dataCell.text.textAlign;
const textBaseline = this.theme.dataCell.text.textBaseline;
textStyle.textBaseline = textBaseline;
const cellBoxCfg = {
x,
Expand Down Expand Up @@ -183,7 +155,7 @@ export class ColCell extends BaseCell<Node> {
}
// const derivedValue = this.spreadsheet.getDerivedValue(value);
// if (
// !_.isEqual(
// !isEqual(
// derivedValue.derivedValueField,
// derivedValue.displayDerivedValueField,
// ) &&
Expand All @@ -197,44 +169,48 @@ export class ColCell extends BaseCell<Node> {
// if (
// key === EXTRA_FIELD &&
// this.spreadsheet.isDerivedValue(value) &&
// _.last(derivedValue.displayDerivedValueField) === value
// last(derivedValue.displayDerivedValueField) === value
// ) {
// // 度量列,找到 value值
// text += '...';
// }
// }
this.addShape('text', {
attrs: {
x: textX,
y: textY,
text,
this.textShape = renderText(
this,
[this.textShape],
textX,
textY,
text,
{
textAlign,
...textStyle,
cursor: 'pointer',
},
});
{ cursor: 'pointer' },
);
}

// 交互使用的背景色
protected drawInteractiveBgShape() {
const { x, y, height, width } = this.meta;
this.interactiveBgShape = renderRect(this, {
x,
y,
width,
height,
fill: 'transparent',
stroke: 'transparent',
});
this.stateShapes.push(this.interactiveBgShape);
this.stateShapes.set(
'interactiveBgShape',
renderRect(this, {
x,
y,
width,
height,
fill: 'transparent',
stroke: 'transparent',
}),
);
}

private showSortIcon() {
const { sortParam } = this.headerConfig;
const query = this.meta.query;
return (
_.isEqual(_.get(sortParam, 'query'), query) &&
_.get(sortParam, 'type') !== 'none'
isEqual(get(sortParam, 'query'), query) &&
get(sortParam, 'type') !== 'none'
);
}

Expand All @@ -245,7 +221,7 @@ export class ColCell extends BaseCell<Node> {
const { sortParam } = this.headerConfig;
const { x, y, width: cellWidth, height: cellHeight } = this.meta;
const iconShape = new GuiIcon({
type: _.get(sortParam, 'type', 'none'),
type: get(sortParam, 'type', 'none'),
x: x + cellWidth - icon.size - icon.margin.right,
y: y + (cellHeight - icon.size) / 2,
width: icon.size,
Expand Down Expand Up @@ -334,16 +310,20 @@ export class ColCell extends BaseCell<Node> {
if (!this.meta.isLeaf) {
const { height, viewportHeight } = this.headerConfig;
const { x, y, width: cellWidth, height: cellHeight } = this.meta;
this.addShape('line', {
attrs: {

renderLine(
this,
{
x1: x + cellWidth,
y1: y + cellHeight,
x2: x + cellWidth,
y2: y + height + viewportHeight, // 高度有多,通过 clip 裁剪掉
y2: y + height + viewportHeight,
},
{
stroke: this.theme.colCell.cell.horizontalBorderColor,
lineWidth: 1,
},
});
);
}
}
}

0 comments on commit 08745f3

Please sign in to comment.