diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/controlPanel.tsx index 29ce20e9d66..3d67f51e830 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/controlPanel.tsx @@ -19,6 +19,7 @@ import { ensureIsArray, t } from '@superset-ui/core'; import { cloneDeep } from 'lodash'; import { + ControlPanelsContainerProps, ControlPanelConfig, ControlPanelSectionConfig, ControlSetRow, @@ -27,6 +28,8 @@ import { getStandardizedControls, sections, sharedControls, + DEFAULT_SORT_SERIES_DATA, + SORT_SERIES_CHOICES, } from '@superset-ui/chart-controls'; import { DEFAULT_FORM_DATA } from './types'; @@ -196,6 +199,23 @@ function createCustomizeSection( }, }, ], + [ + { + name: `only_total${controlSuffix}`, + config: { + type: 'CheckboxControl', + label: t('Only Total'), + default: true, + renderTrigger: true, + description: t( + 'Only show the total value on the stacked chart, and not show on the selected category', + ), + visibility: ({ controls }: ControlPanelsContainerProps) => + Boolean(controls?.show_value?.value) && + Boolean(controls?.stack?.value), + }, + }, + ], [ { name: `opacity${controlSuffix}`, @@ -258,6 +278,35 @@ function createCustomizeSection( }, }, ], + [{t('Series Order')}], + [ + { + name: `sort_series_type${controlSuffix}`, + config: { + type: 'SelectControl', + freeForm: false, + label: t('Sort Series By'), + choices: SORT_SERIES_CHOICES, + default: DEFAULT_SORT_SERIES_DATA.sort_series_type, + renderTrigger: true, + description: t( + 'Based on what should series be ordered on the chart and legend', + ), + }, + }, + ], + [ + { + name: `sort_series_ascending${controlSuffix}`, + config: { + type: 'CheckboxControl', + label: t('Sort Series Ascending'), + default: DEFAULT_SORT_SERIES_DATA.sort_series_ascending, + renderTrigger: true, + description: t('Sort series in ascending order'), + }, + }, + ], ]; } diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts index 478915cfce1..18e46368774 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts @@ -173,6 +173,8 @@ export default function transformProps( showLegend, showValue, showValueB, + onlyTotal, + onlyTotalB, stack, stackB, truncateXAxis, @@ -203,6 +205,10 @@ export default function transformProps( yAxisTitleMargin, yAxisTitlePosition, sliceId, + sortSeriesType, + sortSeriesTypeB, + sortSeriesAscending, + sortSeriesAscendingB, timeGrainSqla, percentageThreshold, metrics = [], @@ -223,18 +229,42 @@ export default function transformProps( } const rebasedDataA = rebaseForecastDatum(data1, verboseMap); + const { totalStackedValues, thresholdValues } = extractDataTotalValues( + rebasedDataA, + { + stack, + percentageThreshold, + xAxisCol: xAxisLabel, + }, + ); const MetricDisplayNameA = getMetricDisplayName(metrics[0], verboseMap); const MetricDisplayNameB = getMetricDisplayName(metricsB[0], verboseMap); - const [rawSeriesA] = extractSeries(rebasedDataA, { + const [rawSeriesA, sortedTotalValuesA] = extractSeries(rebasedDataA, { fillNeighborValue: stack ? 0 : undefined, xAxis: xAxisLabel, + sortSeriesType, + sortSeriesAscending, + stack, + totalStackedValues, }); const rebasedDataB = rebaseForecastDatum(data2, verboseMap); - const [rawSeriesB] = extractSeries(rebasedDataB, { + const { + totalStackedValues: totalStackedValuesB, + thresholdValues: thresholdValuesB, + } = extractDataTotalValues(rebasedDataB, { + stack: Boolean(stackB), + percentageThreshold, + xAxisCol: xAxisLabel, + }); + const [rawSeriesB, sortedTotalValuesB] = extractSeries(rebasedDataB, { fillNeighborValue: stackB ? 0 : undefined, xAxis: xAxisLabel, + sortSeriesType: sortSeriesTypeB, + sortSeriesAscending: sortSeriesAscendingB, + stack: Boolean(stackB), + totalStackedValues: totalStackedValuesB, }); const dataTypes = getColtypesMapping(queriesData[0]); @@ -292,25 +322,11 @@ export default function transformProps( ); const showValueIndexesA = extractShowValueIndexes(rawSeriesA, { stack, + onlyTotal, }); const showValueIndexesB = extractShowValueIndexes(rawSeriesB, { stack, - }); - const { totalStackedValues, thresholdValues } = extractDataTotalValues( - rebasedDataA, - { - stack, - percentageThreshold, - xAxisCol: xAxisLabel, - }, - ); - const { - totalStackedValues: totalStackedValuesB, - thresholdValues: thresholdValuesB, - } = extractDataTotalValues(rebasedDataB, { - stack: Boolean(stackB), - percentageThreshold, - xAxisCol: xAxisLabel, + onlyTotal, }); annotationLayers @@ -406,6 +422,7 @@ export default function transformProps( areaOpacity: opacity, seriesType, showValue, + onlyTotal, stack: Boolean(stack), stackIdSuffix: '\na', yAxisIndex, @@ -420,8 +437,8 @@ export default function transformProps( formatter: seriesFormatter, }) : seriesFormatter, + totalStackedValues: sortedTotalValuesA, showValueIndexes: showValueIndexesA, - totalStackedValues, thresholdValues, timeShiftColor, }, @@ -464,6 +481,7 @@ export default function transformProps( areaOpacity: opacityB, seriesType: seriesTypeB, showValue: showValueB, + onlyTotal: onlyTotalB, stack: Boolean(stackB), stackIdSuffix: '\nb', yAxisIndex: yAxisIndexB, @@ -478,8 +496,8 @@ export default function transformProps( formatter: seriesFormatter, }) : seriesFormatter, + totalStackedValues: sortedTotalValuesB, showValueIndexes: showValueIndexesB, - totalStackedValues: totalStackedValuesB, thresholdValues: thresholdValuesB, timeShiftColor, },