Home / Trends Over Time / Streamgraph

Streamgraph in HTML, CSS and JavaScript

A streamgraph is a stacked area chart that flows around a center line instead of sitting on the bottom. This free template draws one with plain SVG and vanilla JavaScript, no chart library. The example shows weekly listening hours by genre on a radio app.

Open live demoDownload HTML fileView code on GitHub
Streamgraph made with HTML and JavaScript showing weekly listening hours by genre on a radio app

What is a streamgraph?

A streamgraph is a stacked area chart that flows around a center line instead of sitting on the bottom. Each colored stream is one category, and its thickness shows how big it was at each moment.

It is made for seeing rises and falls across many categories at once. It gives up exact totals in exchange for a clear picture of which streams grow, shrink or take over, like podcasts overtaking rock.

At a glance

Best for
Many categories changing over time
Data you need
A date and one number per category for each point
Skip it when
When people need exact numbers. Use lines or bars.
Made with
HTML, CSS and vanilla JavaScript. No library.

When to use a streamgraph

  • Music, film or book genres over time
  • Topics people search or talk about each week
  • Product categories in an online shop over a year
  • Stories for reports and magazines where the shape is the point

When to pick another chart

What you get in this template

How the code works

Here is a short version of the idea behind this streamgraph. The full file adds the axis, labels, tooltips, sorting and resizing on top of it.

const weeks = 5;
const streams = [
  { color: '#e4572e', values: [34, 36, 35, 38, 37] },
  { color: '#29335c', values: [30, 29, 28, 27, 26] },
  { color: '#8e5572', values: [9, 12, 15, 19, 22] }
];
const totals = Array.from({ length: weeks }, (v, i) => streams.reduce((a, s) => a + s.values[i], 0));
const x = i => 40 + i * 130, y = v => 160 - v * 1.6;
let below = totals.map(t => -t / 2); // center on the middle line

streams.forEach(s => {
  const top = below.map((b, i) => b + s.values[i]);
  const up = top.map((v, i) => x(i) + ',' + y(v));
  const down = below.map((v, i) => x(i) + ',' + y(v)).reverse();
  make('path', { d: 'M' + up.join('L') + 'L' + down.join('L') + 'Z', fill: s.color });
  below = top;
});

The example uses four tiny helpers that create SVG shapes. Put them above the code and it runs as is.

const svg = document.querySelector('svg');
function make(tag, attrs) {
  const n = document.createElementNS('http://www.w3.org/2000/svg', tag);
  for (const k in attrs) n.setAttribute(k, attrs[k]);
  svg.appendChild(n);
  return n;
}
function drawRect(x, y, width, height, fill) { return make('rect', { x, y, width, height, fill }); }
function drawCircle(cx, cy, r, fill) { return make('circle', { cx, cy, r, fill }); }
function drawLine(x1, y1, x2, y2, stroke, width, dash) {
  return make('line', { x1, y1, x2, y2, stroke, 'stroke-width': width || 1, 'stroke-dasharray': dash || 'none' });
}
function drawText(x, y, str, anchor) {
  const t = make('text', { x, y, 'text-anchor': anchor || 'start' });
  t.textContent = str;
  return t;
}

How to add it to your website

  1. Download the file. Click Download HTML file above. You get one file called streamgraph.html with everything inside.
  2. Change the data. Open the file in any code editor and find the DATA list near the bottom. Replace the names and numbers with your own.
  3. Change the colors and text. Colors are at the top of the style tag. The title, subtitle and main point are plain HTML near the top of the body.
  4. Put it online. Upload the file to any host, such as GitHub Pages, Netlify or your own server, or paste it into your site. There is no build step.

Questions people ask

What is a streamgraph used for?

It shows how many categories rise and fall over time. It is popular in news stories and reports where the overall shape tells the story better than exact numbers.

How is a streamgraph different from a stacked area chart?

Both stack layers. A stacked area chart starts at zero, so you can read the total. A streamgraph centers the stack on a middle line, which looks smoother and makes each stream easier to follow.

Why does a streamgraph have no y axis?

Because the layers float around a center line, a single axis would not give useful readings. The tooltip gives exact numbers instead.

Is a streamgraph the same as a theme river?

Yes. ThemeRiver was an early name for this chart. Streamgraph is the name most people use today.

More trends over time