Skip to content
wardkitGitHub

Not a medical device and not for clinical use. All patients and data on this site are fictional.

VitalsTrend

An SVG trend of one vital sign from a list of Observations, with gaps and a reference band.

Rule it enforces: A missing reading breaks the line into a visible gap; nothing is interpolated across it.

Install

npx shadcn@latest add https://raw.githubusercontent.com/Henrycarto/wardkit/main/public/r/vitals-trend.json

Usage

import { VitalsTrend } from '@/components/wardkit/vitals-trend';

<VitalsTrend observations={heartRate} maxGapMinutes={120} timeZone="Europe/Vienna" />

Examples

Heart rate overnight, maxGapMinutes 120

A failed reading at 22:00 (probe off), a reading entered in error at 02:00, and nothing from 03:00 to 06:00. The line breaks at each; the band is the reference range.

Heart rate (/min)3 gaps, line not joined across. Shaded: reference range 51 to 90
507510012520:0023:0002:0005:00No reading for 180 minNot measured: Error: Probe off, no valid readingEntered in error, not shown
Readings (15)
TimeReading
20 Oct 2026, 18:0088 /min
20 Oct 2026, 19:0089 /min
20 Oct 2026, 20:0090 /min
20 Oct 2026, 21:0090 /min
20 Oct 2026, 22:00Not measured: Error: Probe off, no valid reading
20 Oct 2026, 23:0090 /min
20 Oct 2026, 23:30104 /min
21 Oct 2026, 00:00112 /min
21 Oct 2026, 00:20118 /min
21 Oct 2026, 01:00124 /min
21 Oct 2026, 01:45116 /min
21 Oct 2026, 02:00Entered in error, not shown
21 Oct 2026, 03:00108 /min
21 Oct 2026, 06:0098 /min
21 Oct 2026, 07:0096 /min

The same readings without maxGapMinutes

Only recorded gaps break the line. 03:00 to 06:00 is joined because nothing says a reading was missed.

Heart rate (/min)2 gaps, line not joined across. Shaded: reference range 51 to 90
507510012520:0023:0002:0005:00Not measured: Error: Probe off, no valid readingEntered in error, not shown
Readings (15)
TimeReading
20 Oct 2026, 18:0088 /min
20 Oct 2026, 19:0089 /min
20 Oct 2026, 20:0090 /min
20 Oct 2026, 21:0090 /min
20 Oct 2026, 22:00Not measured: Error: Probe off, no valid reading
20 Oct 2026, 23:0090 /min
20 Oct 2026, 23:30104 /min
21 Oct 2026, 00:00112 /min
21 Oct 2026, 00:20118 /min
21 Oct 2026, 01:00124 /min
21 Oct 2026, 01:45116 /min
21 Oct 2026, 02:00Entered in error, not shown
21 Oct 2026, 03:00108 /min
21 Oct 2026, 06:0098 /min
21 Oct 2026, 07:0096 /min

Props

PropTypeDescription
observationsObservation[]Observations of one vital sign, in any order. Required.
componentCode?stringPlot this LOINC component instead of valueQuantity, e.g. "8480-6" for systolic from a 85354-9 panel.
maxGapMinutes?numberBreak the line when two readings are further apart than this.
title?stringChart title. Defaults to the Observation code text.
timeZone?stringIANA time zone for displayed times, e.g. "Europe/Vienna". Defaults to the runtime zone; pass it when rendering on a server.
className?stringExtra classes for the outer element.

Clinical rules and sources

  1. A dataAbsentReason, a reading without a value, an entered-in-error reading and a cancelled one each break the line and are marked on the time axis.Source: FHIR R4: DataAbsentReason; FHIR R4: ObservationStatus
  2. Every point on the line is a recorded value. Values are never interpolated, smoothed or clamped; the axis covers all readings.
  3. A value with a comparator ("<", ">") is not exact and is shown as a gap, not plotted.Source: FHIR R4: Quantity.comparator
  4. Readings with different codes or different units are not plotted together and nothing is converted.Source: FHIR R4: Vital signs profiles
  5. The shaded band is the referenceRange of the most recent reading that has one.Source: FHIR R4: Observation.referenceRange
  6. A table of every reading and gap sits under the chart for screen readers and for checking.