Sales & distribution
A demo dashboard, in the shape of the ones I build for sales and distribution.
What is real is how it is put together. The numbers behind every tile, chart and row come from one generated set of facts, and the build script refuses to write the data file unless the totals reconcile against it. The charts are hand-drawn SVG — no charting library, no build step, and the page makes no external network requests at all.
The comparison throughout is like-for-like: the current period runs January to October, so it is measured against January to October last year, not against a full twelve months. Getting that wrong is one of the most common ways a sales dashboard quietly flatters itself.
The headline
Monthly trend
Net sales value by month, current year against last.
- This year
- Last year
Show the figures as a table
| Month | This year | Last year | Change |
|---|
Top movers
Every product line, by change in net sales value against the same months last year.
Outlet coverage
How much of each trading company’s outlet universe was actually served.
| Trading company | Region | Outlets | Covered | Coverage | Change | Status |
|---|
How this page is built
Some of the decisions here are the point of the exercise, so they are worth stating plainly.
- One definition of “good”. A single function turns a percentage change into growing, steady or declining, with a dead band so a fraction of a percent is not painted as growth. The tiles, the mover bars and the table rows all ask that same function, so nothing on the page can disagree with anything else on it.
- Status is never only a colour. Each one is a word, a dot shape and a colour. It survives being printed in black and white, and it survives red-green colour blindness. The palette was checked against simulated protanopia, deuteranopia and tritanopia rather than eyeballed.
- The chart has a text alternative. Every figure in it is one disclosure away as a real table, and each month is reachable by keyboard. A chart that only exists as pixels is unreadable to a screen reader and unquotable to everyone else.
- No tooltip. Hovering, tapping or tabbing a month updates one line above the chart. The same behaviour for a mouse, a finger and a keyboard, and it cannot fall off the edge of a phone.
- No years in the data. The series are “this year” and “last year”. A static page cannot refresh itself, so a hard-coded year in a chart would start reading as stale data the moment it passed. The footer’s year is the site’s date, not the data’s.
- Numbers are set in a monospaced face so digits line up in a column and a figure does not jump sideways when it changes width.
- The phone view is not a second layout. It is this same page, in a container 390px wide, read by a container query instead of the window's own width. What sits inside the phone frame above is exactly what a phone gets — because it is the same markup, not a copy built to match it.
The page weighs almost nothing, loads one font file from this domain, and calls no third party. It does need JavaScript — the tiles, the chart, the movers and the coverage table are all drawn from the data file on load. Without it you get the writing and the notice that the data is invented, and nothing pretending to be a number.