Ten ways to show what people actually said.

A dashboard for qualitative research doesn't have to look like a Google Analytics report. Below: ten ideas — some rigorous, some editorial, some stolen from the trading floor or the philologist's index. All rendered against the real project-ikea data (42 quotes, 4 sessions, 7 sentiment types, 16 topics), now carrying triage verdicts.

Corpus 42 quotes
Sessions 4 (s1 healthcare · s2/s3/s4 IKEA beds & bedding)
Sentiments 8 satisfaction · 7 confusion · 6 frustration · 3 surprise · 3 delight · 1 confidence · 14 neutral
Range of intensity 28×● · 11×●● · 3×●●●
01 — hero chart

The study's pulse

SUPERSEDED → 02Emotion arrives quantised — sentence to sentence, gear to gear as topics shift. The continuous ridge interpolates feelings between quotes that nobody expressed. The tape (02) shows the same story without fabricating the in-betweens. Kept for reference.

Lineage: Joy Division's "Unknown Pleasures" cover · Wilke's ridgeline / joyplot · seismogram.

Emotional pulse across four interviews
y = quote intensity (1–3) · colour = sentiment · x = session-normalised time
s1
p1 · 4:22
s3
p3 · 4:06

Two of four sessions shown — enough to record why it lost: the smooth curve implies p1 passed through moderate feeling between the satisfaction plateau and the frustration ridge. They didn't. They changed topic.

02 — hero strip

Sentiment tape, with section boundaries

PROMOTED — the heroDiscrete ticks honour quantised emotion. Now with topic boundaries from topic_boundaries.json (real pipeline output, confidence 0.72–0.95).

Lineage: Bloomberg / Reuters trading tape · Wall-Street sentiment tickers · tube-map interchange bands.

Each quote is a tick: colour = sentiment, height = intensity. New in v2: section boundaries show where the participant moved — homepage to checkout, pre-surgery to aftercare. Two alignment treatments below solve the "boundaries vs ticks" overlap worry three ways: labels get their own lane (never in the tick field); hairlines render behind ticks, dashed and dim; narrow zones lose labels before they lose their lines.

Variant A — label lane above · Bristlenose · Project IKEA
s1
Pre-surgery info Aftercare Notifications
aftercare-frustration → △ delight
s2
Homepage Top nav Beds category
beds nav — confidence lost
s3
Homepage Browse PDP Browse Search Login Bag
mixed, resolves positive
s4
Intro Duvets & bedding Beds & sofa beds Checkout
late frustration at checkout
Variant B — topic band below (s3 shown for comparison)
s3
Homepage
Browse
PDP
Browse
Search
Login
Bag
tube-map band — same data
Own lane, never the field Labels live above (A) or below (B) the ticks — the tick field stays pure signal. No collision is possible by construction.
Hairlines behind, dashed, dim A tick landing exactly on a boundary is the normal case — boundaries are derived from speech, so the first quote of a zone sits on its line. Rendered behind the tick it reads as "first word on the new screen", which is true.
Narrow zones: line yes, label no s3's checkout zone is seconds wide. It keeps its hairline, loses its label (hover reveals in product). Lines are cheap; text is not.

Which variant? A for the dashboard hero — the strip stays clean and the label lane doubles as a skim-read of the journey. B for compact contexts (session cards, sidebar previews) — it's the same idiom as the existing coverage bar, and the band survives shrinking better than floating labels do.

03 — comparative panel

Kudos & kvetch — the order book

SHORTLISTCandidate replacement for the featured-quotes row: one kudos, one kvetch, maybe one neutral. Selection logic already exists — pick_featured_quotes() already scores and diversifies by polarity; this is a re-hang of the same picks, not new plumbing.

Lineage: Financial order books (bids left, asks right, spread in the middle). Recast as what worked vs what broke, sorted by intensity.

The single question every stakeholder asks — "is this working or not?" — has a shape. This makes the answer scannable in five seconds, both sides at their real weight.

KUDOS · what worked (11)
spread
KVETCH · what broke (13)
"I really like — you should be able to walk around with some pain, but take care not to lift. That is nice to actually say that."
s1 · pre-surgery notification · delight
±3
"There was no aftercare, the aftercare was quite poor."
s1 · post-surgery · frustration
"It works well for me. It's lovely. It's straightforward."
s1 · pre-surgery info · satisfaction
±2
"I rang the secretary asking to make an appointment, they said no. I went back to A&E about four times."
s1 · post-surgery · frustration
"Beds and mattresses. That's easy. That's in the top navigation."
s2 · top nav · confidence
±1
"Beds & mattresses. Beds… Has this gone slow because it's doing screen recording?"
s2 · beds category · confusion
"179. That's quite cheap."
s3 · beds browsing · surprise
±1
"Delivery. Hmm. Why is it £30? That seems a lot."
s4 · checkout · frustration
04

Ambivalence portraits

PARKEDAmbivalence is everywhere at fine grain — you hate the checkout pricing but love the checkout button, and different users voice each differently. Signal cards are designed to draw those distinctions out; a two-cell portrait over-aggregates what is really per-facet nuance. Theory stays interesting (Scharp 2021); the widget doesn't earn dashboard space.

Lineage: Scharp 2021, Thematic Co-occurrence Analysis (Journal of Communication).

Participant 1
Pre-surgery info vs post-surgery aftercare · s1 · 4:22
Praised (2× satisfaction · 1× delight)
"It works well for me. It's lovely. It's straightforward."
00:12 · pre-surgery info
Criticised (3× frustration)
"There was no aftercare. I went back to A&E about four times."
02:08 · post-surgery aftercare
One portrait kept as the record of why it parked: the split reads clean here only because s1's two topics happen to be far apart. At real grain the split multiplies per facet.
05 — rigorous grid · plus 5b, the compact remix

Thematic co-occurrence matrix

DISCUSS05 answers "where do participants agree?" 06 answers "which sections carry the strongest signal?" — see the comparison after 5b. One matrix on the dashboard seems right; the GitHub-grid remix below is the dashboard-scale candidate.

Lineage: Scharp (2021) — participants × themes matrix, cells encode × (present), + (emphatic exemplar), colour (positive/negative/both). Read along three continua: Sporadic ↔ Pervasive (columns), Unilateral ↔ Bilateral (cells), Unbalanced ↔ Balanced (rows).

participant · session Pre-surgery info Post-surgery aftercare Post-surgery notifications Top navigation Beds category Search results Login & app Shopping bag Duvets browsing Checkout & delivery
p1 · s1 ×⁺ ×⁺ ×⁺
p2 · s2 × ×
p3 · s3 × × × × ×
p4 · s4 × ×⁺ ×
Sporadic ↔ Pervasive
column · how many participants touch this theme
Beds category is pervasive (3 of 4). Post-surgery aftercare is sporadic (1 of 4) — but strong.
Unilateral ↔ Bilateral
cell · one sentiment or both
× Bilateral cells (top nav, beds cat, login) — same person, both feelings.
Unbalanced ↔ Balanced
row · does this participant see mostly one thing?
p1's row is unbalanced by topic. p4's is balanced. p3 is balanced with high variance.

Emphasis marker (⁺) = intensity-3 quote in that cell. Method after Scharp, K. (2021), Journal of Communication 71(4).

5b — the same axes, GitHub-contribution clothes
Pre-surgery
Aftercare
Notifications
Top nav
Beds browsing
Duvets
Product page
Search
Login / app
Bag
Checkout
p1
p2
p3
p4
Rows = participants, columns = sections, cell hue = dominant sentiment, cell depth = quote count. 11 of 16 sections shown.

The 05 / 06 / signal-cards triangle. These three matrices carry different questions:

05 asks "where do participants agree?" — consensus and coverage. Its empty cells are information (who didn't hit checkout?). Nothing in the product answers this today.

06 asks "where is the negative signal densest?" — which is adjacent to what signal cards already compute in the analysis lens (concentration per label|sentiment cell). Shipping 06 on the dashboard would duplicate analysis.

So the dashboard slot goes to 05's axes, at 5b's scale. The GitHub grid reads Scharp's continua at a glance: a filled column is pervasive (Beds browsing — 3 of 4 rows, three different hues: everyone went, nobody agrees); a lone saturated cell is sporadic-but-strong (Aftercare, one row, full red); a split column is live disagreement (Checkout: p3 green, p4 red). Click through to the analysis lens for the full-fat version. Compare docs/mockups/mini-heatmaps-dashboard.html — the earlier GitHub-grid experiment this remixes.

06 — where the pain is

Friction heatmap

DISCUSSPairs with 05 — see the triangle discussion there. Strong chart, but its question ("where is negative signal densest?") is signal-cards territory in the analysis lens. If it ships, it ships there — not as a second dashboard matrix.

Lineage: Sports analytics — soccer xG heatmaps, shot-density charts. Topics × sessions, cell heat = negative-sentiment density.

Topic / screen
s1 healthcare
s2 beds
s3 beds
s4 duvets
Post-surgery aftercare
31 str.
Top navigation
1
Beds category page
2
2
0
Login / app
1
Shopping bag
1
Checkout & delivery
0
1

Cell = count of frustration + confusion + doubt quotes on that topic in that session. "str." marks an intensity-3 quote. Reading: beds category is spread across three sessions (product problem); aftercare is one participant, one session, maximum heat (single-voice, still a finding).

07 — dense

Session small multiples

OPENNo verdict yet. The chronology column overlaps with 02's tape; if 02 ships, this row likely slims to donut + intensity + topics.

Lineage: Tufte, The Visual Display of Quantitative Information. Bertin, Semiology of Graphics. Same thumbnail per session, compared at a glance.

SESSION
SENTIMENT MIX
INTENSITY LADDER
CHRONOLOGY
TOPIC SPREAD
s1 p1 · 4:22 10 quotes · healthcare
2● 3● 1● + 4○
peak intensity 3× (frust ×2, delight)
pos → neg → pos arc
3 topics · aftercare heavy
s3 p3 · 4:06 14 quotes · IKEA beds
3● 4● 2● 1● + 4○
shallow but many · 1 spike
confusion → satisfaction
7 topics · widest spread

Two of four rows shown (s1, s3 — the two long sessions).

08 — the front page

Hero quote — "quote of the study"

SHORTLISTThe poster frame — open the study and go "oh yeah, that one." Selection already ships: pick_featured_quotes() (export_core.py) filters to 12–33 words, scores intensity + sentiment + researcher-context, then diversifies across participants and polarities. This idea is the presentation upgrade: rank 1 gets the editorial treatment, runners-up stay small.

Lineage: New Yorker pull quote, FT Weekend leader. One quote, big serif type, air around it. Designed to be screenshotted into a stakeholder deck.

Quote of the study — p1 · s1 · 03:43
That is nice to actually say that, to send that to someone. I think that's really nice.
Participant 1 · post-surgery notifications · intensity ●●● delight · s1 @ 03:43
RUNNER-UP · frustration ●●●
"There was no aftercare, the aftercare was quite poor."
RUNNER-UP · surprise ●●
"179. That's quite cheap."
RUNNER-UP · confidence ●
"Beds and mattresses. That's easy. That's in the top navigation."
09 — the philologist's index

Study fingerprint + KWIC concordance

PURSUEThe word-strip is now the lead: real frequencies from the 42 quotes, each chip carrying a sentiment-mix underline. Twelve words in, you know what kind of study this is — that's the fingerprint. Click a chip, get the concordance.

Lineage: Key-Word-In-Context — philology's standard tool since the 1950s (Voyant, AntConc); classical concordances. Word clouds are decorative; concordances are readable evidence.

Every count below is real. The payoff word is back — 7 uses, frustration-leaning: "went back to my GP", "back to A&E", "referred back". The retry word. A researcher sees the red-tinted underline and clicks; the concordance shows the loop the participant was stuck in. Type size follows frequency; the underline splits by the sentiment mix of quotes containing the word.

okay15 bed12 shopping10 ikea8 beds8 bag8 surgery7 back7 read5 enough5 see5 easy2
s1·p1
…I felt that it wasn't healing … I went
back
to my GP and then they referred me back to North Mid…
aftercare
s1·p1
…and I said no, can I go
back
to another hospital? So I did.
aftercare
s1·p1
…they must be better than North London Hospital. So I just went
back
there.
aftercare
s1·p1
I went
back
to A&E and I showed them my stomach… I went to A&E about four times.
aftercare

Reading the pattern: four of seven uses of "back" are one participant re-entering a system that discharged them. The word itself is the journey map. This is what a concordance does that a word cloud cannot: it keeps the grammar, and the grammar is the finding.

10 — the methods reflex

Saturation curves — topics vs themes

DEVELOPNow two curves. Raw topic labels barely repeat across sessions (every topic in this corpus is session-unique), so a topic-level curve over-reads novelty. The honest curve saturates on clustered themes. Verdict logic: 0 new themes across the 2 most recent sessions → saturated.

Lineage: Glaser & Strauss (1967), grounded theory. Guest, Bunce & Johnson (2006), How many interviews are enough? The chart every methods reviewer wants and no commercial competitor ships.

20 15 10 5 0 cumulative count topics still climbing — +4 in s4 alone themes flat since s3 s1 s2 s3 s4 +3 · +2 +2 · +1 +7 · +1 +4 · +0 sessions processed · deltas: topics · themes
raw topic labels (naive novelty) clustered themes (honest saturation)
Themes saturated; topics still novel.

No new theme since s3 — the pattern has stabilised. New sessions are adding colour, not categories.

Recommendation: 1–2 more sessions to confirm; expect theme count to hold at 4.

Verdict states: Not yet (curve steepening) · Approaching (last session added ≤1) · Saturated (0 new across last 2 sessions).

Topic counts are ground truth (3 → 5 → 12 → 16 cumulative). Theme-per-session attribution is approximated for the mockup; the real implementation keys on theme-cluster membership, which the pipeline already computes at s11.