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'); + }); +});