diff --git a/packages/s2-core/__tests__/unit/utils/tooltip-spec.ts b/packages/s2-core/__tests__/unit/utils/tooltip-spec.ts index c9d259e743..01e1f1600d 100644 --- a/packages/s2-core/__tests__/unit/utils/tooltip-spec.ts +++ b/packages/s2-core/__tests__/unit/utils/tooltip-spec.ts @@ -2,9 +2,11 @@ import { createFakeSpreadSheet, createMockCellInfo, createPivotSheet, + getContainer, } from 'tests/util/helpers'; import type { BBox } from '@antv/g-canvas'; import { omit } from 'lodash'; +import * as dataConfig from 'tests/data/mock-dataset.json'; import type { CellMeta } from '@/common/interface/interaction'; import { getAutoAdjustPosition, @@ -28,6 +30,7 @@ import { VALUE_FIELD, TOOLTIP_CONTAINER_SHOW_CLS, TOOLTIP_CONTAINER_HIDE_CLS, + PivotSheet, } from '@/index'; import type { BaseFacet } from '@/facet/base-facet'; @@ -465,6 +468,68 @@ describe('Tooltip Utils Tests', () => { }); }; + const getTotalInfo = (isTotalCell: boolean, count: number) => { + const dataCells = s2.interaction.getPanelGroupAllDataCells(); + const selectedCells = isTotalCell + ? [ + dataCells.find((cell) => { + const meta = cell.getMeta(); + return meta.isTotals; + }), + ] + : dataCells + .filter((cell) => { + const meta = cell.getMeta(); + return !meta.isTotals; + }) + .slice(0, count); + + const selectedCellMetas = selectedCells.map((cell) => + cell.getMeta(), + ) as unknown as CellMeta[]; + + jest + .spyOn(s2.interaction, 'getCells') + .mockImplementationOnce(() => selectedCellMetas); + + const tooltipData = getTooltipData({ + cellInfos: [selectedCellMetas], + options: { + showSingleTips: false, + }, + targetCell: null, + spreadsheet: s2, + }); + + const baseCellInfo = { + province: '浙江省', + sub_type: '桌子', + type: '家具', + }; + const value = isTotalCell ? 15420 : 18375; + const selectedData = isTotalCell + ? [getCellData(15420)] + : [ + getCellData(7789, false, { + ...baseCellInfo, + city: '杭州市', + }), + getCellData(2367, false, { + ...baseCellInfo, + city: '绍兴市', + }), + getCellData(3877, false, { + ...baseCellInfo, + city: '宁波市', + }), + getCellData(4342, false, { + ...baseCellInfo, + city: '舟山市', + }), + ]; + return { tooltipData, value, selectedData }; + }; + test('should get cell data info keys', () => { s2 = createFakeSpreadSheet(); @@ -500,75 +565,68 @@ describe('Tooltip Utils Tests', () => { col: colTotalOptions, }); s2.render(); + const { tooltipData, value, selectedData } = getTotalInfo( + isTotalCell, + count, + ); - const dataCells = s2.interaction.getPanelGroupAllDataCells(); - const selectedCells = isTotalCell - ? [ - dataCells.find((cell) => { - const meta = cell.getMeta(); - return meta.isTotals; - }), - ] - : dataCells - .filter((cell) => { - const meta = cell.getMeta(); - return !meta.isTotals; - }) - .slice(0, count); - - const selectedCellMetas = selectedCells.map((cell) => - cell.getMeta(), - ) as unknown as CellMeta[]; - - jest - .spyOn(s2.interaction, 'getCells') - .mockImplementationOnce(() => selectedCellMetas); - - const tooltipData = getTooltipData({ - cellInfos: [selectedCellMetas], - options: { - showSingleTips: false, + expect(tooltipData.summaries).toStrictEqual([ + { + name: '数量', + value, + selectedData, + originValue: value, }, - targetCell: null, - spreadsheet: s2, + ]); + + s2.destroy(); + }, + ); + + test.each([ + { count: 1, isTotalCell: true, name: '单选' }, + { count: 4, isTotalCell: false, name: '多选' }, + ])( + `should get data cell summary data info for %o when the meta set formatted`, + ({ count, isTotalCell }) => { + const customMeta = dataConfig.meta.map((meta) => { + if (meta.name === '数量') { + return { + ...meta, + formatter: (value: number) => `${value}%`, + }; + } + return meta; }); - const baseCellInfo = { - province: '浙江省', - sub_type: '桌子', - type: '家具', - }; - const value = isTotalCell ? 15420 : 18375; - const selectedData = isTotalCell - ? [getCellData(15420)] - : [ - getCellData(7789, false, { - ...baseCellInfo, - city: '杭州市', - }), - getCellData(2367, false, { - ...baseCellInfo, - city: '绍兴市', - }), - getCellData(3877, false, { - ...baseCellInfo, - city: '宁波市', - }), - getCellData(4342, false, { - ...baseCellInfo, - city: '舟山市', - }), - ]; + s2 = new PivotSheet( + getContainer(), + { + ...dataConfig, + meta: customMeta, + }, + { + totals: { + row: rowTotalOptions, + col: colTotalOptions, + }, + }, + ); + s2.render(); + + const { tooltipData, value, selectedData } = getTotalInfo( + isTotalCell, + count, + ); expect(tooltipData.summaries).toStrictEqual([ { name: '数量', - value, + value: `${value}%`, selectedData, + originValue: value, }, ]); - - s2.destroy(); }, ); @@ -612,6 +670,7 @@ describe('Tooltip Utils Tests', () => { type: '办公用品', }), ], + originValue: isTotalCell ? 43098 : 15420, }, ], }); diff --git a/packages/s2-core/src/common/interface/tooltip.ts b/packages/s2-core/src/common/interface/tooltip.ts index 824b477b99..3b7ea33339 100644 --- a/packages/s2-core/src/common/interface/tooltip.ts +++ b/packages/s2-core/src/common/interface/tooltip.ts @@ -50,10 +50,13 @@ export interface TooltipOptions { forceRender?: boolean; } +export type TooltipSummaryOptionsValue = number | string | undefined | null; + export interface TooltipSummaryOptions { - name: string; - value: number | string; + name: string | null; selectedData: TooltipDataItem[]; + value: TooltipSummaryOptionsValue; + originValue?: TooltipSummaryOptionsValue; } export interface TooltipNameTipsOptions { diff --git a/packages/s2-core/src/utils/tooltip.ts b/packages/s2-core/src/utils/tooltip.ts index 08c3df0056..82a2eb6080 100644 --- a/packages/s2-core/src/utils/tooltip.ts +++ b/packages/s2-core/src/utils/tooltip.ts @@ -43,6 +43,7 @@ import type { TooltipDetailListItem, Tooltip, ViewMeta, + TooltipSummaryOptionsValue, } from '../common/interface'; import type { S2CellType } from '../common/interface/interaction'; import type { @@ -480,18 +481,20 @@ export const getSummaries = (params: SummaryParam): TooltipSummaryOptions[] => { mapKeys(summary, (selected, field) => { const name = getSummaryName(spreadsheet, field, options?.isTotals); - let value: number | string = getShowValue?.(selected, VALUE_FIELD); + let value: TooltipSummaryOptionsValue = ''; + let originVal: TooltipSummaryOptionsValue = ''; - if (isTableMode) { - value = ''; - } else if (every(selected, (item) => isNotNumber(get(item, VALUE_FIELD)))) { + if (every(selected, (item) => isNotNumber(get(item, VALUE_FIELD)))) { const { placeholder } = spreadsheet.options; const emptyPlaceholder = getEmptyPlaceholder(summary, placeholder); // 如果选中的单元格都无数据,则显示"-" 或 options 里配置的占位符 value = emptyPlaceholder; + originVal = emptyPlaceholder; } else { const currentFormatter = getFieldFormatter(spreadsheet, field); const dataSum = getDataSumByField(selected, VALUE_FIELD); + + originVal = dataSum; value = currentFormatter?.(dataSum, selected) ?? parseFloat(dataSum.toPrecision(PRECISION)); // solve accuracy problems; @@ -500,6 +503,7 @@ export const getSummaries = (params: SummaryParam): TooltipSummaryOptions[] => { selectedData: selected, name, value, + originValue: originVal, }); }); diff --git a/packages/s2-react/src/components/tooltip/components/summary.tsx b/packages/s2-react/src/components/tooltip/components/summary.tsx index b0c5fbb3c0..a0e4a839fa 100644 --- a/packages/s2-react/src/components/tooltip/components/summary.tsx +++ b/packages/s2-react/src/components/tooltip/components/summary.tsx @@ -31,9 +31,15 @@ export const TooltipSummary: React.FC = React.memo( key={`${name}-${value}`} className={`${TOOLTIP_PREFIX_CLS}-summary-item`} > - - {name}({i18n('总和')}) - + {name ? ( + + {name} ({i18n('总和')}) + + ) : ( + +   + + )}