A visualization is kept as the question, not the answer: a declarative spec of what it reads, how it transforms it and how it draws it, stored as a row and drawn again from the entries every time it is opened. That is what turns a one-off look into something you keep coming back to: “Weight vs Water”, built once, is current every time it is opened, and changing it never changes what was logged. A kept visualization is not a different kind of thing from one being edited, which is why there is no separate term for it; this note is titled for the mechanism.
The row
Every visualization is a row of one table, view in SQLite and visualization in the Drizzle schema (packages/core/src/schema.ts): a name, an opaque JSON spec, pinned (on Home as a card of its own), an optional trackable_id and a sort_order. The table knows nothing of the spec’s shape, so a new chart or a new transform never costs a migration.
| a trackable’s tab | a visualization of several | |
|---|---|---|
trackable_id | the trackable | none |
| spec | VisualizationSpec (packages/core/src/value-schema.ts), owned by core | SeriesSpec (apps/renderer/src/hooks/useVisualizations.ts), owned by the renderer |
| read and written by | TrackableVisualizationRepository (trackable-visualization-repository.ts), through the trackable | VisualizationRepository (visualization-repository.ts): list, listPinned, getById, create, update, setPinned, remove |
| order | sort_order, the trackable’s tab order | newest first |
A trackable’s tabs travel with the trackable. The repository attaches them on read as Trackable.visualizations, and a trackable payload’s visualizations writes them, in order; a payload that leaves them out keeps them. A kind the trackable already has keeps its row, so the row’s id holds still for sync, and a kind no longer listed is deleted. They are deleted before their trackable is, since SQLite cannot add a cascade to a column added later, so a trackable’s visualizations go where it goes: deleted, exported and synced with it. What a VisualizationSpec holds is set out in Visualizations.
A visualization of several is a SeriesSpec, version v: 1:
| field | holds |
|---|---|
series | each series’ dotted id, a trackable, a Reading, a record field by its reduce or a text read for a word (see Editor for Several Trackables) |
viz | the chart: scatter, line, matrix, distribution, grouped, histogram, heatmap or timeline |
smooth, lag | the 7-day mean, and the days the second series is shifted |
controls | the series held constant for a partial correlation |
bucket | weekday or month, for a grouping by time |
period, periodFold | days grouped into weeks or months, and how their days fold |
dropStopwords, skipOnHold | common words kept, days on hold left out |
shownOn | the trackables it is a tab on |
colors | a series’ own colour, by series id |
Optional keys are left out at their default, so a spec stays small and readable. A series refers to a trackable by its stable id, so renaming a trackable changes nothing; an id that no longer resolves drops out of the series, so a deleted trackable leaves the visualization drawing what remains rather than failing.
Keeping one
The editor’s Save writes the visualization of several it was opened from; Save as new makes another, named for what it shows rather than for the one it came from, since two under one name read as a duplicate. A new one’s first Save opens what it saved, so its next Save updates it, and a toast says which happened (“Saved”, “Saved as”). Opening a saved one restores the editor field for field from its spec and its row’s pinned, once, so later edits are not undone. A trackable’s tab is saved from the editor’s one-trackable panes with the trackable itself.
Where one shows is part of what is saved. Shown on ticks Home, the row’s pinned, and each trackable the series read, its shownOn; a trackable it no longer reads is dropped from shownOn on Save. On a trackable it is a tab after the trackable’s own (placedOn), as long as one of its series still reads that trackable. Pinned, it is a card on Home.
Drawing one
SeriesVisualization (apps/renderer/src/components/series/SeriesVisualization.tsx) draws a visualization of several from its spec wherever it shows: the list at /visualizations, a Home card and a trackable’s tab. It resolves the series again and reads the selection and its chart data through the same seriesSelection and chartDataOf the editor uses, so a spec means one thing in both places, a text read for a word included. It draws the chart the editor opens on: a saved chart the selection no longer offers draws the one effViz clamps it to. It draws the chart and not the statistics: a card has no significance verdict, and controls is kept but no partial correlation shows outside the editor. What is kept is the chart’s question; the reading of it is the editor’s.
The list at /visualizations shows each one drawn, with its title linking to the editor, a Pin to Home toggle, and Delete, which asks first, because a deleted visualization has no undo and goes from every trackable and from Home. New visualization opens an empty editor. A name is set when a visualization is first saved and is not edited afterwards.
Nothing computed is stored, here or anywhere: a spec is re-run against the entries as they are.
Related
Editor for Several Trackables · Visualizations · Home · Data Model · Synced Databases