feat: Utility function to render chart tooltips (#27950)

This commit is contained in:
Michael S. Molina
2024-05-07 13:00:30 -03:00
committed by GitHub
parent 467e612533
commit b549977f05
23 changed files with 512 additions and 425 deletions

View File

@@ -35,10 +35,12 @@ import {
isIntervalAnnotationLayer,
isPhysicalColumn,
isTimeseriesAnnotationLayer,
NumberFormats,
QueryFormData,
QueryFormMetric,
TimeseriesChartDataResponseResult,
TimeseriesDataRecord,
tooltipHtml,
ValueFormatter,
} from '@superset-ui/core';
import { getOriginalSeries } from '@superset-ui/chart-controls';
@@ -89,6 +91,7 @@ import {
import { TIMEGRAIN_TO_TIMESTAMP, TIMESERIES_CONSTANTS } from '../constants';
import { getDefaultTooltip } from '../utils/tooltip';
import {
getPercentFormatter,
getTooltipTimeFormatter,
getXAxisFormatter,
getYAxisFormatter,
@@ -231,6 +234,7 @@ export default function transformProps(
const xAxisDataType = dataTypes?.[xAxisLabel] ?? dataTypes?.[xAxisOrig];
const xAxisType = getAxisType(stack, xAxisForceCategorical, xAxisDataType);
const series: SeriesOption[] = [];
const percentFormatter = getPercentFormatter(NumberFormats.PERCENT_2_POINT);
const formatter = contributionMode
? getNumberFormatter(',.0%')
: currencyFormat?.symbol
@@ -581,11 +585,23 @@ export default function transformProps(
forecastValue.sort((a, b) => b.data[1] - a.data[1]);
}
const rows: Array<string> = [`${tooltipFormatter(xValue)}`];
const rows: string[][] = [];
const forecastValues =
extractForecastValuesFromTooltipParams(forecastValue);
Object.keys(forecastValues).forEach(key => {
const isForecast = Object.values(forecastValues).some(
value =>
value.forecastTrend || value.forecastLower || value.forecastUpper,
);
const total = Object.values(forecastValues).reduce(
(acc, value) =>
value.observation !== undefined ? acc + value.observation : acc,
0,
);
const showTotal = richTooltip && !isForecast;
const keys = Object.keys(forecastValues);
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
@@ -611,18 +627,30 @@ export default function transformProps(
formatterKey,
!!contributionMode,
);
const content = formatForecastTooltipSeries({
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter: primarySeries.has(key)
? tooltipFormatter
: tooltipFormatterSecondary,
});
const contentStyle =
key === focusedSeries ? 'font-weight: 700' : 'opacity: 0.7';
rows.push(`<span style="${contentStyle}">${content}</span>`);
if (showTotal && value.observation !== undefined) {
row.push(percentFormatter.format(value.observation / (total || 1)));
}
rows.push(row);
});
return rows.join('<br />');
if (showTotal) {
rows.push([
'Total',
formatter.format(total),
percentFormatter.format(1),
]);
}
return tooltipHtml(
rows,
tooltipFormatter(xValue),
keys.findIndex(key => key === focusedSeries),
);
},
},
legend: {