You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2025/06/18 12:32:26 UTC

(superset) 01/01: fix(Echarts): Echarts Legend Scroll fix (#33779)

This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 5.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 9a6261b0269e65606206d4b3642a5d9329cee71b
Author: amaannawab923 <am...@gmail.com>
AuthorDate: Mon Jun 16 21:14:52 2025 +0530

    fix(Echarts): Echarts Legend Scroll fix (#33779)
    
    Co-authored-by: Amaan Nawab <ne...@gmail.com>
---
 .../packages/superset-ui-core/src/chart/models/ChartProps.ts  | 11 +++++++++++
 .../plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx |  4 ++++
 .../plugin-chart-echarts/src/Timeseries/transformProps.ts     |  4 ++++
 superset-frontend/plugins/plugin-chart-echarts/src/types.ts   |  1 +
 superset-frontend/src/components/CachedLabel/index.tsx        |  2 +-
 superset-frontend/src/components/Chart/ChartRenderer.jsx      |  8 ++++++++
 6 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/packages/superset-ui-core/src/chart/models/ChartProps.ts b/superset-frontend/packages/superset-ui-core/src/chart/models/ChartProps.ts
index 829440133a..f953e49858 100644
--- a/superset-frontend/packages/superset-ui-core/src/chart/models/ChartProps.ts
+++ b/superset-frontend/packages/superset-ui-core/src/chart/models/ChartProps.ts
@@ -67,6 +67,8 @@ type Hooks = {
   setDataMask?: SetDataMaskHook;
   /** handle tooltip */
   setTooltip?: HandlerFunction;
+  /* handle legend scroll changes */
+  onLegendScroll?: HandlerFunction;
 } & PlainObject;
 
 /**
@@ -105,6 +107,8 @@ export interface ChartPropsConfig {
   inputRef?: RefObject<any>;
   /** Theme object */
   theme: SupersetTheme;
+  /* legend index */
+  legendIndex?: number;
 }
 
 const DEFAULT_WIDTH = 800;
@@ -135,6 +139,8 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
 
   legendState?: LegendState;
 
+  legendIndex?: number;
+
   queriesData: QueryData[];
 
   width: number;
@@ -164,6 +170,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
       ownState = {},
       filterState = {},
       legendState,
+      legendIndex,
       initialValues = {},
       queriesData = [],
       behaviors = [],
@@ -190,6 +197,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
     this.ownState = ownState;
     this.filterState = filterState;
     this.legendState = legendState;
+    this.legendIndex = legendIndex;
     this.behaviors = behaviors;
     this.displaySettings = displaySettings;
     this.appSection = appSection;
@@ -215,6 +223,7 @@ ChartProps.createSelector = function create(): ChartPropsSelector {
     input => input.ownState,
     input => input.filterState,
     input => input.legendState,
+    input => input.legendIndex,
     input => input.behaviors,
     input => input.displaySettings,
     input => input.appSection,
@@ -235,6 +244,7 @@ ChartProps.createSelector = function create(): ChartPropsSelector {
       ownState,
       filterState,
       legendState,
+      legendIndex,
       behaviors,
       displaySettings,
       appSection,
@@ -255,6 +265,7 @@ ChartProps.createSelector = function create(): ChartPropsSelector {
         ownState,
         filterState,
         legendState,
+        legendIndex,
         width,
         behaviors,
         displaySettings,
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
index b91db0b4c1..7bfab8e3ef 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
@@ -57,6 +57,7 @@ export default function EchartsTimeseries({
   refs,
   emitCrossFilters,
   coltypeMapping,
+  onLegendScroll,
 }: TimeseriesChartTransformedProps) {
   const { stack } = formData;
   const echartRef = useRef<EchartsHandler | null>(null);
@@ -159,6 +160,9 @@ export default function EchartsTimeseries({
     mouseover: params => {
       onFocusedSeries(params.seriesName);
     },
+    legendscroll: payload => {
+      onLegendScroll?.(payload.scrollDataIndex);
+    },
     legendselectchanged: payload => {
       onLegendStateChanged?.(payload.selected);
     },
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
index 0fb392a12d..bb62d6f128 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
@@ -122,6 +122,7 @@ export default function transformProps(
     theme,
     inContextMenu,
     emitCrossFilters,
+    legendIndex,
   } = chartProps;
 
   let focusedSeries: string | null = null;
@@ -450,6 +451,7 @@ export default function transformProps(
     setControlValue = () => {},
     onContextMenu,
     onLegendStateChanged,
+    onLegendScroll,
   } = hooks;
 
   const addYAxisLabelOffset = !!yAxisTitle;
@@ -624,6 +626,7 @@ export default function transformProps(
         legendState,
         padding,
       ),
+      scrollDataIndex: legendIndex || 0,
       data: legendData as string[],
     },
     series: dedupSeries(reorderForecastSeries(series) as SeriesOption[]),
@@ -692,5 +695,6 @@ export default function transformProps(
     },
     refs,
     coltypeMapping: dataTypes,
+    onLegendScroll,
   };
 }
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
index 294437c745..1a45714b3c 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
@@ -138,6 +138,7 @@ export interface BaseTransformedProps<F> {
   width: number;
   emitCrossFilters?: boolean;
   coltypeMapping?: Record<string, number>;
+  onLegendScroll?: (currentIndex: number) => void;
 }
 
 export type CrossFilterTransformedProps = {
diff --git a/superset-frontend/src/components/CachedLabel/index.tsx b/superset-frontend/src/components/CachedLabel/index.tsx
index 3ac26c2f5e..67f40e9d56 100644
--- a/superset-frontend/src/components/CachedLabel/index.tsx
+++ b/superset-frontend/src/components/CachedLabel/index.tsx
@@ -22,7 +22,7 @@ import { css, t } from '@superset-ui/core';
 import Label from 'src/components/Label';
 import { Tooltip } from 'src/components/Tooltip';
 import { TooltipContent } from './TooltipContent';
-import { Icons } from '../Icons';
+import Icons from '../Icons';
 
 export interface CacheLabelProps {
   onClick?: MouseEventHandler<HTMLElement>;
diff --git a/superset-frontend/src/components/Chart/ChartRenderer.jsx b/superset-frontend/src/components/Chart/ChartRenderer.jsx
index 25fc045d21..3707269ee1 100644
--- a/superset-frontend/src/components/Chart/ChartRenderer.jsx
+++ b/superset-frontend/src/components/Chart/ChartRenderer.jsx
@@ -95,6 +95,7 @@ class ChartRenderer extends Component {
         isFeatureEnabled(FeatureFlag.DrillToDetail),
       inContextMenu: false,
       legendState: undefined,
+      legendIndex: 0,
     };
     this.hasQueryResponseChange = false;
 
@@ -109,6 +110,7 @@ class ChartRenderer extends Component {
     this.handleContextMenuClosed = this.handleContextMenuClosed.bind(this);
     this.handleLegendStateChanged = this.handleLegendStateChanged.bind(this);
     this.onContextMenuFallback = this.onContextMenuFallback.bind(this);
+    this.handleLegendScroll = this.handleLegendScroll.bind(this);
 
     this.hooks = {
       onAddFilter: this.handleAddFilter,
@@ -123,6 +125,7 @@ class ChartRenderer extends Component {
       setDataMask: dataMask => {
         this.props.actions?.updateDataMask(this.props.chartId, dataMask);
       },
+      onLegendScroll: this.handleLegendScroll,
     };
 
     // TODO: queriesResponse comes from Redux store but it's being edited by
@@ -246,6 +249,10 @@ class ChartRenderer extends Component {
     }
   }
 
+  handleLegendScroll(legendIndex) {
+    this.setState({ legendIndex });
+  }
+
   render() {
     const { chartAlert, chartStatus, chartId, emitCrossFilters } = this.props;
 
@@ -367,6 +374,7 @@ class ChartRenderer extends Component {
             postTransformProps={postTransformProps}
             emitCrossFilters={emitCrossFilters}
             legendState={this.state.legendState}
+            legendIndex={this.state.legendIndex}
             {...drillToDetailProps}
           />
         </div>