Skip to content

Latest commit

 

History

History
111 lines (88 loc) · 4.25 KB

File metadata and controls

111 lines (88 loc) · 4.25 KB

Markdown Chart Protocol v1

Goals

The protocol identifies a renderer and keeps renderer-neutral data separate from the renderer-owned JSON chart specification. It does not prescribe a UI framework, data transport, or chart engine.

Canonical fence

The canonical language is markdown-chart. Its body is a strict JSON object:

{
  "version": 1,
  "renderer": "echarts",
  "data": {
    "kind": "inline",
    "dimensions": ["category", "value"],
    "source": [["A", 1], ["B", 2]]
  },
  "spec": {}
}
  • version MUST be 1.
  • renderer MUST be a non-empty renderer identifier registered by the host.
  • data is optional. When present, it MUST use the renderer-neutral dataset schema below so hosts can inspect it without understanding spec.
  • spec MUST be JSON. Its schema belongs to the selected renderer.
  • Unknown renderer identifiers MUST fail without falling back to executable content.

Renderer packages MAY explicitly define shorthand fence aliases. A renderer identifier alone is not a fence language. A shorthand fence sends the entire JSON body to that renderer. A renderer-owned shorthand MAY define a versioned envelope and MAY normalize its data into renderer-neutral ChartData for the shared Data view. That shorthand version belongs to the renderer schema and does not change the canonical protocol version. Aliases are resolved by the registry; the core has no hard-coded ECharts, Plotly, or Vega branches.

Markdown adapters MUST route shorthand fences through the live registry rather than maintain renderer-specific language defaults. The canonical markdown-chart fence is recognized independently of which renderers are currently registered.

Data

Canonical data is either inline or referenced. Inline data is directly available to hosts for actions such as “View data”. The default framework adapters expose a Chart/Data switch for inline data and for referenced data after a renderer materializes the reference as inline rows:

{
  "kind": "inline",
  "dimensions": ["category", "value"],
  "source": [["A", 1], ["B", 2]]
}

data.kind is either:

  • inline: contains source and optional dimensions.
  • ref: contains an opaque ref, optional format, and optional dimensions. A host-provided resolver returns the source. Renderers do not interpret the reference or perform network requests. A renderer MAY return resolved inline rows from its materialization step. The adapter then creates the shared Chart/Data view before mounting the chart.

Rows MUST be arrays of JSON scalar values or objects whose values are JSON scalars. dimensions, when present, MUST contain non-empty strings.

ECharts specification

For the canonical fence, spec is the ECharts option object directly:

{
  "xAxis": { "type": "category" },
  "yAxis": {},
  "series": [{ "type": "bar", "encode": { "x": "category", "y": "value" } }]
}

When canonical data is present, spec.dataset is reserved and MUST NOT also be set. The renderer inserts the resolved dataset before calling ECharts.

Streaming

Hosts pass the outer document streaming state to a Markdown adapter. The adapter MUST translate it into block-level state: explicitly closed chart fences render immediately, while only an unterminated fence at the active tail is deferred. An implicitly closed fence followed by later document content is complete.

Adapters SHOULD preserve the DOM element and mounted renderer for unchanged, completed blocks as later tokens arrive. An incomplete block is not parsed or mounted. Once its fence closes, the same block is rendered normally. Invalid JSON in an explicitly completed block is an error even while the surrounding document is still streaming.

Evolution

The outer markdown-chart.version belongs only to the canonical envelope. Renderer specifications inside canonical spec do not introduce a second protocol version. A renderer-owned shorthand MAY independently version its own envelope; that version is interpreted only under the exact shorthand fence. New incompatible canonical envelopes or data schemas require a new numeric canonical version; incompatible renderer schemas should use a new renderer identifier or shorthand version. New renderer implementations are published as independent packages and registered at runtime.