-
Notifications
You must be signed in to change notification settings - Fork 120
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): improve chart figure #1104
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1104 +/- ##
==========================================
+ Coverage 72.05% 72.52% +0.46%
==========================================
Files 381 398 +17
Lines 11929 12255 +326
Branches 2603 2652 +49
==========================================
+ Hits 8596 8888 +292
- Misses 3308 3334 +26
- Partials 25 33 +8
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
jenkins test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, LGTM. I just left a few comments.
|
||
import { common } from '../page_objects/common'; | ||
|
||
describe('Accessibility tree', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
{seriesTypes.map((value, index) => { | ||
return <dd key={`${index}`}>{value}</dd>; | ||
})} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simplified...
{seriesTypes.map((value, index) => { | |
return <dd key={`${index}`}>{value}</dd>; | |
})} | |
{seriesTypes.map((value, index) => <dd key={`${index}`}>{value}</dd>)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you fixed in e7d1230
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite the fact that I like the approach taken, I think we should follow what was suggested in the original issue first.
I'd recommend tackling this after #1096, #1097, and #1098 otherwise it's too much structure for too little info
@@ -0,0 +1,7 @@ | |||
.screen-reader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
always prefix classes with ech
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call thank you - fixed in e7d1230
Object.entries(geometries).forEach((value) => { | ||
if (value[1].length > 0) { | ||
seriesTypes.push(value[0]); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not base our text on internal object keys. We should be able to get that information in a better/cleaner way. We should not think about text changes if we refactor our internal code structure.
Also remember that we need to add i18n, and having a stronger enum instead of internal object keys can improve the robustness of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you recommend getting this data if not using the object keys?
On the i18n front, I don't think it's fair to expect a PR that improves a11y to also solve Charts' i18n in one fell swoop. Without an existing i18n solution in place (correct me if I'm wrong as I'm only loosely familiar with the codebase), building with a hypothetical solution in mind brings a lot of overhead with little gain imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored in e7d1230 thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you recommend getting this data if not using the object keys?
I'm referring to the fact that we are extracting the chart type "strings" from an object geometries
that is an internal object which structure can change in the future easily.
This refactoring increase also the current issue: if the geometries
object change its signature, the getNameFunction
can just return unkown chart
for each chart type without being warned.
Object.entries(geometries).forEach((value) => {
if (value[1].length > 0 && value[0]) {
seriesTypes.push(getNameFunction(value[0]));
}
});
....
export const getNameFunction = (key: string): string => {
const screenReader: Map<string, string> = new Map();
screenReader
.set('bars', 'Bar chart')
.set('areas', 'Area chart')
.set('lines', 'Line chart')
.set('bubbles', 'Bubble chart');
return screenReader.get(key) ?? 'unknown chart';
};
The concept of chart type is already built into each spec
, the react component that specifies the chart configuration. I'm saying that. instead of taking the chart type information from an internal object, like geometris
, we should create that information from the actual specs using an already well-known and exposed enum called SeriesType
.
A selector that picks the actual series types and creates a Set of unique SeriesType
s is cleaner and we can map the well-known SeriesType
enum values to a set of internationalized strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thanks please see 9e036d3
width, | ||
height, | ||
}} | ||
aria-label="Chart" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As stated in the issue, the aria-*
labels should be then moved to the dl
element.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see e7d1230 thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In e7d1230 I ended up removing the aria-label because it's not read by VoiceOver and this PR adds more information. I was leaning towards not having the aria-label since it's not providing more information on the <dl>
tags.
@markov00 I know I wrote that ☝️ but this PR still does improve the state of charts a11y so I'd rather merge it (when it's green) and do the issues in a different order than have to sit on this PR while it rots. It does actually mean less work in the long run imo because this PR changes the DOM structure somewhat and the other work can be built directly into this new structure instead of needing to refactor it after the fact. TL;DR The new structure is arguably a little overkill... But that's better than the vast gap we have now... |
jenkins test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, I've added few minor comments
const multipleSeriesTypes: string[] = []; | ||
seriesTypes.forEach((value) => multipleSeriesTypes.push(value)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const multipleSeriesTypes: string[] = []; | |
seriesTypes.forEach((value) => multipleSeriesTypes.push(value)); |
It looks like you are not using multipleSeriesTypes
so you can remove these lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! 9b11e85
role="presentation" | ||
> | ||
<dl className="echScreen-reader"> | ||
<dt> Chart type </dt> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
<dt> Chart type </dt> | |
<dt>Chart type</dt> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! 9b11e85
@@ -0,0 +1,8 @@ | |||
.echScreen-reader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.echScreen-reader { | |
.echScreenReader { |
or similar to EUI
.echScreen-reader { | |
.echScreenReaderOnly { |
We should follow the BEM naming coventions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call - 9b11e85
export const getSeriesTypes = createCachedSelector( | ||
[getSeriesSpecsSelector], | ||
(specs): Set<SeriesType> => { | ||
const seriesTypes = new Set<SeriesType>(); | ||
specs.forEach((value) => seriesTypes.add(value.seriesType)); | ||
return seriesTypes; | ||
}, | ||
)(getChartIdSelector); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A way better!
With this, we can call an internationalization function (in the future) that uses SeriesType
to translate the enum values accordingly without having issues when renaming the value of the SeriesType
.
Jenkins, test this please |
# [28.1.0](v28.0.1...v28.1.0) (2021-04-13) ### Bug Fixes * **legend:** sizing for short labels with scrollbar ([#1115](#1115)) ([6e1f223](6e1f223)) * **xy:** negative bar highlight and click ([#1109](#1109)) ([ec17cb2](ec17cb2)), closes [#1100](#1100) ### Features * **a11y:** improve chart figure ([#1104](#1104)) ([815cf39](815cf39)) * **partition:** order slices and sectors ([#1112](#1112)) ([74df29b](74df29b)) * **partitions:** small multipies events pass on smAccessorValue ([#1106](#1106)) ([a3234fe](a3234fe)) * **xy:** optionally rounds the domain to nice values ([#1087](#1087)) ([f644cc4](f644cc4)) * **xy:** specify pixel and ratio width for bars ([#1114](#1114)) ([58de413](58de413)) * mosaic ([#1113](#1113)) ([64bdd88](64bdd88))
🎉 This PR is included in version 28.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [28.1.0](elastic/elastic-charts@v28.0.1...v28.1.0) (2021-04-13) ### Bug Fixes * **legend:** sizing for short labels with scrollbar ([opensearch-project#1115](elastic/elastic-charts#1115)) ([ebf2552](elastic/elastic-charts@ebf2552)) * **xy:** negative bar highlight and click ([opensearch-project#1109](elastic/elastic-charts#1109)) ([065673c](elastic/elastic-charts@065673c)), closes [opensearch-project#1100](elastic/elastic-charts#1100) ### Features * **a11y:** improve chart figure ([opensearch-project#1104](elastic/elastic-charts#1104)) ([373ea72](elastic/elastic-charts@373ea72)) * **partition:** order slices and sectors ([opensearch-project#1112](elastic/elastic-charts#1112)) ([72c0d1b](elastic/elastic-charts@72c0d1b)) * **partitions:** small multipies events pass on smAccessorValue ([opensearch-project#1106](elastic/elastic-charts#1106)) ([0e1f7de](elastic/elastic-charts@0e1f7de)) * **xy:** optionally rounds the domain to nice values ([opensearch-project#1087](elastic/elastic-charts#1087)) ([9c2eefc](elastic/elastic-charts@9c2eefc)) * **xy:** specify pixel and ratio width for bars ([opensearch-project#1114](elastic/elastic-charts#1114)) ([6294d5f](elastic/elastic-charts@6294d5f)) * mosaic ([opensearch-project#1113](elastic/elastic-charts#1113)) ([15c0d78](elastic/elastic-charts@15c0d78))
Summary
Closes #1099
Adding series types for Cartesian charts.
Checklist
Delete any items that are not applicable to this PR.
Unfortunately the previous test in the accessibility.test.tsx tests has been removed
The issue is that the accessibilitySnapshot is not capturing the aria-label consistently in the testAccessibilityTree function in common
Luckily, we are capturing the aria-label in
chart.test.tsx.snap