The Chart is one of a trackable’s visualizations (Visualizations): its values a day over a period, one point or bar per day. It is drawn by TrackableChart (apps/renderer/src/components/charts/TrackableChart.tsx) on the shared day chart, DayChart, the same one a visualization of several draws its lines with (Editor for Several Trackables), and its days come from the shared series primitive, so a chart and a comparison never compute a trackable’s days two ways.

The chart a value type gets

chartKindFor (apps/renderer/src/lib/chart.ts) picks the chart from the value type and the trackable’s aggregation, how its day’s entries fold into one value:

valuechart
a number read as a level (Weight, read by its last or mean)a line over the days
a number that adds up (Water, Pushups, read by Sum or Count)a bar per day
an interval, or anything with an interval field (Sleep)a bar per day of its length, which adds up like a sum
a clock timea line, since a time of day is a level, never a total
an ordered scale (Mood)a stepped line with the option labels on the Y axis
an unordered scale, an enuma category timeline: a dot a day in the option’s colour
a yes/no, or anything read as Any (Exercised, Meditate’s “did it”)bars of its yes days, the axis in its own words; a heat strip of every day where chosen
a moment logged with no valuea line of its times when it reads a time of day, else a bar of how many
a record (Strength)no chart of its own; a small chart per number field, a day’s entries folded by Mean, Sum or Max (RecordFieldCharts), on its page, its card and in the editor alike, as an interval’s number fields are charted below its bars
a tagits members, one small chart each (below)
text, a referenceno chart; the Table shows its entries

A chart can set its own type, the chart visualization’s chart (VisualizationSpec in packages/core/src/value-schema.ts), chosen as Chart type in the editor’s settings: Auto, or one of the types the value can be drawn as (chartTypesFor). A number or a duration is a line or bars; a clock time only a line, because a bar runs up from midnight, which is not a quantity; an ordered scale only its stepped line, since anything else plots codes as amounts and loses the labels; a yes/no a heat strip or bars of its yes days; an unordered scale, text, a reference or a record none. The setting shows only where there is a choice beyond Auto, on the Chart tab. Auto is not stored, since it is the default. A stored type the value can no longer be drawn as, because the value type changed under it, is ignored and the default is drawn.

Which chart suits a single trackable is this note’s question. Which charts and statistics suit a selection of several, and why, is the editor’s (Editor for Several Trackables).

Days and the period

Every chart plots the daily value, the trackable’s entries for a day folded by its aggregation, or by the Reading the chart is read as. A planned entry after today is not yet a point. The period runs back from today: 7, 14, 30, 90 or 365 days, or every day, 30 by default; it is the chart visualization’s period, so its page and its Home card show the same days. The period chips on a trackable’s page look at other periods; which controls save is set out in Visualizations.

Units, ticks and zones

Values arrive converted to the display unit (the caller converts; the chart plots what it is given), and the unit is printed over the value axis, except for a duration, whose ticks name themselves. Ticks and the point readout are in the trackable’s own terms: an interval reads “7h 11m” on whole-hour ticks, a clock time “06:30”, an option its label, a number its value (scaleFormat, fmtDisplay). A scale’s axis runs over every option, retired ones included, because an entry logged against a retired option is still real and the axis has to reach it.

A trackable’s zones are drawn as bands behind the marks, in the display unit. A zone band answers to hover and pin like a point; how is in Inspect Without Leaving.

The left gutter fits the widest tick label. Tick labels are monospace at a fixed 9 px, so the room they need is arithmetic, characters × 9 px × 0.6, and axisGutter sizes the left margin to the widest label with no measuring pass. 40 px is the floor. 40% of the chart’s width is the ceiling, because option labels are typed by people and one long one must not eat the plot; past it, a label is cut with an ellipsis and keeps its full text in a <title>. An SVG label that overflows its margin is clipped rather than ellipsised, so without this a seven-letter option such as “Charged” would read as a different word, “harged”.

The stat header

A trackable’s page shows a stat header over its tabs for the open visualization’s days: Last, Mean, Min, Max, Sum (only where the trackable adds up, read by Sum or Count), Streak and Days. Each figure is formatted as the chart’s values are, so an option reads its label and an interval a duration. The Streak is the run of days with a value ending today or yesterday, carried across days on hold; a day of No, of 0, or of a choice’s none breaks it, and Mood’s Low does not (summarizeDays in packages/core/src/day-folds.ts).

The Mean is not a value, so it is not formatted as one (meanLabel in lib/labels.ts):

valueMean reads
a number, an intervalthe value, in its unit
an ordered scalethe nearest option’s label and the code average, “Low · 0.2”, since nothing on screen says the codes run 0 to 3
an unordered scalenothing: the cell is left out, because a code is an identity and its average means nothing
a yes/nothe share of days that were yes, “40%”, the mean of 0 and 1 as a rate

A chart axis is the other question: there a scale’s mean stays a number, because an axis is a magnitude and a label on it would be wrong. An axis wants 0.4 where a header wants 40%.

Derived trackables and tags

A derived trackable charts its computed daily series, and its Table says it is computed on read, with no stored entries, rather than showing an empty grid. A tag’s Chart is its members, one small chart each (SubtreeCharts), rather than one shared axis: a tag’s members are not chosen to be comparable, and Wellbeing holds scales, hours of sleep, free text and an enum, which no single axis can carry. Tags themselves are not plotted. Overlaying chosen series on one axis is the editor’s job, where choosing them is what makes the shared axis mean something.

Visualizations · Value Types · Presentation Layer · Editor for Several Trackables · Data Table · Calendar Drill-down