Skip to content

Commit

Permalink
feat(interaction): 行列宽高支持控制拖拽范围 (#1583)
Browse files Browse the repository at this point in the history
* feat(interaction): 行列宽高支持控制拖拽范围

* feat(interaction): 增加测试和文档

* feat(interaction): 增加主题色

* Update row-column-resize-spec.ts

* Update packages/s2-core/src/interaction/row-column-resize.ts

Co-authored-by: Wenjun Xu <[email protected]>

* fix: rename

Co-authored-by: Wenjun Xu <[email protected]>
  • Loading branch information
2 people authored and zishang committed Jul 22, 2022
1 parent 95b597a commit f7298e6
Show file tree
Hide file tree
Showing 19 changed files with 354 additions and 57 deletions.
42 changes: 42 additions & 0 deletions packages/s2-core/__tests__/spreadsheet/spread-sheet-resize-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,46 @@ describe('SpreadSheet Resize Active Tests', () => {

expect(group.findById(KEY_GROUP_COL_RESIZE_AREA)).toBeDefined();
});

test('should disable all cell resize area by visible', () => {
const s2 = renderSheet({
interaction: {
resize: {
visible: () => false,
},
},
} as S2Options);

const group = s2.facet.foregroundGroup;

[
KEY_GROUP_CORNER_RESIZE_AREA,
KEY_GROUP_COL_RESIZE_AREA,
KEY_GROUP_ROW_RESIZE_AREA,
].forEach((key) => {
expect(group.findById(key)).toBeNull();
});
});

test('should only show col cell resize area by visible', () => {
const s2 = renderSheet({
interaction: {
resize: {
visible: (cell) => {
const meta = cell.getMeta();
return meta.id === 'root[&]笔[&]price';
},
},
},
} as S2Options);

const group = s2.facet.foregroundGroup;
const colResizeGroups = group
.getChildren()
.filter((element) => element.cfg.id === KEY_GROUP_COL_RESIZE_AREA);

expect(colResizeGroups).toHaveLength(1);
expect(group.findById(KEY_GROUP_ROW_RESIZE_AREA)).toBeNull();
expect(group.findById(KEY_GROUP_CORNER_RESIZE_AREA)).toBeNull();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ describe('Interaction Row Column Resize Tests', () => {
};

const getStartGuideLine = () => {
return rowColumnResizeInstance.resizeReferenceGroup.findById(
return rowColumnResizeInstance.resizeReferenceGroup?.findById(
RESIZE_START_GUIDE_LINE_ID,
) as IShape;
};

const getEndGuideLine = () => {
return rowColumnResizeInstance.resizeReferenceGroup.findById(
return rowColumnResizeInstance.resizeReferenceGroup?.findById(
RESIZE_END_GUIDE_LINE_ID,
) as IShape;
};

const getResizeMask = () => {
return rowColumnResizeInstance.resizeReferenceGroup.findById(
return rowColumnResizeInstance.resizeReferenceGroup?.findById(
RESIZE_MASK_ID,
) as IShape;
};
Expand Down Expand Up @@ -502,4 +502,84 @@ describe('Interaction Row Column Resize Tests', () => {
);
expect(s2.interaction.reset).toHaveBeenCalledTimes(1);
});

test('should not update col width after resized if resize disabled', () => {
s2.setOptions({
interaction: {
resize: {
disable: () => true,
},
},
});

const resizeInfo = emitResize(
ResizeDirectionType.Horizontal,
ResizeAreaEffect.Field,
);

expect(s2.options.style.rowCfg.widthByField).toEqual({
[resizeInfo.id]: resizeInfo.width,
});
});

test('should set no drop cursor and gray guide line if disable resize', () => {
const disable = jest.fn(() => true);

s2.setOptions({
interaction: {
resize: {
disable,
},
},
});

const resizeInfo = {
theme: {},
type: ResizeDirectionType.Vertical,
offsetX: 2,
offsetY: 2,
width: 5,
height: 2,
isResizeArea: true,
effect: ResizeAreaEffect.Cell,
id: '',
} as ResizeInfo;

emitResizeEvent(
S2Event.LAYOUT_RESIZE_MOUSE_DOWN,
{
offsetX: 10,
offsetY: 20,
},
resizeInfo,
);

emitResizeEvent(
S2Event.LAYOUT_RESIZE_MOUSE_MOVE,
{
offsetX: 20,
offsetY: 20,
},
resizeInfo,
);

expect(getResizeMask().attr('cursor')).toEqual('no-drop');
expect(getEndGuideLine().attr('stroke')).toEqual('rgba(0,0,0,0.25)');
expect(disable).toHaveBeenCalledWith({
...resizeInfo,
resizedWidth: 0,
resizedHeight: 16,
});

emitResizeEvent(
S2Event.GLOBAL_MOUSE_UP,
{
offsetX: 20,
offsetY: 20,
},
resizeInfo,
);

expect(getResizeMask()).toBeFalsy();
});
});
25 changes: 21 additions & 4 deletions packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import type { BBox, IShape, Point, SimpleBBox } from '@antv/g-canvas';
import { Group } from '@antv/g-canvas';
import { each, get, includes, isBoolean, isNumber, keys, pickBy } from 'lodash';
import {
each,
get,
includes,
isBoolean,
isFunction,
isNumber,
keys,
pickBy,
} from 'lodash';
import {
CellTypes,
InteractionStateName,
Expand All @@ -11,7 +20,7 @@ import type {
CellThemes,
DefaultCellTheme,
FormatResult,
ResizeActiveOptions,
ResizeInteractionOptions,
ResizeArea,
S2CellType,
S2Theme,
Expand Down Expand Up @@ -154,12 +163,20 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
return this.getStyle('resizeArea') as ResizeArea;
}

protected shouldDrawResizeAreaByType(type: keyof ResizeActiveOptions) {
const resize = this.spreadsheet.options?.interaction?.resize;
protected shouldDrawResizeAreaByType(
type: keyof ResizeInteractionOptions,
cell: S2CellType,
) {
const { resize } = this.spreadsheet.options.interaction;

if (isBoolean(resize)) {
return resize;
}

if (isFunction(resize.visible)) {
return resize.visible(cell);
}

return resize[type];
}

Expand Down
6 changes: 4 additions & 2 deletions packages/s2-core/src/cell/col-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export class ColCell extends HeaderCell {
}

protected drawHorizontalResizeArea() {
if (!this.shouldDrawResizeAreaByType('colCellVertical')) {
if (!this.shouldDrawResizeAreaByType('colCellVertical', this)) {
return;
}

Expand Down Expand Up @@ -289,6 +289,7 @@ export class ColCell extends HeaderCell {
offsetY: y,
width: resizeAreaWidth,
height,
meta: this.meta,
}),
name: resizeAreaName,
x: 0,
Expand Down Expand Up @@ -343,7 +344,7 @@ export class ColCell extends HeaderCell {
protected drawVerticalResizeArea() {
if (
!this.meta.isLeaf ||
!this.shouldDrawResizeAreaByType('colCellHorizontal')
!this.shouldDrawResizeAreaByType('colCellHorizontal', this)
) {
return;
}
Expand Down Expand Up @@ -372,6 +373,7 @@ export class ColCell extends HeaderCell {
offsetY,
width,
height,
meta: this.meta,
}),
x: offsetX + width - resizeStyle.size / 2,
y: offsetY,
Expand Down
3 changes: 2 additions & 1 deletion packages/s2-core/src/cell/corner-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export class CornerCell extends HeaderCell {
}

protected drawResizeArea() {
if (!this.shouldDrawResizeAreaByType('cornerCellHorizontal')) {
if (!this.shouldDrawResizeAreaByType('cornerCellHorizontal', this)) {
return;
}

Expand Down Expand Up @@ -296,6 +296,7 @@ export class CornerCell extends HeaderCell {
offsetY,
width,
height,
meta: this.meta,
}),
x: offsetX + width - resizeStyle.size / 2,
y: offsetY,
Expand Down
3 changes: 2 additions & 1 deletion packages/s2-core/src/cell/row-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export class RowCell extends HeaderCell {
protected drawResizeAreaInLeaf() {
if (
!this.meta.isLeaf ||
!this.shouldDrawResizeAreaByType('rowCellVertical')
!this.shouldDrawResizeAreaByType('rowCellVertical', this)
) {
return;
}
Expand Down Expand Up @@ -307,6 +307,7 @@ export class RowCell extends HeaderCell {
offsetY,
width,
height,
meta: this.meta,
}),
x: offsetX,
y: offsetY + height - resizeStyle.size / 2,
Expand Down
1 change: 1 addition & 0 deletions packages/s2-core/src/cell/table-series-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class TableSeriesCell extends DataCell {
offsetY: yOffset,
width,
height,
meta: this.meta,
}),
x,
y: yOffset + height - resizeStyle.size / 2,
Expand Down
6 changes: 3 additions & 3 deletions packages/s2-core/src/common/interface/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type { HeaderCell } from '../../cell/header-cell';
import type { Node } from '../../facet/layout/node';
import type { BaseEvent } from '../../interaction/base-event';
import type { SpreadSheet } from '../../sheet-type';
import type { ResizeActiveOptions } from './resize';
import type { ResizeInteractionOptions } from './resize';
import type { ViewMeta } from './basic';

export type S2CellType<T extends SimpleBBox = ViewMeta> =
Expand Down Expand Up @@ -129,7 +129,7 @@ export interface InteractionOptions {
// the ratio to control scroll speed, default set to 1
scrollSpeedRatio?: ScrollSpeedRatio;
// enable resize area, default set to all enable
resize?: boolean | ResizeActiveOptions;
resize?: boolean | ResizeInteractionOptions;
// enable mouse drag brush selection
brushSelection?: boolean;
// enable Command / Ctrl + click multi selection
Expand All @@ -143,7 +143,7 @@ export interface InteractionOptions {
// An object that specifies characteristics about the event listener
// https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
eventListenerOptions?: boolean | AddEventListenerOptions;
// hightlight col and row header for selected cell
// highlight col and row header for selected cell
selectedCellHighlight?: boolean;
// https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior
overscrollBehavior?: 'auto' | 'none' | 'contain';
Expand Down
16 changes: 14 additions & 2 deletions packages/s2-core/src/common/interface/resize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import type {
ResizeDirectionType,
ResizeType,
} from '../../common/constant/resize';
import type { Style } from './basic';
import type { Node } from '../../facet/layout/node';
import type { Style, ViewMeta } from './basic';
import type { S2CellType } from './interaction';
import type { ResizeArea } from './theme';

export type ResizeGuideLinePath = [operation: 'M' | 'L', x: number, y: number];
Expand Down Expand Up @@ -58,12 +60,22 @@ export interface ResizeInfo {
isResizeArea?: boolean;
/** 字段id */
id?: string;
/** 当前拖拽热区对应的节点信息 */
meta: Node | ViewMeta;
/** 拖拽后的宽度 */
resizedWidth?: number;
/** 拖拽后的高度 */
resizedHeight?: number;
}

export interface ResizeActiveOptions {
export interface ResizeInteractionOptions {
rowCellVertical?: boolean; // 行头垂直方向resize -> 针对行头叶子节点
cornerCellHorizontal?: boolean; // 角头水平方向resize -> 针对角头CornerNodeType为Series和Row
colCellHorizontal?: boolean; // 列头水平方向resize -> 针对列头叶子节点
colCellVertical?: boolean; // 列头垂直方向resize -> 针对列头各层级节点
rowResizeType?: ResizeType; // 行高调整时,影响当前行还是全部行
// 是否允许调整, 返回 false 时拖拽的宽高无效
disable?: (resizeInfo: ResizeInfo) => boolean;
// 是否显示热区
visible?: (cell: S2CellType) => boolean;
}
2 changes: 2 additions & 0 deletions packages/s2-core/src/common/interface/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ export interface ResizeArea {
background?: string;
/* 参考线颜色 */
guideLineColor?: string;
/* 参考线不可用颜色 */
guideLineDisableColor?: string;
/* 参考线间隔 */
guideLineDash?: number[];
/* 热区背景色透明度 */
Expand Down
4 changes: 2 additions & 2 deletions packages/s2-core/src/facet/table-facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { FrozenCellGroupMap } from '../common/constant/frozen';
import { DebuggerUtil } from '../common/debug';
import type {
LayoutResult,
ResizeActiveOptions,
ResizeInteractionOptions,
S2CellType,
SplitLine,
SpreadSheetFacetCfg,
Expand Down Expand Up @@ -866,7 +866,7 @@ export class TableFacet extends BaseFacet {

const shouldDrawResize = isBoolean(resize)
? resize
: (resize as ResizeActiveOptions)?.rowCellVertical;
: (resize as ResizeInteractionOptions)?.rowCellVertical;
if (!shouldDrawResize) {
return;
}
Expand Down
Loading

0 comments on commit f7298e6

Please sign in to comment.