For AI agents: the complete documentation index is available at https://a3s-lab.github.io/UI/v0.4.0/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/UI/v0.4.0/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/UI/v0.4.0/en/components/chart.md.

Chart

Chart turns numeric relationships into comparable visual structure. Use it for trends, differences, and composition—not as a substitute for exact data or as decoration for an empty surface.

Live preview
Desktop visits peak at 314 in June; mobile visits peak at 220.
Desktop visits peak at 314 in June; mobile visits peak at 220.
Monthly visits by device
MonthDesktopMobile
Jan18680
Feb305200
Mar237120
Apr273190
May209130
Jun314220

Usage

Import the Chart structure and A3S visual tokens. Chart.js remains an explicit host dependency.

@import "tailwindcss";
@import "@a3s-lab/ui/base.css";
@import "@a3s-lab/ui/components/chart.css";
@import "@a3s-lab/ui/styles/a3s.css";

a3sUI.chart() accepts a native canvas and applies A3S tokens to axes, tooltips, and an optional legend. Pass Chart.js explicitly through Chart in module environments instead of relying on an implicit global.

import ChartJS from "chart.js/auto";
import "@a3s-lab/ui/runtime";
import "@a3s-lab/ui/chart";

const rows = [
  { month: "Jan", desktop: 186, mobile: 80 },
  { month: "Feb", desktop: 305, mobile: 200 },
  { month: "Mar", desktop: 237, mobile: 120 },
];

const chart = window.a3sUI.chart("#visitors-chart", {
  Chart: ChartJS,
  type: "bar",
  labelKey: "month",
  data: rows,
  series: {
    desktop: { label: "Desktop", color: "var(--chart-1)" },
    mobile: { label: "Mobile", color: "var(--chart-2)" },
  },
  legend: true,
});

Place the canvas, a visible title, a concise conclusion, and equivalent data in one figure. The graphic must never be the only representation of the values.

<figure aria-labelledby="visitors-title">
  <figcaption id="visitors-title">
    <strong>Monthly visits by device</strong>
    <span id="visitors-summary">Desktop and mobile visits both peak in February.</span>
  </figcaption>
  <div class="chart">
    <canvas id="visitors-chart" aria-describedby="visitors-summary">
      The chart is unavailable in this environment. Use the data table below.
    </canvas>
  </div>
  <table class="sr-only">
    <caption>Monthly visits by device</caption>
    <thead><tr><th scope="col">Month</th><th scope="col">Desktop</th><th scope="col">Mobile</th></tr></thead>
    <tbody>
      <tr><th scope="row">Jan</th><td>186</td><td>80</td></tr>
      <tr><th scope="row">Feb</th><td>305</td><td>200</td></tr>
      <tr><th scope="row">Mar</th><td>237</td><td>120</td></tr>
    </tbody>
  </table>
</figure>

The helper reuses an existing .chart container or creates one around a bare canvas. When the theme or style pack changes, it resolves the current CSS color tokens again.

Parameters

OptionDefaultPurpose
Chartwindow.ChartChart.js constructor; pass it explicitly in module environments
type"bar"Chart.js chart type
labelKey"label"Row key used for the category or horizontal-axis label
data[]Row objects, or raw Chart.js data with datasets
series{}Maps data keys to labels, colors, and dataset options
legendfalseGenerates a read-only A3S legend
tooltiptrueUses the themed external tooltip
options{}Passes through Chart.js options
plugins[]Passes through Chart.js plugins
chartDataUndefinedComplete Chart.js data; overrides row mapping

Each series.label must be localized user-facing copy. Use stable --chart-1 through --chart-5 tokens for color. surface accepts true, "gradient", or { from, to }; place only native Chart.js dataset options in dataset.

States and variants

Choose the right graphic

  • Bar charts compare discrete categories and normally start from a zero baseline.
  • Line charts communicate an ordered trend. Avoid smoothing that implies unsampled values.
  • Stacked charts work only when users need both total and composition; use a table when categories become dense.
  • Doughnut charts suit a small number of categories that form a clear whole and must show the values alongside the graphic.
  • Radar charts are difficult to compare precisely. Reserve them for a small overview of dimensions on the same scale, never for a critical decision.
Live preview

Continuous trend

Desktop visits peak at 314 in June; mobile visits peak at 220.
Desktop visits peak at 314 in June; mobile visits peak at 220.
Monthly visits by device
MonthDesktopMobile
Jan18680
Feb305200
Mar237120
Apr273190
May209130
Jun314220

Whole composition

Direct traffic is 42%, search 31%, social 17%, and referrals 10%.
Direct traffic is 42%, search 31%, social 17%, and referrals 10%.
Traffic source share
SourceShare
Direct42%
Search31%
Social17%
Referral10%

Loading, empty, and error

Keep the chart measurement box while data is unavailable, and explain the current condition inside data-chart-state. Empty state says why no values exist; error state includes a recovery path. Do not disguise missing data as a zero-value chart.

Live preview
Loading visit dataChart dimensions remain stable while the data resolves.
No comparable dataSelect at least two points in time or expand the date range.
Visit data failed to loadCheck the data connection and retry. Current filters will remain.

The host drives loading, empty, and error from its data lifecycle. Prefer the Chart.js update API when values change so focus, size, and animation context remain stable. An interactive legend is a filter control and needs real buttons with synchronized aria-pressed; the generated default legend only identifies series.

Accessibility

Charts need a visible title, a concise conclusion, and an equivalent data table. A canvas aria-label may summarize the main finding but cannot replace exact values. Distinguish series with labels, shape, or position as well as color. Tooltip values must also be available in the table. Keep the default read-only legend out of the tab order; interactive legends must use buttons. Preserve label and data comprehension at 200% zoom, in dark mode, in RTL, and on narrow screens. Respect reduced-motion preferences and avoid noisy live announcements for streaming data. The host owns data truth, formatting, units, time zones, and remote states; the component owns visual mapping and theme integration.