Share a Chart.js chart

Chart.js is what you reach for when the question is "can you plot this by Friday". A canvas, a script tag, a data array — twenty lines and you have something worth showing people.

Showing people is where it stops being twenty lines.

The file works on your machine. Emailed, it arrives as an attachment that downloads rather than opens. Committed to a repo, GitHub shows the source. Pasted into Slack, it becomes a filename. So it gets screenshotted, and a screenshot of an interactive chart is a chart with the hover values, the legend toggles and the zoom removed.

Publish it

Drag the HTML into the app, or POST it:

curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html chart.html \
        --arg t "Weekly active users — Q3" '{title: $t, html: $html}')"

Report HTML renders with scripts enabled inside a sandboxed iframe (allow-scripts, no allow-same-origin), so Chart.js initialises, draws to its canvas, and keeps its interactions: hover tooltips, click-to-toggle series in the legend, and the zoom plugin if you are using it.

Make the page self-contained

The one thing that reliably breaks a shared Chart.js page is the CDN reference:

<!-- fragile: depends on a third party, and on the protocol matching -->
<script src="http://cdn.example.com/chart.js"></script>

Two failure modes. An http:// script inside an https:// page is blocked as mixed content with no visible error — just a blank canvas. And a CDN that stops serving that version, or a reader behind a proxy that blocks it, produces the same blank canvas years later.

For a chart that has to keep working, inline the library:

curl -sL https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.js > chart.umd.js
python3 - <<'EOF'
html = open("chart.html").read()
lib  = open("chart.umd.js").read()
open("chart.html","w").write(
    html.replace('<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.js"></script>',
                 f"<script>{lib}</script>"))
EOF

Now the report is one file that renders identically in five years.

Publish the data with the chart

A chart is a claim. Upload the CSV or JSON behind it as an asset on the same report and it becomes a claim somebody can check — which is the difference between a chart people believe and a chart people act on.

Keep one URL as the numbers change

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 "Weekly active users — week $(date +%V)" '{title: $t, html: $html}')"

Regenerate the chart on a schedule and PATCH the same report id: the link in the channel keeps showing current numbers, and the revision list is the history. See scheduled HTML reports.

What review adds

  • Anchored threads on the anomaly, so the explanation travels with the chart — see commenting on HTML.
  • Revisions, so "was it already trending down in August?" is answerable.
  • Access per report — private, team, domain-gated or named reviewers. See the sharing model.

Limits

  • Entry HTML: 5 MB. Inlining Chart.js costs roughly 200 KB; a large embedded dataset is the part that grows — upload it as an asset and fetch it instead.
  • 60 requests/minute per token.

Try it

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

Publish a chart →

Related