← Blog

michi-vz chart by chart: gap and comparable bars

August 26, 20264 min read

This is part 6 of 9 in a series touring all 22 michi-vz chart types, family by family. The series starts in Introducing @michi-vz. Part 5 covered gauge, radar and radial tree.

Sixth stop: two values per label, and the difference is the story. Three charts, three ways to draw the same comparison. 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 gap chart

Before and after, target and actual, them and us: plot the two endpoints per row and the bar between them becomes the message. Life expectancy since 2000 makes the point; the gap bars are two decades of progress:

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

One row per label with the two endpoint values:

const data = [
  { label: "Vietnam", value1: 66, value2: 74 },
  { label: "Ethiopia", value1: 52, value2: 68 },
  // ...value1 -> value2, one gap bar per row...
];
import { GapChart } from "@michi-vz/react";

<GapChart
  dataSet={data}
  width={640}
  height={320}
  colorMode="shape"
  showLegend
  xAxisDomain={[40, 90]}
/>;
  • colorMode: "shape" colours by role (value1, value2, gap) instead of by row, with shapesLabelsMapping naming the roles in the legend.
  • shapeValue1 and shapeValue2 pick circle, square or triangle per endpoint, so the ends stay distinguishable in print.
  • xAxisDomain zooms the axis into the interesting band instead of starting from zero.

Full props on the gap chart API page.

The comparable horizontal bar

Where the gap chart abstracts the two values into endpoints, the comparable bar keeps them as real bars: a muted "before" behind, a solid "after" in front, overlaid on one row per label. The first thing readers see is whether the front bar outgrew the back one:

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

One row per label with the reference value and the compared value:

const data = [
  { label: "Electronics", valueBased: 42, valueCompared: 61 },
  { label: "Textiles", valueBased: 35, valueCompared: 39 },
  // ...valueBased renders behind, valueCompared in front...
];
import { ComparableHorizontalBarChart } from "@michi-vz/react";

<ComparableHorizontalBarChart
  dataSet={data}
  width={640}
  height={320}
/>;
  • layout: "grouped" puts the two bars side by side when overlap hides more than it shows.
  • deltaIndicator adds a per-row change arrow with a formatted difference.
  • patternsMapping fills the reference bar with a hatch pattern, which survives grayscale printing.

Full props on the comparable horizontal bar API page.

The comparable vertical bar

The vertical sibling: full-bandwidth columns, reference behind, compared in front, diverging from zero so negatives read correctly. It suits time buckets like quarters, where vertical is the natural reading:

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

The data shape is identical to the horizontal variant:

const data = [
  { label: "Q1", valueBased: 18, valueCompared: 24 },
  { label: "Q2", valueBased: 22, valueCompared: 26 },
  // ...one column pair per category...
];
import { ComparableVerticalBarChart } from "@michi-vz/react";

<ComparableVerticalBarChart
  dataSet={data}
  width={640}
  height={320}
/>;
  • deltaIndicator draws the change arrow and difference above each column pair.
  • symmetricYDomain centres zero for plus-or-minus data like growth rates.
  • xAxisMode: "horizontal" keeps crowded category labels flat and thins them instead of tilting.

Full props on the comparable vertical bar API page.

Next in the series: tornado and bar-bell.