Skip to documentation content

Data Status

Mark each value as measured, estimated, provisional, forecast, or missing, and show the bounds you have for it.

Revenue with an open month and a forecast

Overview

A chart can mix numbers that deserve different amounts of trust: closed months, a month that is still open, a projection, a gap. Data status lets you say which is which. You supply the status of each value, and every Honest UI chart draws it, lists it in a key beside the plot, and explains it in the tooltip.

The charts never work a status out for you. A value with no status is drawn as an ordinary value and is not labelled "Measured". A range appears only where you supply both bounds.

Statuses

StatusUse it for
measuredA value recorded from the source.
estimatedA value that was calculated or modelled instead of recorded.
provisionalA value that is incomplete or unconfirmed and can still change.
forecastA projection for a period that has not been recorded yet.
missingA point where no value was recorded.

Each chart draws a status with the mark it has room for. A missing value is a dashed ring wherever the plot has a place for it; a pie chart names it in the key and a scatter chart counts it there.

StatusLine and areaBar and pieScatterHeatmap
measuredSolid strokeSolid fillFilled pointPlain cell
estimatedDotted strokeDotted fill with an outlineRing with a centre dotDot in the cell's corner
provisionalShort dashesHatched fill with an outlineHalf-filled pointSlash in the cell's corner
forecastLong dashesEmpty shape with a dashed outlineEmpty ringDashed outline inside the cell
missingA gap, with a ring on the baselineNo bar, with a ring on the baseline; a sector is named in the keyNot drawn; counted in the keyEmpty cell with a ring

Status is shown with stroke, fill, and shape, and it is named in the key and the tooltip, so it does not depend on color. A heatmap cell keeps its color, because the color is the value.

Usage

Put the status in the same row as the value it describes, then name that field with statusKey. Add lowerKey and upperKey when you have bounds for a value. These props go wherever the chart's value key goes: on the series part for LineChart, AreaChart, and BarChart, and on the chart root for PieChart, ScatterChart, and Heatmap.

import { LineChart, type ChartConfig } from "honestui/charts";

const data = [
  { month: "September", revenue: 428, status: "measured" },
  { month: "October", revenue: 187, status: "provisional" },
  { month: "November", revenue: 436, status: "forecast", low: 398, high: 471 },
  { month: "December", revenue: null, status: "missing" },
];

<LineChart data={data} config={chartConfig} xDataKey="month">
  <LineChart.XAxis dataKey="month" />
  <LineChart.Tooltip />
  <LineChart.Line dataKey="revenue" statusKey="status" lowerKey="low" upperKey="high" />
</LineChart>

When a chart has several series, give each one its own fields, such as webStatus and mobileStatus. AreaChart.Area and BarChart.Bar take the same three props.

PieChart and Heatmap read one value per row, so they take the props on the root:

<PieChart data={data} config={chartConfig} dataKey="tickets" nameKey="channel" statusKey="status">
  <PieChart.Pie />
</PieChart>

<Heatmap data={data} config={chartConfig} xDataKey="day" yDataKey="hour" valueDataKey="orders" statusKey="status">
  <Heatmap.Cells />
</Heatmap>

A scatter point has two values, so ScatterChart takes one statusKey for the point and separate bounds for each axis: yLowerKey and yUpperKey, and xLowerKey and xUpperKey.

<ScatterChart
  data={data}
  config={chartConfig}
  xDataKey="floorArea"
  yDataKey="energyUse"
  statusKey="status"
  yLowerKey="low"
  yUpperKey="high"
>
  <ScatterChart.Scatter dataKey="office" />
</ScatterChart>

How segments are drawn

A line segment joins two points, so it needs a rule when their statuses differ. A segment is solid only when both of its ends are measured or have no status. Otherwise it takes the status of its later point, or of its earlier point when the later one is solid. The line never crosses a point that has no value.

Ranges

On line, area, bar, and scatter charts, a range is drawn as a whisker from the lower bound to the upper bound, at that point only. The chart does not join whiskers into a band, because that would draw bounds between points that you did not supply. A range can appear with any status, including measured, and on a line, area, or bar point that has bounds but no value.

A pie sector and a heatmap cell have no place to draw a whisker, so those charts report the range in the tooltip only.

Examples

An estimated value and a missing value

statusKey with a gap

Area

Two series with their own status fields

Bar

Every status on a grouped bar chart

Pie

A missing sector cannot be drawn, so the key names it. The remaining sectors are then shares of the known total, not of the whole.

A donut with a missing sector

Scatter

Point status with bounds on the y value

Heatmap

Cell status over the value color

Behavior to know about

  • Other stroke and fill options. Dashes and fills carry status on a series that sets statusKey, lowerKey, or upperKey. On that series, strokeVariant, glowing, enableBufferLine, bufferBar, and connectNulls are not applied, and a bar's status fill replaces its variant fill for estimated, provisional, and forecast values.
  • Absent values. On a series or chart that reads a status, a null, empty, or non-numeric value is left empty instead of being drawn at zero. Charts and series that do not read a status keep their existing behavior.
  • Points that cannot be placed. A scatter point needs both coordinates. A point marked missing is left out and counted in the key, for example "Missing: 1 not shown".
  • Small marks. Heatmap status marks need room. In a dense heatmap with cells only a few pixels wide, rely on the tooltip and a text summary.
  • Stacked charts. In a stacked chart, a range moves up with the series it belongs to. In an expanded area chart or a percent bar chart, ranges are not drawn, because bounds on a value are not bounds on its share. If any value in a category is missing, every share in that category is unknown and the category is left empty.
  • Invalid input. In development, the chart logs a console warning and skips the claim it cannot draw: a status that is not one of the five, a row marked missing that still has a value, a single bound, bounds that are out of order or exclude the value, or a scatter point whose x or y is not a number.

Accessibility

The key is a list under the plot, or above it when the chart's legend sits at the bottom. Each entry carries its explanation for screen readers, and the default ariaLabel names the statuses in the chart. The plot itself is a canvas, and the tooltip is pointer-operated, so give readers a text summary or a data table that includes each value's status when the difference matters to a decision.

Changing the text

Pass dataStatusText to the chart root to translate or reword the labels and explanations. Anything you leave out keeps its default. Define the object outside the component so the chart does not rebuild on every render.

import { LineChart, type DataStatusText } from "honestui/charts";

const dataStatusText: DataStatusText = {
  keyLabel: "Datenstatus",
  rangeLabel: "Spanne",
  noValueLabel: "Kein Wert",
  statuses: {
    forecast: {
      label: "Prognose",
      description: "Eine Hochrechnung für einen Zeitraum, der noch nicht erfasst ist.",
    },
  },
};

<LineChart data={data} config={chartConfig} dataStatusText={dataStatusText}>
  <LineChart.Line dataKey="revenue" statusKey="status" />
</LineChart>

API Reference

Line, Area, and Bar parts; PieChart and Heatmap roots
PropTypeDefaultDescription
statusKeystring–

The row field that holds this series' status: "measured", "estimated", "provisional", "forecast", or "missing". Rows without the field are drawn without a status.

lowerKeystring–

The row field that holds the lower bound. Set it together with upperKey.

upperKeystring–

The row field that holds the upper bound. Set it together with lowerKey.

ScatterChart root
PropTypeDefaultDescription
statusKeystring–

The row field that holds each point's status.

yLowerKeystring–

The row field that holds the lower bound of the y value. Set it together with yUpperKey.

yUpperKeystring–

The row field that holds the upper bound of the y value. Set it together with yLowerKey.

xLowerKeystring–

The row field that holds the lower bound of the x value. Set it together with xUpperKey.

xUpperKeystring–

The row field that holds the upper bound of the x value. Set it together with xLowerKey.

Every chart root
PropTypeDefaultDescription
dataStatusTextDataStatusText–

Replacement text for the status labels and explanations, the key label, the range label, the label shown for a point with no value, and the count of points that are not shown.