diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/controlPanel.tsx index e18ba6ba6b7..e19960e7460 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/controlPanel.tsx @@ -58,41 +58,109 @@ const config: ControlPanelConfig = { }, }, ], + ], + }, + { + label: t('Series settings'), + expanded: true, + controlSetRows: [ [ - {t('Series colors')} + {t('Series increase setting')} , ], [ { name: 'increase_color', config: { - label: t('Increase'), + label: t('Increase color'), type: 'ColorPickerControl', default: { r: 90, g: 193, b: 137, a: 1 }, renderTrigger: true, + description: t( + 'Select the color used for values that indicate an increase in the chart', + ), }, }, { - name: 'decrease_color', + name: 'increase_label', config: { - label: t('Decrease'), - type: 'ColorPickerControl', - default: { r: 224, g: 67, b: 85, a: 1 }, - renderTrigger: true, - }, - }, - { - name: 'total_color', - config: { - label: t('Total'), - type: 'ColorPickerControl', - default: { r: 102, g: 102, b: 102, a: 1 }, + label: t('Increase label'), + type: 'TextControl', renderTrigger: true, + description: t( + 'Customize the label displayed for increasing values in the chart tooltips and legend.', + ), }, }, ], - [{t('X Axis')}], + [ + + {t('Series decrease setting')} + , + ], + [ + { + name: 'decrease_color', + config: { + label: t('Decrease color'), + type: 'ColorPickerControl', + default: { r: 224, g: 67, b: 85, a: 1 }, + renderTrigger: true, + description: t( + 'Select the color used for values ​​that indicate a decrease in the chart.', + ), + }, + }, + { + name: 'decrease_label', + config: { + label: t('Decrease label'), + type: 'TextControl', + renderTrigger: true, + description: t( + 'Customize the label displayed for decreasing values in the chart tooltips and legend.', + ), + }, + }, + ], + [ + + {t('Series total setting')} + , + ], + [ + { + name: 'total_color', + config: { + label: t('Total color'), + type: 'ColorPickerControl', + default: { r: 102, g: 102, b: 102, a: 1 }, + renderTrigger: true, + description: t( + 'Select the color used for values that represent total bars in the chart', + ), + }, + }, + + { + name: 'total_label', + config: { + label: t('Total label'), + type: 'TextControl', + renderTrigger: true, + description: t( + 'Customize the label displayed for total values in the chart tooltips, legend, and chart axis.', + ), + }, + }, + ], + ], + }, + { + label: t('X Axis'), + expanded: true, + controlSetRows: [ [ { name: 'x_axis_label', @@ -134,7 +202,12 @@ const config: ControlPanelConfig = { }, }, ], - [{t('Y Axis')}], + ], + }, + { + label: t('Y Axis'), + expanded: true, + controlSetRows: [ [ { name: 'y_axis_label', diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts index e2fc17e2398..62c9724f423 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts @@ -51,11 +51,13 @@ function formatTooltip({ breakdownName, defaultFormatter, xAxisFormatter, + totalMark, }: { params: ICallbackDataParams[]; breakdownName?: string; defaultFormatter: NumberFormatter | CurrencyFormatter; xAxisFormatter: (value: number | string, index: number) => string; + totalMark: string; }) { const series = params.find( param => param.seriesName !== ASSIST_MARK && param.data.value !== TOKEN, @@ -66,7 +68,7 @@ function formatTooltip({ return ''; } - const isTotal = series?.seriesName === LEGEND.TOTAL; + const isTotal = series?.seriesName === totalMark; if (!series) { return NULL_STRING; } @@ -82,7 +84,7 @@ function formatTooltip({ defaultFormatter(series.data.originalValue), ]); } - rows.push([TOTAL_MARK, defaultFormatter(series.data.totalSum)]); + rows.push([totalMark, defaultFormatter(series.data.totalSum)]); return tooltipHtml(rows, title); } @@ -91,11 +93,13 @@ function transformer({ xAxis, metric, breakdown, + totalMark, }: { data: DataRecord[]; xAxis: string; metric: string; breakdown?: string; + totalMark: string; }) { // Group by series (temporary map) const groupedData = data.reduce((acc, cur) => { @@ -119,7 +123,7 @@ function transformer({ // Push total per period to the end of period values array tempValue.push({ [xAxis]: key, - [breakdown]: TOTAL_MARK, + [breakdown]: totalMark, [metric]: sum, }); transformedData.push(...tempValue); @@ -138,7 +142,7 @@ function transformer({ total += sum; }); transformedData.push({ - [xAxis]: TOTAL_MARK, + [xAxis]: totalMark, [metric]: total, }); } @@ -179,11 +183,21 @@ export default function transformProps( xAxisLabel, yAxisFormat, showValue, + totalLabel, + increaseLabel, + decreaseLabel, } = formData; const defaultFormatter = currencyFormat?.symbol ? new CurrencyFormatter({ d3Format: yAxisFormat, currency: currencyFormat }) : getNumberFormatter(yAxisFormat); + const totalMark = totalLabel || TOTAL_MARK; + const legendNames = { + INCREASE: increaseLabel || LEGEND.INCREASE, + DECREASE: decreaseLabel || LEGEND.DECREASE, + TOTAL: totalLabel || LEGEND.TOTAL, + }; + const seriesformatter = (params: ICallbackDataParams) => { const { data } = params; const { originalValue } = data; @@ -205,6 +219,7 @@ export default function transformProps( breakdown: breakdownName, xAxis: xAxisName, metric: metricLabel, + totalMark, }); const assistData: ISeriesData[] = []; @@ -217,18 +232,18 @@ export default function transformProps( transformedData.forEach((datum, index, self) => { const totalSum = self.slice(0, index + 1).reduce((prev, cur, i) => { if (breakdownName) { - if (cur[breakdownName] !== TOTAL_MARK || i === 0) { + if (cur[breakdownName] !== totalMark || i === 0) { return prev + ((cur[metricLabel] as number) ?? 0); } - } else if (cur[xAxisName] !== TOTAL_MARK) { + } else if (cur[xAxisName] !== totalMark) { return prev + ((cur[metricLabel] as number) ?? 0); } return prev; }, 0); const isTotal = - (breakdownName && datum[breakdownName] === TOTAL_MARK) || - datum[xAxisName] === TOTAL_MARK; + (breakdownName && datum[breakdownName] === totalMark) || + datum[xAxisName] === totalMark; const originalValue = datum[metricLabel] as number; let value = originalValue; @@ -270,9 +285,9 @@ export default function transformProps( : 'transparent'; let opacity = 1; - if (legendState?.[LEGEND.INCREASE] === false && value > 0) { + if (legendState?.[legendNames.INCREASE] === false && value > 0) { opacity = 0; - } else if (legendState?.[LEGEND.DECREASE] === false && value < 0) { + } else if (legendState?.[legendNames.DECREASE] === false && value < 0) { opacity = 0; } @@ -301,7 +316,7 @@ export default function transformProps( const xAxisData = transformedData.map(row => { let column = xAxisName; let value = row[xAxisName]; - if (breakdownName && row[breakdownName] !== TOTAL_MARK) { + if (breakdownName && row[breakdownName] !== totalMark) { column = breakdownName; value = row[breakdownName]; } @@ -316,8 +331,8 @@ export default function transformProps( }); const xAxisFormatter = (value: number | string, index: number) => { - if (value === TOTAL_MARK) { - return TOTAL_MARK; + if (value === totalMark) { + return totalMark; } if (coltypeMapping[xAxisColumns[index]] === GenericDataType.Temporal) { if (typeof value === 'string') { @@ -370,7 +385,7 @@ export default function transformProps( }, { ...seriesProps, - name: LEGEND.INCREASE, + name: legendNames.INCREASE, label: { ...labelProps, position: 'top', @@ -382,7 +397,7 @@ export default function transformProps( }, { ...seriesProps, - name: LEGEND.DECREASE, + name: legendNames.DECREASE, label: { ...labelProps, position: 'bottom', @@ -394,7 +409,7 @@ export default function transformProps( }, { ...seriesProps, - name: LEGEND.TOTAL, + name: legendNames.TOTAL, label: { ...labelProps, position: 'top', @@ -417,7 +432,7 @@ export default function transformProps( legend: { show: showLegend, selected: legendState, - data: [LEGEND.INCREASE, LEGEND.DECREASE, LEGEND.TOTAL], + data: [legendNames.INCREASE, legendNames.DECREASE, legendNames.TOTAL], }, xAxis: { data: xAxisData, @@ -450,6 +465,7 @@ export default function transformProps( breakdownName, defaultFormatter, xAxisFormatter, + totalMark, }), }, series: barSeries, diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/types.ts index 71a28dd9f75..10cf1ee4230 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/types.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/types.ts @@ -57,6 +57,9 @@ export type EchartsWaterfallFormData = QueryFormData & xTicksLayout?: WaterfallFormXTicksLayout; yAxisLabel: string; yAxisFormat: string; + increaseLabel?: string; + decreaseLabel?: string; + totalLabel?: string; }; export const DEFAULT_FORM_DATA: Partial = { diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx index 488ae5ef2e0..695305e1b46 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx @@ -128,7 +128,7 @@ export const showValueControl: ControlSetItem = { name: 'show_value', config: { type: 'CheckboxControl', - label: t('Show Value'), + label: t('Show value'), default: false, renderTrigger: true, description: t('Show series values on the chart'), diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/Waterfall/transformProps.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/Waterfall/transformProps.test.ts index a4abec6d496..761bc00b972 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/test/Waterfall/transformProps.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/test/Waterfall/transformProps.test.ts @@ -31,6 +31,14 @@ const extractSeries = (props: WaterfallChartTransformedProps) => { return series.map(item => item.data).map(item => item.map(i => i.value)); }; +const extractSeriesName = (props: WaterfallChartTransformedProps) => { + const { echartOptions } = props; + const { series } = echartOptions as unknown as { + series: [{ name: string }]; + }; + return series.map(item => item.name); +}; + describe('Waterfall tranformProps', () => { const data = [ { year: '2019', name: 'Sylvester', sum: 10 }, @@ -94,4 +102,44 @@ describe('Waterfall tranformProps', () => { ['-', '-', 13, '-', '-', 8], ]); }); + + it('renaming series names, checking legend and X axis labels', () => { + const chartProps = new ChartProps({ + formData: { + ...formData, + increaseLabel: 'sale increase', + decreaseLabel: 'sale decrease', + totalLabel: 'sale total', + }, + width: 800, + height: 600, + queriesData: [ + { + data, + }, + ], + theme: supersetTheme, + }); + const transformedProps = transformProps( + chartProps as unknown as EchartsWaterfallChartProps, + ); + expect((transformedProps.echartOptions.legend as any).data).toEqual([ + 'sale increase', + 'sale decrease', + 'sale total', + ]); + + expect((transformedProps.echartOptions.xAxis as any).data).toEqual([ + '2019', + '2020', + 'sale total', + ]); + + expect(extractSeriesName(transformedProps)).toEqual([ + 'Assist', + 'sale increase', + 'sale decrease', + 'sale total', + ]); + }); });