From 0e57dbaf8b233b42c6d848651682c2b55d021a30 Mon Sep 17 00:00:00 2001 From: srmukher <120183316+srmukher@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:43:26 +0000 Subject: [PATCH] Adding handlers for legend multi select --- .../react-charting/etc/react-charting.api.md | 1 - .../VerticalStackedBarChart.base.tsx | 57 ++++++++++++------- .../VerticalStackedBarChart.types.ts | 6 -- .../VerticalStackedBarChart.Basic.Example.tsx | 3 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/packages/charts/react-charting/etc/react-charting.api.md b/packages/charts/react-charting/etc/react-charting.api.md index 6481fd7695bc14..543e8d624e2679 100644 --- a/packages/charts/react-charting/etc/react-charting.api.md +++ b/packages/charts/react-charting/etc/react-charting.api.md @@ -1476,7 +1476,6 @@ export interface IVerticalStackedBarChartProps extends ICartesianChartProps { barMinimumHeight?: number; barWidth?: number | 'default' | 'auto'; calloutProps?: Partial; - canSelectMultipleLegends?: boolean; chartTitle?: string; // @deprecated colors?: string[]; diff --git a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx index 755db0f39b814a..4c49af05bf04ba 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx @@ -419,7 +419,7 @@ export class VerticalStackedBarChartBase extends React.Component< strokeLinecap="round" stroke={lineObject[item][i].color} transform={`translate(${xScaleBandwidthTranslate}, 0)`} - {...(this.state.selectedLegends.includes(item) && { + {...(this._isLegendHighlighted(item) && { onMouseOver: this._lineHover.bind(this, lineObject[item][i - 1]), onMouseLeave: this._lineHoverOut, })} @@ -439,11 +439,11 @@ export class VerticalStackedBarChartBase extends React.Component< circlePoint.useSecondaryYScale && secondaryYScale ? secondaryYScale(circlePoint.y) : yScale(circlePoint.y) } onMouseOver={ - this.state.selectedLegends.includes(item) + this._isLegendHighlighted(item) ? this._lineHover.bind(this, circlePoint) : this._onStackHover.bind(this, circlePoint.xItem) } - {...(this.state.selectedLegends.includes(item) && { + {...(this._isLegendHighlighted(item) && { onMouseLeave: this._lineHoverOut, })} r={this._getCircleVisibilityAndRadius(circlePoint.xItem.xAxisPoint, circlePoint.legend).radius} @@ -476,11 +476,11 @@ export class VerticalStackedBarChartBase extends React.Component< xAxisPoint: string | number | Date, legend: string, ): { visibility: CircleVisbility; radius: number } => { - const { selectedLegends, activeXAxisDataPoint } = this.state; - if (selectedLegends.length > 0) { - if (xAxisPoint === activeXAxisDataPoint && selectedLegends.includes(legend)) { + const { activeXAxisDataPoint } = this.state; + if (!this._noLegendHighlighted()) { + if (xAxisPoint === activeXAxisDataPoint && this._isLegendHighlighted(legend)) { return { visibility: CircleVisbility.show, radius: 8 }; - } else if (selectedLegends.includes(legend)) { + } else if (this._isLegendHighlighted(legend)) { return { visibility: CircleVisbility.show, radius: 0.3 }; } else { return { visibility: CircleVisbility.hide, radius: 0 }; @@ -612,9 +612,6 @@ export class VerticalStackedBarChartBase extends React.Component< title: point.title, color: point.color, isLineLegendInBarChart: true, - action: () => { - this._onLegendClick(point.title); - }, hoverAction: allowHoverOnLegend ? () => { this._handleChartMouseLeave(); @@ -635,14 +632,36 @@ export class VerticalStackedBarChartBase extends React.Component< focusZonePropsInHoverCard={this.props.focusZonePropsForLegendsInHoverCard} overflowText={this.props.legendsOverflowText} {...this.props.legendProps} - onChange={this._onLegendChange} - canSelectMultipleLegends={this.props.canSelectMultipleLegends} + onChange={this._onLegendSelectionChange} /> ); } - private _onLegendChange = (selectedLegends: string[]) => { - this.setState({ selectedLegends }); + private _onLegendSelectionChange = ( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ) => { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: [currentLegend?.title || ''] }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + }; + + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.activeLegend + ? [this.state.activeLegend] + : []; + } + + private _isLegendHighlighted = (legend: string): boolean => { + return this._getHighlightedLegend().indexOf(legend) > -1; }; private _onRectHover( @@ -672,7 +691,7 @@ export class VerticalStackedBarChartBase extends React.Component< * Show the callout if highlighted bar is focused/hovered * and Hide it if unhighlighted bar is focused/hovered */ - isCalloutVisible: this.state.selectedLegends.length === 0 || this.state.selectedLegends.includes(point.legend), + isCalloutVisible: this._noLegendHighlighted() || this._legendHighlighted(point.legend), calloutLegend: point.legend, dataForHoverCard: point.data, color, @@ -726,11 +745,11 @@ export class VerticalStackedBarChartBase extends React.Component< stack: IVerticalStackedChartProps, refSelected: React.MouseEvent | SVGGElement, ): void { - if (this.state.selectedLegends.length > 1) { + if (!this._noLegendHighlighted()) { stack = { ...stack, - chartData: stack.chartData.filter(dataPoint => this.state.selectedLegends.includes(dataPoint.legend)), - lineData: stack.lineData?.filter(dataPoint => this.state.selectedLegends.includes(dataPoint.legend)), + chartData: stack.chartData.filter(dataPoint => this._legendHighlighted(dataPoint.legend)), + lineData: stack.lineData?.filter(dataPoint => this._legendHighlighted(dataPoint.legend)), }; } const lineData = stack.lineData; @@ -1114,7 +1133,7 @@ export class VerticalStackedBarChartBase extends React.Component< * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegends.length === 0 && this.state.activeLegend === undefined; + return this._getHighlightedLegend().length === 0; }; private _getAriaLabel = (singleChartData: IVerticalStackedChartProps, point?: IVSChartDataPoint): string => { diff --git a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts index f4ee2ce798b663..5e47df049599cf 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts @@ -155,12 +155,6 @@ export interface IVerticalStackedBarChartProps extends ICartesianChartProps { * The prop used to enable rounded corners for the chart. */ roundCorners?: boolean; - - /** - * The prop used to enable multiple legend selection. - * @default false - */ - canSelectMultipleLegends?: boolean; } /** diff --git a/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx index e825a3d91ef11a..d90e45872e4888 100644 --- a/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx @@ -334,6 +334,7 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe lineOptions={lineOptions} legendProps={{ allowFocusOnLegends: true, + canSelectMultipleLegends: this.state.legendMultiSelect, }} hideLabels={this.state.hideLabels} enableReflow={true} @@ -341,7 +342,6 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe xAxisTitle={this.state.showAxisTitles ? 'Number of days' : undefined} enableGradient={this.state.enableGradient} roundCorners={this.state.roundCorners} - canSelectMultipleLegends={this.state.legendMultiSelect} /> )} @@ -358,6 +358,7 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe lineOptions={lineOptions} legendProps={{ allowFocusOnLegends: true, + canSelectMultipleLegends: this.state.legendMultiSelect, }} hideLabels={this.state.hideLabels} enableReflow={true}