fix(plugin-chart-echarts): sort tooltip correctly (#30819)
This commit is contained in:
parent
d466383df2
commit
b02d18a39e
|
|
@ -62,6 +62,7 @@ import {
|
|||
extractDataTotalValues,
|
||||
extractSeries,
|
||||
extractShowValueIndexes,
|
||||
extractTooltipKeys,
|
||||
getAxisType,
|
||||
getColtypesMapping,
|
||||
getLegendProps,
|
||||
|
|
@ -584,9 +585,13 @@ 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 =
|
||||
|
|
@ -594,44 +599,46 @@ export default function transformProps(
|
|||
|
||||
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);
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import {
|
|||
extractDataTotalValues,
|
||||
extractSeries,
|
||||
extractShowValueIndexes,
|
||||
extractTooltipKeys,
|
||||
getAxisType,
|
||||
getColtypesMapping,
|
||||
getLegendProps,
|
||||
|
|
@ -251,7 +252,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];
|
||||
|
|
@ -543,11 +544,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);
|
||||
|
||||
|
|
@ -570,24 +572,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) {
|
||||
|
|
|
|||
|
|
@ -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]];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import {
|
|||
extractGroupbyLabel,
|
||||
extractSeries,
|
||||
extractShowValueIndexes,
|
||||
extractTooltipKeys,
|
||||
formatSeriesName,
|
||||
getAxisType,
|
||||
getChartPadding,
|
||||
|
|
@ -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']);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue