Skip to content

Commit 33f8510

Browse files
rusackasclaude
andcommitted
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 <noreply@anthropic.com>
1 parent a87a006 commit 33f8510

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,12 @@ export default function transformProps(
686686
trigger: richTooltip ? 'axis' : 'item',
687687
formatter: (params: any) => {
688688
const [xIndex, yIndex] = isHorizontal ? [1, 0] : [0, 1];
689+
// For axis tooltips, prefer axisValue/axisValueLabel which contains the full label
690+
// even when the axis label is visually truncated
689691
const xValue: number = richTooltip
690-
? params[0].value[xIndex]
692+
? (params[0].axisValue ??
693+
params[0].axisValueLabel ??
694+
params[0].value[xIndex])
691695
: params.value[xIndex];
692696
const forecastValue: CallbackDataParams[] = richTooltip
693697
? params

superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,3 +1317,99 @@ test('should not apply axis bounds calculation when seriesType is not Bar for ho
13171317
// Should not have explicit max set when seriesType is not Bar
13181318
expect(xAxisRaw.max).toBeUndefined();
13191319
});
1320+
1321+
describe('Tooltip with long labels', () => {
1322+
test('should use axisValue for tooltip when available (richTooltip)', () => {
1323+
const longLabelData: ChartDataResponseResult[] = [
1324+
createTestQueryData([
1325+
{
1326+
'This is a very long category name that would normally be truncated': 100,
1327+
__timestamp: 599616000000,
1328+
},
1329+
{
1330+
'Another extremely long category name for testing purposes': 200,
1331+
__timestamp: 599916000000,
1332+
},
1333+
]),
1334+
];
1335+
1336+
const chartProps = createTestChartProps({
1337+
formData: {
1338+
richTooltip: true,
1339+
},
1340+
queriesData: longLabelData,
1341+
});
1342+
1343+
const transformedProps = transformProps(chartProps);
1344+
1345+
// Get the tooltip formatter function
1346+
const tooltipFormatter = (transformedProps.echartOptions as any).tooltip
1347+
.formatter;
1348+
1349+
// Simulate params from ECharts with axisValue containing full label
1350+
// Use distinct values for axisValue and seriesName to verify axisValue is used
1351+
const mockParams = [
1352+
{
1353+
axisValue:
1354+
'This is a very long category name that would normally be truncated',
1355+
value: [599616000000, 100],
1356+
seriesName: 'Some Series Name',
1357+
},
1358+
];
1359+
1360+
// Call the formatter and check it uses the full label from axisValue
1361+
const result = tooltipFormatter(mockParams);
1362+
expect(result).toContain(
1363+
'This is a very long category name that would normally be truncated',
1364+
);
1365+
});
1366+
1367+
test('should fallback to value when axisValue is not available', () => {
1368+
const chartProps = createTestChartProps({
1369+
formData: {
1370+
richTooltip: true,
1371+
},
1372+
});
1373+
1374+
const transformedProps = transformProps(chartProps);
1375+
1376+
const tooltipFormatter = (transformedProps.echartOptions as any).tooltip
1377+
.formatter;
1378+
1379+
// Simulate params without axisValue
1380+
const mockParams = [
1381+
{
1382+
value: [599616000000, 1],
1383+
seriesName: 'San Francisco',
1384+
},
1385+
];
1386+
1387+
// Should still work with fallback to value
1388+
const result = tooltipFormatter(mockParams);
1389+
expect(result).toBeDefined();
1390+
expect(typeof result).toBe('string');
1391+
});
1392+
1393+
test('should handle item tooltips correctly', () => {
1394+
const chartProps = createTestChartProps({
1395+
formData: {
1396+
richTooltip: false,
1397+
},
1398+
});
1399+
1400+
const transformedProps = transformProps(chartProps);
1401+
1402+
const tooltipFormatter = (transformedProps.echartOptions as any).tooltip
1403+
.formatter;
1404+
1405+
// For item tooltips, params is a single object
1406+
const mockParams = {
1407+
value: [599616000000, 1],
1408+
seriesName: 'San Francisco',
1409+
};
1410+
1411+
const result = tooltipFormatter(mockParams);
1412+
expect(result).toBeDefined();
1413+
expect(typeof result).toBe('string');
1414+
});
1415+
});

0 commit comments

Comments
 (0)