beta

Chart — <mv-chart>

Dependency-free SVG chart (area, bar, line, sparkline): pixel-perfect rendering, rounded scale, animated draw-in on appearance, crosshair and tooltip on hover and keyboard, and a data table for screen readers.

CategoryData display
TypeWeb Component (<mv-chart>)
Statusbeta
Keywordschart, graph, area, bar, line, sparkline, dataviz, dashboard

When to use

Avoid when

Install

node scripts/add.mjs chart --out ./src/marvelous

AI agent with the Marvelous UI MCP server: install_components({ slugs: ["chart"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Files copied (dependencies included): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/chart/chart.js, components/chart/chart.css.

Usage

Canonical markup — start from it and customize with attributes, data-* and CSS variables:

<div id="chart-demo" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr));gap:1rem;width:100%;max-width:64rem;margin-inline:auto">
  <article class="mv-card" style="grid-column:1/-1">
    <header class="mv-card-header">
      <h3 class="mv-card-title">Revenue</h3>
      <p class="mv-card-description">2026 vs. 2025, by month</p>
    </header>
    <div class="mv-card-content">
      <mv-chart type="area" format="currency" height="240" label="Monthly revenue, 2026 and 2025"
        data='{"labels":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"series":[{"name":"2026","values":[31200,34800,33100,39400,42800,41200,45900,38700,48290,null,null,null]},{"name":"2025","values":[26400,27900,30100,29800,33600,35200,34100,30900,37800,40200,43900,47100]}]}'></mv-chart>
    </div>
  </article>

  <article class="mv-card">
    <header class="mv-card-header">
      <h3 class="mv-card-title">New sign-ups</h3>
      <p class="mv-card-description">Last 14 days</p>
    </header>
    <div class="mv-card-content">
      <mv-chart type="bar" height="200" label="Daily sign-ups"
        data='{"labels":["10","11","12","13","14","15","16","17","18","19","20","21","22","23"],"series":[{"name":"Sign-ups","values":[42,58,51,64,72,38,31,69,77,81,74,93,48,40]}]}'></mv-chart>
    </div>
  </article>

  <article class="mv-card">
    <header class="mv-card-header">
      <h3 class="mv-card-title">Response time</h3>
      <p class="mv-card-description">Median and 95th percentile, in ms</p>
    </header>
    <div class="mv-card-content">
      <mv-chart type="line" height="200" curve="linear" label="API response time"
        data='{"labels":["12 AM","3 AM","6 AM","9 AM","12 PM","3 PM","6 PM","9 PM"],"series":[{"name":"Median","values":[82,76,79,118,134,126,142,96]},{"name":"p95","values":[210,188,204,312,356,338,388,254]}]}'></mv-chart>
    </div>
  </article>
</div>

API

Attributes

NameTypeDefaultDescription
typearea | bar | lineareaChart type.
dataJSON{ labels: string[], series: [{ name, values: number[], color? }] }. Also via the data property or a <script type="application/json"> child.
heightnumber (px)240 (44 as sparkline)Height of the plot area.
labelstringAccessible name of the chart and caption of the data table.
formatdecimal | currency | percentdecimalIntl format of the values (axis, tooltip, table).
currencyISO 4217USDCurrency for format=currency.
compactbooleanCompact notation everywhere (12.4K). The axis switches to compact above 10,000.
localeBCP 47en-USFormatting locale.
curvesmooth | linearsmoothMonotone interpolation (no overshoot) or straight segments.
sparklinebooleanMini chart with no axes or interaction (KPI tiles).
legendtrue | falseauto (≥ 2 series)Forces or hides the legend.
animateview | noneviewAnimated draw-in the first time it appears on screen.

Properties

NameTypeDescription
dataobjectRead/write; writing redraws instantly.

Methods

NameDescription
render()Redraws (called automatically on resize).

Events

NameDescription
mv-hoverActive point changed. detail: { index, label }.

CSS classes

NameDescription
mv-chart-legend / -plot / -tooltipGenerated, stylable parts.

CSS variables

NameDescription
--mv-chart-1 … --mv-chart-5Categorical palette, in a fixed order (1 = accent).
--mv-chart-gridGrid line color.
--mv-chart-surfaceColor of the ring around points (= card background).

Accessibility

role=group + aria-roledescription “chart” and aria-label; focusable: ← → Home End step through the points and the value is announced (aria-live). A visually hidden data table lists every value. The SVG is aria-hidden. Color is never the only cue: a legend appears for ≥ 2 series. Reduced motion: no draw-in animation.