Accessibility

ApexSankey ships with WCAG 2.1 AA accessibility support enabled by default. The SVG root gets an auto-generated aria-label summarizing the diagram, and each node and edge is labeled for screen readers.

a11y options

OptionTypeDefaultDescription
a11y.enabledbooleantrueEnable accessibility features (ARIA labels and descriptions)
a11y.diagramLabelstringauto-generatedOverride the auto-generated aria-label on the SVG root
a11y.descriptionstringPopulate the <desc> element with a longer description
const sankey = new ApexSankey(document.getElementById('chart'), {
  a11y: {
    enabled: true,
    diagramLabel: 'Energy flow from sources to end uses',
    description: 'A Sankey diagram showing how coal, gas, and oil are converted to electricity and distributed to homes and industry.',
  },
})
sankey.render(data)

Auto-generated labels

When a11y.enabled is true and no diagramLabel is supplied, ApexSankey builds the root aria-label automatically from the data — including the node count, flow count, and the largest flow. Each node and edge also receives its own descriptive aria-label.

To take full control of the summary, set a11y.diagramLabel explicitly, or override the generator function via locale.messages.diagramLabel.

Providing a long description

a11y.description fills the SVG's <desc> element, which screen readers can read on demand for a fuller explanation than the concise aria-label:

const sankey = new ApexSankey(el, {
  a11y: {
    diagramLabel: 'Website traffic sources and conversions',
    description: 'Traffic enters from search, social, and direct channels, flows through landing pages, and converts to signups or bounces.',
  },
})

Customizing the generated strings

For localization or fine-grained control over every generated string (node labels, edge labels, the diagram summary), override the message builders via locale.messages:

const sankey = new ApexSankey(el, {
  locale: {
    messages: {
      diagramLabel: ({ nodeCount, flowCount, largestFlow }) => {
        let label = `Sankey diagram: ${nodeCount} nodes, ${flowCount} flows.`
        if (largestFlow) {
          label += ` Largest flow: ${largestFlow.source} to ${largestFlow.target}, ${largestFlow.value}.`
        }
        return label
      },
      nodeAriaLabel: ({ name, incoming, outgoing }) => {
        const parts = [name]
        if (incoming) parts.push(`${incoming.total} in from ${incoming.sources.join(', ')}`)
        if (outgoing) parts.push(`${outgoing.total} out to ${outgoing.targets.join(', ')}`)
        return parts.join('. ')
      },
      edgeAriaLabel: ({ source, target, value }) =>
        `${source} to ${target}, value ${value}`,
    },
  },
})

See Localization and RTL for the full SankeyMessages reference.

Disabling accessibility features

Set a11y.enabled: false to skip ARIA attributes entirely. This is rarely recommended — leave it on unless you have a specific reason:

const sankey = new ApexSankey(el, {
  a11y: { enabled: false },
})

Reduced motion

The entrance animation is automatically disabled when the user's system requests reduced motion (prefers-reduced-motion), independent of the a11y and animation options. See Animation.

React example

import { ApexSankey } from 'react-apexsankey'

const options = {
  a11y: {
    enabled: true,
    diagramLabel: 'Budget allocation across departments',
    description: 'Total budget flows into engineering, sales, and operations, then splits into sub-teams.',
  },
}

export default function AccessibleSankey() {
  return <ApexSankey data={data} options={options} />
}