diff --git a/change/@fluentui-react-charts-b1922719-3717-4980-93ed-552008a42e4a.json b/change/@fluentui-react-charts-b1922719-3717-4980-93ed-552008a42e4a.json new file mode 100644 index 0000000000000..33883213b4498 --- /dev/null +++ b/change/@fluentui-react-charts-b1922719-3717-4980-93ed-552008a42e4a.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix nvda bugs", + "packageName": "@fluentui/react-charts", + "email": "anushgupta@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/charts/react-charts/library/src/components/AnnotationOnlyChart/__snapshots__/AnnotationOnlyChart.test.tsx.snap b/packages/charts/react-charts/library/src/components/AnnotationOnlyChart/__snapshots__/AnnotationOnlyChart.test.tsx.snap index 64685525b16bf..2546438e02db9 100644 --- a/packages/charts/react-charts/library/src/components/AnnotationOnlyChart/__snapshots__/AnnotationOnlyChart.test.tsx.snap +++ b/packages/charts/react-charts/library/src/components/AnnotationOnlyChart/__snapshots__/AnnotationOnlyChart.test.tsx.snap @@ -64,11 +64,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with all props 1`] = ` >
Test Annotation 1
@@ -89,11 +90,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with all props 1`] = ` >
Test Annotation 2
@@ -191,11 +193,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with default props 1`] = >
Test Annotation 1
@@ -216,11 +219,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with default props 1`] = >
Test Annotation 2
diff --git a/packages/charts/react-charts/library/src/components/CommonComponents/Annotations/ChartAnnotationLayer.tsx b/packages/charts/react-charts/library/src/components/CommonComponents/Annotations/ChartAnnotationLayer.tsx index ffc465f0a1e7a..6650a245efeb8 100644 --- a/packages/charts/react-charts/library/src/components/CommonComponents/Annotations/ChartAnnotationLayer.tsx +++ b/packages/charts/react-charts/library/src/components/CommonComponents/Annotations/ChartAnnotationLayer.tsx @@ -649,11 +649,16 @@ export const ChartAnnotationLayer: React.FC = React.m data-annotation-key={key} >
diff --git a/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.test.tsx b/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.test.tsx index 14d1a613dca3b..1c70bedcfec76 100644 --- a/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.test.tsx +++ b/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.test.tsx @@ -31,14 +31,14 @@ describe('FunnelChart', () => { it('renders basic funnel chart correctly', () => { render(); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); expect(screen.getByLabelText('Test Funnel Chart')).toBeInTheDocument(); }); it('renders stacked funnel chart correctly', () => { render(); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); expect(screen.getByLabelText('Stacked Funnel Chart')).toBeInTheDocument(); }); @@ -52,7 +52,7 @@ describe('FunnelChart', () => { it('renders with horizontal orientation by default', () => { render(); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); }); it('renders with vertical orientation when specified', () => { @@ -60,7 +60,7 @@ describe('FunnelChart', () => { , ); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); }); it('hides legend when hideLegend is true', () => { @@ -68,13 +68,13 @@ describe('FunnelChart', () => { , ); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); // Legend should not be present when hideLegend is true }); it('renders with custom culture for number formatting', () => { render(); - expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBeGreaterThan(0); }); }); diff --git a/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.tsx b/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.tsx index 4ea4faefcd18a..bda043be00ac8 100644 --- a/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.tsx +++ b/packages/charts/react-charts/library/src/components/FunnelChart/FunnelChart.tsx @@ -135,6 +135,20 @@ export const FunnelChart: React.FunctionComponent = React.forw return getHighlightedLegend().length === 0; } + function _getAriaLabel( + data: FunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } }, + ): string { + if ('subValue' in data) { + // Stacked funnel segment + const formattedValue = formatToLocaleString(data.subValue.value.toString(), props.culture); + return `${data.stage}, ${data.subValue.category}, ${formattedValue}.`; + } else { + // Non-stacked funnel segment + const formattedValue = formatToLocaleString((data.value ?? 0).toString(), props.culture); + return `${data.stage}, ${formattedValue}.`; + } + } + function _getEventHandlerProps( data: FunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } }, opacity?: number, @@ -238,7 +252,16 @@ export const FunnelChart: React.FunctionComponent = React.forw const textColor = getContrastTextColor(fill); return ( - + {textProps && {_renderSegmentText({ ...textProps, textColor, opacity })}} ); @@ -441,14 +464,7 @@ export const FunnelChart: React.FunctionComponent = React.forw return !_isChartEmpty() ? (
- + = React.forwardR onMouseOver={event => _onMouseOverLargeDataset(i, verticaLineHeight, event, yScale)} onFocus={event => _onFocusLargeDataset(i, verticaLineHeight, event, yScale, k)} onMouseOut={_handleMouseOut} + role="img" + aria-label={_points[i].data[k].text ?? _getAriaLabel(i, k)} />, ); } diff --git a/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/VerticalStackedBarChart.tsx b/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/VerticalStackedBarChart.tsx index 406f744ef279b..f69a0bad7bd42 100644 --- a/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/VerticalStackedBarChart.tsx +++ b/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/VerticalStackedBarChart.tsx @@ -14,6 +14,7 @@ import { import { useId } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; import { tokens } from '@fluentui/react-theme'; +import { useArrowNavigationGroup } from '@fluentui/react-tabster'; import { AccessibilityProps, CartesianChart, @@ -98,6 +99,7 @@ export const VerticalStackedBarChart: React.FunctionComponent _getLineLegends(data); const _emptyChartId: string = useId('_VSBC_empty'); + const _arrowNavigationAttributes = useArrowNavigationGroup({ axis: 'vertical', circular: true }); let _points: VerticalStackedChartProps[] = []; let _dataset: VerticalStackedBarDataPoint[]; let _xAxisLabels: string[] = []; @@ -237,17 +239,14 @@ export const VerticalStackedBarChart: React.FunctionComponent { lineObject[item].forEach((circlePoint: LinePoint, subIndex: number) => { const circleRef: { refElement: SVGCircleElement | null } = { refElement: null }; - const noBarsAndLinesActive = - circlePoint.xItem.chartData.filter( - dataPoint => _noLegendHighlighted() || _isLegendHighlighted(dataPoint.legend), - ).length === 0; const yScaleBandwidthTranslate = !circlePoint.useSecondaryYScale && _yAxisType === YAxisType.StringAxis ? (yScalePrimary as StringScale).bandwidth() / 2 : 0; + const shouldHighlight = _isLegendHighlighted(circlePoint.legend) || _noLegendHighlighted() ? true : false; dots.push( { circleRef.refElement = e; }} - {...(noBarsAndLinesActive - ? { - tabIndex: !props.hideTooltip ? 0 : undefined, - onFocus: event => _lineFocus(event, circlePoint, circleRef), - onBlur: _handleMouseOut, - role: 'img', - 'aria-label': _getAriaLabel(circlePoint.xItem, circlePoint as VSChartDataPoint), - } - : {})} + tabIndex={!props.hideTooltip && shouldHighlight ? 0 : undefined} + onFocus={event => _lineFocus(event, circlePoint, circleRef)} + onBlur={_handleMouseOut} + role="img" + aria-label={_getAriaLabel(circlePoint.xItem, circlePoint as VSChartDataPoint, true)} />, ); }); @@ -999,10 +981,7 @@ export const VerticalStackedBarChart: React.FunctionComponent item.lineData && item.lineData.length > 0, - ); - const shouldFocusWholeStack = _toFocusWholeStack(_isHavingLines); + const shouldFocusWholeStack = _toFocusWholeStack(); if (_xAxisType === XAxisTypes.StringAxis) { _barWidth = getBarWidth(props.barWidth, props.maxBarWidth, xBarScale.bandwidth()); @@ -1357,7 +1336,7 @@ export const VerticalStackedBarChart: React.FunctionComponent item.lineData && item.lineData.length > 0, ); - const shouldFocusWholeStack = _toFocusWholeStack(_isHavingLines); + const shouldFocusWholeStack = _toFocusWholeStack(); _dataset = _createDataSetLayer(); const legendBars: JSXElement = _getLegendData(_points, _createLegendsForLine(props.data)); const calloutProps: ModifiedCartesianChartProps['calloutProps'] = { @@ -1371,8 +1350,7 @@ export const VerticalStackedBarChart: React.FunctionComponent 1)), + isCalloutForStack: shouldFocusWholeStack, isCartesian: true, customCallout: { customizedCallout: _getCustomizedCallout() !== null ? _getCustomizedCallout()! : undefined, @@ -1420,7 +1398,7 @@ export const VerticalStackedBarChart: React.FunctionComponent { return ( <> - {_bars} + {_bars} {_isHavingLines && _createLines( diff --git a/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/__snapshots__/VerticalStackedBarChart.test.tsx.snap b/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/__snapshots__/VerticalStackedBarChart.test.tsx.snap index 961d768119f9f..6da6a464a309d 100644 --- a/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/__snapshots__/VerticalStackedBarChart.test.tsx.snap +++ b/packages/charts/react-charts/library/src/components/VerticalStackedBarChart/__snapshots__/VerticalStackedBarChart.test.tsx.snap @@ -201,33 +201,38 @@ exports[`Vertical stacked bar chart - Screen resolution Should remain unchanged - + @@ -716,33 +742,38 @@ exports[`Vertical stacked bar chart - Screen resolution Should remain unchanged - + @@ -1383,7 +1435,9 @@ exports[`Vertical stacked bar chart rendering Should render the vertical stacked - + - + - + - + @@ -3226,37 +3298,39 @@ exports[`VerticalStackedBarChart - mouse events Should render customized callout role="group" style="position: fixed; left: 0px; top: 0px; margin: 0px;" > -
-
-            {
-  "chartData": [
-    {
-      "legend": "Metadata1",
-      "data": 40,
-      "color": "aqua",
-      "xAxisCalloutData": "2020/04/30",
-      "yAxisCalloutData": "40%"
-    },
-    {
-      "legend": "Metadata2",
-      "data": 5,
-      "color": "navy",
-      "xAxisCalloutData": "2020/04/30",
-      "yAxisCalloutData": "5%"
-    }
-  ],
-  "xAxisPoint": 0,
-  "lineData": [
-    {
-      "y": 15,
-      "legend": "Line1",
-      "color": "yellow",
-      "data": 15,
-      "shouldDrawBorderBottom": true
-    }
-  ]
-}
-          
+
+
+
+ 2020/04/30 + +
+
+
+
+
+ Metadata1 +
+
+ 40% +
+
+
@@ -3616,7 +3690,9 @@ exports[`VerticalStackedBarChart snapShot testing Should not render bar labels 1 - + - + - + - + - + - + - + - + - + - + - +