From 67d8ed5a700fe3b171c5724afbd6acadb5728e43 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Sat, 21 Feb 2026 22:11:01 -0800 Subject: [PATCH] fix(echarts): Show full labels in bar chart tooltips Fixes #31864 When bar chart axis labels are visually truncated by ECharts due to space constraints, the tooltip now shows the full label text by preferring the axisValue/axisValueLabel properties which contain the complete text. This allows users to hover over data points and see the full name even when the axis label is shortened for display purposes. Co-Authored-By: Claude Opus 4.5 --- .../src/Timeseries/transformProps.ts | 6 +- .../test/Timeseries/transformProps.test.ts | 96 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts index 114c374d659..266d7c0d8cc 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts @@ -1010,8 +1010,12 @@ export default function transformProps( trigger: richTooltip ? 'axis' : 'item', formatter: (params: any) => { const [xIndex, yIndex] = isHorizontal ? [1, 0] : [0, 1]; + // For axis tooltips, prefer axisValue/axisValueLabel which contains the full label + // even when the axis label is visually truncated const xValue: number = richTooltip - ? params[0].value[xIndex] + ? (params[0].axisValue ?? + params[0].axisValueLabel ?? + params[0].value[xIndex]) : params.value[xIndex]; const forecastValue: CallbackDataParams[] = richTooltip ? params diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts index 373cf6a0d54..d9c1683d415 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts @@ -1520,3 +1520,99 @@ test('should assign distinct dash patterns for multiple time offsets consistentl // must be different patterns expect(symbol1).not.toEqual(symbol2); }); + +describe('Tooltip with long labels', () => { + test('should use axisValue for tooltip when available (richTooltip)', () => { + const longLabelData: ChartDataResponseResult[] = [ + createTestQueryData([ + { + 'This is a very long category name that would normally be truncated': 100, + __timestamp: 599616000000, + }, + { + 'Another extremely long category name for testing purposes': 200, + __timestamp: 599916000000, + }, + ]), + ]; + + const chartProps = createTestChartProps({ + formData: { + richTooltip: true, + }, + queriesData: longLabelData, + }); + + const transformedProps = transformProps(chartProps); + + // Get the tooltip formatter function + const tooltipFormatter = (transformedProps.echartOptions as any).tooltip + .formatter; + + // Simulate params from ECharts with axisValue containing full label + // Use distinct values for axisValue and seriesName to verify axisValue is used + const mockParams = [ + { + axisValue: + 'This is a very long category name that would normally be truncated', + value: [599616000000, 100], + seriesName: 'Some Series Name', + }, + ]; + + // Call the formatter and check it uses the full label from axisValue + const result = tooltipFormatter(mockParams); + expect(result).toContain( + 'This is a very long category name that would normally be truncated', + ); + }); + + test('should fallback to value when axisValue is not available', () => { + const chartProps = createTestChartProps({ + formData: { + richTooltip: true, + }, + }); + + const transformedProps = transformProps(chartProps); + + const tooltipFormatter = (transformedProps.echartOptions as any).tooltip + .formatter; + + // Simulate params without axisValue + const mockParams = [ + { + value: [599616000000, 1], + seriesName: 'San Francisco', + }, + ]; + + // Should still work with fallback to value + const result = tooltipFormatter(mockParams); + expect(result).toBeDefined(); + expect(typeof result).toBe('string'); + }); + + test('should handle item tooltips correctly', () => { + const chartProps = createTestChartProps({ + formData: { + richTooltip: false, + }, + }); + + const transformedProps = transformProps(chartProps); + + const tooltipFormatter = (transformedProps.echartOptions as any).tooltip + .formatter; + + // For item tooltips, params is a single object + const mockParams = { + value: [599616000000, 1], + seriesName: 'San Francisco', + }; + + const result = tooltipFormatter(mockParams); + expect(result).toBeDefined(); + expect(typeof result).toBe('string'); + }); +});