feat: Implement currencies formatter for saved metrics (#24517)

This commit is contained in:
Kamil Gabryjelski
2023-06-28 20:51:40 +02:00
committed by GitHub
parent e402c94a9f
commit 83ff4cd86a
61 changed files with 906 additions and 75 deletions

View File

@@ -22,6 +22,7 @@ import {
AnnotationLayer,
AxisType,
CategoricalColorNamespace,
CurrencyFormatter,
ensureIsArray,
GenericDataType,
getMetricLabel,
@@ -32,9 +33,13 @@ import {
isFormulaAnnotationLayer,
isIntervalAnnotationLayer,
isPhysicalColumn,
isSavedMetric,
isTimeseriesAnnotationLayer,
NumberFormats,
QueryFormMetric,
t,
TimeseriesChartDataResponseResult,
ValueFormatter,
} from '@superset-ui/core';
import {
extractExtraMetrics,
@@ -92,6 +97,36 @@ import {
TIMEGRAIN_TO_TIMESTAMP,
} from '../constants';
import { getDefaultTooltip } from '../utils/tooltip';
import {
buildCustomFormatters,
getCustomFormatter,
} from '../utils/valueFormatter';
const getYAxisFormatter = (
metrics: QueryFormMetric[],
forcePercentFormatter: boolean,
customFormatters: Record<string, ValueFormatter>,
yAxisFormat: string = NumberFormats.SMART_NUMBER,
) => {
if (forcePercentFormatter) {
return getNumberFormatter(',.0%');
}
const metricsArray = ensureIsArray(metrics);
if (
metricsArray.every(isSavedMetric) &&
metricsArray
.map(metric => customFormatters[metric])
.every(
(formatter, _, formatters) =>
formatter instanceof CurrencyFormatter &&
(formatter as CurrencyFormatter)?.currency?.symbol ===
(formatters[0] as CurrencyFormatter)?.currency?.symbol,
)
) {
return customFormatters[metricsArray[0]];
}
return getNumberFormatter(yAxisFormat);
};
export default function transformProps(
chartProps: EchartsTimeseriesChartProps,
@@ -109,7 +144,11 @@ export default function transformProps(
inContextMenu,
emitCrossFilters,
} = chartProps;
const { verboseMap = {} } = datasource;
const {
verboseMap = {},
columnFormats = {},
currencyFormats = {},
} = datasource;
const [queryData] = queriesData;
const { data = [], label_map = {} } =
queryData as TimeseriesChartDataResponseResult;
@@ -232,8 +271,15 @@ export default function transformProps(
const xAxisType = getAxisType(xAxisDataType);
const series: SeriesOption[] = [];
const formatter = getNumberFormatter(
contributionMode || isAreaExpand ? ',.0%' : yAxisFormat,
const forcePercentFormatter = Boolean(contributionMode || isAreaExpand);
const percentFormatter = getNumberFormatter(',.0%');
const defaultFormatter = getNumberFormatter(yAxisFormat);
const customFormatters = buildCustomFormatters(
metrics,
currencyFormats,
columnFormats,
yAxisFormat,
);
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
@@ -262,7 +308,13 @@ export default function transformProps(
seriesType,
legendState,
stack,
formatter,
formatter: forcePercentFormatter
? percentFormatter
: getCustomFormatter(
customFormatters,
metrics,
labelMap[seriesName]?.[0],
) ?? defaultFormatter,
showValue,
onlyTotal,
totalStackedValues: sortedTotalValues,
@@ -440,7 +492,14 @@ export default function transformProps(
max,
minorTick: { show: true },
minorSplitLine: { show: minorSplitLine },
axisLabel: { formatter },
axisLabel: {
formatter: getYAxisFormatter(
metrics,
forcePercentFormatter,
customFormatters,
yAxisFormat,
),
},
scale: truncateYAxis,
name: yAxisTitle,
nameGap: convertInteger(yAxisTitleMargin),
@@ -485,10 +544,17 @@ export default function transformProps(
if (value.observation === 0 && stack) {
return;
}
// 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
const formatterKey =
groupby.length === 0 ? inverted[key] : labelMap[key]?.[0];
const content = formatForecastTooltipSeries({
...value,
seriesName: key,
formatter,
formatter: forcePercentFormatter
? percentFormatter
: getCustomFormatter(customFormatters, metrics, formatterKey) ??
defaultFormatter,
});
if (!legendState || legendState[key]) {
rows.push(`<span style="font-weight: 700">${content}</span>`);