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

Add Accessibility support for charts. #1060

Open
mlvea opened this issue May 21, 2016 · 17 comments
Open

Add Accessibility support for charts. #1060

mlvea opened this issue May 21, 2016 · 17 comments
Labels

Comments

@mlvea
Copy link

mlvea commented May 21, 2016

Currently graphs are not accessible to VoiceOver and other accessible technologies.

@danielgindi
Copy link
Collaborator

A PR is welcome :-)

@liuxuan30
Copy link
Member

liuxuan30 commented Jun 2, 2016

What does the support looks like? curious

@graesser-tiaa
Copy link

graesser-tiaa commented Jun 14, 2016

See this example for using alt tags to add accessibility support to a web page - http://accessibilityresources.org/joomla/index.php/blog/alt-attributes-it-s-not-that-hard
The blog post shows what to do for a bar chart.

@pauljadam
Copy link

If you want to see what an accessible chart looks like on iOS just view the Stocks app from Apple it's got VoiceOver Accessibility for data points.

https://pbs.twimg.com/media/DOR8G6lVQAEQ7Hi.jpg:large

I found this chart library because they're using it at work and it's not accessible. Can you copy the Apple stocks implementation?

mathewa6 added a commit to mathewa6/Charts that referenced this issue May 10, 2018
This commit makes PieChartView adhere to the UIAccessibility container
protocol. See the Accessibility section marked for the methods. To allow
conformance, 3 properties are added to IPieChartDataSet and
PieChartDataSet that enable a more user friendly audio descriptionfor
data elements. PieChartRenderer has a new private method
createAccessibleElement() that populates the accessiblePieChartElements
property, which in turn is used in PieChartView. Note that to prevent
contextless audio descriptions, the default Chart Description header
text was deleted in Description.swift since it is already an optional.
@mathewa6
Copy link
Contributor

mathewa6 commented May 10, 2018

Hello!

Thanks for the great library. I'd be happy to try and tackle this issue for as many chart types as possible, so feel free to assign it to me.

While I'm working on it, does anyone have any resources or recommendations for what the Scatter and Combined chart should sound like to a VO user? Right now I'm leaning toward a axis based range summarization (For eg, the sample scatter plot would sound like "0 to 10, DS1: 9 points from 81 to 99, DS2: 5 points between 50 and 87... etc"), however as you can imagine in these two cases, it can be an auditory overload given enough categories.

The other option is to simply let the creator describe the visual. But in that case should the description be a required property? This might not work as well for charts with dynamic data.

There is also the option for simply narrating a table of values, but usability wise, I think that is a poor choice, since the point of a visualization is to make the information contained palatable.

As of now these (and variants) are what I'm working on:

  • Line
  • Bar
  • Pie
  • Bubble
  • Radar

mathewa6 added a commit to mathewa6/Charts that referenced this issue May 12, 2018
Minor changes to spacing in PieChartRenderer.swift. Removed formatting
and use of "self." to match library style.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 14, 2018
Updated ChartViewBase, ChartData and ChartDataRendererBase to declare
the primary properties required for accessibility support within the
Charts library. This includes the UIAccessibility protocol methods
within ChartViewBase and the internal accessibleChartElements property
in the base renderer. ChartData also has 3 optional properties to allow
proper formatting of audio.
@pmairoldi
Copy link
Collaborator

Thanks for looking into this @mathewa6. This resource might help you. It’s for the web but the same ideas apply https://www.w3.org/WAI/tutorials/images/complex/

@mathewa6
Copy link
Contributor

@petester42 Thanks! I hadn't considered splitting descriptions so that is very helpful.

iOS/tvOS allows for a little more interactivity and that way, most folks who use this library will get accessibility "for free" based on titles and legends already provided, without needing to manually add descriptions.

Multiple descriptions sounds like it'd be a great way for static scatter/combined plots or even on macOS for static plots.

@pmairoldi
Copy link
Collaborator

At least for the web the idea of having multiple descriptions is for the user to be able skip I if they don’t care. It’s pretty bad experience to read an entire graph without user consent.

@mathewa6
Copy link
Contributor

Absolutely.

iOS/tvOS let you browse by Header using the VoiceOver rotor. I'm making sure to make the first element of the graphs a Header item (which uses the existing title/legend/description), so they can just skip to next header if they're not interested.

Then again, since Charts is cross platform, let me know if you'd prefer a description on all platforms as primary.

@pmairoldi
Copy link
Collaborator

Rotor is also supported in the latest version of macOS. I think it’s fine

@mathewa6
Copy link
Contributor

Awesome! Thanks for bringing this up: worth getting these sorts of issues out the way before a PR imo.

mathewa6 added a commit to mathewa6/Charts that referenced this issue May 18, 2018
Added accessibilityChildren to ChartViewBase which is a layer over both UIAccessibilityContainer and NSAccessibilityGroup protocols. Updated PieChartRenderer to use the platform agnostic NSUIAccessibilityElement. Added init() overrides in NSUIView declaration for macOS to add .list NSAccessibilityRole. Added Platform+Accessibility.swift which extends NSUIView with accessibility container and group protocols and also declares NSUIAccessibilityElement, which acts as an abstraction over NSAccessibilityElement and UIAccessibilityElement.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 18, 2018
Moved Platform+Accessibility.swift to Utils folder. Changed
accessibleChartElements to be final since Renderer subclasses should not need to
modify its working. Simply populating it in draw() functions will add
basic accessibility.
@mathewa6
Copy link
Contributor

mathewa6 commented May 18, 2018

@petester42
I've updated NSUIView so that iOS and tvOS now use UIAccessibilityContainer with the first element being a header, whereas macOS uses NSAccessibilityGroup, while still keeping the first cell/row a static text element (i.e VoiceOver (VO) will skip right over the chart, only providing a label, unless the person is interested enough to enter the group). I think this will allow for the option of adding a secondary detailed description as that first element for macOS, while keeping with platform conventions wrt screenreaders.

@mathewa6
Copy link
Contributor

Quick question:

I had a couple VO testers use the sample Radar chart I was working on and we ended up with equal preference for two different ways of parsing the data. I thought I’d ask here, in case there is some statistical or common use case for the chart type that makes one particular method easier. Basically, for the Radar chart, we can present the data in two ways:

  • By data set (in which case we sort by decreasing order of value, otherwise the clockwise arbitrary order made little sense to our VO users)
  • By variable (in which case we are comparing the value across datasets)

Here’s a 30s video demonstrating the difference.

Is there a preference on the library's side for these ordering based on how the Charts library is used and/or intended to be used?

If not, I will use the first method, since it seemed to make more sense initially to our blind colleagues.

mathewa6 added a commit to mathewa6/Charts that referenced this issue May 20, 2018
Created internal property accessibilityOrderedElements to make
BarChartRenderer be composed of logically ordered accessible elements (See inline comments for details). Updated ChartDataRendererBase, PieChartRenderer and Platform+Accessibility with updated comments to reflect the platform agnostic NSUIAccessibilityElement's use.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 21, 2018
Updated HorizontalBarChartRenderer to populate
accessibilityOrderedElements, which in turn is used by the
BarChartRenderer superclass to enable accessibility. Added minor note to
BarChartRenderer's createAccesibleElement() for edge case where x-axis
labels can be inaccurate if multiple data sets are present.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 27, 2018
LineChartRenderer now has a private accessibilityOrderedElements nested array that is then used to populate accessibleChartElements. Do note that the nesting is unnecessary for now, but will be needed once a custom rotor is added. Also unlike most other renderers, LineChartRenderer's accessibleChartElements is populated in drawCircles(). This required moving the check for isDrawCirclesEnabled() after accessibleChartElements are populated.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 27, 2018
Updated BubbleChartRenderer to mirror LineChartRenderer's nested
use of accessibilityOrderedElements to populate accessibleChartElements.
Minor updates to comments in LineChartRenderer.
mathewa6 added a commit to mathewa6/Charts that referenced this issue May 29, 2018
Updated RadarChartRenderer with accessibility properties and calls in
drawData and drawDataSet. Due to the unique spatial arrangement of radar
charts, accessibleChartElements is populated by dataset, within which
variables are ordered in decreasing order.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 18, 2018
Fixed crash due to incorrect use of maxEntryCountSet instead of dataSetCount
in BubbleChartRenderer and LineChartRenderer's
accessibilityCreateEmptyOrderedElements(). Updated BubbleChartRenderer's
bubble accessibilityLabel to include percentage size of bubble based on
maxSize property of IBubbleChartDataSet.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 18, 2018
Updated CandleStickChartRenderer to populate accessibleChartElements.
Unlike most other renderers with multiple dataSet support, we do not
attempt to order elements logically and hence dataSets are presented to
VO in the same order they are drawn with the dataSet label acting as a
separating heading.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 19, 2018
Added a workaround for non updating accessibility frame when resizing
windows and using Charts on macOS by using setAccessibilityFrameInParent() in Platform+Accessibility. See inline comments for details.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 20, 2018
Added createAccessibleHeader() to ChartRendererBase.swift that is used
to create a descriptive header for all subclasses based on dataSet count
and labels. RadarChartRenderer and PieChartRenderer updated to add
dataSet label to each item and with documentation respectively.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 20, 2018
Added an offset to BarChartRenderer's barRect calculation in prepareBuffer() to prevent
calculation of rects outside visible chart area, while still allowing
automatic offset of the axis minima visually. This workaround is only
used when using auto calculated y-axis minima and isn't used when a custom
minimum is manually set.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jun 29, 2018
Updated return value for the index(of:) function to be NSNotFound in
Platform+Accessibility's iOS section. This is as required by the
documentation for UIAccessibilityContainer protocol.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jul 8, 2018
)

Updated Platform+Accessibility with postAnnouncementNotification() to
let VoiceOver speak provided strings. Added accessibilityHighlight() to
ChartViewBase which finds the highlighted accessibilityElement when an
NSUIPanGesture is detected and passes it to a VO notification. For now,
this only works with 1 dataset.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jul 8, 2018
Allowed hints to let header elements for Bar and Line charts (set in Bar/Line chart renderers) let users know they can pan to skim. Removed refocus on entire chart in
BarLineChartViewBase.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jul 8, 2018
…rg#1060)

Allowed manual setting of the ability to allow VoiceOver panning
internally in the Charts framework for all views using
_allowsHighlightedAccessibilityElements. Currently only Bar and Line
chart views set this to true, since panning on other charts can lead to
misinterpretation due to their shape/layout. Fixed LineChartRenderer to
create accessibilityOrdererElements similarly to BarChartRenderer.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jul 8, 2018
…#1060)

Updated ChartViewBase's accessibilityHighlight to account for index
calculations into accessibleChartElements when bar chart data is
stacked. Also enabled panning support for CandlestickCharts. Added
checks for allowsHighlightedAccessibilityElements before adding an
accessibilityHint to headers in Line and Bar chart renderers.
mathewa6 added a commit to mathewa6/Charts that referenced this issue Jul 8, 2018
Updated BubbleChartView and Renderer to set
_allowsHighlightedAccessibilityElements and to more closely mirror Line
and Bar chart renderer's indices for accessibilityOrderedElements.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
This commit makes PieChartView adhere to the UIAccessibility container
protocol. See the Accessibility section marked for the methods. To allow
conformance, 3 properties are added to IPieChartDataSet and
PieChartDataSet that enable a more user friendly audio descriptionfor
data elements. PieChartRenderer has a new private method
createAccessibleElement() that populates the accessiblePieChartElements
property, which in turn is used in PieChartView. Note that to prevent
contextless audio descriptions, the default Chart Description header
text was deleted in Description.swift since it is already an optional.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Minor changes to spacing in PieChartRenderer.swift. Removed formatting
and use of "self." to match library style.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated ChartViewBase, ChartData and ChartDataRendererBase to declare
the primary properties required for accessibility support within the
Charts library. This includes the UIAccessibility protocol methods
within ChartViewBase and the internal accessibleChartElements property
in the base renderer. ChartData also has 3 optional properties to allow
proper formatting of audio.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Added accessibilityChildren to ChartViewBase which is a layer over both UIAccessibilityContainer and NSAccessibilityGroup protocols. Updated PieChartRenderer to use the platform agnostic NSUIAccessibilityElement. Added init() overrides in NSUIView declaration for macOS to add .list NSAccessibilityRole. Added Platform+Accessibility.swift which extends NSUIView with accessibility container and group protocols and also declares NSUIAccessibilityElement, which acts as an abstraction over NSAccessibilityElement and UIAccessibilityElement.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Moved Platform+Accessibility.swift to Utils folder. Changed
accessibleChartElements to be final since Renderer subclasses should not need to
modify its working. Simply populating it in draw() functions will add
basic accessibility.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Created internal property accessibilityOrderedElements to make
BarChartRenderer be composed of logically ordered accessible elements (See inline comments for details). Updated ChartDataRendererBase, PieChartRenderer and Platform+Accessibility with updated comments to reflect the platform agnostic NSUIAccessibilityElement's use.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated HorizontalBarChartRenderer to populate
accessibilityOrderedElements, which in turn is used by the
BarChartRenderer superclass to enable accessibility. Added minor note to
BarChartRenderer's createAccesibleElement() for edge case where x-axis
labels can be inaccurate if multiple data sets are present.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
LineChartRenderer now has a private accessibilityOrderedElements nested array that is then used to populate accessibleChartElements. Do note that the nesting is unnecessary for now, but will be needed once a custom rotor is added. Also unlike most other renderers, LineChartRenderer's accessibleChartElements is populated in drawCircles(). This required moving the check for isDrawCirclesEnabled() after accessibleChartElements are populated.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated BubbleChartRenderer to mirror LineChartRenderer's nested
use of accessibilityOrderedElements to populate accessibleChartElements.
Minor updates to comments in LineChartRenderer.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated RadarChartRenderer with accessibility properties and calls in
drawData and drawDataSet. Due to the unique spatial arrangement of radar
charts, accessibleChartElements is populated by dataset, within which
variables are ordered in decreasing order.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Fixed crash due to incorrect use of maxEntryCountSet instead of dataSetCount
in BubbleChartRenderer and LineChartRenderer's
accessibilityCreateEmptyOrderedElements(). Updated BubbleChartRenderer's
bubble accessibilityLabel to include percentage size of bubble based on
maxSize property of IBubbleChartDataSet.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated CandleStickChartRenderer to populate accessibleChartElements.
Unlike most other renderers with multiple dataSet support, we do not
attempt to order elements logically and hence dataSets are presented to
VO in the same order they are drawn with the dataSet label acting as a
separating heading.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Added a workaround for non updating accessibility frame when resizing
windows and using Charts on macOS by using setAccessibilityFrameInParent() in Platform+Accessibility. See inline comments for details.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Added createAccessibleHeader() to ChartRendererBase.swift that is used
to create a descriptive header for all subclasses based on dataSet count
and labels. RadarChartRenderer and PieChartRenderer updated to add
dataSet label to each item and with documentation respectively.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Added an offset to BarChartRenderer's barRect calculation in prepareBuffer() to prevent
calculation of rects outside visible chart area, while still allowing
automatic offset of the axis minima visually. This workaround is only
used when using auto calculated y-axis minima and isn't used when a custom
minimum is manually set.
shineeth pushed a commit to shineeth/Charts that referenced this issue Oct 31, 2018
Updated return value for the index(of:) function to be NSNotFound in
Platform+Accessibility's iOS section. This is as required by the
documentation for UIAccessibilityContainer protocol.
@SaiPasumarthy
Copy link

@mindgraffiti Does anybody looking at Dynamic Type Support for Chart Labels?

@mindgraffiti
Copy link

@mindgraffiti Does anybody looking at Dynamic Type Support for Chart Labels?

Hello Sai,

Sadly, no. This task was de-prioritized and there are no plans for Woo Mobile to work on it.

@lingzlu
Copy link

lingzlu commented Aug 31, 2023

Accessibility support request: is it possible to include the capability for a custom accessibility value that differs from the displayed axis label? I'm working with bar charts containing string values as axis labels. To ensure proper chart rendering, I had to truncate long axis labels to a certain length using a custom AxisValueFormatter implementation. However, for the accessibility value, I want it to announce the complete label string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants