mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
feat: Implement support for currencies in more charts (#24594)
This commit is contained in:
parent
c573cfcd12
commit
d74d7eca23
@ -19,3 +19,4 @@
|
|||||||
|
|
||||||
export { default as CurrencyFormatter } from './CurrencyFormatter';
|
export { default as CurrencyFormatter } from './CurrencyFormatter';
|
||||||
export * from './CurrencyFormatter';
|
export * from './CurrencyFormatter';
|
||||||
|
export * from './utils';
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
import {
|
import {
|
||||||
Currency,
|
Currency,
|
||||||
CurrencyFormatter,
|
CurrencyFormatter,
|
||||||
@ -16,10 +34,8 @@ export const buildCustomFormatters = (
|
|||||||
) => {
|
) => {
|
||||||
const metricsArray = ensureIsArray(metrics);
|
const metricsArray = ensureIsArray(metrics);
|
||||||
return metricsArray.reduce((acc, metric) => {
|
return metricsArray.reduce((acc, metric) => {
|
||||||
const actualD3Format = isSavedMetric(metric)
|
|
||||||
? columnFormats[metric] ?? d3Format
|
|
||||||
: d3Format;
|
|
||||||
if (isSavedMetric(metric)) {
|
if (isSavedMetric(metric)) {
|
||||||
|
const actualD3Format = d3Format ?? columnFormats[metric];
|
||||||
return currencyFormats[metric]
|
return currencyFormats[metric]
|
||||||
? {
|
? {
|
||||||
...acc,
|
...acc,
|
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
buildCustomFormatters,
|
||||||
|
CurrencyFormatter,
|
||||||
|
getCustomFormatter,
|
||||||
|
getNumberFormatter,
|
||||||
|
getValueFormatter,
|
||||||
|
NumberFormatter,
|
||||||
|
ValueFormatter,
|
||||||
|
} from '@superset-ui/core';
|
||||||
|
|
||||||
|
it('buildCustomFormatters without saved metrics returns empty object', () => {
|
||||||
|
expect(
|
||||||
|
buildCustomFormatters(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
expressionType: 'SIMPLE',
|
||||||
|
aggregate: 'COUNT',
|
||||||
|
column: { column_name: 'test' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
',.1f',
|
||||||
|
),
|
||||||
|
).toEqual({});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
buildCustomFormatters(
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
',.1f',
|
||||||
|
),
|
||||||
|
).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('buildCustomFormatters with saved metrics returns custom formatters object', () => {
|
||||||
|
const customFormatters: Record<string, ValueFormatter> =
|
||||||
|
buildCustomFormatters(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
expressionType: 'SIMPLE',
|
||||||
|
aggregate: 'COUNT',
|
||||||
|
column: { column_name: 'test' },
|
||||||
|
},
|
||||||
|
'sum__num',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||||
|
},
|
||||||
|
{ sum__num: ',.2' },
|
||||||
|
',.1f',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(customFormatters).toEqual({
|
||||||
|
sum__num: expect.any(Function),
|
||||||
|
count: expect.any(Function),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(customFormatters.sum__num).toBeInstanceOf(CurrencyFormatter);
|
||||||
|
expect(customFormatters.count).toBeInstanceOf(NumberFormatter);
|
||||||
|
expect((customFormatters.sum__num as CurrencyFormatter).d3Format).toEqual(
|
||||||
|
',.1f',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('buildCustomFormatters uses dataset d3 format if not provided in control panel', () => {
|
||||||
|
const customFormatters: Record<string, ValueFormatter> =
|
||||||
|
buildCustomFormatters(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
expressionType: 'SIMPLE',
|
||||||
|
aggregate: 'COUNT',
|
||||||
|
column: { column_name: 'test' },
|
||||||
|
},
|
||||||
|
'sum__num',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||||
|
},
|
||||||
|
{ sum__num: ',.2' },
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect((customFormatters.sum__num as CurrencyFormatter).d3Format).toEqual(
|
||||||
|
',.2',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getCustomFormatter', () => {
|
||||||
|
const customFormatters = {
|
||||||
|
sum__num: new CurrencyFormatter({
|
||||||
|
currency: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||||
|
}),
|
||||||
|
count: getNumberFormatter(),
|
||||||
|
};
|
||||||
|
expect(getCustomFormatter(customFormatters, 'count')).toEqual(
|
||||||
|
customFormatters.count,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
getCustomFormatter(customFormatters, ['count', 'sum__num'], 'count'),
|
||||||
|
).toEqual(customFormatters.count);
|
||||||
|
expect(getCustomFormatter(customFormatters, ['count', 'sum__num'])).toEqual(
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getValueFormatter', () => {
|
||||||
|
expect(
|
||||||
|
getValueFormatter(['count', 'sum__num'], {}, {}, ',.1f'),
|
||||||
|
).toBeInstanceOf(NumberFormatter);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getValueFormatter(['count', 'sum__num'], {}, {}, ',.1f', 'count'),
|
||||||
|
).toBeInstanceOf(NumberFormatter);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getValueFormatter(
|
||||||
|
['count', 'sum__num'],
|
||||||
|
{ count: { symbol: 'USD', symbolPosition: 'prefix' } },
|
||||||
|
{},
|
||||||
|
',.1f',
|
||||||
|
'count',
|
||||||
|
),
|
||||||
|
).toBeInstanceOf(CurrencyFormatter);
|
||||||
|
});
|
@ -51,7 +51,7 @@ const propTypes = {
|
|||||||
leftMargin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
leftMargin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
metric: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
metric: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||||
normalized: PropTypes.bool,
|
normalized: PropTypes.bool,
|
||||||
numberFormat: PropTypes.string,
|
valueFormatter: PropTypes.object,
|
||||||
showLegend: PropTypes.bool,
|
showLegend: PropTypes.bool,
|
||||||
showPercentage: PropTypes.bool,
|
showPercentage: PropTypes.bool,
|
||||||
showValues: PropTypes.bool,
|
showValues: PropTypes.bool,
|
||||||
@ -90,7 +90,7 @@ function Heatmap(element, props) {
|
|||||||
leftMargin,
|
leftMargin,
|
||||||
metric,
|
metric,
|
||||||
normalized,
|
normalized,
|
||||||
numberFormat,
|
valueFormatter,
|
||||||
showLegend,
|
showLegend,
|
||||||
showPercentage,
|
showPercentage,
|
||||||
showValues,
|
showValues,
|
||||||
@ -115,8 +115,6 @@ function Heatmap(element, props) {
|
|||||||
const pixelsPerCharX = 4.5; // approx, depends on font size
|
const pixelsPerCharX = 4.5; // approx, depends on font size
|
||||||
let pixelsPerCharY = 6; // approx, depends on font size
|
let pixelsPerCharY = 6; // approx, depends on font size
|
||||||
|
|
||||||
const valueFormatter = getNumberFormatter(numberFormat);
|
|
||||||
|
|
||||||
// Dynamically adjusts based on max x / y category lengths
|
// Dynamically adjusts based on max x / y category lengths
|
||||||
function adjustMargins() {
|
function adjustMargins() {
|
||||||
let longestX = 1;
|
let longestX = 1;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { getValueFormatter } from '@superset-ui/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
@ -17,7 +19,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
export default function transformProps(chartProps) {
|
export default function transformProps(chartProps) {
|
||||||
const { width, height, formData, queriesData } = chartProps;
|
const { width, height, formData, queriesData, datasource } = chartProps;
|
||||||
const {
|
const {
|
||||||
bottomMargin,
|
bottomMargin,
|
||||||
canvasImageRendering,
|
canvasImageRendering,
|
||||||
@ -37,7 +39,13 @@ export default function transformProps(chartProps) {
|
|||||||
yAxisBounds,
|
yAxisBounds,
|
||||||
yAxisFormat,
|
yAxisFormat,
|
||||||
} = formData;
|
} = formData;
|
||||||
|
const { columnFormats = {}, currencyFormats = {} } = datasource;
|
||||||
|
const valueFormatter = getValueFormatter(
|
||||||
|
metric,
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
yAxisFormat,
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@ -50,7 +58,6 @@ export default function transformProps(chartProps) {
|
|||||||
leftMargin,
|
leftMargin,
|
||||||
metric,
|
metric,
|
||||||
normalized,
|
normalized,
|
||||||
numberFormat: yAxisFormat,
|
|
||||||
showLegend,
|
showLegend,
|
||||||
showPercentage: showPerc,
|
showPercentage: showPerc,
|
||||||
showValues,
|
showValues,
|
||||||
@ -59,5 +66,6 @@ export default function transformProps(chartProps) {
|
|||||||
xScaleInterval: parseInt(xscaleInterval, 10),
|
xScaleInterval: parseInt(xscaleInterval, 10),
|
||||||
yScaleInterval: parseInt(yscaleInterval, 10),
|
yScaleInterval: parseInt(yscaleInterval, 10),
|
||||||
yAxisBounds,
|
yAxisBounds,
|
||||||
|
valueFormatter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import d3 from 'd3';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { extent as d3Extent } from 'd3-array';
|
import { extent as d3Extent } from 'd3-array';
|
||||||
import {
|
import {
|
||||||
getNumberFormatter,
|
|
||||||
getSequentialSchemeRegistry,
|
getSequentialSchemeRegistry,
|
||||||
CategoricalColorNamespace,
|
CategoricalColorNamespace,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
@ -47,10 +46,9 @@ const propTypes = {
|
|||||||
setDataMask: PropTypes.func,
|
setDataMask: PropTypes.func,
|
||||||
onContextMenu: PropTypes.func,
|
onContextMenu: PropTypes.func,
|
||||||
emitCrossFilters: PropTypes.bool,
|
emitCrossFilters: PropTypes.bool,
|
||||||
|
formatter: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatter = getNumberFormatter();
|
|
||||||
|
|
||||||
function WorldMap(element, props) {
|
function WorldMap(element, props) {
|
||||||
const {
|
const {
|
||||||
countryFieldtype,
|
countryFieldtype,
|
||||||
@ -71,6 +69,7 @@ function WorldMap(element, props) {
|
|||||||
inContextMenu,
|
inContextMenu,
|
||||||
filterState,
|
filterState,
|
||||||
emitCrossFilters,
|
emitCrossFilters,
|
||||||
|
formatter,
|
||||||
} = props;
|
} = props;
|
||||||
const div = d3.select(element);
|
const div = d3.select(element);
|
||||||
div.classed('superset-legacy-chart-world-map', true);
|
div.classed('superset-legacy-chart-world-map', true);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { rgb } from 'd3-color';
|
import { rgb } from 'd3-color';
|
||||||
|
import { getValueFormatter } from '@superset-ui/core';
|
||||||
|
|
||||||
export default function transformProps(chartProps) {
|
export default function transformProps(chartProps) {
|
||||||
const {
|
const {
|
||||||
@ -28,6 +29,7 @@ export default function transformProps(chartProps) {
|
|||||||
inContextMenu,
|
inContextMenu,
|
||||||
filterState,
|
filterState,
|
||||||
emitCrossFilters,
|
emitCrossFilters,
|
||||||
|
datasource,
|
||||||
} = chartProps;
|
} = chartProps;
|
||||||
const { onContextMenu, setDataMask } = hooks;
|
const { onContextMenu, setDataMask } = hooks;
|
||||||
const {
|
const {
|
||||||
@ -40,8 +42,17 @@ export default function transformProps(chartProps) {
|
|||||||
colorBy,
|
colorBy,
|
||||||
colorScheme,
|
colorScheme,
|
||||||
sliceId,
|
sliceId,
|
||||||
|
metric,
|
||||||
} = formData;
|
} = formData;
|
||||||
const { r, g, b } = colorPicker;
|
const { r, g, b } = colorPicker;
|
||||||
|
const { currencyFormats = {}, columnFormats = {} } = datasource;
|
||||||
|
|
||||||
|
const formatter = getValueFormatter(
|
||||||
|
metric,
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
countryFieldtype,
|
countryFieldtype,
|
||||||
@ -61,5 +72,6 @@ export default function transformProps(chartProps) {
|
|||||||
inContextMenu,
|
inContextMenu,
|
||||||
filterState,
|
filterState,
|
||||||
emitCrossFilters,
|
emitCrossFilters,
|
||||||
|
formatter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@ import {
|
|||||||
getMetricLabel,
|
getMetricLabel,
|
||||||
extractTimegrain,
|
extractTimegrain,
|
||||||
QueryFormData,
|
QueryFormData,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { BigNumberTotalChartProps, BigNumberVizProps } from '../types';
|
import { BigNumberTotalChartProps, BigNumberVizProps } from '../types';
|
||||||
import { getDateFormatter, parseMetricValue } from '../utils';
|
import { getDateFormatter, parseMetricValue } from '../utils';
|
||||||
import { Refs } from '../../types';
|
import { Refs } from '../../types';
|
||||||
import { getValueFormatter } from '../../utils/valueFormatter';
|
|
||||||
|
|
||||||
export default function transformProps(
|
export default function transformProps(
|
||||||
chartProps: BigNumberTotalChartProps,
|
chartProps: BigNumberTotalChartProps,
|
||||||
|
@ -28,6 +28,7 @@ import {
|
|||||||
getXAxisLabel,
|
getXAxisLabel,
|
||||||
Metric,
|
Metric,
|
||||||
ValueFormatter,
|
ValueFormatter,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { EChartsCoreOption, graphic } from 'echarts';
|
import { EChartsCoreOption, graphic } from 'echarts';
|
||||||
import {
|
import {
|
||||||
@ -39,7 +40,6 @@ import {
|
|||||||
import { getDateFormatter, parseMetricValue } from '../utils';
|
import { getDateFormatter, parseMetricValue } from '../utils';
|
||||||
import { getDefaultTooltip } from '../../utils/tooltip';
|
import { getDefaultTooltip } from '../../utils/tooltip';
|
||||||
import { Refs } from '../../types';
|
import { Refs } from '../../types';
|
||||||
import { getValueFormatter } from '../../utils/valueFormatter';
|
|
||||||
|
|
||||||
const defaultNumberFormatter = getNumberFormatter();
|
const defaultNumberFormatter = getNumberFormatter();
|
||||||
export function renderTooltipFactory(
|
export function renderTooltipFactory(
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
NumberFormats,
|
NumberFormats,
|
||||||
ValueFormatter,
|
ValueFormatter,
|
||||||
getColumnLabel,
|
getColumnLabel,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
||||||
import { EChartsCoreOption, FunnelSeriesOption } from 'echarts';
|
import { EChartsCoreOption, FunnelSeriesOption } from 'echarts';
|
||||||
@ -45,7 +46,6 @@ import { defaultGrid } from '../defaults';
|
|||||||
import { OpacityEnum, DEFAULT_LEGEND_FORM_DATA } from '../constants';
|
import { OpacityEnum, DEFAULT_LEGEND_FORM_DATA } from '../constants';
|
||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import { Refs } from '../types';
|
import { Refs } from '../types';
|
||||||
import { getValueFormatter } from '../utils/valueFormatter';
|
|
||||||
|
|
||||||
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
DataRecord,
|
DataRecord,
|
||||||
getMetricLabel,
|
getMetricLabel,
|
||||||
getColumnLabel,
|
getColumnLabel,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { EChartsCoreOption, GaugeSeriesOption } from 'echarts';
|
import { EChartsCoreOption, GaugeSeriesOption } from 'echarts';
|
||||||
import { GaugeDataItemOption } from 'echarts/types/src/chart/gauge/GaugeSeries';
|
import { GaugeDataItemOption } from 'echarts/types/src/chart/gauge/GaugeSeries';
|
||||||
@ -46,7 +47,6 @@ import { OpacityEnum } from '../constants';
|
|||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import { Refs } from '../types';
|
import { Refs } from '../types';
|
||||||
import { getColtypesMapping } from '../utils/series';
|
import { getColtypesMapping } from '../utils/series';
|
||||||
import { getValueFormatter } from '../utils/valueFormatter';
|
|
||||||
|
|
||||||
const setIntervalBoundsAndColors = (
|
const setIntervalBoundsAndColors = (
|
||||||
intervals: string,
|
intervals: string,
|
||||||
|
@ -34,6 +34,11 @@ import {
|
|||||||
isPhysicalColumn,
|
isPhysicalColumn,
|
||||||
isDefined,
|
isDefined,
|
||||||
ensureIsArray,
|
ensureIsArray,
|
||||||
|
buildCustomFormatters,
|
||||||
|
ValueFormatter,
|
||||||
|
NumberFormatter,
|
||||||
|
QueryFormMetric,
|
||||||
|
getCustomFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { getOriginalSeries } from '@superset-ui/chart-controls';
|
import { getOriginalSeries } from '@superset-ui/chart-controls';
|
||||||
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
||||||
@ -83,6 +88,23 @@ import {
|
|||||||
} from '../Timeseries/transformers';
|
} from '../Timeseries/transformers';
|
||||||
import { TIMESERIES_CONSTANTS, TIMEGRAIN_TO_TIMESTAMP } from '../constants';
|
import { TIMESERIES_CONSTANTS, TIMEGRAIN_TO_TIMESTAMP } from '../constants';
|
||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
|
import { getYAxisFormatter } from '../utils/getYAxisFormatter';
|
||||||
|
|
||||||
|
const getFormatter = (
|
||||||
|
customFormatters: Record<string, ValueFormatter>,
|
||||||
|
defaultFormatter: NumberFormatter,
|
||||||
|
metrics: QueryFormMetric[],
|
||||||
|
formatterKey: string,
|
||||||
|
forcePercentFormat: boolean,
|
||||||
|
) => {
|
||||||
|
if (forcePercentFormat) {
|
||||||
|
return getNumberFormatter(',.0%');
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
getCustomFormatter(customFormatters, metrics, formatterKey) ??
|
||||||
|
defaultFormatter
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function transformProps(
|
export default function transformProps(
|
||||||
chartProps: EchartsMixedTimeseriesProps,
|
chartProps: EchartsMixedTimeseriesProps,
|
||||||
@ -99,7 +121,11 @@ export default function transformProps(
|
|||||||
inContextMenu,
|
inContextMenu,
|
||||||
emitCrossFilters,
|
emitCrossFilters,
|
||||||
} = chartProps;
|
} = chartProps;
|
||||||
const { verboseMap = {} } = datasource;
|
const {
|
||||||
|
verboseMap = {},
|
||||||
|
currencyFormats = {},
|
||||||
|
columnFormats = {},
|
||||||
|
} = datasource;
|
||||||
const { label_map: labelMap } =
|
const { label_map: labelMap } =
|
||||||
queriesData[0] as TimeseriesChartDataResponseResult;
|
queriesData[0] as TimeseriesChartDataResponseResult;
|
||||||
const { label_map: labelMapB } =
|
const { label_map: labelMapB } =
|
||||||
@ -160,6 +186,8 @@ export default function transformProps(
|
|||||||
sliceId,
|
sliceId,
|
||||||
timeGrainSqla,
|
timeGrainSqla,
|
||||||
percentageThreshold,
|
percentageThreshold,
|
||||||
|
metrics = [],
|
||||||
|
metricsB = [],
|
||||||
}: EchartsMixedTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
}: EchartsMixedTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
||||||
|
|
||||||
const refs: Refs = {};
|
const refs: Refs = {};
|
||||||
@ -194,6 +222,18 @@ export default function transformProps(
|
|||||||
const formatterSecondary = getNumberFormatter(
|
const formatterSecondary = getNumberFormatter(
|
||||||
contributionMode ? ',.0%' : yAxisFormatSecondary,
|
contributionMode ? ',.0%' : yAxisFormatSecondary,
|
||||||
);
|
);
|
||||||
|
const customFormatters = buildCustomFormatters(
|
||||||
|
[...metrics, ...metricsB],
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
yAxisFormat,
|
||||||
|
);
|
||||||
|
const customFormattersSecondary = buildCustomFormatters(
|
||||||
|
[...metrics, ...metricsB],
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
yAxisFormatSecondary,
|
||||||
|
);
|
||||||
|
|
||||||
const primarySeries = new Set<string>();
|
const primarySeries = new Set<string>();
|
||||||
const secondarySeries = new Set<string>();
|
const secondarySeries = new Set<string>();
|
||||||
@ -292,12 +332,6 @@ export default function transformProps(
|
|||||||
parseYAxisBound,
|
parseYAxisBound,
|
||||||
);
|
);
|
||||||
|
|
||||||
const maxLabelFormatter = getOverMaxHiddenFormatter({ max, formatter });
|
|
||||||
const maxLabelFormatterSecondary = getOverMaxHiddenFormatter({
|
|
||||||
max: maxSecondary,
|
|
||||||
formatter: formatterSecondary,
|
|
||||||
});
|
|
||||||
|
|
||||||
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
|
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
|
||||||
const inverted = invert(verboseMap);
|
const inverted = invert(verboseMap);
|
||||||
|
|
||||||
@ -306,6 +340,14 @@ export default function transformProps(
|
|||||||
const seriesName = inverted[entryName] || entryName;
|
const seriesName = inverted[entryName] || entryName;
|
||||||
const colorScaleKey = getOriginalSeries(seriesName, array);
|
const colorScaleKey = getOriginalSeries(seriesName, array);
|
||||||
|
|
||||||
|
const seriesFormatter = getFormatter(
|
||||||
|
customFormatters,
|
||||||
|
formatter,
|
||||||
|
metrics,
|
||||||
|
labelMap[seriesName]?.[0],
|
||||||
|
!!contributionMode,
|
||||||
|
);
|
||||||
|
|
||||||
const transformedSeries = transformSeries(
|
const transformedSeries = transformSeries(
|
||||||
entry,
|
entry,
|
||||||
colorScale,
|
colorScale,
|
||||||
@ -325,8 +367,11 @@ export default function transformProps(
|
|||||||
queryIndex: 0,
|
queryIndex: 0,
|
||||||
formatter:
|
formatter:
|
||||||
seriesType === EchartsTimeseriesSeriesType.Bar
|
seriesType === EchartsTimeseriesSeriesType.Bar
|
||||||
? maxLabelFormatter
|
? getOverMaxHiddenFormatter({
|
||||||
: formatter,
|
max,
|
||||||
|
formatter: seriesFormatter,
|
||||||
|
})
|
||||||
|
: seriesFormatter,
|
||||||
showValueIndexes: showValueIndexesA,
|
showValueIndexes: showValueIndexesA,
|
||||||
totalStackedValues,
|
totalStackedValues,
|
||||||
thresholdValues,
|
thresholdValues,
|
||||||
@ -340,6 +385,14 @@ export default function transformProps(
|
|||||||
const seriesName = `${inverted[entryName] || entryName} (1)`;
|
const seriesName = `${inverted[entryName] || entryName} (1)`;
|
||||||
const colorScaleKey = getOriginalSeries(seriesName, array);
|
const colorScaleKey = getOriginalSeries(seriesName, array);
|
||||||
|
|
||||||
|
const seriesFormatter = getFormatter(
|
||||||
|
customFormattersSecondary,
|
||||||
|
formatterSecondary,
|
||||||
|
metricsB,
|
||||||
|
labelMapB[seriesName]?.[0],
|
||||||
|
!!contributionMode,
|
||||||
|
);
|
||||||
|
|
||||||
const transformedSeries = transformSeries(
|
const transformedSeries = transformSeries(
|
||||||
entry,
|
entry,
|
||||||
colorScale,
|
colorScale,
|
||||||
@ -361,8 +414,11 @@ export default function transformProps(
|
|||||||
queryIndex: 1,
|
queryIndex: 1,
|
||||||
formatter:
|
formatter:
|
||||||
seriesTypeB === EchartsTimeseriesSeriesType.Bar
|
seriesTypeB === EchartsTimeseriesSeriesType.Bar
|
||||||
? maxLabelFormatterSecondary
|
? getOverMaxHiddenFormatter({
|
||||||
: formatterSecondary,
|
max: maxSecondary,
|
||||||
|
formatter: seriesFormatter,
|
||||||
|
})
|
||||||
|
: seriesFormatter,
|
||||||
showValueIndexes: showValueIndexesB,
|
showValueIndexes: showValueIndexesB,
|
||||||
totalStackedValues: totalStackedValuesB,
|
totalStackedValues: totalStackedValuesB,
|
||||||
thresholdValues: thresholdValuesB,
|
thresholdValues: thresholdValuesB,
|
||||||
@ -434,7 +490,14 @@ export default function transformProps(
|
|||||||
max,
|
max,
|
||||||
minorTick: { show: true },
|
minorTick: { show: true },
|
||||||
minorSplitLine: { show: minorSplitLine },
|
minorSplitLine: { show: minorSplitLine },
|
||||||
axisLabel: { formatter },
|
axisLabel: {
|
||||||
|
formatter: getYAxisFormatter(
|
||||||
|
metrics,
|
||||||
|
!!contributionMode,
|
||||||
|
customFormatters,
|
||||||
|
yAxisFormat,
|
||||||
|
),
|
||||||
|
},
|
||||||
scale: truncateYAxis,
|
scale: truncateYAxis,
|
||||||
name: yAxisTitle,
|
name: yAxisTitle,
|
||||||
nameGap: convertInteger(yAxisTitleMargin),
|
nameGap: convertInteger(yAxisTitleMargin),
|
||||||
@ -449,7 +512,14 @@ export default function transformProps(
|
|||||||
minorTick: { show: true },
|
minorTick: { show: true },
|
||||||
splitLine: { show: false },
|
splitLine: { show: false },
|
||||||
minorSplitLine: { show: minorSplitLine },
|
minorSplitLine: { show: minorSplitLine },
|
||||||
axisLabel: { formatter: formatterSecondary },
|
axisLabel: {
|
||||||
|
formatter: getYAxisFormatter(
|
||||||
|
metricsB,
|
||||||
|
!!contributionMode,
|
||||||
|
customFormattersSecondary,
|
||||||
|
yAxisFormatSecondary,
|
||||||
|
),
|
||||||
|
},
|
||||||
scale: truncateYAxis,
|
scale: truncateYAxis,
|
||||||
name: yAxisTitleSecondary,
|
name: yAxisTitleSecondary,
|
||||||
alignTicks,
|
alignTicks,
|
||||||
@ -475,10 +545,36 @@ export default function transformProps(
|
|||||||
|
|
||||||
Object.keys(forecastValues).forEach(key => {
|
Object.keys(forecastValues).forEach(key => {
|
||||||
const value = forecastValues[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 content = formatForecastTooltipSeries({
|
const content = formatForecastTooltipSeries({
|
||||||
...value,
|
...value,
|
||||||
seriesName: key,
|
seriesName: key,
|
||||||
formatter: primarySeries.has(key) ? formatter : formatterSecondary,
|
formatter: primarySeries.has(key)
|
||||||
|
? tooltipFormatter
|
||||||
|
: tooltipFormatterSecondary,
|
||||||
});
|
});
|
||||||
rows.push(`<span style="opacity: 0.7">${content}</span>`);
|
rows.push(`<span style="opacity: 0.7">${content}</span>`);
|
||||||
});
|
});
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
NumberFormats,
|
NumberFormats,
|
||||||
t,
|
t,
|
||||||
ValueFormatter,
|
ValueFormatter,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
||||||
import { EChartsCoreOption, PieSeriesOption } from 'echarts';
|
import { EChartsCoreOption, PieSeriesOption } from 'echarts';
|
||||||
@ -47,7 +48,6 @@ import { defaultGrid } from '../defaults';
|
|||||||
import { convertInteger } from '../utils/convertInteger';
|
import { convertInteger } from '../utils/convertInteger';
|
||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import { Refs } from '../types';
|
import { Refs } from '../types';
|
||||||
import { getValueFormatter } from '../utils/valueFormatter';
|
|
||||||
|
|
||||||
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
||||||
|
|
||||||
|
@ -24,10 +24,11 @@ import {
|
|||||||
getNumberFormatter,
|
getNumberFormatter,
|
||||||
getSequentialSchemeRegistry,
|
getSequentialSchemeRegistry,
|
||||||
getTimeFormatter,
|
getTimeFormatter,
|
||||||
|
getValueFormatter,
|
||||||
NumberFormats,
|
NumberFormats,
|
||||||
NumberFormatter,
|
|
||||||
SupersetTheme,
|
SupersetTheme,
|
||||||
t,
|
t,
|
||||||
|
ValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { EChartsCoreOption } from 'echarts';
|
import { EChartsCoreOption } from 'echarts';
|
||||||
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
||||||
@ -74,7 +75,7 @@ export function formatLabel({
|
|||||||
}: {
|
}: {
|
||||||
params: CallbackDataParams;
|
params: CallbackDataParams;
|
||||||
labelType: EchartsSunburstLabelType;
|
labelType: EchartsSunburstLabelType;
|
||||||
numberFormatter: NumberFormatter;
|
numberFormatter: ValueFormatter;
|
||||||
}): string {
|
}): string {
|
||||||
const { name = '', value } = params;
|
const { name = '', value } = params;
|
||||||
const formattedValue = numberFormatter(value as number);
|
const formattedValue = numberFormatter(value as number);
|
||||||
@ -93,7 +94,8 @@ export function formatLabel({
|
|||||||
|
|
||||||
export function formatTooltip({
|
export function formatTooltip({
|
||||||
params,
|
params,
|
||||||
numberFormatter,
|
primaryValueFormatter,
|
||||||
|
secondaryValueFormatter,
|
||||||
colorByCategory,
|
colorByCategory,
|
||||||
totalValue,
|
totalValue,
|
||||||
metricLabel,
|
metricLabel,
|
||||||
@ -107,7 +109,8 @@ export function formatTooltip({
|
|||||||
value: number;
|
value: number;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
numberFormatter: NumberFormatter;
|
primaryValueFormatter: ValueFormatter;
|
||||||
|
secondaryValueFormatter: ValueFormatter | undefined;
|
||||||
colorByCategory: boolean;
|
colorByCategory: boolean;
|
||||||
totalValue: number;
|
totalValue: number;
|
||||||
metricLabel: string;
|
metricLabel: string;
|
||||||
@ -116,8 +119,10 @@ export function formatTooltip({
|
|||||||
}): string {
|
}): string {
|
||||||
const { data, treePathInfo = [] } = params;
|
const { data, treePathInfo = [] } = params;
|
||||||
const node = data as TreeNode;
|
const node = data as TreeNode;
|
||||||
const formattedValue = numberFormatter(node.value);
|
const formattedValue = primaryValueFormatter(node.value);
|
||||||
const formattedSecondaryValue = numberFormatter(node.secondaryValue);
|
const formattedSecondaryValue = secondaryValueFormatter?.(
|
||||||
|
node.secondaryValue,
|
||||||
|
);
|
||||||
|
|
||||||
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
||||||
const compareValuePercentage = percentFormatter(
|
const compareValuePercentage = percentFormatter(
|
||||||
@ -177,6 +182,7 @@ export default function transformProps(
|
|||||||
theme,
|
theme,
|
||||||
inContextMenu,
|
inContextMenu,
|
||||||
emitCrossFilters,
|
emitCrossFilters,
|
||||||
|
datasource,
|
||||||
} = chartProps;
|
} = chartProps;
|
||||||
const { data = [] } = queriesData[0];
|
const { data = [] } = queriesData[0];
|
||||||
const coltypeMapping = getColtypesMapping(queriesData[0]);
|
const coltypeMapping = getColtypesMapping(queriesData[0]);
|
||||||
@ -195,12 +201,28 @@ export default function transformProps(
|
|||||||
showTotal,
|
showTotal,
|
||||||
sliceId,
|
sliceId,
|
||||||
} = formData;
|
} = formData;
|
||||||
|
const { currencyFormats = {}, columnFormats = {} } = datasource;
|
||||||
const refs: Refs = {};
|
const refs: Refs = {};
|
||||||
|
const primaryValueFormatter = getValueFormatter(
|
||||||
|
metric,
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
numberFormat,
|
||||||
|
);
|
||||||
|
const secondaryValueFormatter = secondaryMetric
|
||||||
|
? getValueFormatter(
|
||||||
|
secondaryMetric,
|
||||||
|
currencyFormats,
|
||||||
|
columnFormats,
|
||||||
|
numberFormat,
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const numberFormatter = getNumberFormatter(numberFormat);
|
const numberFormatter = getNumberFormatter(numberFormat);
|
||||||
const formatter = (params: CallbackDataParams) =>
|
const formatter = (params: CallbackDataParams) =>
|
||||||
formatLabel({
|
formatLabel({
|
||||||
params,
|
params,
|
||||||
numberFormatter,
|
numberFormatter: primaryValueFormatter,
|
||||||
labelType,
|
labelType,
|
||||||
});
|
});
|
||||||
const minShowLabelAngle = (showLabelsThreshold || 0) * 3.6;
|
const minShowLabelAngle = (showLabelsThreshold || 0) * 3.6;
|
||||||
@ -319,7 +341,8 @@ export default function transformProps(
|
|||||||
formatter: (params: any) =>
|
formatter: (params: any) =>
|
||||||
formatTooltip({
|
formatTooltip({
|
||||||
params,
|
params,
|
||||||
numberFormatter,
|
primaryValueFormatter,
|
||||||
|
secondaryValueFormatter,
|
||||||
colorByCategory,
|
colorByCategory,
|
||||||
totalValue,
|
totalValue,
|
||||||
metricLabel,
|
metricLabel,
|
||||||
@ -356,7 +379,7 @@ export default function transformProps(
|
|||||||
top: 'center',
|
top: 'center',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
style: {
|
style: {
|
||||||
text: t('Total: %s', numberFormatter(totalValue)),
|
text: t('Total: %s', primaryValueFormatter(totalValue)),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,6 @@ import {
|
|||||||
AnnotationLayer,
|
AnnotationLayer,
|
||||||
AxisType,
|
AxisType,
|
||||||
CategoricalColorNamespace,
|
CategoricalColorNamespace,
|
||||||
CurrencyFormatter,
|
|
||||||
ensureIsArray,
|
ensureIsArray,
|
||||||
GenericDataType,
|
GenericDataType,
|
||||||
getMetricLabel,
|
getMetricLabel,
|
||||||
@ -33,13 +32,11 @@ import {
|
|||||||
isFormulaAnnotationLayer,
|
isFormulaAnnotationLayer,
|
||||||
isIntervalAnnotationLayer,
|
isIntervalAnnotationLayer,
|
||||||
isPhysicalColumn,
|
isPhysicalColumn,
|
||||||
isSavedMetric,
|
|
||||||
isTimeseriesAnnotationLayer,
|
isTimeseriesAnnotationLayer,
|
||||||
NumberFormats,
|
|
||||||
QueryFormMetric,
|
|
||||||
t,
|
t,
|
||||||
TimeseriesChartDataResponseResult,
|
TimeseriesChartDataResponseResult,
|
||||||
ValueFormatter,
|
buildCustomFormatters,
|
||||||
|
getCustomFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
extractExtraMetrics,
|
extractExtraMetrics,
|
||||||
@ -97,36 +94,7 @@ import {
|
|||||||
TIMEGRAIN_TO_TIMESTAMP,
|
TIMEGRAIN_TO_TIMESTAMP,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import {
|
import { getYAxisFormatter } from '../utils/getYAxisFormatter';
|
||||||
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(
|
export default function transformProps(
|
||||||
chartProps: EchartsTimeseriesChartProps,
|
chartProps: EchartsTimeseriesChartProps,
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
getTimeFormatter,
|
getTimeFormatter,
|
||||||
NumberFormats,
|
NumberFormats,
|
||||||
ValueFormatter,
|
ValueFormatter,
|
||||||
|
getValueFormatter,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { TreemapSeriesNodeItemOption } from 'echarts/types/src/chart/treemap/TreemapSeries';
|
import { TreemapSeriesNodeItemOption } from 'echarts/types/src/chart/treemap/TreemapSeries';
|
||||||
import { EChartsCoreOption, TreemapSeriesOption } from 'echarts';
|
import { EChartsCoreOption, TreemapSeriesOption } from 'echarts';
|
||||||
@ -48,7 +49,6 @@ import { OpacityEnum } from '../constants';
|
|||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import { Refs } from '../types';
|
import { Refs } from '../types';
|
||||||
import { treeBuilder, TreeNode } from '../utils/treeBuilder';
|
import { treeBuilder, TreeNode } from '../utils/treeBuilder';
|
||||||
import { getValueFormatter } from '../utils/valueFormatter';
|
|
||||||
|
|
||||||
export function formatLabel({
|
export function formatLabel({
|
||||||
params,
|
params,
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
CurrencyFormatter,
|
||||||
|
ensureIsArray,
|
||||||
|
getNumberFormatter,
|
||||||
|
isSavedMetric,
|
||||||
|
NumberFormats,
|
||||||
|
QueryFormMetric,
|
||||||
|
ValueFormatter,
|
||||||
|
} from '@superset-ui/core';
|
||||||
|
|
||||||
|
export 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);
|
||||||
|
};
|
@ -518,7 +518,7 @@ export function getAxisType(dataType?: GenericDataType): AxisType {
|
|||||||
export function getOverMaxHiddenFormatter(
|
export function getOverMaxHiddenFormatter(
|
||||||
config: {
|
config: {
|
||||||
max?: number;
|
max?: number;
|
||||||
formatter?: NumberFormatter;
|
formatter?: ValueFormatter;
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
const { max, formatter } = config;
|
const { max, formatter } = config;
|
||||||
|
Loading…
Reference in New Issue
Block a user