plouc / nivo

nivo provides a rich set of dataviz components, built on top of the awesome d3 and React libraries
https://nivo.rocks
MIT License
13.18k stars 1.03k forks source link

Accessibility #126

Open dgennetten opened 6 years ago

dgennetten commented 6 years ago

Nivo is great. Fantastic. Only disappointment is an apparent disregard for accessibility? Any plans to fix that?

rpearce commented 5 years ago

This is a huge question, and there are likely to be different ideas for what a11y even means with a lot of these. For example: a11y in the sense that a chart is an image and here is the data? Or should the chart be totally keyboard accessible?

Starting with the simplest type of chart seems like it'd be the place to start. I dunno how @plouc is able to do all this work, so this'll perhaps get kicked to the curb.

What we're doing short-term is making the chart role="img" and using aria-labelledby and aria-describedby to explain what the chart is an image of and then describe the data values in there for screenreaders.

shipleydaniel commented 5 years ago

@rpearce Would it be possible to append that aria label with a short summary of the data in the chart?

One of the core utilities of charting seems to be glanceable data. Reading out the raw data in an AX use case seems analogous to digging into a table view which I think puts AX compliance in question.

Would it be possible to have some sort of conditional logic that checks if the data matches a prepreprogrammed pattern? For example, in a line chart we could search for trends, peaks and nadirs and then update the alt text with some details on page load or whenever the graph is changed.

Happy to prototype something if there is any interest.

rpearce commented 5 years ago

@shipleydaniel (not sure if you think I work on nivo or something...I don't!)

Unfortunately, at work we're not using nivo for our charts anymore, but we are still using role="img" and then using an <h*> tag with aria-labelledby hidden <p> to contain some chart data that is connected by aria-describedby. It's not ideal, but it's what I had to go with to get the job done.

To address your ideas: you could totally do something like that if it were worth your time, and I would first think about how valuable it would be to those who would consume it. Only you can answer that!

wyze commented 4 years ago

Added ability to pass role property to all charts, that is now in the latest version. Anything further we could do to be more accessible?

rpearce commented 4 years ago

@wyze Unless a lot of a11y changes have come down in the past year or so with this project, you may want to check out https://www.highcharts.com/docs/accessibility/accessibility-module-feature-overview and a simple example, https://www.highcharts.com/demo/accessible-line, for some ideas about a11y with charts.

Charts that are not interactive with assistive devices (like a keyboard, screen reader, etc), end up having to be ignored entirely, and separate, "visually hidden" descriptions usually need be provided to summarize the charts.

Ideally, assistive devices would have at least the same access to the charts that sighted users get.

wyze commented 4 years ago

Thank you for the references @rpearce! Going to keep this as an umbrella issue and as we start to tackle accessibility, open separate issues for those.

cbleslie commented 3 years ago

Hello all,

Problem statement:

I am a developer. Charts are described as role="img", unfortunately, there is no (simple or easy) way for the charting API to allow me to add the required ~alt~aria-label tag attribute to appropriately describe the 'image' itself.

Possible solutions:

Allow the passage of an ~alt~ aria-label text prop.

Commentary:

This is the lowest common denominator for A11y. You've presented an image to the user, and should be able to describe it for those who are blind/low vision. Now, it would be wonderful for the graph to procedurally create the description text based on the data in the graph, but that's not expected. The developer could very well do that themselves if offered the option to pass the data they need to the component.

rpearce commented 3 years ago

@cbleslie Unless I am mistaken, alt is only available on <img /> tags.

If you use role="img" on a non-<img /> element, the appropriate way to provide alternative text for that image is to use aria-label or aria-labelledby.

This is easily doable outside of nivo by wrapping whatever you're doing in a <div> with the aforementioned attributes.

cbleslie commented 3 years ago

So let's assume @rpearce is correct. In this case it is still expected that the element with role="img" still have the ablity to be correctly labeled? Thus must be on the SVG element itself? As described in the below reference? https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Role_Img#svg_and_roleimg

rpearce commented 3 years ago

I haven't used nivo in a while -- does it put role="img" on the SVG?

When I did use it, I wrapped it in an aria-hidden="true" div so that screen readers wouldn't read it (that also assumes nothing in there is focusable), and that was wrapped in a div that had aria-label="(The info here)" and role="img".

cbleslie commented 3 years ago

@rpearce as of the version I am using; this is how it renders. Screen Shot 2021-04-26 at 12 56 28 PM

As for your workaround, I would say it's less than ideal, and does not accurately reflect the document's structure and purpose. This is a "Retrofit" for something that should be a11y friendly in the first place.

The web is a11y friendly, until we make it otherwise.

rpearce commented 3 years ago

I checked nivo's website, and it is indeed adding role="img" to the charts; perhaps @plouc could consider allowing for aria-label, aria-labelledby, and aria-describedby somehow?

As for my suggestions above, the result is the same, regardless: you have to use role="img" and a label somewhere if the chart tool doesn't have the accessibility you need (which is incredibly hard to build into a free, open source chart tool).

cbleslie commented 3 years ago

(which is incredibly hard to build into a free, open source chart tool).

I am not sure I understand, are you suggesting create a PR for the fix? I can if need be.

rpearce commented 3 years ago

(which is incredibly hard to build into a free, open source chart tool).

I am not sure I understand, are you suggesting create a PR for the fix? I can if need be.

Making a charting library fully accessible is incredibly hard to do when it isn't baked into the library from the start, and that can help explain why this issue we're having this exchange on exists.

In lieu of not having fully accessible charts, the best one can do is try to get aria-label, aria-labelledby, and aria-describedby rendering on the SVG charts since there is already a role="img" on there. If @plouc or someone else (like you) can do that, then great.

But there are also <canvas> charts that do not have role="img", so if somebody wants to make those into labelled images, I believe they'll need to do some version of what I stated above. For example:

<div aria-label="(Info here...)" role="img">
  <TheCanvasChartGoesHere />
</div>
plouc commented 3 years ago

A small update about this issue, which is obviously really important, but unfortunately equally hard to implement.

I've started to look at how to improve the bar chart (@nivo/bar), only the SVG implementation at the moment as the options are quite limited for canvas based charts. Now, we'll be able to specify some aria attributes for the chart itself plus for each bar (dynamic via a function):

Screen Shot 2021-08-14 at 16 51 36

isFocusable enable keyboard usage (limited, just via tab)

Aug-14-2021 16-57-27

It's far from perfect and I admit I'm no expert regarding a11y, but I hope it'll help.

julianna-langston commented 1 year ago

Hi! I recently stumbled on this charting library and issue, but just wanted to add something.

I work on an open source tool, Chart2Music, which turns charts into music so the blind can hear data. It provides hooks for interactivity (like keyboard navigation), so that you can make your charts accessible to keyboard-only users and screen reader users (blind + low vision users).

If you want to play with it, see this canvas-based line chart made with Chart.js or this svg-based heatmap made with Plotly.

oncet commented 2 months ago

Is it possible to pass aria-label or aria-labelledby props to Nivo charts? If so, how? I just tried something like but it doesn't seem to work:

<ResponsiveLine aria-label="My label" />