DEV Community

Tiny Octopus
Tiny Octopus

Posted on • Updated on • Originally published at tiny-octopus.com

How to Create Accessible Charts in React: A Guide to Inclusive Data Visualisation

What is Accessibility in Data Visualisation

Data visualisation is key to communication but we found that many of the popular charting and graph libraries in ReactJS can be inaccessible to people using a screen reader. Accessibility in data visualisation is essential to making sure that all users, regardless of how they consume that data, can understand and interact with charts and graphs on your website.

We've recently tested out Highcharts, and have been impressed with the tools and features baked into the library to help you create accessible charts in React. Highcharts do charge for a license to use their software, but the quality and feature-set Highcharts provides outstrips any of the open source alternatives we've tested.

The biggest accessibility draw for us was the ability for users to navigate through the charts using a keyboard, with the data being read out in a useful and meaningful way. Highcharts have lots of demos you can go through, and very thorough documentation. However we did find their documentation for using Highcharts with React a bit limited, so we've spent some time experimenting and written 3 examples below for building a line chart, a spline chart and a bar chart in React.

Choosing the Right Chart Type

Different chart types serve different data and user needs, making the selection process critical for effective and clear data visualisation. For example, bar charts are excellent for presenting categorical data and comparing values across multiple categories and subcategories. They clearly illustrate the differences between data points, making trends easy to spot. In this chart, each bar represents the sales figures for a different product category across four quarters, allowing for a straightforward comparison of sales performance within each category over time.

Bar chart titled ‘Sales Performance by Product Category,’ illustrating the sales figures (in thousands) for Electronics, Furniture, Clothing, Groceries, and Books across four quarters. The chart shows Groceries as the top-performing category in each quarter, with sales steadily increasing from Q1 to Q4, while Books have the lowest sales figures throughout the year.

Line charts are ideal for visualising data over time, helping to illustrate trends, progressions, or changes in a continuous dataset. They are particularly useful when you need to show the relationship between different data points over time, such as tracking the performance of a product or monitoring the growth in website traffic over a period.

A line chart example, titled ‘Monthly Sales Data’ depicting example sales data (in thousands) across each month of the year.

Spline charts, a variation of line charts, offer a smoother curve by using splines (pronounced /splaɪn/ - rhymes with line) instead of straight lines to connect data points. This type of chart is good for emphasising the smoothness of transitions or when the data represents a pattern that naturally follows a curved pattern, such as temperature changes throughout a day.

Spline chart titled ‘Temperature Changes Throughout the Day’ depicting temperature variations (in °C) from midnight to midnight. The chart shows a low of 12.5°C at 6 AM and a peak of 23.2°C at 3 PM, illustrating how the temperature rises during the morning and early afternoon and gradually cools down towards the evening.

Choosing the right chart type is essential for clear and effective data visualization. Highcharts provides a wide range of chart types, including bar charts, line charts, spline charts, and scatter plots (plus many many more chart types), enabling you to select the best option tailored to your specific data and the insights you wish to convey.

Creating Accessible Charts in React with Highcharts

Highcharts makes it easy to create accessible charts. Here’s how to create a simple accessible line chart, spline chart & bar chart in a React application:

Code example:

In an existing React application, install the highcharts and highcharts-react-official packages:

npm install highcharts highcharts-react-official
Enter fullscreen mode Exit fullscreen mode

Create a line chart component:

import React from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import HighchartsAccessibility from 'highcharts/modules/accessibility';

// Initialise HighchartsAccessibility module
HighchartsAccessibility(Highcharts);

export const AccessibleLineChart = () => {
  const options = {
    title: {
      text: 'Monthly Sales Data'
    },
    xAxis: {
      categories: [
        'January', 'February', 'March', 'April', 'May', 'June', 
        'July', 'August', 'September', 'October', 'November', 'December'
      ],
      title: {
        text: 'Month'
      }
    },
    yAxis: {
      title: {
        text: 'Sales (in thousands)'
      }
    },
    series: [
      {
        name: 'Sales',
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
      }
    ],
    accessibility: {
      enabled: true,
      description: 'This chart shows the monthly sales data over a year, with sales peaking in September and October.'
    }
  };

  return (
    <HighchartsReact highcharts={Highcharts} options={options} />
  );
};
Enter fullscreen mode Exit fullscreen mode

In this line chart example, the HighchartsAccessibility module is imported and initialised to enable accessibility features. The accessibility option in the chart configuration provides a description for screen readers.

Create a spline chart component:

You'll see in the example above that we're not actually telling Highcharts to return a line chart. Line charts seem to be the default chart type, so lets now get a Spline chart rendering instead.

import React from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import HighchartsAccessibility from 'highcharts/modules/accessibility';

// Initialise HighchartsAccessibility module
HighchartsAccessibility(Highcharts);

export const AccessibleSplineChart = () => {
  const options = {
    chart: {
      type: 'spline'
    },
    title: {
      text: 'Temperature Changes Throughout the Day',
    },
    xAxis: {
      categories: [
        '12 AM', '1 AM', '2 AM', '3 AM', '4 AM', '5 AM', '6 AM', '7 AM', '8 AM', '9 AM', 
        '10 AM', '11 AM', '12 PM', '1 PM', '2 PM', '3 PM', '4 PM', '5 PM', '6 PM', '7 PM', 
        '8 PM', '9 PM', '10 PM', '11 PM'
      ],
      title: {
        text: 'Time of Day',
      },
    },
    yAxis: {
      title: {
        text: 'Temperature (°C)',
      },
    },
    series: [
      {
        name: 'Temperature',
        data: [
          14.0, 13.8, 13.5, 13.2, 13.0, 12.8, 12.5, 13.0, 14.5, 16.5, 
          18.0, 19.5, 21.0, 22.5, 23.0, 23.2, 22.8, 21.5, 19.8, 18.2, 
          17.0, 16.0, 15.2, 14.5
        ],
      },
    ],
    accessibility: {
      enabled: true,
      description:
        'This spline chart shows temperature variations throughout a day, with the lowest temperature observed early in the morning and the highest in the early afternoon.',
    },
  };

  return (
    <HighchartsReact highcharts={Highcharts} options={options} />
  );
};
Enter fullscreen mode Exit fullscreen mode

The main difference here is that in the options object, we're defining a chart property with a type key set to spline.

Create a bar chart component:

import React from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import HighchartsAccessibility from 'highcharts/modules/accessibility';

// Initialise HighchartsAccessibility module
HighchartsAccessibility(Highcharts);

export const AccessibleBarChart = () => {
  const options = {
    chart: {
      type: 'bar'
    },
    title: {
      text: 'Sales Performance by Product Category',
    },
    xAxis: {
      categories: ['Electronics', 'Furniture', 'Clothing', 'Groceries', 'Books'],
      title: {
        text: 'Product Categories',
      },
    },
    yAxis: {
      title: {
        text: 'Sales (in thousands)',
      },
    },
    series: [
      {
        name: 'Q1',
        data: [150, 200, 100, 250, 80],
      },
      {
        name: 'Q2',
        data: [170, 240, 120, 280, 90],
      },
      {
        name: 'Q3',
        data: [180, 260, 140, 300, 100],
      },
      {
        name: 'Q4',
        data: [200, 280, 160, 320, 120],
      },
    ],
    accessibility: {
      enabled: true,
      description:
        'This bar chart compares sales performance across different product categories over four quarters, with the highest sales consistently seen in Groceries and the lowest in Books.',
    },
  };

  return (
    <HighchartsReact highcharts={Highcharts} options={options} />
  );
};
Enter fullscreen mode Exit fullscreen mode

In this bar chart example, once again all we need to update are the properties in the options object. This time we're defining a type: 'bar', but you might also notice that we're returning 5 sets of data this time in the series property. Highcharts manages multiple datasets with ease, and still manages to organise that data in an intuitive way for screenreader users.

Chart Design Best Practices

We always keep 3 points in mind when designing accessible charts:

  • Accessibility: Design charts with screen reader support and high-contrast colours to accommodate all users.
  • Simplicity: Keep charts straightforward and easy to interpret, with clear and concise labels and annotations.
  • Colour Considerations: Avoid relying solely on colour to convey information, ensuring the data is accessible to users with colour vision deficiencies.

Creating accessible charts is key to all users being able to read and interact with your visualisations. By following best practices developers can create clear, accessible & useful charts.

Have you used Highcharts, or found another React charting library which meets your accessibility needs? Let us know in the comments below!

Top comments (1)

Collapse
 
gurmukh_panesar_e51b512e8 profile image
Gurmukh Panesar

Thanks for sharing this writeup. When I use VoiceOver on Mac and linearly navigate, the Chart doesn't get any focus. It's read out as "frame 0" and then "end of frame". It doesn't look like it's accessible at all:

highcharts.com/demo/highcharts/lin...
Chrome on Mac