Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(a11y): add data table for screen readers (sunburst, treemap, icicle, flame) #1155

Merged
merged 63 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ebbee47
feat: add partition data table for screen readers
rshen91 May 10, 2021
d70b995
feat: add percentage row
rshen91 May 11, 2021
b7a030d
fix: update chart api
rshen91 May 11, 2021
8340b51
feat: add screen reader data data structure
rshen91 May 13, 2021
863d6dc
feat: add screen reader data table to partitions
rshen91 May 13, 2021
547c7af
feat: refactor utillity function and format data values
rshen91 May 13, 2021
2acc45e
fix: remove icicle and flame from getscreenreaderData check
rshen91 May 14, 2021
fcd3fc8
test: update tests
rshen91 May 14, 2021
15132c7
fix: add catch for large data charts
rshen91 May 17, 2021
51a8be3
fix: fix conditional within td tag to display value.valueText
rshen91 May 18, 2021
b9b7dfd
refactor: add code review clean up
rshen91 May 19, 2021
7cb0d70
fix: update per code review
rshen91 May 19, 2021
7e69878
test: fix tests
rshen91 May 19, 2021
d070a6c
feat: add incremental table rows
rshen91 May 24, 2021
cdef1c2
fix: fix tr table issues
rshen91 May 24, 2021
6f74271
style: clean up code
rshen91 May 24, 2021
99a6d61
fix: fix conditional tfoot for show more cells
rshen91 May 25, 2021
a14cc62
fix: clean up code
rshen91 May 25, 2021
060d4ff
fix: generate more data on button click
rshen91 May 25, 2021
77fce3a
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 May 25, 2021
8763b91
refactor: improve button functionality and code review changes
rshen91 May 26, 2021
46cb755
fix: clean up code
rshen91 May 26, 2021
df537b4
test: add selector unit test
rshen91 May 26, 2021
691b89d
test: add data table tests
rshen91 May 27, 2021
e5f141e
fix: update configMaxCount for flame charts
rshen91 May 27, 2021
d39ab17
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 May 28, 2021
4dd1136
feat: some code review changes
rshen91 May 28, 2021
e253fb3
feat: add some focus managemetn
rshen91 May 28, 2021
71050c0
fix: code review feedback
rshen91 May 28, 2021
04edce2
fix: update tests
rshen91 May 28, 2021
aebfe90
refactor: add parent name to data table
rshen91 Jun 1, 2021
e654f11
feat: code review changes
rshen91 Jun 1, 2021
97b5b57
fix: make sure to not show button at end of data
rshen91 Jun 2, 2021
6c984bb
fix: refactor renderTableContent
rshen91 Jun 2, 2021
e1cf63b
refactor: trying to fix focus management after handleMoreData
rshen91 Jun 3, 2021
554c3f2
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 3, 2021
12dd739
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 3, 2021
654668a
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 3, 2021
adb7bbe
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 4, 2021
fa0c61c
feat: add conditional logic for moreThanOneLayer
rshen91 Jun 4, 2021
9fba9c1
test: update nested pie slices
rshen91 Jun 4, 2021
204abef
refactor: remove formatter from component
rshen91 Jun 4, 2021
793b81f
fix: clean up legend labels for partitions
rshen91 Jun 4, 2021
a65028a
feat: improve focus management
rshen91 Jun 4, 2021
ef443b0
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 4, 2021
17568c6
fix: update valueText formatter
rshen91 Jun 4, 2021
49165d0
test: update tests
rshen91 Jun 6, 2021
dd1ba26
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 7, 2021
b180214
refactor: update table generation
markov00 Jun 7, 2021
42b4f0e
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 7, 2021
3cd61db
refactor: small storybook changes and refactor legend labels
rshen91 Jun 7, 2021
be561f9
fix: getLegendItemsLabels uses all small multiple panel data for the …
monfera Jun 8, 2021
228bc32
chore: removed superseded function
monfera Jun 8, 2021
c3a361d
feat: add sort and update tests
rshen91 Jun 8, 2021
d31fad8
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 8, 2021
5646771
Merge remote-tracking branch 'origin/sunburst-a11y-slices' into sunbu…
rshen91 Jun 8, 2021
3e5cd36
feat: update table pagination
rshen91 Jun 8, 2021
b0b02fc
fix: code review
rshen91 Jun 8, 2021
82e8219
feat: add colSpan
rshen91 Jun 8, 2021
5dabaea
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 8, 2021
f929208
fix: merge commit
rshen91 Jun 9, 2021
b019245
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 9, 2021
f98dee7
Merge remote-tracking branch 'upstream/master' into sunburst-a11y-slices
rshen91 Jun 9, 2021
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
3 changes: 2 additions & 1 deletion api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ export const DEFAULT_TOOLTIP_SNAP = true;
export const DEFAULT_TOOLTIP_TYPE: "vertical";

// @public (undocumented)
export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'animateData' | 'debug' | 'tooltip' | 'theme' | 'hideDuplicateAxes' | 'brushAxis' | 'minBrushDelta' | 'externalPointerEvents' | 'showLegend' | 'showLegendExtra' | 'legendPosition' | 'legendMaxDepth' | 'ariaUseDefaultSummary' | 'ariaLabelHeadingLevel';
export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'animateData' | 'debug' | 'tooltip' | 'theme' | 'hideDuplicateAxes' | 'brushAxis' | 'minBrushDelta' | 'externalPointerEvents' | 'showLegend' | 'showLegendExtra' | 'legendPosition' | 'legendMaxDepth' | 'ariaUseDefaultSummary' | 'ariaLabelHeadingLevel' | 'ariaTableCaption';

// @public (undocumented)
export const DEPTH_KEY = "depth";
Expand Down Expand Up @@ -1748,6 +1748,7 @@ export interface SettingsSpec extends Spec, LegendSpec {
ariaLabel?: string;
ariaLabelHeadingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
ariaLabelledBy?: string;
ariaTableCaption: string;
ariaUseDefaultSummary: boolean;
baseTheme?: Theme;
brushAxis?: BrushAxis;
Expand Down
45 changes: 45 additions & 0 deletions src/chart_types/partition_chart/layout/utils/group_by_rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import { CategoryKey } from '../../../../common/category';
import { Relation } from '../../../../common/text_utils';
import { LegendPath } from '../../../../state/actions/legend';
import { LegendItemLabel } from '../../../../state/selectors/get_legend_items_labels';
import { Datum, ValueAccessor } from '../../../../utils/common';
import { Layer } from '../../specs';

/** @public */
export const AGGREGATE_KEY = 'value';
Expand Down Expand Up @@ -297,3 +299,46 @@ export const aggregators = {
// },
// },
};

/** @internal */
export function flatSlicesNames(
monfera marked this conversation as resolved.
Show resolved Hide resolved
layers: Layer[],
depth: number,
tree: HierarchyOfArrays,
keys: Map<LegendItemLabel['label'], any> = new Map(),
monfera marked this conversation as resolved.
Show resolved Hide resolved
) {
if (tree.length === 0) {
return [];
}
monfera marked this conversation as resolved.
Show resolved Hide resolved

for (let i = 0; i < tree.length; i++) {
const branch = tree[i];
const arrayNode = branch[1];
const key = branch[0];
monfera marked this conversation as resolved.
Show resolved Hide resolved

// format the key with the layer formatter
const layer = layers[depth - 1];
const formatter = layer?.nodeLabel;
monfera marked this conversation as resolved.
Show resolved Hide resolved
monfera marked this conversation as resolved.
Show resolved Hide resolved
let formattedValue = '';
if (key != null) {
formattedValue = formatter ? formatter(key) : `${key}`;
}
monfera marked this conversation as resolved.
Show resolved Hide resolved
// preventing errors from external formatters
if (formattedValue != null && formattedValue !== '' && formattedValue !== HIERARCHY_ROOT_KEY) {
monfera marked this conversation as resolved.
Show resolved Hide resolved
const current = new Map();
current.set('depth', Math.max(depth, keys.get(formattedValue)?.get(depth) ?? 0));
current.set('percentage', `${Math.round((arrayNode.value / arrayNode[STATISTICS_KEY].globalAggregate) * 100)}%`);
current.set('valueText', arrayNode.value);
keys.set(formattedValue, current);
monfera marked this conversation as resolved.
Show resolved Hide resolved
}

const children = arrayNode[CHILDREN_KEY];
flatSlicesNames(layers, depth + 1, children, keys);
monfera marked this conversation as resolved.
Show resolved Hide resolved
}
return [...keys.keys()].map((k) => ({
label: k,
depth: keys.get(k)?.get('depth') ?? 0,
percentage: keys.get(k)?.get('percentage'),
valueText: keys.get(k)?.get('valueText'),
}));
monfera marked this conversation as resolved.
Show resolved Hide resolved
}
43 changes: 4 additions & 39 deletions src/chart_types/partition_chart/layout/utils/legend_labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,11 @@

import { LegendItemLabel } from '../../../../state/selectors/get_legend_items_labels';
import { Layer } from '../../specs';
import { CHILDREN_KEY, HIERARCHY_ROOT_KEY, HierarchyOfArrays } from './group_by_rollup';
import { flatSlicesNames, HierarchyOfArrays } from './group_by_rollup';

/** @internal */
export function getLegendLabels(layers: Layer[], tree: HierarchyOfArrays, legendMaxDepth: number) {
return flatSlicesNames(layers, 0, tree).filter(({ depth }) => depth <= legendMaxDepth);
}

function flatSlicesNames(
layers: Layer[],
depth: number,
tree: HierarchyOfArrays,
keys: Map<string, number> = new Map(),
): LegendItemLabel[] {
if (tree.length === 0) {
return [];
}

for (let i = 0; i < tree.length; i++) {
const branch = tree[i];
const arrayNode = branch[1];
const key = branch[0];

// format the key with the layer formatter
const layer = layers[depth - 1];
const formatter = layer?.nodeLabel;
let formattedValue = '';
if (key != null) {
formattedValue = formatter ? formatter(key) : `${key}`;
}
// preventing errors from external formatters
if (formattedValue != null && formattedValue !== '' && formattedValue !== HIERARCHY_ROOT_KEY) {
// save only the max depth, so we can compute the the max extension of the legend
keys.set(formattedValue, Math.max(depth, keys.get(formattedValue) ?? 0));
}

const children = arrayNode[CHILDREN_KEY];
flatSlicesNames(layers, depth + 1, children, keys);
}
return [...keys.keys()].map((k) => ({
label: k,
depth: keys.get(k) ?? 0,
}));
return flatSlicesNames(layers, 0, tree).reduce((acc, val) => {
return val.depth <= legendMaxDepth ? acc.concat({ label: val.label, depth: val.depth }) : acc;
}, [] as LegendItemLabel[]);
monfera marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 2 additions & 0 deletions src/chart_types/partition_chart/renderer/canvas/partition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';

import { ScreenReaderSummary } from '../../../../components/accessibility';
import { ScreenReaderSunburstTable } from '../../../../components/accessibility/sunburst_table';
import { clearCanvas } from '../../../../renderers/canvas';
import { onChartRendered } from '../../../../state/actions/chart';
import { ChartId, GlobalChartState } from '../../../../state/chart_state';
Expand Down Expand Up @@ -169,6 +170,7 @@ class PartitionComponent extends React.Component<PartitionProps> {
role="presentation"
>
<ScreenReaderSummary />
<ScreenReaderSunburstTable />
</canvas>
</figure>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import createCachedSelector from 're-reselect';

import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
import { flatSlicesNames, HierarchyOfArrays } from '../../layout/utils/group_by_rollup';
import { Layer, PartitionSpec } from '../../specs';
import { partitionMultiGeometries } from './geometries';
import { getPartitionSpecs } from './get_partition_specs';
import { getTrees } from './tree';

/** @internal */
export interface LabelsInterface {
label: string;
valueText: number;
depth: number;
percentage: string;
}

/** @internal */
const getFlattenedLabels = (layers: Layer[], tree: HierarchyOfArrays, legendMaxDepth: number = 0) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
return flatSlicesNames(layers, 0, tree).filter((val) => val.depth <= legendMaxDepth);
};

/**
* @internal
*/
const getScreenReaderDataForPartitions = (
specs: PartitionSpec[],
legendMaxDepth: number,
trees: { tree: HierarchyOfArrays }[],
) => {
return specs.flatMap((spec) => getFlattenedLabels(spec.layers, trees[0].tree, legendMaxDepth));
};

/** @internal */
export const getScreenReaderDataSelector = createCachedSelector(
[getPartitionSpecs, getSettingsSpecSelector, getTrees, partitionMultiGeometries],
(specs, { legendMaxDepth }, trees) => {
const lengthOfResults = getScreenReaderDataForPartitions(specs, legendMaxDepth, trees).length;
// how to control how much is calculated
return lengthOfResults > 20
Copy link
Contributor

@monfera monfera May 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if 20 is good hardcoded, @markov00 might want to chime in. Also, even if it's too many, maybe the top N values could be kept, to not disadvantage the user with the loss of all items. Also, what's the harm in just doing it unconditionally for all sectors? Hopefully the VO user can "back out", ie. doesn't need to resort to hearing all the 0.1% slices before continuing with the rest of the page contents

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we really limit that, or is the user that can directly skip the content after the first top N values?

Copy link
Contributor Author

@rshen91 rshen91 May 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think the data table definitely impacts rendering performance when loading flame/icicle charts (particularly in terms of #1155 (comment)), so I wondering about implementing some sort of escape hatch if results are in the 1000s. This 20 is just arbitrary for now but I am definitely open to suggestions. 🙇🏻‍♀️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only rendering the top N in a data table sounds interesting! I wouldn't mind trying to implement that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@myasonik do you have suggestions for larger datasets? I see the top N being kind fo cool and just having somewhere (maybe the table caption?) say the amount of results there were?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@myasonik in line with Rachel's question, it would be interesting to know if there's a good practice for handling the current tradeoffs between accessibility annotations (DOM with ARIA labels etc.) and other goals, as I'm not currently aware of an API that would detect if a screen reader is used. The other goals include, bounded rendering time, responding page, economy of power and CPU utilization, economy with browser memory. Unfortunately the resource usage of DOM rendering is roughly 100x larger than that of DOM rendering.

Rachel I'm also thinking that maybe, reaching a cap, a "slice row" for "Other" could be created, with a single, longer text description for screen reading. While that can still be a long string, it'd establish a bounded DOM element count. DOM and general webpage performance worsens with every DOM element, even if those DOM elements do nothing.

Rachel, another important thing to do is to ensure that the table and row creation do not cause undue layout work for the browser. Depending on a few factors, table rendering speed can vary wildly. The rule of thumb is that if the columns are of fixed width, then the layouting is quite fast, but if the column widths are driven by the table contents, which I believe is the default, then it becomes a much heavier task. Let's chat about this when we look at the PR together.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was just going back through this PR and thought I'd document the outcome of this (we 3 chatted on zoom): In short, we're only rendering some subset of data at first (until a user interacts with a "load all" button) so there shouldn't be consequential impact to performance.

? [
{
label: `There are ${lengthOfResults} data points in this chart`,
depth: 0,
valueText: lengthOfResults,
percentage: 'N/A',
},
]
: getScreenReaderDataForPartitions(specs, legendMaxDepth, trees);
},
)(getChartIdSelector);
8 changes: 4 additions & 4 deletions src/components/__snapshots__/chart.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ exports[`Chart should render the legend name test 1`] = `
<Connect(SpecsParserComponent)>
<SpecsParserComponent specParsed={[Function (anonymous)]} specUnmounted={[Function (anonymous)]}>
<Connect(SpecInstance) debug={true} rendering=\\"svg\\" showLegend={true}>
<SpecInstance debug={true} rendering=\\"svg\\" showLegend={true} upsertSpec={[Function (anonymous)]} removeSpec={[Function (anonymous)]} id=\\"__global__settings___\\" chartType=\\"global\\" specType=\\"settings\\" rotation={0} animateData={true} resizeDebounce={10} tooltip={{...}} externalPointerEvents={{...}} hideDuplicateAxes={false} baseTheme={{...}} brushAxis=\\"x\\" minBrushDelta={2} ariaUseDefaultSummary={true} ariaLabelHeadingLevel=\\"p\\" showLegendExtra={false} legendMaxDepth={Infinity} legendPosition=\\"right\\" />
<SpecInstance debug={true} rendering=\\"svg\\" showLegend={true} upsertSpec={[Function (anonymous)]} removeSpec={[Function (anonymous)]} id=\\"__global__settings___\\" chartType=\\"global\\" specType=\\"settings\\" rotation={0} animateData={true} resizeDebounce={10} tooltip={{...}} externalPointerEvents={{...}} hideDuplicateAxes={false} baseTheme={{...}} brushAxis=\\"x\\" minBrushDelta={2} ariaUseDefaultSummary={true} ariaLabelHeadingLevel=\\"p\\" ariaTableCaption=\\"Table of the data for screen reader navigation\\" showLegendExtra={false} legendMaxDepth={Infinity} legendPosition=\\"right\\" />
</Connect(SpecInstance)>
<Connect(SpecInstance) id=\\"test\\" data={{...}}>
<SpecInstance id=\\"test\\" data={{...}} upsertSpec={[Function (anonymous)]} removeSpec={[Function (anonymous)]} chartType=\\"xy_axis\\" specType=\\"series\\" seriesType=\\"bar\\" groupId=\\"__global__\\" xScaleType=\\"ordinal\\" yScaleType=\\"linear\\" xAccessor=\\"x\\" yAccessors={{...}} yScaleToDataExtent={false} hideInLegend={false} enableHistogramMode={false} />
Expand All @@ -75,9 +75,9 @@ exports[`Chart should render the legend name test 1`] = `
<Connect(ScreenReaderSummaryComponent)>
<ScreenReaderSummaryComponent chartTypeDescription=\\"bar chart\\" a11ySettings={{...}} dispatch={[Function: dispatch]}>
<div className=\\"echScreenReaderOnly\\">
<ScreenReaderLabel label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" />
<ScreenReaderDescription label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" />
<ScreenReaderTypes label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" chartTypeDescription=\\"bar chart\\">
<ScreenReaderLabel label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" tableCaption=\\"Table of the data for screen reader navigation\\" />
<ScreenReaderDescription label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" tableCaption=\\"Table of the data for screen reader navigation\\" />
<ScreenReaderTypes label={[undefined]} labelId={[undefined]} labelHeadingLevel=\\"p\\" description={[undefined]} descriptionId=\\"chart1--defaultSummary\\" defaultSummaryId=\\"chart1--defaultSummary\\" tableCaption=\\"Table of the data for screen reader navigation\\" chartTypeDescription=\\"bar chart\\">
<dl>
<dt>
Chart type:
Expand Down
92 changes: 74 additions & 18 deletions src/components/accessibility/accessibility.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,83 @@
import { mount } from 'enzyme';
import React from 'react';

import { BarSeries, LineSeries, Settings } from '../../specs';
import { config } from '../../chart_types/partition_chart/layout/config';
import { PartitionLayout } from '../../chart_types/partition_chart/layout/types/config_types';
import { arrayToLookup } from '../../common/color_calcs';
import { mocks } from '../../mocks/hierarchical';
import { productDimension } from '../../mocks/hierarchical/dimension_codes';
import { BarSeries, LineSeries, Partition, Settings } from '../../specs';
import { Datum } from '../../utils/common';
import { Chart } from '../chart';

describe('Accessibility', () => {
it('should include the series types if one type of series', () => {
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Settings debug rendering="svg" showLegend />
<BarSeries id="test" data={[{ x: 0, y: 2 }]} />
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('bar chart');
describe('Screen reader summary xy charts', () => {
it('should include the series types if one type of series', () => {
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Settings debug rendering="svg" showLegend />
<BarSeries id="test" data={[{ x: 0, y: 2 }]} />
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('bar chart');
});
it('should include the series types if multiple types of series', () => {
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Settings debug rendering="svg" showLegend />
<BarSeries id="test" data={[{ x: 0, y: 2 }]} />
<LineSeries id="test2" data={[{ x: 3, y: 5 }]} />
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('Mixed chart: bar and line chart');
});
});
it('should include the series types if multiple types of series', () => {
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Settings debug rendering="svg" showLegend />
<BarSeries id="test" data={[{ x: 0, y: 2 }]} />
<LineSeries id="test2" data={[{ x: 3, y: 5 }]} />
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('Mixed chart: bar and line chart');

describe('Screen reader summary, other chart types', () => {
it('should include the series type if partition chart', () => {
const productLookup = arrayToLookup((d: any) => d.sitc1, productDimension);
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Partition
id="spec_1"
data={mocks.pie}
valueAccessor={(d: Datum) => d.exportVal as number}
valueFormatter={(d: number) => `$${config.fillLabel.valueFormatter(Math.round(d / 1000000000))}\u00A0Bn`}
layers={[
{
groupByRollup: (d: Datum) => d.sitc1,
nodeLabel: (d: Datum) => productLookup[d].name,
},
]}
/>
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('sunburst chart');
});
it('should include series type if treemap type', () => {
const productLookup = arrayToLookup((d: any) => d.sitc1, productDimension);
const wrapper = mount(
<Chart size={[100, 100]} id="chart1">
<Partition
id="spec_1"
data={mocks.pie}
valueAccessor={(d: Datum) => d.exportVal as number}
valueFormatter={(d: number) => `$${config.fillLabel.valueFormatter(Math.round(d / 1000000000))}\u00A0Bn`}
layers={[
{
groupByRollup: (d: Datum) => d.sitc1,
nodeLabel: (d: Datum) => productLookup[d].name,
},
]}
config={{
partitionLayout: PartitionLayout.treemap,
}}
/>
</Chart>,
);
expect(wrapper.find('dd').first().text()).toBe('treemap chart');
});
});

describe('Data table for screen readers', () => {});
});
Loading