diff --git a/packages/s2-core/__tests__/spreadsheet/hidden-columns-spec.ts b/packages/s2-core/__tests__/spreadsheet/hidden-columns-spec.ts
index 8774ead68e..7dc973370c 100644
--- a/packages/s2-core/__tests__/spreadsheet/hidden-columns-spec.ts
+++ b/packages/s2-core/__tests__/spreadsheet/hidden-columns-spec.ts
@@ -152,6 +152,58 @@ describe('SpreadSheet Hidden Columns Tests', () => {
expect(costDetail.hideColumnNodes).toHaveLength(1);
expect(costDetail.hideColumnNodes[0].field).toEqual('cost');
});
+
+ // https://github.com/antvis/S2/issues/2495
+ test('should reset latest hidden columns detail when hiddenColumnFields changed', () => {
+ const hiddenColumns = ['province', 'city'];
+ const sheet = new TableSheet(getContainer(), mockTableDataConfig, {
+ ...s2Options,
+ interaction: {
+ hiddenColumnFields: hiddenColumns,
+ },
+ });
+ sheet.render();
+
+ sheet.setOptions({
+ interaction: {
+ hiddenColumnFields: ['city'],
+ },
+ });
+
+ sheet.render(false);
+
+ const hiddenColumnsDetail = sheet.store.get('hiddenColumnsDetail', []);
+ const [cityDetail] = hiddenColumnsDetail;
+
+ expect(sheet.options.interaction.hiddenColumnFields).toEqual(['city']);
+ expect(hiddenColumnsDetail).toHaveLength(1);
+ expect(cityDetail.hideColumnNodes).toHaveLength(1);
+ expect(cityDetail.hideColumnNodes[0].field).toEqual('city');
+ });
+
+ test('should clear hidden columns detail if hiddenColumnFields is empty', () => {
+ const hiddenColumns = ['province', 'city'];
+ const sheet = new TableSheet(getContainer(), mockTableDataConfig, {
+ ...s2Options,
+ interaction: {
+ hiddenColumnFields: hiddenColumns,
+ },
+ });
+ sheet.render();
+
+ sheet.setOptions({
+ interaction: {
+ hiddenColumnFields: [],
+ },
+ });
+
+ sheet.render(false);
+
+ const hiddenColumnsDetail = sheet.store.get('hiddenColumnsDetail', []);
+
+ expect(sheet.options.interaction.hiddenColumnFields).toBeEmpty();
+ expect(hiddenColumnsDetail).toBeEmpty();
+ });
});
describe('PivotSheet', () => {
diff --git a/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts b/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts
index 246d6fbdf6..6ed8370e28 100644
--- a/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts
+++ b/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts
@@ -657,7 +657,7 @@ describe('PivotSheet Tests', () => {
test('should clear init column nodes', () => {
s2.store.set('initColumnLeafNodes', [null, null]);
- s2.clearColumnLeafNodes();
+ s2.clearInitColumnLeafNodes();
expect(s2.store.get('initColumnLeafNodes')).toBeFalsy();
});
diff --git a/packages/s2-core/src/sheet-type/spread-sheet.ts b/packages/s2-core/src/sheet-type/spread-sheet.ts
index 6eb4ef9699..c1acbd81dc 100644
--- a/packages/s2-core/src/sheet-type/spread-sheet.ts
+++ b/packages/s2-core/src/sheet-type/spread-sheet.ts
@@ -394,9 +394,20 @@ export abstract class SpreadSheet extends EE {
this.initTooltip();
}
+ this.resetHiddenColumnsDetailInfoIfNeeded();
this.registerIcons();
}
+ /**
+ * 配置都是 merge 操作, 但是隐藏列配置比较特殊, 变更时, 应该是全量覆盖, 而不应该是合并
+ * https://github.com/antvis/S2/issues/2495
+ */
+ private resetHiddenColumnsDetailInfoIfNeeded() {
+ if (!isEmpty(this.options.interaction?.hiddenColumnFields)) {
+ this.store.set('hiddenColumnsDetail', []);
+ }
+ }
+
public render(reloadData = true, options: S2RenderOptions = {}) {
// 防止表格卸载后, 再次调用 render 函数的报错
if (!this.getCanvasElement()) {
@@ -689,7 +700,14 @@ export abstract class SpreadSheet extends EE {
return this.store.get('initColumnLeafNodes', []);
}
+ /**
+ * @deprecated 已废弃, 请使用 clearInitColumnLeafNodes
+ */
public clearColumnLeafNodes() {
+ this.clearInitColumnLeafNodes();
+ }
+
+ public clearInitColumnLeafNodes() {
this.store.set('initColumnLeafNodes', undefined);
}
diff --git a/packages/s2-react/src/hooks/useSpreadSheet.ts b/packages/s2-react/src/hooks/useSpreadSheet.ts
index b56984901b..344b3ec9a2 100644
--- a/packages/s2-react/src/hooks/useSpreadSheet.ts
+++ b/packages/s2-react/src/hooks/useSpreadSheet.ts
@@ -1,7 +1,7 @@
import { PivotSheet, SpreadSheet, TableSheet } from '@antv/s2';
import type { S2DataConfig, S2Options, ThemeCfg } from '@antv/s2';
import { useUpdate, useUpdateEffect } from 'ahooks';
-import { identity } from 'lodash';
+import { identity, isEmpty } from 'lodash';
import React from 'react';
import type {
SheetComponentOptions,
@@ -94,7 +94,7 @@ export function useSpreadSheet(props: SheetComponentsProps) {
prevDataCfg?.fields?.columns?.length !==
dataCfg?.fields?.columns?.length
) {
- s2Ref.current?.clearColumnLeafNodes();
+ s2Ref.current?.clearInitColumnLeafNodes();
}
reloadData = true;
diff --git a/packages/s2-vue/src/hooks/useSheetUpdate.ts b/packages/s2-vue/src/hooks/useSheetUpdate.ts
index f8ee791f22..94580a1c55 100644
--- a/packages/s2-vue/src/hooks/useSheetUpdate.ts
+++ b/packages/s2-vue/src/hooks/useSheetUpdate.ts
@@ -39,7 +39,7 @@ export const useSheetUpdate = (
prevDataCfg?.fields?.columns?.length !==
dataCfg?.fields?.columns?.length
) {
- s2Ref.value?.clearColumnLeafNodes();
+ s2Ref.value?.clearInitColumnLeafNodes();
}
updateFlag.rerender = true;
updateFlag.reloadData = true;
diff --git a/s2-site/docs/api/basic-class/spreadsheet.en.md b/s2-site/docs/api/basic-class/spreadsheet.en.md
index 063bc7dd2c..64834d623d 100644
--- a/s2-site/docs/api/basic-class/spreadsheet.en.md
+++ b/s2-site/docs/api/basic-class/spreadsheet.en.md
@@ -68,7 +68,7 @@ s2.xx()
| getTotalsConfig | Get Total Subtotal Configuration | (dimension: string) => [Total](/docs/api/general/S2Options#totals) | |
| getInitColumnLeafNodes | Get the leaf node of the column header for the first rendering (for example: before hiding the column header) | () => [Node\[\]](/docs/api/basic-class/node/) | |
| getCanvasElement | Get the `` HTML element corresponding to the table | () => [HTMLCanvasElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement) | |
-| clearColumnLeafNodes | Clear the initial leaf nodes stored in the store | () => void | |
+| clearInitColumnLeafNodes | Clear the initial leaf nodes stored in the store | () => void | |
| updateSortMethodMap | Update the node sorting method map stored in the store, replace is whether to overwrite the last value | (nodeId: string, sortMethod: string, replace?: boolean) => void | |
| getMenuDefaultSelectedKeys | Get the key value of the menu item selected in the tooltip | `(nodeId: string) => string[]` | |
| measureText | Get the measurement information of the text in the canvas | (text: `string` , font: [TextTheme](/docs/api/general/S2Theme#texttheme) ) => [TextMetrics](https://developer.mozilla.org/zh-CN/docs/Web/API/TextMetrics) \| `null` | |
diff --git a/s2-site/docs/api/basic-class/spreadsheet.zh.md b/s2-site/docs/api/basic-class/spreadsheet.zh.md
index 37d949e8c1..187d809a8f 100644
--- a/s2-site/docs/api/basic-class/spreadsheet.zh.md
+++ b/s2-site/docs/api/basic-class/spreadsheet.zh.md
@@ -49,8 +49,8 @@ s2.isPivotMode()
| hideTooltip | 隐藏 tooltip | `() => void` | |
| destroyTooltip | 销毁 tooltip | `() => void` | |
| registerIcons | 注册 自定义 svg 图标 (根据 `options.customSVGIcons`) | `() => void` | |
-| setDataCfg | 更新数据配置 | `(dataCfg: T extends true ?` [`S2DataConfig`](/docs/api/general/S2DataConfig) `: Partial<`[`S2DataConfig`](/docs/api/general/S2DataConfig)`>, reset?: T) => void` | `reset` 参数需在 `@antv/s2-v1.34.0`版本使用 |
-| setOptions | 更新表格配置 | (options: [S2Options](/docs/api/general/S2Options), reset?: boolean) => void | `reset` 参数需在 `@antv/s2-v1.34.0`版本使用 |
+| setDataCfg | 更新数据配置 | `(dataCfg: T extends true ?` [`S2DataConfig`](/docs/api/general/S2DataConfig) `: Partial<`[`S2DataConfig`](/docs/api/general/S2DataConfig)`>, reset?: T) => void` | `reset` 参数需在 `@antv/s2@^1.34.0`版本使用 |
+| setOptions | 更新表格配置 | (options: [S2Options](/docs/api/general/S2Options), reset?: boolean) => void | `reset` 参数需在 `@antv/s2@^1.34.0`版本使用 |
| render | 重新渲染表格,如果 `reloadData` = true, 则会重新计算数据,`reBuildDataSet` = true, 重新构建数据集,`reBuildHiddenColumnsDetail` = true 重新构建隐藏列信息 | `(reloadData?: boolean, { reBuildDataSet?: boolean; reBuildHiddenColumnsDetail?: boolean }) => void` | |
| destroy | 销毁表格 | `() => void` | |
| setThemeCfg | 更新主题配置 (含主题 schema, 色板,主题名) | (themeCfg: [ThemeCfg](/docs/api/general/S2Theme/#themecfg)) => void | |
@@ -69,7 +69,8 @@ s2.isPivotMode()
| getTotalsConfig | 获取总计小计配置 | (dimension: string) => [Total](/docs/api/general/S2Options#totals) | |
| getInitColumnLeafNodes | 获取初次渲染的列头叶子节点 (比如:隐藏列头前) | () => [Node[]](/docs/api/basic-class/node/) | |
| getCanvasElement | 获取表格对应的 `` HTML 元素 | () => [HTMLCanvasElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement) | |
-| clearColumnLeafNodes | 清空存储在 store 中的初始叶子节点 | () => void | |
+| clearColumnLeafNodes | 清空存储在 store 中的初始叶子节点 (已废弃,请使用 `clearInitColumnLeafNodes` ) | () => void | |
+| clearInitColumnLeafNodes | 清空存储在 store 中的初始叶子节点 | () => void | `@antv/s2@^1.54.3` |
| updateSortMethodMap | 更新存储在 store 中的节点排序方式 map, replace 为是否覆盖上一次的值 | (nodeId: string, sortMethod: string, replace?: boolean) => void | |
| getMenuDefaultSelectedKeys | 获取 tooltip 中选中的菜单项 key 值 | `(nodeId: string) => string[]` | |
| measureText | 获取文本在画布中的测量信息 | (text: `string`, font: [TextTheme](/docs/api/general/S2Theme#texttheme)) => [TextMetrics](https://developer.mozilla.org/zh-CN/docs/Web/API/TextMetrics) \| `null` | |
diff --git a/s2-site/examples/analysis/sort/demo/table-sort.tsx b/s2-site/examples/analysis/sort/demo/table-sort.tsx
index 7313e461d7..44404870ca 100644
--- a/s2-site/examples/analysis/sort/demo/table-sort.tsx
+++ b/s2-site/examples/analysis/sort/demo/table-sort.tsx
@@ -110,7 +110,7 @@ fetch('https://assets.antv.antgroup.com/s2/basic-table-mode.json')
sortFieldId: 'price',
sortMethod: 'DESC',
query: {
- city: '浙江',
+ province: '浙江',
},
},
],
diff --git a/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts b/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
index 82b5baa7e1..3708b6a024 100644
--- a/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
+++ b/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
@@ -1,5 +1,33 @@
import { PivotSheet, S2Event } from '@antv/s2';
+function hideSelectedColumns(s2) {
+ // 兼容多选
+ const selectedColumnNodes = s2.interaction
+ .getActiveCells()
+ .map((cell) => cell.getMeta());
+
+ const selectedColumnFields = selectedColumnNodes.map((node) => node.id);
+ s2.interaction.hideColumns(selectedColumnFields, true);
+}
+
+function getTooltipContent(cell, options) {
+ const { spreadsheet, isLeaf } = cell.getMeta();
+
+ if (!isLeaf || !spreadsheet.options.tooltip.operation.hiddenColumns) {
+ return null;
+ }
+
+ const button = document.createElement('button');
+ button.type = 'button';
+ button.innerHTML = '隐藏';
+ button.className = 'ant-btn';
+ button.addEventListener('click', () => {
+ hideSelectedColumns(spreadsheet);
+ });
+
+ return button;
+}
+
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/2a5dbbc8-d0a7-4d02-b7c9-34f6ca63cff6.json',
)
@@ -21,6 +49,7 @@ fetch(
// 开启手动隐藏, 叶子节点有效
hiddenColumns: true,
},
+ content: getTooltipContent,
},
};
const s2 = new PivotSheet(container, dataCfg, s2Options);
diff --git a/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts b/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
index 08f3ad06c3..8e65be2b8a 100644
--- a/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
+++ b/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
@@ -1,8 +1,34 @@
import { TableSheet, S2Event } from '@antv/s2';
-fetch(
- 'https://assets.antv.antgroup.com/s2/basic-table-mode.json',
-)
+function hideSelectedColumns(s2) {
+ // 兼容多选
+ const selectedColumnNodes = s2.interaction
+ .getActiveCells()
+ .map((cell) => cell.getMeta());
+
+ const selectedColumnFields = selectedColumnNodes.map((node) => node.field);
+ s2.interaction.hideColumns(selectedColumnFields, true);
+}
+
+function getTooltipContent(cell, options) {
+ const { spreadsheet, isLeaf } = cell.getMeta();
+
+ if (!isLeaf || !spreadsheet.options.tooltip.operation.hiddenColumns) {
+ return null;
+ }
+
+ const button = document.createElement('button');
+ button.type = 'button';
+ button.innerHTML = '隐藏';
+ button.className = 'ant-btn';
+ button.addEventListener('click', () => {
+ hideSelectedColumns(spreadsheet);
+ });
+
+ return button;
+}
+
+fetch('https://assets.antv.antgroup.com/s2/basic-table-mode.json')
.then((res) => res.json())
.then((data) => {
const container = document.getElementById('container');
@@ -48,13 +74,16 @@ fetch(
// 开启手动隐藏
hiddenColumns: true,
},
+ content: getTooltipContent,
},
};
+
const s2 = new TableSheet(container, s2DataConfig, s2Options);
s2.on(S2Event.LAYOUT_COLS_EXPANDED, (cell) => {
console.log('列头展开', cell);
});
+
s2.on(
S2Event.LAYOUT_COLS_HIDDEN,
(currentHiddenColumnsInfo, hiddenColumnsDetail) => {
diff --git a/s2-site/examples/react-component/switcher/demo/pure-switcher.tsx b/s2-site/examples/react-component/switcher/demo/pure-switcher.tsx
index 6811f5283d..5f339685b6 100644
--- a/s2-site/examples/react-component/switcher/demo/pure-switcher.tsx
+++ b/s2-site/examples/react-component/switcher/demo/pure-switcher.tsx
@@ -8,11 +8,14 @@ const switcherFields = {
allowEmpty: false,
},
columns: {
- items: [{ id: 'type' }],
+ items: [{ id: 'type', displayName: '类型 (type)' }],
},
values: {
selectable: true,
- items: [{ id: 'price' }, { id: 'cost' }],
+ items: [
+ { id: 'price', checked: true },
+ { id: 'cost', checked: false },
+ ],
},
};
diff --git a/s2-site/examples/react-component/switcher/demo/table.tsx b/s2-site/examples/react-component/switcher/demo/table.tsx
index a1e8e1f729..d9c0bc74f0 100644
--- a/s2-site/examples/react-component/switcher/demo/table.tsx
+++ b/s2-site/examples/react-component/switcher/demo/table.tsx
@@ -23,11 +23,11 @@ fetch(
columns: {
selectable: true,
items: [
- { id: 'province' },
- { id: 'city' },
- { id: 'type' },
- { id: 'sub_type' },
- { id: 'number' },
+ { id: 'province', displayName: '省份 (province)' },
+ { id: 'city', displayName: '城市 (city)' },
+ { id: 'type', displayName: '类别 (type)' },
+ { id: 'sub_type', displayName: '子类别 (sub_type)' },
+ { id: 'number', displayName: '数量 (number)' },
],
},
};