Skip to content

Error bars ​

Error bars are first-class series config: set errorLowProperty and errorHighProperty to the data properties holding a point's absolute lower and upper bounds, and the chart draws a capped whisker through every bar or line point.

ts
// Error bars are first-class series config: point errorLowProperty and
// errorHighProperty at the properties holding each point's absolute bounds and
// the chart draws a capped whisker per bar (or line point).
import type { MochartInputConfig } from '@mochart/core';

export const config: MochartInputConfig = {
  version: '1.0.0',
  title: { text: 'Monthly Output with 95% CI (fictional)' },
  categoryAxis: { property: 'month', type: 'string', scale: 'ordinal' },
  valueAxes: [{ title: { text: 'units per day' } }],
  seriesGroups: [{ id: 'plants' }],
  series: [
    { id: 'a', title: 'Plant A', property: 'a', renderer: 'bar', group: 'plants',
      errorLowProperty: 'aLow', errorHighProperty: 'aHigh', valueFormat: ',.1f' },
    { id: 'b', title: 'Plant B', property: 'b', renderer: 'bar', group: 'plants',
      errorLowProperty: 'bLow', errorHighProperty: 'bHigh', valueFormat: ',.1f' },
    { id: 'target', title: 'Target', property: 'target', renderer: 'line', group: null,
      errorLowProperty: 'targetLow', errorHighProperty: 'targetHigh', valueFormat: ',.1f' }
  ]
};

export const data = [
  { month: 'Jan', a: 52.1, aLow: 46.1, aHigh: 58.1, b: 47.7, bLow: 44.0, bHigh: 52.4, target: 52.0, targetLow: 50.0, targetHigh: 53.8 },
  { month: 'Feb', a: 64.1, aLow: 58.5, aHigh: 68.2, b: 50.1, bLow: 43.6, bHigh: 55.9, target: 56.5, targetLow: 54.6, targetHigh: 59.5 },
  { month: 'Mar', a: 69.6, aLow: 64.6, aHigh: 75.2, b: 47.1, bLow: 42.7, bHigh: 51.3, target: 59.8, targetLow: 57.7, targetHigh: 61.5 },
  { month: 'Apr', a: 65.5, aLow: 58.6, aHigh: 69.5, b: 54.4, bLow: 50.0, bHigh: 60.3, target: 61.0, targetLow: 58.5, targetHigh: 62.7 },
  { month: 'May', a: 59.7, aLow: 55.4, aHigh: 64.3, b: 51.5, bLow: 46.6, bHigh: 55.9, target: 59.8, targetLow: 57.6, targetHigh: 62.3 },
  { month: 'Jun', a: 55.7, aLow: 49.2, aHigh: 60.4, b: 45.6, bLow: 40.4, bHigh: 51.1, target: 56.5, targetLow: 53.9, targetHigh: 58.6 }
];

How it works ​

  • The bounds are absolute values in value-axis units (e.g. the ends of a confidence interval), not deltas from the value. For value ± error data, derive the bound properties once when preparing the rows.
  • The bounds join the value axis domain, so whiskers never clip: the axis above reaches past the tallest bar to cover its upper bound. The exception is a bound at or below 0 on a log axis, which has no position for it, so the whisker runs off the plot edge.
  • Whiskers center on each bar's layout slot (including grouped sub-slots, as in the two plant series above), and on the point position for line, area and none renderer series. On horizontal charts they run horizontally with vertical caps.
  • Either bound works alone: a category missing one bound draws a one-sided whisker from the point to the defined bound, and a category missing both draws no whisker. A missing bound is a legitimate one-sided error bar, so the tooltip shows nothing for it rather than the missing-value text.
  • Stacked series can't take error properties (absolute bounds have no meaning against a cumulative stack position), and config validation rejects the combination.
  • The tooltip appends the bounds after the value, joined by the tooltip's rangeValueSeparator: 56.5 (53.9 - 58.6).
  • Styling: errorBar.capSize sets the cap width in pixels (default 6; 0 hides the caps; on bars the caps clamp to the bar slot), and errorBar.style styles the whisker itself. Being a line, it takes a stroke-only style: strokeColor, strokeOpacity, strokeWidth and strokeDashArray (e.g. "5, 5"; null for a solid whisker), once per focus state. The default strokeColor is "series" in normal and "same" in focused and defocused, so whiskers follow their series' color through focus, while the opacities (0.9 normally, 1 focused, 0.5 defocused) dim them alongside it. Only the members you name are overridden, so thickening just the focused whisker is errorBar.style: { focused: { strokeWidth: 3 } }.
  • Whiskers animate with their series: value transitions share one duration across the point and its bounds, so the whisker stays glued to a moving bar, and entering categories grow their whisker out of the axis base with the bar.

Released under the MIT License.