Share an Observable Plot

Observable Plot is the rare visualization library with no runtime dependency on a platform. It is a normal npm package that returns a DOM node — which makes it much easier to share than a notebook, and much easier to fail to share than a chart image, because "a DOM node" is not a thing you can email.

The result is that Plot charts get screenshotted more than any other kind, and the tooltip — the whole reason to use tip: true — never leaves the machine that made it.

Make it a page

<!doctype html>
<meta charset="utf-8" />
<title>Signups by week</title>
<div id="chart"></div>
<script type="module">
  import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";

  const data = [
    /* inlined rows */
  ];

  document.querySelector("#chart").append(
    Plot.plot({
      marks: [
        Plot.ruleY([0]),
        Plot.lineY(data, { x: "week", y: "signups", stroke: "channel", tip: true }),
      ],
      width: 900,
    }),
  );
</script>

That is the entire artifact: one file, one script, the data inline.

Publish it

Drop the file into Comma, or from a build step:

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html chart.html \
        --arg t "Signups by channel — $(date -u +%F)" '{title: $t, html: $html}')"

Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the module loads, the marks render and tip: true tooltips follow the pointer. See the API reference.

Inline the data and the library

Two changes turn a chart that works today into one that works in a year:

  • Inline the data. A fetch("data.csv") is a dependency on a file existing at a path. Under a megabyte, put the rows in the page. Larger, upload the CSV as a report asset — relative references are rewritten to the uploaded copy, so the fetch resolves over https:// instead of failing from a file:// origin.
  • Bundle Plot. @0.6 from a CDN is a moving target and a third party you have no agreement with. esbuild --bundle --minify over an entry that imports Plot is a one-line build step and removes both problems.

What it is worth over a screenshot

A Plot chart with a tip and a colour legend is a small interface: hover for the exact value, click the legend to isolate a series, read the axis at the resolution you need. A PNG is one of those states, chosen by whoever took it, usually the wrong one for the question being asked.

Published, the reader answers their own question — and the follow-up lands as an anchored thread on the series it is about rather than as "which line is which?" in a reply. See commenting on HTML.

Republishing at the same report id when the data refreshes appends a revision, so the chart has a history rather than a filename with a date in it.

Limits

  • Entry HTML: 5 MB, inlined data included. Pre-aggregate rather than shipping raw rows the mark immediately bins.
  • Assets: 25 MB per file, 250 MB and 500 files total.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a chart →

Related