feat: Dynamic currency (#36416)

This commit is contained in:
Richard Fogaca Nienkotter
2026-01-17 02:58:41 -03:00
committed by GitHub
parent 896947c787
commit f4474b2e3e
72 changed files with 3068 additions and 173 deletions

View File

@@ -82,7 +82,11 @@ export default function transformProps(chartProps: ChartProps) {
height,
formData,
queriesData,
datasource: { currencyFormats = {}, columnFormats = {} },
datasource: {
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
},
} = chartProps;
const {
boldText,
@@ -100,7 +104,8 @@ export default function transformProps(chartProps: ChartProps) {
subtitleFontSize,
columnConfig = {},
} = formData;
const { data: dataA = [] } = queriesData[0];
const { data: dataA = [], detected_currency: detectedCurrency } =
queriesData[0] || {};
const data = dataA;
const metricName = metric ? getMetricLabel(metric) : '';
const metrics = chartProps.datasource?.metrics || [];
@@ -162,6 +167,10 @@ export default function transformProps(chartProps: ChartProps) {
columnFormats,
metricEntry?.d3format || yAxisFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const compTitles = {

View File

@@ -42,7 +42,11 @@ export default function transformProps(
formData,
rawFormData,
hooks,
datasource: { currencyFormats = {}, columnFormats = {} },
datasource: {
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
},
theme,
} = chartProps;
const {
@@ -60,7 +64,11 @@ export default function transformProps(
subheaderFontSize,
} = formData;
const refs: Refs = {};
const { data = [], coltypes = [] } = queriesData[0] || {};
const {
data = [],
coltypes = [],
detected_currency: detectedCurrency,
} = queriesData[0] || {};
const granularity = extractTimegrain(rawFormData as QueryFormData);
const metrics = chartProps.datasource?.metrics || [];
const originalLabel = getOriginalLabel(metric, metrics);
@@ -92,6 +100,10 @@ export default function transformProps(
columnFormats,
metricEntry?.d3format || yAxisFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const headerFormatter =

View File

@@ -83,7 +83,11 @@ export default function transformProps(
hooks,
inContextMenu,
theme,
datasource: { currencyFormats = {}, columnFormats = {} },
datasource: {
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
},
} = chartProps;
const {
colorPicker,
@@ -117,6 +121,7 @@ export default function transformProps(
coltypes = [],
from_dttm: fromDatetime,
to_dttm: toDatetime,
detected_currency: detectedCurrency,
} = queriesData[0];
const aggregatedQueryData = queriesData.length > 1 ? queriesData[1] : null;
@@ -259,6 +264,10 @@ export default function transformProps(
columnFormats,
metricEntry?.d3format || yAxisFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const xAxisFormatter = getXAxisFormatter(timeFormat);
const yAxisFormatter =

View File

@@ -31,7 +31,7 @@ import { ColorFormatters } from '@superset-ui/chart-controls';
import { BaseChartProps, Refs } from '../types';
export interface BigNumberDatum {
[key: string]: number | null;
[key: string]: number | string | null;
}
export type BigNumberTotalFormData = QueryFormData & {

View File

@@ -99,6 +99,7 @@ export default function transformProps(
datasource,
} = chartProps;
const data: DataRecord[] = queriesData[0].data || [];
const detectedCurrency = queriesData[0]?.detected_currency;
const coltypeMapping = getColtypesMapping(queriesData[0]);
const {
colorScheme,
@@ -127,7 +128,11 @@ export default function transformProps(
...DEFAULT_FUNNEL_FORM_DATA,
...formData,
};
const { currencyFormats = {}, columnFormats = {} } = datasource;
const {
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
} = datasource;
const refs: Refs = {};
const metricLabel = getMetricLabel(metric);
const groupbyLabels = groupby.map(getColumnLabel);
@@ -154,6 +159,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const transformedData: {

View File

@@ -112,6 +112,7 @@ export default function transformProps(
verboseMap = {},
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
} = datasource;
const {
groupby,
@@ -139,6 +140,7 @@ export default function transformProps(
}: EchartsGaugeFormData = { ...DEFAULT_GAUGE_FORM_DATA, ...formData };
const refs: Refs = {};
const data = (queriesData[0]?.data || []) as DataRecord[];
const detectedCurrency = queriesData[0]?.detected_currency;
const coltypeMapping = getColtypesMapping(queriesData[0]);
const numberFormatter = getValueFormatter(
metric,
@@ -146,6 +148,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
const axisLineWidth = calculateAxisLineWidth(data, fontSize, overlap);

View File

@@ -201,8 +201,17 @@ export default function transformProps(
const xAxisLabel = getColumnLabel(xAxis);
// groupby is overridden to be a single value
const yAxisLabel = getColumnLabel(groupby as unknown as QueryFormColumn);
const { data, colnames, coltypes } = queriesData[0];
const { columnFormats = {}, currencyFormats = {} } = datasource;
const {
data,
colnames,
coltypes,
detected_currency: detectedCurrency,
} = queriesData[0];
const {
columnFormats = {},
currencyFormats = {},
currencyCodeColumn,
} = datasource;
const colorColumn = normalized ? 'rank' : metricLabel;
const colors = getSequentialSchemeRegistry().get(linearColorScheme)?.colors;
const getAxisFormatter =
@@ -225,6 +234,10 @@ export default function transformProps(
columnFormats,
yAxisFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
let [min, max] = (valueBounds || []).map(parseAxisBound);

View File

@@ -36,6 +36,7 @@ import {
isTimeseriesAnnotationLayer,
QueryFormData,
QueryFormMetric,
resolveAutoCurrency,
TimeseriesChartDataResponseResult,
TimeseriesDataRecord,
tooltipHtml,
@@ -138,10 +139,11 @@ export default function transformProps(
verboseMap = {},
currencyFormats = {},
columnFormats = {},
currencyCodeColumn,
} = datasource;
const { label_map: labelMap } =
const { label_map: labelMap, detected_currency: backendDetectedCurrency } =
queriesData[0] as TimeseriesChartDataResponseResult;
const { label_map: labelMapB } =
const { label_map: labelMapB, detected_currency: backendDetectedCurrencyB } =
queriesData[1] as TimeseriesChartDataResponseResult;
const data1 = (queriesData[0].data || []) as TimeseriesDataRecord[];
const data2 = (queriesData[1].data || []) as TimeseriesDataRecord[];
@@ -279,20 +281,34 @@ export default function transformProps(
xAxisType,
});
const series: SeriesOption[] = [];
const resolvedCurrency = resolveAutoCurrency(
currencyFormat,
backendDetectedCurrency,
data1,
currencyCodeColumn,
);
const resolvedCurrencySecondary = resolveAutoCurrency(
currencyFormatSecondary,
backendDetectedCurrencyB,
data2,
currencyCodeColumn,
);
const formatter = contributionMode
? getNumberFormatter(',.0%')
: currencyFormat?.symbol
: resolvedCurrency?.symbol
? new CurrencyFormatter({
d3Format: yAxisFormat,
currency: currencyFormat,
currency: resolvedCurrency,
})
: getNumberFormatter(yAxisFormat);
const formatterSecondary = contributionMode
? getNumberFormatter(',.0%')
: currencyFormatSecondary?.symbol
: resolvedCurrencySecondary?.symbol
? new CurrencyFormatter({
d3Format: yAxisFormatSecondary,
currency: currencyFormatSecondary,
currency: resolvedCurrencySecondary,
})
: getNumberFormatter(yAxisFormatSecondary);
const customFormatters = buildCustomFormatters(
@@ -300,14 +316,18 @@ export default function transformProps(
currencyFormats,
columnFormats,
yAxisFormat,
currencyFormat,
resolvedCurrency,
data1,
currencyCodeColumn,
);
const customFormattersSecondary = buildCustomFormatters(
[...ensureIsArray(metrics), ...ensureIsArray(metricsB)],
currencyFormats,
columnFormats,
yAxisFormatSecondary,
currencyFormatSecondary,
resolvedCurrencySecondary,
data2,
currencyCodeColumn,
);
const primarySeries = new Set<string>();

View File

@@ -135,8 +135,13 @@ export default function transformProps(
emitCrossFilters,
datasource,
} = chartProps;
const { columnFormats = {}, currencyFormats = {} } = datasource;
const { data: rawData = [] } = queriesData[0];
const {
columnFormats = {},
currencyFormats = {},
currencyCodeColumn,
} = datasource;
const { data: rawData = [], detected_currency: detectedCurrency } =
queriesData[0];
const coltypeMapping = getColtypesMapping(queriesData[0]);
const {
@@ -181,6 +186,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
rawData,
currencyCodeColumn,
detectedCurrency,
);
let data = rawData;

View File

@@ -170,7 +170,7 @@ export default function transformProps(
emitCrossFilters,
datasource,
} = chartProps;
const { data = [] } = queriesData[0];
const { data = [], detected_currency: detectedCurrency } = queriesData[0];
const coltypeMapping = getColtypesMapping(queriesData[0]);
const {
groupby = [],
@@ -192,6 +192,7 @@ export default function transformProps(
currencyFormats = {},
columnFormats = {},
verboseMap = {},
currencyCodeColumn,
} = datasource;
const refs: Refs = {};
const primaryValueFormatter = getValueFormatter(
@@ -200,6 +201,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const secondaryValueFormatter = secondaryMetric
? getValueFormatter(
@@ -208,6 +213,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
)
: undefined;

View File

@@ -37,6 +37,7 @@ import {
isIntervalAnnotationLayer,
isPhysicalColumn,
isTimeseriesAnnotationLayer,
resolveAutoCurrency,
TimeseriesChartDataResponseResult,
NumberFormats,
} from '@superset-ui/core';
@@ -134,10 +135,14 @@ export default function transformProps(
verboseMap = {},
columnFormats = {},
currencyFormats = {},
currencyCodeColumn,
} = datasource;
const [queryData] = queriesData;
const { data = [], label_map = {} } =
queryData as TimeseriesChartDataResponseResult;
const {
data = [],
label_map = {},
detected_currency: backendDetectedCurrency,
} = queryData as TimeseriesChartDataResponseResult;
const dataTypes = getColtypesMapping(queryData);
const annotationData = getAnnotationData(chartProps);
@@ -275,15 +280,29 @@ export default function transformProps(
const percentFormatter = forcePercentFormatter
? getPercentFormatter(yAxisFormat)
: getPercentFormatter(NumberFormats.PERCENT_2_POINT);
const defaultFormatter = currencyFormat?.symbol
? new CurrencyFormatter({ d3Format: yAxisFormat, currency: currencyFormat })
// Resolve currency for AUTO mode (backend detection takes precedence)
const resolvedCurrency = resolveAutoCurrency(
currencyFormat,
backendDetectedCurrency,
data,
currencyCodeColumn,
);
const defaultFormatter = resolvedCurrency?.symbol
? new CurrencyFormatter({
d3Format: yAxisFormat,
currency: resolvedCurrency,
})
: getNumberFormatter(yAxisFormat);
const customFormatters = buildCustomFormatters(
metrics,
currencyFormats,
columnFormats,
yAxisFormat,
currencyFormat,
resolvedCurrency,
data,
currencyCodeColumn,
);
const array = ensureIsArray(chartProps.rawFormData?.time_compare);

View File

@@ -119,8 +119,12 @@ export default function transformProps(
emitCrossFilters,
datasource,
} = chartProps;
const { data = [] } = queriesData[0];
const { columnFormats = {}, currencyFormats = {} } = datasource;
const { data = [], detected_currency: detectedCurrency } = queriesData[0];
const {
columnFormats = {},
currencyFormats = {},
currencyCodeColumn,
} = datasource;
const { setDataMask = () => {}, onContextMenu } = hooks;
const coltypeMapping = getColtypesMapping(queriesData[0]);
const BORDER_COLOR = theme.colorBgBase;
@@ -150,6 +154,10 @@ export default function transformProps(
columnFormats,
numberFormat,
currencyFormat,
undefined,
data,
currencyCodeColumn,
detectedCurrency,
);
const formatter = (params: TreemapSeriesCallbackDataParams) =>