Skip to content

Thresholds and ranges ​

Three ways to show reference context around your values: a threshold line drawn at a fixed value on an axis, a threshold range filled between two fixed values, and a range series that fills the band between two data properties.

ts
// A threshold line with a title on the value axis, plus a range series: the
// band spans from rangeProperty (low) to property (high), with the actual
// values drawn as a line on top.
import type { MochartInputConfig } from '@mochart/core';

export const config: MochartInputConfig = {
  version: '1.0.0',
  title: { text: 'Response Time' },
  categoryAxis: { property: 'day', type: 'string', scale: 'ordinal' },
  valueAxes: [
    {
      thresholds: [{
        value: 200,
        title: { text: 'SLA limit' },
        style: { normal: { strokeDashArray: '6 3' } }
      }]
    }
  ],
  series: [
    {
      property: 'p95',
      rangeProperty: 'p5',
      title: 'p5–p95 range',
      renderer: 'area',
      shapeStyle: { normal: { strokeOpacity: 0, fillOpacity: 0.25 } }
    },
    { property: 'median', title: 'Median', renderer: 'line' }
  ]
};

export const data = [
  { day: 'Mon', median: 120, p5: 80, p95: 170 },
  { day: 'Tue', median: 135, p5: 90, p95: 190 },
  { day: 'Wed', median: 150, p5: 95, p95: 230 },
  { day: 'Thu', median: 128, p5: 85, p95: 180 },
  { day: 'Fri', median: 160, p5: 100, p95: 250 },
  { day: 'Sat', median: 95, p5: 70, p95: 140 },
  { day: 'Sun', median: 88, p5: 65, p95: 130 }
];

How it works ​

  • thresholds on a value axis draws one reference line per entry. Each entry has a value, an optional title beside the line (its text, and side, textStyle and the other members that place and style the label), and a style for the line (color, width and dash array in normal, focused and defocused states); front puts the line in front of or behind the series. A linear category axis takes the same thresholds for vertical reference lines (a date axis value is an ISO string or timestamp); an ordinal one places them by category, described below.
  • The data band is an ordinary area series with rangeProperty: the shape spans from the rangeProperty value (here p5) to the property value (p95) instead of starting at the axis base. Dropping shapeStyle.normal.strokeOpacity to 0 and fillOpacity low keeps it as background context; the colors and the focused/defocused states stay at their defaults. rangeProperty works with the other renderers too: bar draws floating bars, and line draws the two bounds as a pair of lines sharing the series' style and legend entry.
  • For ranged series the tooltip prints the rangeProperty value, then tooltip.rangeValueSeparator, then the property value. That order comes from the config, not from the two magnitudes, so the example above reads low - high because it puts p5 in rangeProperty. When both ends format to the same text, the tooltip shows it once instead of repeating it either side of the separator.
  • A category with only one of the two values collapses to a zero-extent span at the defined one, so the band stays connected; set partialRangeIsMissing to treat such categories as missing instead.
  • Thresholds never extend the axis: a line whose value falls outside the current domain is simply not drawn. If the data alone wouldn't reach the threshold, set softMax at or above it so the axis covers it.

Threshold ranges ​

Give a thresholds entry a rangeValue and it fills the range between its two values instead of drawing a line:

ts
// A threshold range: rangeValue turns a thresholds entry into a range between
// two axis values, filled by the style fill members and edged by its stroke
// members, with a title centered inside it.
import type { MochartInputConfig } from '@mochart/core';

export const config: MochartInputConfig = {
  version: '1.0.0',
  title: { text: 'Response Time' },
  categoryAxis: {
    property: 'day',
    type: 'string',
    scale: 'ordinal',
    thresholds: [{ value: 'Wed', title: { text: 'Midweek' } }]
  },
  valueAxes: [
    {
      thresholds: [
        {
          value: 100,
          rangeValue: 150,
          front: false,
          style: { normal: { fillColor: '#1baf7a', fillOpacity: 0.15, strokeColor: '#1baf7a', strokeOpacity: 0.8 } },
          title: { text: 'Target', side: 'inside', anchor: 'middle' }
        },
        { value: 200, title: { text: 'SLA limit' }, style: { normal: { strokeDashArray: '6 3' } } }
      ]
    }
  ],
  series: [{ property: 'median', title: 'Median', renderer: 'line' }]
};

export const data = [
  { day: 'Mon', median: 120 },
  { day: 'Tue', median: 135 },
  { day: 'Wed', median: 150 },
  { day: 'Thu', median: 128 },
  { day: 'Fri', median: 160 },
  { day: 'Sat', median: 95 },
  { day: 'Sun', median: 88 }
];
  • The stroke members of style draw the range's two edge lines and its fill members fill the interior; a stroke opacity of 0 leaves just the fill. A pattern or gradient id fills the range with that definition instead, and a pattern's owner color resolves to the range's fill color. front: false keeps the range behind the series.
  • The title's side is low or high of the whole range, or inside to center it within the range; anchor places any threshold title at the start, middle or end of the plot instead of the axis side.
  • A range partly outside the axis domain is clipped to it; one wholly outside is not drawn.
  • Ordinal category axes take thresholds too: a value names a category, so a line sits at that category's center, as the Midweek line at Wed above, and a range covers whole slots from the first named category to the second.
  • thresholdStep repeats a line or range by rule instead of listing values. It is off by default, so set visible: true along with the rule: every and offset choose which candidates get a threshold, where the candidates are an ordinal axis's categories, the periods of a date axis when interval is a period, or the multiples of a number interval, in axis values on a number scale or in milliseconds on a linear date axis. interval: 'week' with every: 2 draws a range over every other week of a daily trading axis, holidays included, as the threshold step demo in the gallery does, and on a value axis interval: 10 with every: 2 draws ranges over 0 to 10, 20 to 30 and so on. range: false draws lines at the candidates instead. The stepped shapes share one style, pattern or gradient and carry no title. On a linear axis minSpacing is the least distance in pixels allowed between the thresholds the rule draws: when they would sit closer together than that, none are drawn and a console warning names the axis.

Released under the MIT License.