← Blog

michi-vz chart by chart: tornado and bar-bell

August 26, 20263 min read

This is part 7 of 9 in a series touring all 22 michi-vz chart types, family by family. The series starts in Introducing @michi-vz. Part 6 covered gap and comparable bars.

Seventh stop: two bar charts that stopped being ordinary. One splits around a centre line, the other lays its segments end to end. Every michi-vz chart takes the same props in React, Vue, Svelte, Angular and plain HTML; the first chart below shows all four flavours, the rest show React to keep things short.

The tornado chart

Anchor two values to a shared centre line, one extending left and one right, and imbalance becomes the whole chart. This is the population pyramid, the sensitivity tornado of financial modelling, and every imports-versus-exports figure you have ever seen:

Live chart, rendered in your browser by @michi-vz/wc straight from the CDN. Hover it.

One row per band; value1 extends right, value2 extends left:

const data = [
  { label: "75+", value1: 3.4, value2: 2.3 },
  { label: "60-74", value1: 6.8, value2: 6.1 },
  // ...value1 draws right, value2 draws left...
];
import { DualHorizontalBarChart } from "@michi-vz/react";

<DualHorizontalBarChart
  dataSet={data}
  width={640}
  height={340}
  yAxisPosition="left"
/>;
  • yAxisPosition: "left" moves row labels into the margin for the classic pyramid look; "center" overlays them on the centre line.
  • value1Opacity and value2Opacity differentiate the sides beyond colour.
  • filter ranks rows by either side, handy for sensitivity tornados where the widest bars belong on top.

Full props on the dual horizontal bar API page.

The bar-bell chart

Lay each row's parts end to end as thin bars, cap every step with a circle, and you can read two things at once: how far the total reaches, and how much each segment contributed to getting there:

Live chart, rendered in your browser by @michi-vz/wc straight from the CDN. Hover it.

One row per date with a value per key; the keys accumulate left to right:

const data = [
  { date: 2022, "Existing markets": 40, "New markets": 12, Online: 8 },
  // ...each key's value extends the row cumulatively...
];
const keys = ["Existing markets", "New markets", "Online"];
import { BarBellChart } from "@michi-vz/react";

<BarBellChart
  dataSet={data}
  keys={keys}
  width={640}
  height={300}
/>;
  • dodgeOverlappingCaps spreads end-caps vertically when segments are too close to distinguish; on by default.
  • xAxisPosition: "bottom" moves the cumulative axis under the chart.
  • progressiveDraw animates the reach growing left to right.

Full props on the bar-bell chart API page.

Next in the series: the maps.