cassionData Analysis

Lesson 8 of 8

Unit · The room

Seven dashboards, and what each one refuses to show

Eight kilobytes, no JavaScript, no external request, byte-identical on rebuild. Each of the seven states the decision it informs and ends by naming what it does not show — and one of them found an error in this platform's own teaching.

PythonR135 minOECD DAC evaluation criteriaCore Humanitarian Standard (CHS)UNICEF indicator definitionsSphere StandardsIntegrated Food Security Phase Classification (IPC)

What is actually shipped

pnpm project:dashboards
ls apps/data-analysis/public/projects/*/dashboard/

Seven projects, two languages, fourteen files, about 8 kB each. Static HTML built from committed CSVs, with the project’s committed SVG figure inlined.

No JavaScript, no external request, no generation date. Rebuilding on unchanged data produces byte-identical files, which is the property that makes a diff mean something.

The four constraints that decided the design

The audience works offline and on metered connections. That removed anything needing a live server or a CDN before any other consideration.

The Content-Security-Policy forbids inline script bodies. script-src has no 'unsafe-inline', so a script in a static file under public/ is refused by the browser — silently, which is the failure the slide reader shipped once. Inline styles are allowed, and tiles, tables and a figure need nothing else.

The deploy has no Python, no TeX and no pandoc. Rendering the project notebook would need Quarto, Python, pandas and a network fetch. The builder reads the CSV directly in bare Node instead, so pnpm project:dashboards runs anywhere pnpm does.

The output has to be reviewable. No clock, no build stamp, no generated identifier — so the page is a function of the data and the project entry.

Three of those four are constraints rather than preferences, and the design is what is left once they are respected. That is usually how a good constraint feels from the inside.

What each one is for, and what it refuses

Project Decision Refuses
WASH coverage Which six communities get rehabilitation Unweighted proportions from a clustered survey; the district column normalised from six spellings
Nutrition screening Where the next round goes The commune ranking beyond the three highlighted; screening is not a survey
Protection pathway Which gate to fix first Four-way disaggregation — nineteen cells of one
Food security Which instrument the caseload rests on Averaging the four prevalences; none is an IPC classification
School attendance Which schools need a response Counting the strike period as absence; any causal claim about feeding
SMART survey Whether a prevalence is publishable The prevalence itself, until quality control passes
Vaccination Whether coverage is service or denominator Months with no report drawn as zero

The refusal column is the one to read first. It is the section each page ends with, and it took longer to write than the numbers.

The SMART row is the strongest of the seven. The dashboard for a nutrition survey declines to show the prevalence, because one team’s mean sits beyond the SMART concern threshold and quality control has to pass before a prevalence is publishable. A dashboard whose main number is withheld, with the reason, is doing its job.

The one that found an error

Building the WASH dashboard meant computing improved water coverage from the same file the project’s indicator documentation used. They disagreed: 82.3% in the documentation, 79.7% in the dashboard, the lesson and the figure.

The documentation was right. The JMP improved list includes packaged or delivered water — tanker-truck here — and the course had omitted it, in a course that names the JMP ladder and SDG 6.1.1 explicitly.

Nothing else would have found it. The lesson was internally consistent, the figure used the same set so it agreed, the tests passed, and 79.7% is a plausible number. It surfaced because a second artefact computed the same indicator and was compared.

That is the argument for a definition panel, made by a failure rather than by assertion, and it is why the correction ships with a change-log entry and an assertion in the pipeline rather than only a fix.

What these dashboards do not do

Being honest about the gaps, as the workflows course insisted.

No interactivity. A reader cannot filter, drill or re-slice. Everything beyond the one question is a link to the notebook or the CSV. For an audience on a metered connection that is the right bargain and it is still a bargain.

No live refresh. The page is rebuilt when the data is, by a script somebody runs. A monthly programme dashboard would need that script on a schedule, and this platform’s data does not change.

No access control. They are public static files, which is fine because every dataset here is synthetic — and would not be fine for a protection caseload. A real deployment of this pattern needs to answer the access question before the first file is written.

No accessibility audit. They are semantic HTML with a documented reading order and they have not been tested with a screen reader, which is a gap rather than a claim.

The pattern, portable

Five properties, and any tool can have them.

One file per audience-question, not per data source.

Every number computed by a script from a versioned file, with nothing typed.

Provenance and definitions on the page, not in a separate document nobody opens.

A section naming what the page does not show, written before the page is considered finished.

Deterministic output, so “is this current?” is a question the version control system answers.

Report it whole

Project dashboards

  Seven projects, two languages, 14 files, ~8 kB each. Static HTML built by
  scripts/export/build-project-dashboards.mjs from the committed dataset
  files, with each project's committed SVG figure inlined.

  No JavaScript (the CSP forbids inline script bodies), no external request,
  no generation date. Rebuilding on unchanged data is byte-identical.

  Each page states the decision it informs and ends with what it does not
  show. dashboard.ready is true on all seven projects and
  project-files.test.ts fails if a declared file is missing.

  Not done: no interactivity, no scheduled refresh, no access control, no
  screen-reader audit.

The last line is the one to copy. A dashboard section without a “not done” is a section nobody has audited.

What comes next

That is the course, and it is the last one in the programme’s spine.

Twenty-one courses and one argument. A number in a programme report is a claim, and everything here is about what has to be true for the claim to hold: a denominator you can defend, an interval that says how sure you are, a comparison group that is one, a design that could have detected what matters, a chart that does not say more than the data, a pipeline that produces the same answer when somebody else runs it — and, finally, a page and a report that put all of that in front of the person who has to decide.

The last step is the one the others are for. An analysis that never reaches a decision is an analysis that did not happen, and this audience is judged on defending a number in a review rather than on producing it.

Teach this lesson

The lesson as a slide deck, with the prose kept in the speaker notes rather than on the slide. Generated from this page, so it cannot fall out of step with it.

Start the slideshowRead the slides

The PDF needs no software and projects from any machine. The PowerPoint file is there to be edited — add your organisation's branding, cut a section for a shorter session, or merge two lessons into a workshop.