billboard.js in HTML: compare planned and actual work by category

Compare planned and actual packing quantities with their source rows beside the bars.

Three categories need two values each: what was planned and what happened. Give billboard.js separate named columns for Planned and Actual, then supply the category labels in the same order. A chart can draw valid bars while attaching them to the wrong work packages.

Use a fictional packing report. Package A has ten planned units and nine actual units; B has twelve and thirteen; C has eight and six. The planned total is thirty and the actual total is twenty-eight. The difference is two fewer actual units overall, even though B exceeds its plan by one.

Packing quantities: grouped bars and a plan visibility control
Packing quantities: grouped bars and a plan visibility control
Open the full example ↗

Open the complete example · Download the full HTML source

Keep series names separate from categories

The billboard.js API documentation describes bb.generate(), data columns, chart types, and the category axis. After loading a compatible browser distribution and stylesheet, initialize the comparison:

const chart = bb.generate({
  bindto: '#comparison',
  data: {
    columns: [
      ['Planned', 10, 12, 8],
      ['Actual', 9, 13, 6]
    ],
    type: 'bar'
  },
  axis: {
    x: { type: 'category', categories: ['A', 'B', 'C'] }
  }
});

The first entry in each column is the series identifier. It is not another observation. Each following number aligns with a category position. Keep a readable source table beneath the chart so the reader can reconcile the association without inspecting JavaScript.

Compare the same quantities

Label both series as units of the same thing. Do not compare a planned count with an actual percentage under the same axis. If the measures differ, resolve that analytical question before choosing a different color or chart shape.

For the fixture, the per-package Actual minus Planned differences are minus one, plus one, and minus two. Their sum is minus two, matching twenty-eight minus thirty. An overall shortfall does not mean every package is below plan.

Make a visibility control a view choice

The chart API includes hide() and show() for series. A Show plan checkbox can call chart.hide('Planned') when cleared and chart.show('Planned') when restored. Keep the source rows and totals visible while the series is hidden.

The checkbox should not delete the planned values or recalculate an “actual” total from whichever bars are currently visible. Name the control for the series it changes. If you retain the chart's interactive legend as well, keep both ways of changing visibility understandable.

The existing HTML line chart guide builds SVG directly. This named-library recipe instead addresses billboard's column format, category alignment, and chart instance controls. A grouped category comparison does not need to imply a time trend.

Preserve the reading context with the output

The saved HTML still needs its JavaScript and CSS. Use the matching distributions, retain their source versions, and include the required runtime in the file when a self-contained handoff is the goal. A screenshot preserves the comparison but removes the show/hide behavior.

If you review the report in NOS, put the source table and the reporting unit beside the chart. Ask the reviewer to confirm the A, B, C mapping before accepting the apparent differences between bars.

Keep reading