From cfb8974bc813e40a5d0df970c0c914523aa0abfa Mon Sep 17 00:00:00 2001 From: Diego Medina Date: Fri, 1 Jul 2022 15:10:52 -0300 Subject: [PATCH] fix: Bar stacking on v2 doesn't work if the x-axis is value type --- .../superset-ui-chart-controls/src/types.ts | 8 +++--- .../plugin-chart-echarts/src/controls.tsx | 26 ++++++++++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 5ae2f26c4f77..9aff1d955998 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -193,10 +193,10 @@ export type TabOverride = 'data' | 'customize' | boolean; * show a warning based on the value of another component. It's also possible to bind * arbitrary data from the redux store to the component this way. * - tabOverride: set to 'data' if you want to force a renderTrigger to show up on the `Data` - tab, or 'customize' if you want it to show up on that tam. Otherwise sections with ALL - `renderTrigger: true` components will show up on the `Customize` tab. + tab, or 'customize' if you want it to show up on that tam. Otherwise sections with ALL + `renderTrigger: true` components will show up on the `Customize` tab. * - visibility: a function that uses control panel props to check whether a control should - * be visibile. + * be visible. Return undefined if the result of the function call should not be used. */ export interface BaseControlConfig< T extends ControlType = ControlType, @@ -230,7 +230,7 @@ export interface BaseControlConfig< visibility?: ( props: ControlPanelsContainerProps, controlData: AnyDict, - ) => boolean; + ) => boolean | undefined; } export interface ControlValueValidator< diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx index 38eee33e7459..29f684895030 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { t } from '@superset-ui/core'; +import { DTTM_ALIAS, getColumnLabel, t } from '@superset-ui/core'; import { ControlPanelsContainerProps, ControlSetItem, @@ -26,6 +26,7 @@ import { } from '@superset-ui/chart-controls'; import { DEFAULT_LEGEND_FORM_DATA } from './constants'; import { DEFAULT_FORM_DATA } from './Timeseries/constants'; +import { getAxisType, getColtypesMapping } from './utils/series'; const { legendMargin, legendOrientation, legendType, showLegend } = DEFAULT_LEGEND_FORM_DATA; @@ -120,6 +121,29 @@ export const stackControl: ControlSetItem = { renderTrigger: true, default: false, description: t('Stack series on top of each other'), + visibility: (props: ControlPanelsContainerProps) => { + // Bar stacking is not supported if the x-axis is value type + // Source: https://github.com/apache/echarts/issues/15102 + const vizType = props?.form_data?.viz_type; + if (vizType !== 'echarts_timeseries_bar') { + return undefined; + } + + const data = props?.chart?.queriesResponse?.[0]; + const verboseMap = props?.exploreState?.datasource?.verbose_map ?? {}; + const xAxis = props?.form_data?.x_axis; + + if (!data || !xAxis) { + return undefined; + } + + const dataTypes = getColtypesMapping(data); + const xAxisCol = verboseMap[xAxis] || getColumnLabel(xAxis || DTTM_ALIAS); + const xAxisDataType = dataTypes?.[xAxisCol]; + const xAxisType = getAxisType(xAxisDataType); + + return xAxisType === 'category'; + }, }, };