Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(interaction): 修复行列头圈选后滑出可视范围后, 错误的选择了数值单元格 close #2340 #2411

Merged
merged 3 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions packages/s2-core/__tests__/bugs/issue-2340-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @description spec for issue #2340
* https://github.com/antvis/S2/issues/2340
*/
import { map } from 'lodash';
import {
CellTypes,
InteractionStateName,
getCellMeta,
type S2Options,
HeaderCell,
} from '../../src';
import { createPivotSheet, sleep } from '../util/helpers';

const s2Options: S2Options = {
width: 800,
height: 600,
style: {
cellCfg: {
width: 200,
height: 200,
},
},
};

describe('Header Brush Selection Tests', () => {
test.each([CellTypes.COL_CELL, CellTypes.ROW_CELL])(
'should not trigger data cell selected when header selected and scroll out of viewport',
async (cellType) => {
const s2 = createPivotSheet(s2Options, { useSimpleData: false });
s2.render();

const isRow = cellType === CellTypes.ROW_CELL;
const targetCells = isRow
? s2.interaction.getAllRowHeaderCells()
: s2.interaction.getAllColHeaderCells();

const cells = [
(targetCells as HeaderCell[]).find((cell) => {
const meta = cell.getMeta();
return meta.isLeaf;
}),
];

s2.interaction.changeState({
cells: map(cells, getCellMeta),
stateName: InteractionStateName.BRUSH_SELECTED,
});

await sleep(500);

const offsetKey = isRow ? 'offsetY' : 'offsetX';
// 将圈选的单元格滑出可视范围
s2.facet.updateScrollOffset({
[offsetKey]: { value: 300 },
});

await sleep(500);

// 还原
s2.facet.updateScrollOffset({
[offsetKey]: { value: 0 },
});

expect(s2.interaction.getActiveCells()).toHaveLength(1);
expect(s2.interaction.getCurrentStateName()).toEqual(
InteractionStateName.BRUSH_SELECTED,
);

// 交互过的不应该有 dataCell (未触发过列头多选)
s2.interaction.getInteractedCells().forEach((cell) => {
expect(cell.cellType).toEqual(
isRow ? CellTypes.ROW_CELL : CellTypes.COL_CELL,
);
});
},
);
});
2 changes: 1 addition & 1 deletion packages/s2-core/src/cell/data-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@
return;
}

const { currentRow, currentCol } =
this.spreadsheet.interaction.getHoverHighlight();

Check warning on line 122 in packages/s2-core/src/cell/data-cell.ts

View check run for this annotation

Codecov / codecov/patch

packages/s2-core/src/cell/data-cell.ts#L121-L122

Added lines #L121 - L122 were not covered by tests

if (currentRow || currentCol) {
// 如果当前是hover,要绘制出十字交叉的行列样式
Expand Down Expand Up @@ -393,7 +393,7 @@
);
}

// dataCell根据state 改变当前样式,
// dataCell 根据 state 改变当前样式,
protected changeRowColSelectState(indexType: ViewMetaIndexType) {
const { interaction } = this.spreadsheet;
const currentIndex = get(this.meta, indexType);
Expand Down
1 change: 1 addition & 0 deletions packages/s2-core/src/cell/header-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
shouldFormat = !(isGrandTotals && isTotalRoot);
} else {
shouldFormat = !isTotalRoot;
}

Check warning on line 105 in packages/s2-core/src/cell/header-cell.ts

View check run for this annotation

Codecov / codecov/patch

packages/s2-core/src/cell/header-cell.ts#L105

Added line #L105 was not covered by tests

const formattedValue =
shouldFormat && formatter
Expand Down Expand Up @@ -415,6 +415,7 @@

switch (stateInfo?.stateName) {
case InteractionStateName.SELECTED:
case InteractionStateName.BRUSH_SELECTED:
this.handleSelect(cells, stateInfo?.nodes);
break;
case InteractionStateName.HOVER_FOCUS:
Expand Down
1 change: 1 addition & 0 deletions packages/s2-core/src/common/constant/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum InteractionName {
export enum InteractionStateName {
ALL_SELECTED = 'allSelected',
SELECTED = 'selected',
BRUSH_SELECTED = 'brushSelected',
UNSELECTED = 'unselected',
HOVER = 'hover',
HOVER_FOCUS = 'hoverFocus',
Expand Down
6 changes: 3 additions & 3 deletions packages/s2-core/src/facet/header/col.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ export class ColHeader extends BaseHeader<ColHeaderConfig> {
return this.scrollGroup;
}

protected isColCellInRect(item: Node): boolean {
protected isColCellInRect(node: Node): boolean {
const { spreadsheet, cornerWidth, width, scrollX } = this.headerConfig;

return (
// don't care about scrollY, because there is only freeze col-header exist
width + scrollX > item.x &&
width + scrollX > node.x &&
scrollX - (spreadsheet.isFrozenRowHeader() ? 0 : cornerWidth) <
item.x + item.width
node.x + node.width
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,14 @@ export class ColBrushSelection extends BaseBrushSelection {
);
}

// 最终刷选的cell
// 最终刷选的 cell
protected updateSelectedCells() {
const { interaction } = this.spreadsheet;

interaction.changeState({
cells: map(this.brushRangeCells, getCellMeta),
stateName: InteractionStateName.SELECTED,
onUpdateCells: (root) => {
root.updateCells(root.getAllColHeaderCells());
},
stateName: InteractionStateName.BRUSH_SELECTED,
onUpdateCells: this.onUpdateCells,
});

this.spreadsheet.emit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,14 @@ export class DataCellBrushSelection extends BaseBrushSelection {
return metas;
};

// 最终刷选的cell
// 最终刷选的 cell
protected updateSelectedCells() {
const brushRange = this.getBrushRange();
const selectedCellMetas = this.getSelectedCellMetas(brushRange);

this.spreadsheet.interaction.changeState({
cells: selectedCellMetas,
// TODO: 怕上层有直接消费 stateName, 暂时保留, 2.0 版本改成 InteractionStateName.BRUSH_SELECTED
stateName: InteractionStateName.SELECTED,
onUpdateCells: afterSelectDataCells,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class RowBrushSelection extends BaseBrushSelection {

this.spreadsheet.interaction.changeState({
cells: selectedCellMetas,
stateName: InteractionStateName.SELECTED,
stateName: InteractionStateName.BRUSH_SELECTED,
onUpdateCells: this.onUpdateCells,
});

Expand Down
5 changes: 4 additions & 1 deletion packages/s2-core/src/interaction/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ export class RootInteraction {
}

public isSelectedState() {
return this.isStateOf(InteractionStateName.SELECTED);
return (
this.isStateOf(InteractionStateName.SELECTED) ||
this.isStateOf(InteractionStateName.BRUSH_SELECTED)
);
}

public isAllSelectedState() {
Expand Down
Loading