IndiaCN UI

Chart

Chart.js charts with UX4G presentation defaults and a screen-reader data table.

Introduction

UX4G's charts page is built on Chart.js, and specifies fifteen chart types across five breakpoints. Chart.js already draws all fifteen, so this is one component that themes them rather than fifteen that redraw them.

Installation

npx shadcn@latest add https://indiacn.in/r/chart.json

Chart.js is a real dependency, installed with the component:

npm install chart.js
import { Chart } from '@/components/ui/chart';

Usage

<Chart
type="bar"
data={{
  labels: ['Apr', 'May', 'Jun'],
  datasets: [{ label: 'Applications', data: [420, 405, 190] }],
}}
title="Applications by month"
summary="Applications received between April and June."
/>

type takes any Chart.js type: bar, line, pie, doughnut, radar, polarArea, scatter, bubble.

The chart types

Each type has its own page, because choosing the right one matters more than configuring it.

For
BarComparing magnitudes across categories
Horizontal barLong labels, or a ranking
Stacked barA total and its composition
LineA value over time, or against a target
Multi-axis lineTwo series in different units
PieRough shares of one whole
DoughnutShares, with a total in the middle
Polar areaCyclical categories on a shared radius
RadarOne subject across several dimensions
ScatterThe relationship between two variables
BubbleTwo positions and a size

UX4G's page also shows Multitype, Chart Events, Chart Ref and Gradient. Those are Chart.js techniques rather than chart types — they work through options and data on this same component, and need no separate wrapper.

A canvas tells a screen reader nothing

This is the part worth reading. A <canvas> is a pixel buffer — it has no structure, no labels and no values. A chart that ships without an alternative is a chart that a blind citizen cannot read at all.

So Chart requires a title, marks the canvas aria-hidden, and renders the same data as a visually-hidden table with proper row and column headers. Screen-reader users get the numbers; sighted users get the picture; nobody gets less.

summary is optional and read before the table. Use it for the thing the chart is meant to show, which is rarely obvious from the values alone.

If you pass your own options, they merge over the defaults — but the table comes from data, so it stays correct regardless.

What is measured, and what is ours

Measured off the Figma symbols and reproduced:

titlecentred, bold, above the legend
legendabove the plot, rectangular swatches, 40×16
gridboth axes, no axis border
line segmentsstraight — tension: 0
line stroke4px, with 7px ringed points
x tick labelsrotate up to 45° when they do not fit

The palette is ours, deliberately. UX4G's three sample charts use three different colour sets — the bar chart uses primary and primary-100, the line chart a pale yellow with primary, and the pie chart a pastel mix (#c3f8df, #fcecb0, #fedebc) that appears nowhere in the token set. In one of them the legend swatch does not even match the series it labels.

Read together, that page specifies presentation, not a palette. So two-series charts land on primary and primary-100, matching the bar chart exactly, and beyond that the series walk the semantic scales. Colours are read from CSS custom properties at render time, so charts follow light and dark like everything else.

Notes

  • Charts repaint when the theme changes. A canvas is painted, not inherited: once Chart.js has drawn a legend label in the light-mode ink, switching to dark leaves it invisible. The component watches the document element and rebuilds. This was a real bug during development — the legend labels disappeared in dark mode and the measurements looked fine.
  • Animation is disabled under prefers-reduced-motion: reduce.
  • Datasets keep any colour you set explicitly; the palette only fills gaps.
  • height defaults to 320px. Chart.js needs a bounded height, so the canvas sits in a sized wrapper rather than growing without limit.

API Reference

Chart

PropTypeDefaultDescription
typeChartTypeAny Chart.js type
dataChartDataChart.js data object
titlestringRequired. Heading, and the accessible name
optionsChartOptionsMerged over the UX4G defaults
summarystringOne sentence, read before the data table
heightnumber320Canvas height in pixels

chartPalette()

Returns the series palette as an array of resolved colour strings, for anything you draw yourself alongside a chart.

On this page