views beyond river and grid
The useful pivot isn't "which other views" — it's noticing that every view you have or want is one function: position = f(block). That reframing prices the whole roadmap, because it says you are not building N views; you are building axis bindings for one renderer.
| view | x | y | needs from the block |
|---|---|---|---|
| river | — | order key | nothing — works on any set |
| grid | manual | manual | nothing, but stores position outside the data |
| table | key names | order key | shared keys |
| board | one key's values | order within column | one key, few distinct values |
| timeline | a date key | lane / stack | a date — every block has one |
| chart | a date key | a numeric key, reduced | date + number + your aggregation |
Grid is the odd one out: it's the only view whose position isn't derived from the block. Every alternative below is more attractive precisely because its layout means something.
1 · Board — the one I'd build first pick
Group by a single key; each distinct value is a column; the card's column is the value. Attractive for one reason that nothing else on this list can claim: it writes. Dragging a card from next to doing sets status=doing. It's the grid's drag gesture, except the position is data instead of decoration — which is exactly the objection you raised against a free canvas.
Why it fits your model better than a table: it needs exactly one key to exist, not a whole shared key space, so it works on day one with the metadata you already have. It also degrades gracefully — a key with 30 distinct values just gives you 30 columns and you learn not to board on that key. And board:tag is free: columns are tags, dragging re-tags. That's a genuinely new capability, not a redraw.
2 · Timeline — the one that needs nothing pick
The table's weakness is that it dies on sparse metadata. Time has no such problem: every block already has a date (created, plus when/due/logbook entries when present). A timeline is therefore the only alternative view that works on any set, including Home — the same universality that makes river safe.
Two things make this worth more than a sorted river: gaps are visible (wed 12 is empty, and that's information — the river silently closes up), and past and future share one axis, so retrospection and agenda stop being two features. It's also where your :LOGBOOK: durations finally render as what they are: spans, not a drawer count. Month Lenses is this view zoomed out — same binding, coarser grain.
3 · Chart — nearly free once aggregation exists cheap
Not a rival view so much as the natural drawing of the thing you just built. If a lens can already reduce kcal by day, the only missing part is rendering the series as bars instead of rows. Same query, same reducers, ~zero new model.
Keep it deliberately poor: one series, bars or a line, no legends, no dual axes, no colours beyond the accent. A charting library here would be the first thing in LifeLab that doesn't look like a terminal buffer. The sparkline is the inline degenerate case — same series, 11px tall, in a river row or a table cell (and probably explains the sparkline that keeps appearing uninvited in your TODO list).
4 · Gallery — small, cheap, only if doodles land later
Blocks whose payload is visual are the one case where the river's text-first row actively hides the content. A gallery is ~40 lines: thumbnail + date caption, click opens the block.
But it's strictly downstream of #+begin_draw and image blocks — until those exist there's nothing to show, and it earns nothing on a text corpus.
5 · The trap: graph view no
It's the most requested and the least used. Concretely, for LifeLab: a force graph of blocks-and-links has no stable position (so no muscle memory), no readable labels past ~50 nodes, and it answers a question you can already answer better — "what touches this?" — which is the LINKED section. If you want the honest 90%, build the neighbourhood: one block, one hop, as a small list of incoming and outgoing with the relation named. That's a panel, not a view, and it's useful every day rather than twice.
Same verdict on map and tag-hierarchy tree: map waits until a location key actually exists (mobile capture), and the tag tree is the pages browser you already have.
6 · How I'd sequence it
| # | view | why now | cost |
|---|---|---|---|
| 0 | fix grid | shares the projection plumbing everything below reuses | — |
| 1 | board:key | only view that writes; needs one key, not a schema; re-tagging by drag is new capability | medium |
| 2 | timeline | works on every set with zero metadata; unifies retrospection and agenda; renders logbook spans | medium |
| 3 | table | the entry surface for macros-style data; wants grain + coverage from §8 of the other doc | medium |
| 4 | chart / sparkline | aggregation already computes it; drawing only | small |
| 5 | gallery | after draw/image blocks | small |
All five are {view} words in a lens line with an axis argument — board:status, timeline:when, chart:kcal:sum, table cols:…. One grammar, one renderer, one place where "which blocks" is decided. If a view can't be expressed as an axis binding over a lens result, that's the signal it's a different feature wearing a view's clothes.
7 · Open
- Board on an unset key: is the "no status" column always shown, or opt-in? (I'd always show it — it's the only way you notice unlabelled work.)
- Timeline of what date? Default to
whenif present elsecreated, or make the axis explicit every time? Implicit is friendlier, explicit is honest. - Does a view belong to a tag? :meal: always wants a table, :draw: always a gallery. That's a tag remembering a presentation — real change to what a tag is, same open question as the table doc.
- Is grid worth keeping once board and timeline exist? Its remaining unique job is spatial thinking during composition — which may really be the doodle canvas's job.