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 #2503 #2545

Merged
merged 8 commits into from
Feb 23, 2024
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import * as mockDataConfig from 'tests/data/simple-data.json';
import { createMockCellInfo, getContainer } from 'tests/util/helpers';
import {
createMockCellInfo,
createPivotSheet,
getContainer,
sleep,
} from 'tests/util/helpers';
import { size, sumBy } from 'lodash';
import { getTooltipData, mergeCellInfo } from '../../src/utils/tooltip';
import { PivotSheet, SpreadSheet } from '@/sheet-type';
Expand All @@ -20,8 +25,8 @@ const s2Options: S2Options = {
describe('Interaction Multi Selection Tests', () => {
let s2: SpreadSheet;

const expectNodes = (ids: string[] = []) => {
const state = s2.interaction.getState();
const expectNodes = (ids: string[] = [], instance: SpreadSheet = s2) => {
const state = instance.interaction.getState();
const nodeIds = state.nodes.map((node) => node.id);
expect(nodeIds).toEqual(ids);
};
Expand Down Expand Up @@ -120,7 +125,11 @@ describe('Interaction Multi Selection Tests', () => {
cell: rowRootCell,
});

expectNodes(['root[&]中国[&]浙江[&]义乌', 'root[&]中国[&]浙江[&]杭州']);
expectNodes([
'root[&]中国[&]浙江',
'root[&]中国[&]浙江[&]义乌',
'root[&]中国[&]浙江[&]杭州',
]);

const tooltipData = getTestTooltipData(rowRootCell);

Expand Down Expand Up @@ -150,11 +159,67 @@ describe('Interaction Multi Selection Tests', () => {
cell: colRootCell,
});

expectNodes(['root[&]中国[&]浙江[&]price', 'root[&]中国[&]浙江[&]cost']);
expectNodes([
'root[&]中国[&]浙江',
'root[&]中国[&]浙江[&]price',
'root[&]中国[&]浙江[&]cost',
]);

const tooltipData = getTestTooltipData(colRootCell);

expect(getSelectedCount(tooltipData.summaries)).toEqual(4);
expect(getSelectedSum(tooltipData.summaries)).toEqual(6);
});

// https://github.com/antvis/S2/issues/2503
test('should keep all cell highlighted after scroll', async () => {
const pivotSheet = createPivotSheet(
{
style: {
// 显示滚动条
cellCfg: {
width: 200,
},
},
},
{ useSimpleData: false },
);

pivotSheet.render();

const colRootCell = pivotSheet.interaction.getAllColHeaderCells()[0];

pivotSheet.interaction.selectHeaderCell({
cell: colRootCell,
});

await sleep(100);

pivotSheet.updateScrollOffset({
offsetX: {
value: 100,
animate: true,
},
});

await sleep(500);

expectNodes(
[
'root[&]家具[&]桌子',
'root[&]家具[&]桌子[&]number',
'root[&]家具[&]沙发',
'root[&]家具[&]沙发[&]number',
],
pivotSheet,
);

const interactedCells = pivotSheet.interaction.getInteractedCells();

['root[&]家具[&]桌子', 'root[&]家具[&]沙发'].forEach((id) => {
expect(
interactedCells.find((cell) => cell.getMeta().id === id),
).toBeTruthy();
});
});
});
6 changes: 5 additions & 1 deletion packages/s2-core/__tests__/unit/utils/tooltip-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,13 @@ describe('Tooltip Utils Tests', () => {
let s2: SpreadSheet;

const getMockTooltipData = (cell: S2CellType) => {
const node = cell.getMeta() as Node;
// #getSelectedCellIndexes mock
node.isLeaf = true;

jest.spyOn(s2.interaction, 'getState').mockImplementationOnce(() => ({
cells: [getCellMeta(cell)],
nodes: [cell.getMeta() as Node],
nodes: [node],
}));

jest
Expand Down
4 changes: 1 addition & 3 deletions packages/s2-core/src/interaction/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,10 @@ export class RootInteraction {
return;
}

// 高亮所有的子节点, 但是只有叶子节点需要参与数据计算
const needCalcNodes = childrenNodes.filter((node) => node?.isLeaf);
// 兼容行列多选 (高亮 行/列头 以及相对应的数值单元格)
this.changeState({
cells: selectedCells,
nodes: needCalcNodes,
nodes: childrenNodes,
stateName: InteractionStateName.SELECTED,
});

Expand Down
17 changes: 13 additions & 4 deletions packages/s2-core/src/utils/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import type {
import { getLeafColumnsWithKey } from '../facet/utils';
import type { SpreadSheet } from '../sheet-type';
import { getDataSumByField, isNotNumber } from '../utils/number-calculate';
import type { Node as S2Node } from '../facet/layout/node';
import { handleDataItem } from './cell/data-cell';
import { isMultiDataItem } from './data-item-type-checker';
import { customMerge } from './merge';
Expand Down Expand Up @@ -330,7 +331,11 @@ export const getSummaryName = (
return name && name !== 'undefined' ? name : '';
};

const getRowOrColSelectedIndexes = (nodes, leafNodes, isRow = true) => {
const getRowOrColSelectedIndexes = (
nodes: S2Node[],
leafNodes: S2Node[],
isRow = true,
) => {
const selectedIndexes = [];
forEach(leafNodes, (leaf, index) => {
forEach(nodes, (item) => {
Expand All @@ -352,12 +357,15 @@ export const getSelectedCellIndexes = (
const { rowLeafNodes, colLeafNodes } = layoutResult;
const { nodes = [], cells = [] } = spreadsheet.interaction.getState();
const cellType = cells?.[0]?.type;
// 高亮所有的子节点, 但是只有叶子节点需要参与数据计算 https://github.com/antvis/S2/pull/1443
const needCalcNodes = nodes.filter((node) => node?.isLeaf);

if (cellType === CellTypes.COL_CELL) {
return getRowOrColSelectedIndexes(nodes, rowLeafNodes, false);
return getRowOrColSelectedIndexes(needCalcNodes, rowLeafNodes, false);
}

if (cellType === CellTypes.ROW_CELL) {
return getRowOrColSelectedIndexes(nodes, colLeafNodes);
return getRowOrColSelectedIndexes(needCalcNodes, colLeafNodes);
}

return [];
Expand All @@ -375,7 +383,7 @@ export const getSelectedCellsData = (
* 1. [点击列头单元格时], 选中列所对应的数值单元格的数据如果是小计/总计, 则不应该参与计算:
* - 1.1 [小计/总计 位于行头]: 点击的都是 (普通列头), 需要去除 (数值单元格) 对应 (行头为小计) 的单元格的数据
* - 1.2 [小计/总计 位于列头]: 点击的是 (普通列头/小计/总计列头), 由于行头没有, 所有数值单元格参与计算即可
* - 1.3 [小计/总计 同时位于行头/列头]: 和 1.1 处理一致
* - 1.3 [小计/总计 同时位于行头/列头]: 和 1.1 处理一致

* 2. [点击行头单元格时]:
* - 2.1 如果本身就是小计/总计单元格, 且列头无小计/总计, 则当前行所有 (数值单元格) 参与计算
Expand Down Expand Up @@ -568,6 +576,7 @@ export const getTooltipData = (params: TooltipDataParam): TooltipData => {
details = getTooltipDetailList(spreadsheet, firstCellInfo, options);
}
const { interpretation, infos, tips, name } = firstCellInfo || {};

return {
summaries,
interpretation,
Expand Down
3 changes: 2 additions & 1 deletion packages/s2-react/playground/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const s2Options: SheetComponentOptions = {
width: 600,
height: 400,
frozenFirstRow: false,
showSeriesNumber: true,
showSeriesNumber: false,
interaction: {
enableCopy: true,
copyWithHeader: true,
Expand All @@ -95,6 +95,7 @@ export const s2Options: SheetComponentOptions = {
},
},
tooltip: {
showTooltip: true,
operation: {
trend: true,
},
Expand Down
Loading