JSON to chart

Paste JSON from an API, a script or a Chart.js config. The builder finds the labels and the numbers, draws the chart, and exports an SVG or a PNG.

Your data

Data format

Paste from a spreadsheet, a CSV file or an API response. The first row (or the keys) name the columns.

12 rows, 3 columns. Read as a list of objects.

Try a sample:

Your data stays in your browser. Nothing you paste is uploaded. Share links carry the data after the #, which browsers never send to a server.

Chart

800 × 400 px

Chart type
Weekly signupsLine chart: New accounts, and accounts that finished setup (sample data). 12 categories, from Jul 6 to Sep 21. signups: lowest 182 (Jul 6), highest 398 (Sep 21). activated: lowest 96 (Jul 6), highest 241 (Sep 21). Values: Jul 6: signups 182, activated 96; Jul 13: signups 205, activated 112; Jul 20: signups 198, activated 104; Jul 27: signups 240, activated 131; Aug 3: signups 262, activated 150; Aug 10: signups 251, activated 139; Aug 17: signups 298, activated 171; Aug 24: signups 315, activated 186; Aug 31: signups 302, activated 179; Sep 7: signups 344, activated 205; Sep 14: signups 371, activated 226; Sep 21: signups 398, activated 241.Weekly signupsNew accounts, and accounts that finished setup (sample data)signupsactivated0100200300400Jul 6Jul 13Jul 20Jul 27Aug 3Aug 10Aug 17Aug 24Aug 31Sep 7Sep 14Sep 21
Size

Export

PNG resolution

Settings

Columns
Series to chart
Titles
Numbers
Style

JSON shapes it reads

Paste any of these as they are. The builder says which shape it found under the text box.

A list of objects

The most common shape: one object per row, keys as columns. Keys missing from some rows leave gaps.

a list of objects.json
[
  { "week": "2026-07-06", "signups": 182, "activated": 96 },
  { "week": "2026-07-13", "signups": 205, "activated": 112 }
]

An object of lists

One list per column, as dataframes and many APIs return them.

an object of lists.json
{
  "week": ["2026-07-06", "2026-07-13"],
  "signups": [182, 205]
}

Labels and values

Pairs, or an object whose keys are the labels. Good for pie and donut charts.

labels and values.json
[{ "label": "Chrome", "value": 62 }, { "label": "Safari", "value": 21 }]

{ "Chrome": 62, "Safari": 21, "Firefox": 9 }

Chart.js data

The data part of a Chart.js chart, or the whole config. Its chart type carries over; colors and other options don’t.

chart.js data.json
{
  "type": "bar",
  "data": {
    "labels": ["Q1", "Q2", "Q3"],
    "datasets": [{ "label": "Revenue", "data": [412, 448, 501] }]
  }
}

A wrapped API response

When the rows sit under one key, like "data" or "results", that list is used.

a wrapped api response.json
{ "data": [{ "day": "Mon", "requests": 1200 }, { "day": "Tue", "requests": 1350 }] }

How values are read

The same rules as the CSV reader, so a number means the same thing either way.

Numbers

JSON numbers, and numbers written as text the way people write them: with thousands separators, % signs or currency symbols.

1200 "1,200" "12%" "$1,200"
Gaps

null, a missing key or an empty string leaves a gap in the series, not a zero.

Labels

The first key holding text or ISO dates labels the rows. Choose another under Columns.

Not charted

Nested objects, lists inside rows and true or false. Flatten them first: one object per row, one number per key.

Other formats

Arrays of arrays (first row as names), a plain list of numbers, and JSON Lines with one object per line.

Early access

Get a hosted link

Some places can’t run a chart script or take a file upload: email, Slack messages, PDFs, pull request descriptions. A hosted link is a plain image URL that draws your chart when it’s opened.

What it will do:

  • An image URL per chart. Put it in an <img> tag or a Markdown image and the chart shows up, SVG or PNG.
  • Signed. Nobody can change the chart by editing the link.
  • Cached close to readers, so a newsletter sent to thousands loads quickly.
  • The same renderer as this builder, so the link and the file you download look the same.

Not built yet: we’re checking that enough people want it first. Leave your email and we’ll tell you when it opens. Nothing else.

You confirm your address first. Then one email when hosted links open.

What a hosted link could look like (format not final)
![Weekly signups](https://boringutils.com/c/…/weekly-signups.png)

<img src="https://boringutils.com/c/…/weekly-signups.png"
     width="600" height="300" alt="Weekly signups, July to September">

Questions

Short answers to the usual ones.

Anything else: hello@boringutils.com

Is my JSON uploaded anywhere?

No. It is read and drawn in your browser. Share links carry the data after the # in the address, which browsers never send to a server.

Which JSON shapes work?

A list of objects, an object of lists, label and value pairs, an object of numbers, Chart.js data or configs, arrays of arrays, a list of numbers, JSON Lines, and any of those wrapped in a single key like "data".

Can I paste a Chart.js config and get a PNG?

Yes. Paste the config (or just its data), and the labels, datasets and chart type are read. Then use Download PNG.

Colors, scales and plugin options are not carried over: the chart is drawn by our renderer with one of its themes. Doing it in your own code instead? The Chart.js to PNG guide covers that.

My JSON is nested. What now?

Charts need a table: one row per label and one number per series. Reshape nested data into a list of flat objects first, for example with jq: .items | map({ name: .name, visits: .stats.visits }).

What does the error with a line and column mean?

The JSON has a syntax error at that spot. The usual suspects are a trailing comma after the last item, single quotes instead of double quotes, and keys without quotes, which JavaScript allows but JSON does not.

Why did a column not show up as a series?

Only columns that are mostly numbers can be series. Columns of text become label candidates, and up to 8 series fit on one chart.