SQL is excellent at slicing and aggregating data. But a table of numbers rarely tells the full story. Wrap those query results in a chart and patterns jump out immediately — growth accelerates, one category dominates, a trend reverses.

Chart.js is one of the most popular open-source charting libraries for the web. It supports bar, line, pie, doughnut, radar, and many more chart types out of the box. Combined with sql.js (SQLite compiled to WebAssembly), you can query a database and render the result as a chart entirely in the browser — no server required.

This tutorial walks through five interactive examples, each demonstrating a different chart type on the same theme — vehicle registrations and fuel data in Australia:

  1. Table — preview the raw data
  2. Bar chart — compare EV vs diesel registrations by year
  3. Line chart — the same data, reframed as a trend
  4. Pie chart — fuel type composition
  5. Doughnut chart — average price by station

If you have used Python’s matplotlib or seaborn, think of Chart.js as the browser-native equivalent. Instead of plt.bar(x, y) you write new Chart(canvas, { type: 'bar', data, options }). The mental model is the same: query data, pick a chart type, map columns to axes.

The dataset

We use two tables. The first, registrations, tracks the number of new electric vehicle (EV) and diesel vehicle registrations in Australia from 2018 to 2023. The second is the same fuel table used in our other SQL tutorials — petrol station transactions with station name, fuel type, litres, and price.

Click Run on the first block to create the tables and inspect the registrations data:

SQL — editable
Figure 1: EV and diesel registrations in Australia, 2018–2023.

EV registrations grew from around 2,200 in 2018 to over 87,000 in 2023 — a 39x increase. Diesel registrations declined steadily over the same period. A table shows the numbers, but a chart reveals the crossover point and the acceleration curve at a glance.

How the data flows from SQL to Chart.js

Each chart block below has two editors: a SQL editor on top and a Chart.js editor below it. When you click Run, the SQL query executes first and the result columns are automatically passed to the Chart.js code as variables:

This means the Chart.js code never contains hardcoded data. If you change the SQL query — add a WHERE, swap columns, or query a different table — the same Chart.js code adapts automatically because columns[0], columns[1], etc. always reflect whatever the query returned.

Bar chart — comparing categories

A bar chart is the right choice when you want to compare discrete values side by side. Here each year is a category, and the two bars (EV vs diesel) let you instantly see which was higher and by how much:

SQL — editable
Chart.js — editable
Figure 2: Grouped bar chart — EV vs diesel registrations by year.

The grouped bar chart makes the 2022 crossover obvious: EV registrations overtook diesel for the first time. In Chart.js, a grouped bar is the default when you provide multiple datasets with type: 'bar'.

Line chart — showing trends over time

A line chart emphasises the direction and rate of change. The same query, rendered as lines instead of bars, tells a story about momentum rather than discrete comparison:

SQL — editable
Chart.js — editable
Figure 3: Line chart — the same data shows the acceleration trend more clearly.

Notice how the EV line curves upward exponentially while diesel slopes gently down. The line chart reveals the shape of the trend — something the bar chart hinted at but did not make as vivid. Use line charts when your x-axis is continuous (dates, years, months) and you want to emphasise trajectory.

Pie chart — showing composition

A pie chart shows how parts relate to a whole. It works best with a small number of categories where one or two slices clearly dominate. Here we use the fuel table to show the distribution of fuel types across all transactions:

SQL — editable
Chart.js — editable
Figure 4: Pie chart — fuel type distribution across transactions.

With only three fuel types, the pie chart is easy to read. Unleaded dominates, followed by Diesel and Premium. If you had ten or more categories of similar size, a horizontal bar chart would be more readable — pie slices become hard to compare when they are close in size.

Doughnut chart — a cleaner ring

A doughnut chart is a pie chart with a hollow centre. The empty space can hold a label or summary statistic. It is often considered more modern and easier to read than a solid pie. Here we show the average fuel price per station:

SQL — editable
Chart.js — editable
Figure 5: Doughnut chart — average fuel price per station.

The doughnut shows that average prices are fairly similar across stations, with Shell Fortitude Valley slightly higher. When values are close, the visual difference between slices is subtle — this is a case where a bar chart might actually be more effective. Choosing the right chart type is always about matching the question to the visual encoding.

Choosing the right chart type

Here is a quick decision guide:

The most common mistake is using a pie chart when a bar chart would be clearer. If your audience needs to compare precise values rather than get a rough sense of proportion, bars win every time.

SQL + Chart.js vs Python (matplotlib / seaborn)

In Python, the typical workflow is df = pd.read_sql(query, conn) followed by df.plot.bar() or sns.barplot(data=df). The SQL + Chart.js approach has a different set of trade-offs:

For exploratory data analysis, Python is hard to beat. For sharing interactive results on the web, SQL + Chart.js is a lightweight and powerful combination.

Try editing the queries above — change the ORDER BY, add a WHERE clause, or swap column names to see how the charts respond in real time.

References

Suhith Illesinghe
Curiosity is the first step to make a difference. I hope to inspire others to explore, build and champion collaborative growth.