A dashboard is a saved document
Canvases
A canvas is a named collection of visuals over one or more datasets, laid
out on a grid and saved as a document. Opening /a/:id
re-renders every card against the files as they are today, so a canvas is a
question rather than a snapshot.
What a card can be
Anything a chart page can draw can be a card: a table, a bar, pie, line,
scatter, heatmap, stacked, combo, treemap or histogram, a map, or a word
cloud. A card added to a filtered or parameterised canvas is drawn through
that same state, so it lands on screen already narrowed like its neighbours.
A card can also be your own words: a title, an explanation
or a label.
Layout
A 12-column grid
Every card has an x, y, w and
h on a grid twelve columns wide. A card spans at most six
rows, and x + w - 1 cannot exceed twelve. Positions are
stored as given — a gap is a gap — and two cards may not share
a cell.
Layout
Drag, or use the keyboard
Drag a card by its header to any free cell, or focus the header and use
the arrow keys, with Shift going to the edge. Each move is announced:
the column and row the card landed in, and any card the move pushed
down. The position is saved as you go.
Layout
Sizes without a drag
A card's Size menu sets full, half, a third or a quarter of the width,
and one, two, three or six rows high. The size the card currently is
sits on the card itself, beside the menu, so a width left by the corner
grip reads without opening anything.
Adding
Add current view
The toolbar appends another table, chart or map without leaving the
canvas, and a status region announces the card and the new count. When a
card's script has drawn, the region says so — and if D3 or Leaflet
could not be loaded, it names the missing library instead of failing
silently.
Titles and explanations
Add text in the toolbar puts a card of plain text on the
canvas. It reads no data, so a filter or a time range leaves its words alone,
and it moves and resizes like any other card.
Text
How it looks
Each card has its own font (the page's, Arial, Georgia, Times New Roman,
Verdana, Trebuchet MS or Courier New), a size from 8 to 96 points, an
alignment, bold and italic, a text colour and a background. The fonts are
ones browsers already have, so a canvas loads nothing extra for them.
Text
A heading, not a box
A card can hide its frame and header until it is pointed at or has
keyboard focus, so a title reads as a heading. On a printed or
shared canvas the header stays hidden.
Text
Rows that fit
A new card starts full width. A row holding only one-row text cards is as
tall as its text, rather than the usual 15rem. Beside a chart, the card is
as tall as the chart, and a text card two rows high or more keeps full
rows, so the Size menu is how to ask for a taller one.
Text
Editing and removing
Double-click the text, or use Edit text in its header. The
card shows each change as it is made, and Cancel or Escape puts it back.
Remove card is in the same panel. Undo and redo cover the
canvas's filters, not its cards, so removing one cannot be undone.
Text is plain text: HTML tags and Markdown show as the characters typed. A
colour left unset follows the light or dark
theme. A chosen colour stays the same in
both, so give it a background it can be read against. Text cards have no
chart or data to save, so they carry no download buttons; they appear in the
printed canvas. They are also the only cards that can be removed.
A card picks its own measure
A card that shows an aggregated value chooses the function in its own panel,
from the vocabulary the pivot uses and with the same names: Sum, Average,
Min, Max, Count distinct, Median, Std dev, First, Last, Range, or a percentile
with its level. That is what lets one card show a median where the chart page
it came from could only sum. A card's derived title says which function it
used — median(amount) by region — while a plain sum
keeps the title it has always had.
Cross-filtering
Cards share the page. Clicking a mark cross-filters the canvas to the value
behind it, and the card that was clicked is marked as the source rather than
narrowed by its own click. The remaining cards re-render against the narrowed
rows, each through its own filters, the page's cross-filter and its own
options — which is why a word cloud card narrowed to one region shows the
words of that region.
The source is drawn as the source, not as a card that failed to narrow, so a
reader can always see which mark the page is answering. A page-wide relative
time range narrows every card, the source included, because it is the page's
range rather than a card's click.
Drill-through
A canvas can carry drill hierarchies: ?dd=<column>&dl=<level>
opens a card at a deeper level of the hierarchy, with the cards around it
still showing the level the reader is looking at. A visit that filters the
data — a cross-filter or a drill path — leaves the arrangement
alone: the card you put in row four stays in row four.
Parameters
A visual's fields can be bound to named parameters, overridden per visit with
?p.<name>=<value>. A bookmark that carries
p.region=North is one URL, and the same canvas answers the same
question for a different reader by changing that one value.
Per-card cross-row plans
The page's cross-row plan applies to every card unless a card brings one of
its own. That is what lets one card show a running total while the cards
beside it show raw rows, and a card with an empty plan
({ "cs": [] }) runs no cross-row pass at all — which is how
a card opts out of the page's.
The plan is checked against the canvas's columns on every render, not only
when it is saved, so a stored plan that no longer names a column is that
card's error, while a bad page-level plan is the page's 400.
Bookmarks and undo
Bookmarks record the canvas's state, including parameters, and undo and redo
step through them. Because the state lives in the URL as well as in the
document, a bookmark is a link that can be sent; because the range inside it
is relative, the link still means the same thing when it is opened next month.
Sharing and embedding
/a/:id
- The canvas itself, with cross-filter, drill, parameter and range parameters.
/share/:id
- A share link, signed with an HMAC-SHA256 token, for handing a canvas to someone who should not need an account. The canvas toolbar's Share… panel makes one, valid for 30 days.
/embed/:id
- A page with no navigation, for putting the canvas inside another page; the Share panel gives its
<iframe> code. It is sent with X-Frame-Options: SAMEORIGIN, so only pages served from the same site can frame it. Each card is drawn through its own failure: one card that cannot be drawn says so and leaves the others. It stays in the light colours, because it sits on a page whose colours it cannot know.
/catalog
- Every saved canvas in one place, as cards that open.
Exporting from a canvas
Each card can save itself whole — SVG, PNG or a one-page PDF — including
the parts that hang outside the viewBox, such as rotated axis labels. A pie's
HTML legend is drawn into the saved copy, and a map or table card keeps the
image buttons hidden because there is no chart to save. A card's data can
also be downloaded as CSV, from the canvas's own rows rather than from any
other source. The whole canvas prints to paper or PDF. Saved cards and printed
canvases use the light colours, whichever theme
the reader has chosen.
The canvas itself can be kept as a file: the Share panel's Download as
JSON saves it, and Import canvas on the Canvases page (/canvases, the
main navigation's Canvases link) makes a new canvas
from that file, on this server or another.
Canvases live in analyses.json under the model directory, not
in a database. The JSON API can list, create, patch, import and export them,
and can append a visual without a browser — see
the visuals endpoint.
Where the numbers come from
A canvas stores datasets, joins, calculated fields and visuals, not rows. Each
card runs the same pipeline as the page it was saved from
(Data describes the stages), which is why a canvas
over a file that changed overnight shows this morning's figures, and why the
same canvas can be narrowed by a range without storing the dates it resolved
to.