Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix nvda bugs",
"packageName": "@fluentui/react-charts",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with all props 1`] = `
>
<div
aria-label="Test Annotation 1"
class="fui-chartAnnotationLayer__annotationContent"
class="fui-chartAnnotationLayer__annotationContent fui-chartAnnotationLayer__annotationContentInteractive"
data-annotation-key="annotation-1"
data-chart-annotation="true"
role="note"
style="opacity: 1;"
tabindex="0"
>
Test Annotation 1
</div>
Expand All @@ -89,11 +90,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with all props 1`] = `
>
<div
aria-label="Test Annotation 2"
class="fui-chartAnnotationLayer__annotationContent"
class="fui-chartAnnotationLayer__annotationContent fui-chartAnnotationLayer__annotationContentInteractive"
data-annotation-key="annotation-2"
data-chart-annotation="true"
role="note"
style="color: rgb(0, 0, 0); opacity: 1;"
tabindex="0"
>
Test Annotation 2
</div>
Expand Down Expand Up @@ -191,11 +193,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with default props 1`] =
>
<div
aria-label="Test Annotation 1"
class="fui-chartAnnotationLayer__annotationContent"
class="fui-chartAnnotationLayer__annotationContent fui-chartAnnotationLayer__annotationContentInteractive"
data-annotation-key="annotation-1"
data-chart-annotation="true"
role="note"
style="opacity: 1;"
tabindex="0"
>
Test Annotation 1
</div>
Expand All @@ -216,11 +219,12 @@ exports[`AnnotationOnlyChart Snapshots matches snapshot with default props 1`] =
>
<div
aria-label="Test Annotation 2"
class="fui-chartAnnotationLayer__annotationContent"
class="fui-chartAnnotationLayer__annotationContent fui-chartAnnotationLayer__annotationContentInteractive"
data-annotation-key="annotation-2"
data-chart-annotation="true"
role="note"
style="color: rgb(0, 0, 0); opacity: 1;"
tabindex="0"
>
Test Annotation 2
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,16 @@ export const ChartAnnotationLayer: React.FC<ChartAnnotationLayerProps> = React.m
data-annotation-key={key}
>
<div
className={mergeClasses(classes.annotationContent, annotation.style?.className)}
className={mergeClasses(
classes.annotationContent,
classes.annotationContentInteractive,
annotation.style?.className,
)}
style={contentStyle}
role={annotation.accessibility?.role ?? 'note'}
aria-label={annotation.accessibility?.ariaLabel ?? (annotationPlainText ? annotationPlainText : undefined)}
aria-describedby={annotation.accessibility?.ariaDescribedBy}
tabIndex={0}
data-chart-annotation="true"
data-annotation-key={key}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ describe('FunnelChart', () => {
it('renders basic funnel chart correctly', () => {
render(<FunnelChart data={basicData} chartTitle="Test Funnel Chart" width={400} height={300} />);

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(<FunnelChart data={stackedData} chartTitle="Stacked Funnel Chart" width={400} height={300} />);

expect(screen.getByRole('img')).toBeInTheDocument();
expect(screen.getAllByRole('img').length).toBeGreaterThan(0);
expect(screen.getByLabelText('Stacked Funnel Chart')).toBeInTheDocument();
});

Expand All @@ -52,29 +52,29 @@ describe('FunnelChart', () => {
it('renders with horizontal orientation by default', () => {
render(<FunnelChart data={basicData} chartTitle="Horizontal Chart" width={400} height={300} />);

expect(screen.getByRole('img')).toBeInTheDocument();
expect(screen.getAllByRole('img').length).toBeGreaterThan(0);
});

it('renders with vertical orientation when specified', () => {
render(
<FunnelChart data={basicData} chartTitle="Vertical Chart" width={400} height={300} orientation="vertical" />,
);

expect(screen.getByRole('img')).toBeInTheDocument();
expect(screen.getAllByRole('img').length).toBeGreaterThan(0);
});

it('hides legend when hideLegend is true', () => {
render(
<FunnelChart data={basicData} chartTitle="Hidden Legend Chart" width={400} height={300} hideLegend={true} />,
);

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(<FunnelChart data={basicData} chartTitle="Culture Chart" width={400} height={300} culture="en-US" />);

expect(screen.getByRole('img')).toBeInTheDocument();
expect(screen.getAllByRole('img').length).toBeGreaterThan(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ export const FunnelChart: React.FunctionComponent<FunnelChartProps> = 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,
Expand Down Expand Up @@ -238,7 +252,16 @@ export const FunnelChart: React.FunctionComponent<FunnelChartProps> = React.forw
const textColor = getContrastTextColor(fill);
return (
<g key={key}>
<path id={segmentId} d={pathD} fill={fill} opacity={opacity} {...eventHandlers} tabIndex={tabIndex} />
<path
id={segmentId}
d={pathD}
fill={fill}
opacity={opacity}
{...eventHandlers}
tabIndex={tabIndex}
role="img"
aria-label={_getAriaLabel(data)}
/>
{textProps && <g {...eventHandlers}>{_renderSegmentText({ ...textProps, textColor, opacity })}</g>}
</g>
);
Expand Down Expand Up @@ -441,14 +464,7 @@ export const FunnelChart: React.FunctionComponent<FunnelChartProps> = React.forw

return !_isChartEmpty() ? (
<div ref={chartContainerRef} className={classes.root} style={{ width, height }}>
<svg
width={width}
height={height}
className={classes.chart}
{...arrowAttributes}
role={'img'}
aria-label={props.chartTitle}
>
<svg width={width} height={height} className={classes.chart} {...arrowAttributes} aria-label={props.chartTitle}>
<g
transform={
isRTL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,8 +768,9 @@ export const HorizontalBarChartWithAxis: React.FunctionComponent<HorizontalBarCh
}
function _getAriaLabel(point: HorizontalBarChartWithAxisDataPoint): string {
const xValue = point.xAxisCalloutData || point.x;
const legend = point.legend;
const yValue = point.yAxisCalloutData || point.y;
return point.callOutAccessibilityData?.ariaLabel || `${xValue}. ` + `${yValue}.`;
return point.callOutAccessibilityData?.ariaLabel || `${yValue}. ` + (legend ? `${legend}, ` : '') + `${xValue}.`;
}

function _renderBarLabel(
Expand Down
Loading