Skip to content

Chart ​

A self-developed SVG chart component (no third-party chart engine) supporting line / bar / pie / area / donut / stacked-bar / radar / polar-area, plus series-level combo and dual axis. Data updates redraw automatically, and animations are disabled under prefers-reduced-motion.

Line Chart ​

Line chart (default)

The default is type="line". An array [{label, value}] is a single series; hovering over a data point shows its value (native <title>).

Bar Chart ​

Bar chart

type="bar" renders grouped bars.

Pie Chart ​

Pie chart

type="pie" renders sectors, with the tooltip showing the percentage.

Donut Chart ​

Donut chart

type="donut" uses the same data format as the pie chart, with the middle hollowed out into a ring; the tooltip also shows percentages.

Area Chart ​

Area chart (smooth + legend)

type="area" fills a semi-transparent area between the line and the baseline (still readable with multiple series overlaid), and supports options.smooth for smooth curves.

Area chart (gradient fill)

With options.gradient (default false), the area fill fades vertically from the series color at the line (35% opacity at the top) to transparent at the baseline, keeping the visual focus on the data line.

Stacked Bar Chart ​

Stacked bar chart

type="stacked-bar" stacks multiple series from bottom to top into a single bar; the bar height equals the category total, and the y-axis ticks are computed from the totals.

Radar Chart ​

Radar chart (radarShape + max scale)

type="radar" reuses labels as dimension names (the same data shape as line/bar, zero migration cost). options.max sets a global unified scale (defaults to the series max passed through nice ticks); options.radarShape (default polygon, concentric polygons) can be set to circle for concentric-ring grid. Hovering a vertex shows "dimension: value"; legend and colors match the other chart types.

Polar Area Chart ​

Polar area chart (rose)

type="polar-area" renders equal-angle sectors whose radius encodes the value (the maximum fills the full radius); concentric reference rings provide a radial magnitude cue. Unlike the pie chart's "share" mental model, the tooltip shows the raw value instead of a percentage. Single series takes series[0] (same data format as pie/donut).

Combo Chart ​

Combo chart (bar + line series-level mixing)

Combo has no dedicated type value: the top-level type acts as the default series type, and series[].type (bar / line / area) overrides it per series; missing/invalid values fall back to the top-level type. All series share one category axis, and line/area points align to band centers (unlike a pure line chart's endpoint alignment); the draw order is fixed to bar → area → line; colors and legend follow the series declaration order.

Dual Axis ​

Dual-axis combo (right axis + alignTicks)

Dual axis is axis configuration, not a chart type: the right axis renders when a second entry exists in the options.yAxis array AND both sides have series bound via series[].yAxisIndex (name is the axis title rendered at the top; if either side has no bound series a single axis is rendered — no empty axis), and series[].yAxisIndex (0 left, default / 1 right) binds each series; it can be combined with line / bar / combo freely. With dual axes, ticks are force-aligned (alignTicks): the secondary axis recomputes its nice ticks anchored to the primary axis' segment count, so left/right tick lines align horizontally — eliminating the misaligned-ticks misreading. Note the two axes have different units, so readings on the same line are not comparable across axes. yAxis is ignored by stacked-bar / pie-family / radar (single-axis semantics).

Multiple Series + Legend ​

Multi-series line (smooth + legend)

The object format {labels, series:[{name, data}]} supports multiple series; the legend is shown by default for multiple series, and options.smooth enables smooth curves.

Empty Data ​

Empty data placeholder

No data / invalid JSON shows an empty state placeholder without errors.

Data channel contract ​

data / options accept both channels:

  • Attribute channel: write a JSON string in HTML (e.g. data='[{...}]'); the component parses it with JSON.parse.
  • Property channel: assign an object/array from JS (el.data = [{...}]), avoiding serialization; the property is parsed in the setter and takes precedence over the attribute.

Reflection behavior differs (the two components read data differently — follow these rules):

  • oas-table's columns / data setters reflect back to the attribute — after a property assignment, getAttribute('columns') / getAttribute('data') read back the corresponding JSON string (attribute and property stay in sync as one source of truth).
  • oas-chart's data (and options) setter only writes internal state and does not reflect — after a property assignment the attribute still holds the old/empty value, so read through the el.data property (the getter returns the last assigned parsed result); do not read back with getAttribute('data').

Exception: if oas-table's columns contain function fields (such as render, which JSON serialization would drop), the setter takes a pure in-memory path without reflecting — read those columns via the el.columns property.

API ​

oas-chart ​

Attributes ​

AttributeDescriptionTypeDefault
aria-labelChart description (falls back to locale by type)——
dataData. Array single-series [{label, value}] or object multi-series {labels, series:[{name, data, type?, yAxisIndex?}]} (series-level type / yAxisIndex for combo and dual-axis)unknown—
optionsConfig: smooth (smoothing), colors (series palette), showLegend, gradient (area-chart vertical gradient fill, default false), max (radar global scale), radarShape (radar grid polygon/circle, default polygon), yAxis (dual-axis array; dual axis requires the second entry AND series bound on both sides via yAxisIndex, otherwise single axis)unknown—
typeChart type: line / bar / pie / area / donut / stacked-bar / radar / polar-area (combo has no type value — override per series via series.type)ChartTypeline

data / options also support the property channel (JS objects, taking precedence over attributes).

Boundaries ​

  • Data updates redraw the SVG (same pattern as qrcode), without rebuilding nodes
  • Empty / invalid data → empty state placeholder
  • Every data point carries a native <title> tooltip
  • Animations are pure CSS (wrapped in @media (prefers-reduced-motion: no-preference)), auto-disabled under reduced-motion, with no JS timers; zero orphaned overlays
  • Radar uses one global scale (options.max or nice ticks); per-dimension scales are not supported yet — normalize your data first if needed (e.g. a 0–100 score)
  • Polar-area renders no sectors when all values are 0 (same as pie); the radius scale tops at the maximum value
  • Combo only allows mixing bar / line / area (one cartesian coordinate system); other type values silently fall back to the top-level type
  • Series-level type / yAxisIndex is consumed only by cartesian types (line / bar / area / combo); stacked-bar / pie / donut / radar / polar-area ignore series-level overrides and always render per the top-level type
  • Declaring a second options.yAxis entry without bindings on both sides (nothing bound right, or everything bound right leaving the left axis empty) renders a single axis — no zero-tick fake axis (unused axis titles included)
  • Y-axis tick steps are always integers (nice ceiling, minimum step 1): sub-integer ranges (e.g. 0–0.01) degrade to whole-number steps, lifting the range top to a whole-step multiple so data hugs the baseline — rescale such data first (e.g. ×100 as percentages)
  • Color mapping semantics: the pie family (pie / donut / polar-area) colors by category, cartesian types (line / bar / area / stacked-bar / radar / combo) color by series; options.colors overrides in the same order
  • Text inside the chart svg is pinned to direction: ltr (coordinate semantics are orthogonal to writing direction): a host dir=rtl neither flips text anchors nor mirrors geometry

Released under the MIT OR Apache-2.0 License.