Skip to content

Commit

Permalink
fix(plugin-chart-echarts): sort tooltip correctly (#30819)
Browse files Browse the repository at this point in the history
(cherry picked from commit b02d18a)
  • Loading branch information
villebro authored and sadpandajoe committed Nov 1, 2024
1 parent db311eb commit 008ab20
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
extractDataTotalValues,
extractSeries,
extractShowValueIndexes,
extractTooltipKeys,
getAxisType,
getColtypesMapping,
getLegendProps,
Expand Down Expand Up @@ -581,54 +582,60 @@ export default function transformProps(
: params.value[0];
const forecastValue: any[] = richTooltip ? params : [params];

if (richTooltip && tooltipSortByMetric) {
forecastValue.sort((a, b) => b.data[1] - a.data[1]);
}
const sortedKeys = extractTooltipKeys(
forecastValue,
// horizontal mode is not supported in mixed series chart
1,
richTooltip,
tooltipSortByMetric,
);

const rows: string[][] = [];
const forecastValues =
extractForecastValuesFromTooltipParams(forecastValue);

const keys = Object.keys(forecastValues);
let focusedRow;
keys.forEach(key => {
const value = forecastValues[key];
// if there are no dimensions, key is a verbose name of a metric,
// otherwise it is a comma separated string where the first part is metric name
let formatterKey;
if (primarySeries.has(key)) {
formatterKey =
groupby.length === 0 ? inverted[key] : labelMap[key]?.[0];
} else {
formatterKey =
groupbyB.length === 0 ? inverted[key] : labelMapB[key]?.[0];
}
const tooltipFormatter = getFormatter(
customFormatters,
formatter,
metrics,
formatterKey,
!!contributionMode,
);
const tooltipFormatterSecondary = getFormatter(
customFormattersSecondary,
formatterSecondary,
metricsB,
formatterKey,
!!contributionMode,
);
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter: primarySeries.has(key)
? tooltipFormatter
: tooltipFormatterSecondary,
sortedKeys
.filter(key => keys.includes(key))
.forEach(key => {
const value = forecastValues[key];
// if there are no dimensions, key is a verbose name of a metric,
// otherwise it is a comma separated string where the first part is metric name
let formatterKey;
if (primarySeries.has(key)) {
formatterKey =
groupby.length === 0 ? inverted[key] : labelMap[key]?.[0];
} else {
formatterKey =
groupbyB.length === 0 ? inverted[key] : labelMapB[key]?.[0];
}
const tooltipFormatter = getFormatter(
customFormatters,
formatter,
metrics,
formatterKey,
!!contributionMode,
);
const tooltipFormatterSecondary = getFormatter(
customFormattersSecondary,
formatterSecondary,
metricsB,
formatterKey,
!!contributionMode,
);
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter: primarySeries.has(key)
? tooltipFormatter
: tooltipFormatterSecondary,
});
rows.push(row);
if (key === focusedSeries) {
focusedRow = rows.length - 1;
}
});
rows.push(row);
if (key === focusedSeries) {
focusedRow = rows.length - 1;
}
});
return tooltipHtml(rows, tooltipFormatter(xValue), focusedRow);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
extractDataTotalValues,
extractSeries,
extractShowValueIndexes,
extractTooltipKeys,
getAxisType,
getColtypesMapping,
getLegendProps,
Expand Down Expand Up @@ -249,7 +250,7 @@ export default function transformProps(
legendState,
});
const seriesContexts = extractForecastSeriesContexts(
Object.values(rawSeries).map(series => series.name as string),
rawSeries.map(series => series.name as string),
);
const isAreaExpand = stack === StackControlsValue.Expand;
const xAxisDataType = dataTypes?.[xAxisLabel] ?? dataTypes?.[xAxisOrig];
Expand Down Expand Up @@ -539,11 +540,12 @@ export default function transformProps(
? params[0].value[xIndex]
: params.value[xIndex];
const forecastValue: any[] = richTooltip ? params : [params];

if (richTooltip && tooltipSortByMetric) {
forecastValue.sort((a, b) => b.data[yIndex] - a.data[yIndex]);
}

const sortedKeys = extractTooltipKeys(
forecastValue,
yIndex,
richTooltip,
tooltipSortByMetric,
);
const forecastValues: Record<string, ForecastValue> =
extractForecastValuesFromTooltipParams(forecastValue, isHorizontal);

Expand All @@ -566,24 +568,28 @@ export default function transformProps(
const showPercentage = showTotal && !forcePercentFormatter;
const keys = Object.keys(forecastValues);
let focusedRow;
keys.forEach(key => {
const value = forecastValues[key];
if (value.observation === 0 && stack) {
return;
}
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter,
sortedKeys
.filter(key => keys.includes(key))
.forEach(key => {
const value = forecastValues[key];
if (value.observation === 0 && stack) {
return;
}
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter,
});
if (showPercentage && value.observation !== undefined) {
row.push(
percentFormatter.format(value.observation / (total || 1)),
);
}
rows.push(row);
if (key === focusedSeries) {
focusedRow = rows.length - 1;
}
});
if (showPercentage && value.observation !== undefined) {
row.push(percentFormatter.format(value.observation / (total || 1)));
}
rows.push(row);
if (key === focusedSeries) {
focusedRow = rows.length - 1;
}
});
if (stack) {
rows.reverse();
if (focusedRow !== undefined) {
Expand Down
19 changes: 19 additions & 0 deletions superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,3 +642,22 @@ export function getTimeCompareStackId(
}) || defaultId
);
}

const TOOLTIP_SERIES_KEY = 'seriesId';
export function extractTooltipKeys(
forecastValue: any[],
yIndex: number,
richTooltip?: boolean,
tooltipSortByMetric?: boolean,
): string[] {
if (richTooltip && tooltipSortByMetric) {
return forecastValue
.slice()
.sort((a, b) => b.data[yIndex] - a.data[yIndex])
.map(value => value[TOOLTIP_SERIES_KEY]);
}
if (richTooltip) {
return forecastValue.map(s => s[TOOLTIP_SERIES_KEY]);
}
return [forecastValue[0][TOOLTIP_SERIES_KEY]];
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
extractGroupbyLabel,
extractSeries,
extractShowValueIndexes,
extractTooltipKeys,
formatSeriesName,
getAxisType,
getChartPadding,
Expand Down Expand Up @@ -1072,3 +1073,29 @@ describe('getTimeCompareStackId', () => {
expect(result).toEqual('123');
});
});

const forecastValue = [
{
data: [0, 1],
seriesId: 'foo',
},
{
data: [0, 2],
seriesId: 'bar',
},
];

test('extractTooltipKeys with rich tooltip', () => {
const result = extractTooltipKeys(forecastValue, 1, true, false);
expect(result).toEqual(['foo', 'bar']);
});

test('extractTooltipKeys with rich tooltip and sorting by metrics', () => {
const result = extractTooltipKeys(forecastValue, 1, true, true);
expect(result).toEqual(['bar', 'foo']);
});

test('extractTooltipKeys with non-rich tooltip', () => {
const result = extractTooltipKeys(forecastValue, 1, false, false);
expect(result).toEqual(['foo']);
});

0 comments on commit 008ab20

Please sign in to comment.