Appearance
Extension · md-plot
Name: md-plotVersion: 1.0.0 Context: block (non-event) Content model: md-plot-series children only
Motivation
Declarative inline charts rendered as accessible SVG. Supports the streaming use case: data points can arrive over time as additional md-plot-series rows, and the chart updates in place without losing viewport state. A demonstration extension for structured block custom elements per §8.5 with a restricted content model.
Syntax
Block custom element with a constrained child set.
<md-plot kind="line" x-label="time" y-label="value">
<md-plot-series name="cpu" color="#58a6ff">0,10 1,12 2,15 3,22</md-plot-series>
<md-plot-series name="mem" color="#3fb950">0,30 1,32 2,34 3,36</md-plot-series>
</md-plot>Tags registered
| Tag | Context | Content model |
|---|---|---|
md-plot | block | md-plot-series children only |
md-plot-series | inside md-plot only | text (whitespace-delimited point pairs) |
Outside <md-plot>, a bare <md-plot-series> is NOT recognized and falls through to literal text per §8.2.
Attributes
md-plot
| Name | Grammar | Default | Normative |
|---|---|---|---|
kind | line / bar / scatter | line | Normative |
x-label | text | "" | Normative |
y-label | text | "" | Normative |
width | integer (CSS pixels) | auto | Informative |
height | integer (CSS pixels) | auto | Informative |
aria-label | text | derived from labels | Normative |
md-plot-series
| Name | Grammar | Default | Normative |
|---|---|---|---|
name | text | series index "0", "1", … | Normative |
color | CSS hex #rrggbb or #rgb | theme-dependent | Normative |
Color values MUST match the pattern ^#[0-9a-fA-F]{3}$ or ^#[0-9a-fA-F]{6}$. Other CSS color syntaxes (named colors, rgb(), hsl()) are NOT admitted in v1.0. Non-conforming values are replaced with the extension's theme default.
All other attributes are silently dropped per §10.3.3.
Data grammar
md-plot-series content is whitespace-separated pairs x,y where x and y are JSON-compatible numbers. Formal grammar:
series = ( space* point space* )*
point = num ',' num
num = '-'? digits ( '.' digits )? ( [eE] [+-]? digits )?
digits = [0-9]+
space = ' ' / '\t' / '\n' / '\r'Malformed points MUST be silently skipped; the remaining points render normally. This is a data-layer decision to degrade gracefully rather than erroring on streaming partial input.
Rendering (informative)
The rendered DOM SHOULD be an <svg> element with accessible markup:
html
<md-plot aria-label="...">
<svg viewBox="..." role="img" aria-label="...">
<g data-series="cpu">…<polyline points="…" stroke="#58a6ff"/></g>
<g data-series="mem">…</g>
</svg>
</md-plot>Implementations MAY use any rendering strategy. The only normative requirement is that the aria-label is present and descriptive.
Streaming semantics
md-plot is streamable. A new md-plot-series child appearing after a prior render MUST extend the existing plot SVG by appending a series group; it MUST NOT cause a full DOM replacement. Additional x,y points appended to a pending md-plot-series MUST extend the corresponding polyline.
Identity of series for re-render reuse: by name attribute; if absent, by source position within the md-plot parent.
Security
md-plot has no URL attributes and no executable content. The color attribute is restricted to #rrggbb / #rgb hex to prevent CSS injection via color: url(javascript:…) or similar. Series data numbers are restricted to a JSON number pattern.
Accessibility
aria-labelon the parentmd-plotMUST be present (auto-derived fromx-labelandy-labelwhen not given).- Each
<g data-series="name">SHOULD carry anaria-label="series <name>"for screen readers exposing SVG structure.
Test vectors
Vectors live under packages/spec-tests/src/vectors/extensions/md-plot/. Required coverage:
- Single-series line plot.
- Multi-series with default colors.
- Malformed color falls back to default.
- Malformed point is dropped; surrounding points render.
- Streaming: additional series added after initial render.
- Streaming: additional points appended mid-series.
- Data-URI in color attribute is rejected.
- Non-hex color is rejected.
Governance
Changes to this extension follow the MdFlow governance process (Governance) and are versioned independently of core.