Highcharts Integration

MAIDR provides a dedicated adapter for Highcharts that converts a rendered chart instance into MAIDR-compatible data. Once converted, the chart is fully accessible via audio sonification, text descriptions, braille output, and keyboard navigation.

Highcharts is not bundled — bring your own copy. The adapter only reads from the Highcharts chart API; it has zero runtime dependency on Highcharts itself.

Quick Start

Render your chart with Highcharts, convert it with maidrHighcharts.highchartsToMaidr(), attach the result as a maidr-data attribute, and let MAIDR pick it up:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Highcharts Chart</title>
    <!-- 1. Load Highcharts -->
    <script src="https://cdn.jsdelivr.net/npm/highcharts/highcharts.js"></script>
    <!-- 2. Load MAIDR core + the Highcharts adapter -->
    <script src="https://cdn.jsdelivr.net/npm/maidr/dist/maidr.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/maidr/dist/highcharts.js"></script>
  </head>
  <body>
    <div id="chart" style="width: 700px; height: 500px"></div>

    <script>
      // 3. Render your chart normally
      const chart = Highcharts.chart('chart', {
        chart: { type: 'column' },
        title: { text: 'Tips by Day' },
        xAxis: { categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'] },
        yAxis: { title: { text: 'Count' } },
        series: [{ name: 'Tips', data: [20, 14, 23, 25, 22] }],
      });

      // 4. Convert and attach to the container
      const maidrData = maidrHighcharts.highchartsToMaidr(chart, { id: 'chart' });
      document.getElementById('chart').setAttribute('maidr-data', JSON.stringify(maidrData));

      // 5. (Optional) bidirectional tooltip + point highlighting
      maidrHighcharts.createHighchartsSync(chart);
    </script>
  </body>
</html>

The adapter exposes a global maidrHighcharts object with highchartsToMaidr() and createHighchartsSync(). This works directly from file:// URLs — no module server required.

Once the page loads, click on the chart (or Tab to it) and MAIDR activates with:

How It Works

The adapter pipeline runs in three short steps:

  1. ReadhighchartsToMaidr(chart) reads chart.series, chart.xAxis, chart.yAxis, chart.title, and (when present) chart.subtitle / chart.caption. Each series is mapped to a MAIDR TraceType based on its rendered type (bar, line, scatter, etc.) and Highcharts stacking mode.
  2. Locate — Scoped CSS selectors are generated per chart container so MAIDR can highlight the correct SVG element for the active data point.
  3. Sync (optional)createHighchartsSync(chart) wires MAIDR's navigation events back into Highcharts' native tooltip.refresh() and point.setState('hover'), so the visual cursor follows the user as they navigate.

Installation

CDN (script tags — works on file:// and any web server)

<script src="https://cdn.jsdelivr.net/npm/highcharts/highcharts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/maidr/dist/maidr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/maidr/dist/highcharts.js"></script>
<script>
  // Globals: Highcharts, maidrHighcharts
  const maidrData = maidrHighcharts.highchartsToMaidr(chart, { id: 'chart' });
</script>

CDN note: Use cdn.jsdelivr.net/npm/highcharts/... rather than code.highcharts.com/... for local file:// testing — the official Highcharts CDN's WAF blocks requests with no Referer header (which file:// origins always send), returning HTTP 403. jsDelivr does not have this restriction.

ESM (modern build tooling / bundlers)

<script src="https://cdn.jsdelivr.net/npm/highcharts/highcharts.js"></script>
<script type="module">
  import { createHighchartsSync, highchartsToMaidr } from 'https://cdn.jsdelivr.net/npm/maidr/dist/highcharts.mjs';
</script>

ESM imports require an HTTP(S) origin (CORS blocks them on file://). For local-file demos, use the UMD dist/highcharts.js bundle above.

npm

npm install maidr highcharts
import Highcharts from 'highcharts';
import { createHighchartsSync, highchartsToMaidr } from 'maidr/highcharts';

Supported Chart Types

MAIDR Type Highcharts series type(s) Example
Bar bar, column highcharts-bar.html
Line line, spline, area, areaspline highcharts-line.html
Scatter scatter highcharts-scatter.html
Box Plot boxplot highcharts-box.html
Heatmap heatmap (requires modules/heatmap.js) highcharts-heatmap.html
Histogram histogram (requires modules/histogram-bellcurve.js) highcharts-histogram.html
Candlestick candlestick, ohlc (Highstock) highcharts-candlestick.html
Stacked Bar column/bar + plotOptions.column.stacking: 'normal' highcharts-stacked.html
Dodged (Grouped) Bar column/bar (default, no stacking) with multiple series highcharts-dodged.html
Normalized Bar column/bar + plotOptions.column.stacking: 'percent' highcharts-normalized.html

API Reference

highchartsToMaidr(chart, options?)

Converts a rendered Highcharts chart into a Maidr data object.

Parameter Type Description
chart HighchartsChart Return value of Highcharts.chart() (the chart must already be rendered).
options.id string? Override the generated chart ID. Defaults to highcharts-{n}.
options.title string? Override the chart title. Defaults to chart.title.textStr.
options.seriesIndices number[]? Convert only specific series by index. Default: all visible series.

Returns a Maidr object ready to assign to a maidr-data attribute, pass to the <Maidr> React component, or serialize for downstream tooling.

createHighchartsSync(chart)

Creates a bidirectional sync controller so the MAIDR cursor and Highcharts' native tooltip/highlight stay in lock-step. Returns a HighchartsSync object with a dispose() method for cleanup.

const sync = maidrHighcharts.createHighchartsSync(chart);
// ... user navigates with MAIDR; Highcharts tooltip follows automatically
sync.dispose();

Type exports

import type {
  HighchartsAdapterOptions,
  HighchartsAxis,
  HighchartsChart,
  HighchartsPoint,
  HighchartsSeries,
  HighchartsSync,
} from 'maidr/highcharts';

These are minimal structural types — they describe just the subset of the Highcharts API that the adapter actually reads, so MAIDR can stay version-independent of Highcharts releases.

Code Examples

Bar / Column Chart

const chart = Highcharts.chart('bar-chart', {
  chart: { type: 'column' },
  title: { text: 'Number of Tips by Day' },
  xAxis: { categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'], title: { text: 'Day' } },
  yAxis: { title: { text: 'Count' } },
  series: [{ name: 'Tips', data: [20, 14, 23, 25, 22] }],
});

const maidrData = maidrHighcharts.highchartsToMaidr(chart, { id: 'bar-chart' });
document.getElementById('bar-chart').setAttribute('maidr-data', JSON.stringify(maidrData));

Multi-Line Chart

const chart = Highcharts.chart('line-chart', {
  chart: { type: 'line' },
  title: { text: 'Weekly Sales Comparison' },
  xAxis: { categories: ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7'], title: { text: 'Week' } },
  yAxis: { title: { text: 'Sales ($K)' } },
  series: [
    { name: 'Series A', data: [10, 15, 13, 17, 22, 19, 25] },
    { name: 'Series B', data: [16, 5, 11, 9, 14, 20, 12] },
  ],
});

Scatter Plot

const chart = Highcharts.chart('scatter-chart', {
  chart: { type: 'scatter' },
  title: { text: 'Iris Sepal vs Petal Length' },
  xAxis: { title: { text: 'Sepal Length (cm)' } },
  yAxis: { title: { text: 'Petal Length (cm)' } },
  series: [{
    name: 'Setosa',
    data: [[5.1, 1.4], [4.9, 1.4], [4.7, 1.3], [4.6, 1.5], [5.0, 1.4]],
  }],
});

Box Plot

const chart = Highcharts.chart('box-chart', {
  chart: { type: 'boxplot' },
  title: { text: 'Sepal Length Distribution' },
  xAxis: { categories: ['Setosa', 'Versicolor', 'Virginica'] },
  yAxis: { title: { text: 'Sepal Length (cm)' } },
  series: [{
    name: 'Observations',
    data: [
      // [low, q1, median, q3, high]
      [2.3, 2.7, 3.0, 3.4, 4.5],
      [4.7, 5.2, 5.9, 6.3, 7.0],
      [6.0, 6.5, 7.1, 7.5, 8.0],
    ],
  }],
});

Heatmap

Requires the Highcharts heatmap module: <script src="https://cdn.jsdelivr.net/npm/highcharts/modules/heatmap.js"></script>.

const chart = Highcharts.chart('heatmap-chart', {
  chart: { type: 'heatmap' },
  title: { text: 'Activity Heatmap' },
  xAxis: { categories: ['Mon', 'Tue', 'Wed'] },
  yAxis: { categories: ['Morning', 'Afternoon', 'Evening'] },
  colorAxis: { min: 0, minColor: '#FFFFFF', maxColor: '#7CB5EC' },
  series: [{
    name: 'Activity',
    data: [[0, 0, 1], [0, 1, 20], [0, 2, 30], [1, 0, 20], [1, 1, 1], [1, 2, 60]],
  }],
});

Histogram

Requires the Highcharts histogram module: <script src="https://cdn.jsdelivr.net/npm/highcharts/modules/histogram-bellcurve.js"></script>.

const chart = Highcharts.chart('histogram-chart', {
  title: { text: 'Distribution of Values' },
  series: [
    { type: 'histogram', name: 'Histogram', baseSeries: 's1', binsNumber: 15 },
    { type: 'scatter', id: 's1', name: 'Samples', data: samples, visible: false },
  ],
});

Candlestick

Requires Highstock: <script src="https://cdn.jsdelivr.net/npm/highcharts/highstock.js"></script>.

const chart = Highcharts.chart('candlestick-chart', {
  chart: { type: 'candlestick' },
  title: { text: 'Stock Price' },
  xAxis: { categories: ['2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'] },
  yAxis: { title: { text: 'Price ($)' } },
  series: [{
    name: 'AAPL',
    data: [
      // [open, high, low, close]
      [150.0, 153.0, 149.0, 152.5],
      [152.5, 154.0, 151.0, 151.0],
      [151.0, 154.5, 150.0, 153.0],
      [153.0, 155.0, 152.0, 154.5],
    ],
  }],
});

Stacked Bar

const chart = Highcharts.chart('stacked-chart', {
  chart: { type: 'column' },
  title: { text: 'Quarterly Revenue Breakdown' },
  xAxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] },
  yAxis: { title: { text: 'Revenue ($M)' } },
  plotOptions: { column: { stacking: 'normal' } },
  series: [
    { name: 'Product A', data: [20, 14, 23, 25] },
    { name: 'Product B', data: [15, 18, 20, 22] },
  ],
});

Dodged (Grouped) Bar

const chart = Highcharts.chart('dodged-chart', {
  chart: { type: 'column' },
  title: { text: 'Quarterly Sales by Product' },
  xAxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] },
  yAxis: { title: { text: 'Revenue ($M)' } },
  // No `stacking` option = grouped (dodged) by default.
  series: [
    { name: 'Product A', data: [20, 14, 23, 25] },
    { name: 'Product B', data: [15, 18, 20, 22] },
  ],
});

Normalized (Percent-Stacked) Bar

const chart = Highcharts.chart('normalized-chart', {
  chart: { type: 'column' },
  title: { text: 'Quarterly Revenue Share by Product' },
  xAxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] },
  yAxis: { title: { text: 'Share (%)' } },
  plotOptions: { column: { stacking: 'percent' } },
  series: [
    { name: 'Product A', data: [20, 14, 23, 25] },
    { name: 'Product B', data: [15, 18, 20, 22] },
  ],
});

Advanced Usage

Inverted charts (horizontal bars)

The adapter inspects chart.options.chart.inverted and produces a horizontal-oriented MAIDR layer when set. No extra configuration is needed:

Highcharts.chart('h-bar', {
  chart: { type: 'bar', inverted: true },
  // ...
});

Filtering series

Pass seriesIndices to convert only specific series:

const maidrData = maidrHighcharts.highchartsToMaidr(chart, {
  id: 'chart',
  seriesIndices: [0, 2], // skip series index 1
});

Visual sync lifecycle

createHighchartsSync() attaches event listeners to the chart container. Always call sync.dispose() if you destroy the chart manually (otherwise listeners leak):

const sync = maidrHighcharts.createHighchartsSync(chart);

// later:
chart.destroy();
sync.dispose();

Re-rendering charts

If you call chart.update() or chart.addSeries(), re-run maidrHighcharts.highchartsToMaidr() and update the maidr-data attribute so MAIDR sees the new state. Reload maidr.js only on first mount.

Keyboard Controls

Once a chart is focused, use standard MAIDR keyboard shortcuts:

Function Key (Windows / Linux) Key (macOS)
Move between data points Arrow keys Arrow keys
Go to extremes Ctrl + Arrow Cmd + Arrow
Toggle Sonification S S
Toggle Braille Mode B B
Toggle Text Mode T T
Toggle Review Mode R R
Auto-play Ctrl + Shift + Arrow Cmd + Shift + Arrow
Stop Auto-play Ctrl Cmd

For the full list, see the Keyboard Controls reference.

Integration Comparison

Feature Vanilla JS (CDN) React Component Highcharts Adapter
Setup maidr-data attribute with JSON data prop on <Maidr> highchartsToMaidr(chart) + attribute
Data source Manual JSON schema Manual JSON schema Auto-extracted from chart instance
SVG selectors Manual CSS selectors Manual CSS selectors Auto-generated, scoped per container
Chart types All MAIDR types All MAIDR types 10 Highcharts series types
Visual tooltip sync Manual Manual Built-in via createHighchartsSync()

API Documentation

For the complete TypeScript API reference, see the API Documentation.