---
title: "Interactive Dashboards"
subtitle: "Self-contained HTML dashboards for the sample datasets"
description: "Five browser-only dashboards: a paired pre/post BP trial with ANCOVA, a random-effects PUFA meta-analysis with forest plot, a 70-store retail uptime monitor, a live S-value adoption tracker driven by the OpenAlex API, and a live Lighthouse audit of the site driven by the Google PageSpeed Insights API. No server, no R, no Python — all data and interactivity inline."
author: "Zad Rafi"
date: 2026-04-28
date-modified: 2026-04-28
toc: true
toc-depth: 2
toc-location: right
keywords:
- statistical dashboard
- meta-analysis forest plot
- ANCOVA
- retail uptime
- S-value
- surprisal
- OpenAlex
- bibliometrics
- Chart.js
- reproducible analysis
categories: [statistics]
image: "images/HomeLogo-static.png"
image-alt: "Three interactive statistical dashboards: blood pressure trial, PUFA meta-analysis, and retail uptime"
open-graph:
type: article
twitter-card:
card-style: summary_large_image
format:
html:
include-in-header:
text: |
<link rel="canonical" href="https://lesslikely.com/dashboards.html">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "CollectionPage",
"name": "Interactive Statistical Dashboards",
"url": "https://lesslikely.com/dashboards.html",
"description": "Self-contained, browser-only statistical dashboards covering a randomized BP trial, a PUFA meta-analysis, retail store uptime, and live bibliometric adoption of the S-value transform via OpenAlex.",
"isPartOf": {
"@type": "WebSite",
"name": "Less Likely",
"url": "https://lesslikely.com"
},
"author": {
"@type": "Person",
"name": "Zad Rafi",
"url": "https://lesslikely.com/about.html",
"sameAs": [
"https://orcid.org/0000-0003-1545-8199",
"https://twitter.com/dailyzad",
"https://github.com/zadrafi"
]
},
"hasPart": [
{
"@type": "WebApplication",
"name": "Diastolic blood pressure trial dashboard",
"applicationCategory": "Statistical analysis",
"url": "https://lesslikely.com/dashboards/bp.html",
"operatingSystem": "Any (browser)",
"offers": {"@type": "Offer", "price": "0"}
},
{
"@type": "WebApplication",
"name": "PUFA meta-analysis forest plot",
"applicationCategory": "Statistical analysis",
"url": "https://lesslikely.com/dashboards/pufa.html",
"operatingSystem": "Any (browser)",
"offers": {"@type": "Offer", "price": "0"}
},
{
"@type": "WebApplication",
"name": "Atlantis Fresh Market store uptime",
"applicationCategory": "Operational analytics",
"url": "https://lesslikely.com/dashboards/downtime.html",
"operatingSystem": "Any (browser)",
"offers": {"@type": "Offer", "price": "0"}
},
{
"@type": "WebApplication",
"name": "S-value adoption tracker",
"applicationCategory": "Bibliometrics",
"url": "https://lesslikely.com/dashboards/svalues.html",
"operatingSystem": "Any (browser)",
"offers": {"@type": "Offer", "price": "0"}
},
{
"@type": "WebApplication",
"name": "PageSpeed / Lighthouse tracker",
"applicationCategory": "Web performance",
"url": "https://lesslikely.com/dashboards/pagespeed.html",
"operatingSystem": "Any (browser)",
"offers": {"@type": "Offer", "price": "0"}
}
]
}
</script>
---
::: abstract
Five single-file HTML dashboards. Three are built on top of the [sample datasets] and embed their own data; the other two query live APIs — the [OpenAlex] bibliometric API and the [Google PageSpeed Insights] (Lighthouse) API. Each one runs entirely in the browser — no Python, no R, no backend. Filters, sorting, and chart updates are all client-side. Refreshing one of the static dashboards with new data means editing the `const DATA = {...}` blob near the top of one `<script>` tag. Results: a two-arm BP trial of 39 subjects (between-group mean difference −10.46 mmHg, 95% CI −12.23 to −8.69), a six-trial PUFA meta-analysis (pooled RR 0.875, 95% CI 0.764 to 1.001, I² = 16%), seven days of operational data across 70 stores (aggregate uptime 88.2%), a live count of papers citing and reporting the S-value / surprisal transform, and a live Lighthouse audit of the site itself — Core Web Vitals, category scores, and field data on demand.
:::
[sample datasets]: datasets.qmd
[OpenAlex]: https://openalex.org
[Google PageSpeed Insights]: https://developers.google.com/speed/docs/insights/v5/get-started
## At a glance
| Dashboard | Method | n | Headline result | Open |
|---------------|---------------|---------------|---------------|---------------|
| **BP trial** | Paired pre/post + Welch + ANCOVA | 39 subjects | Mean diff −10.46 mmHg \[95% CI −12.23, −8.69\], *p* \< 0.0001 | [↗] |
| **PUFA meta-analysis** | DerSimonian–Laird random-effects | 6 trials | Pooled RR 0.875 \[0.764, 1.001\], I² = 16% | [↗][1] |
| **Atlantis store uptime** | Online ÷ (Online + Offline) minutes | 70 stores × 7 days | Aggregate uptime 88.2% across 5 regions | [↗][2] |
| **S-value adoption** | Live OpenAlex citation + full-text query | 3 seed papers | Cited and reported counts updated on page load | [↗][3] |
| **PageSpeed / Lighthouse** | Live Google PageSpeed Insights (Lighthouse) audit | 8 site pages | Category scores, lab Core Web Vitals & field data on demand | [↗][4] |
[↗]: dashboards/bp.html {target="_blank" rel="noopener"}
[1]: dashboards/pufa.html {target="_blank" rel="noopener"}
[2]: dashboards/downtime.html {target="_blank" rel="noopener"}
[3]: dashboards/svalues.html {target="_blank" rel="noopener"}
[4]: dashboards/pagespeed.html {target="_blank" rel="noopener"}
::: column-margin
The three static dashboards together total \~140 KB of HTML+JS plus one shared CDN load of Chart.js v4; the S-value and PageSpeed trackers each add another self-contained file that fetches its data live (from OpenAlex and the Google PageSpeed Insights API, respectively). All five embed cleanly into this page with sandboxed iframes; nothing here loads from your origin until you scroll to it.
:::
------------------------------------------------------------------------
## Diastolic blood pressure trial {#bp-trial}
A two-arm trial of *n* = 39 subjects (Group A *n* = 20, Group B *n* = 19) with paired baseline and post-treatment diastolic blood pressure (DBP), age, and sex.
**What's in the dashboard**
- Six KPI cards (sample size, per-group mean change, between-group difference, effect size, *p*-value)
- Paired pre → post chart, one line per subject
- Distribution of DBP change by group
- Subgroup forest plot by group × sex
- Hypothesis-test panel with paired *t*-test, Welch's *t*-test on changes, and ANCOVA-adjusted effect — all with 95% CIs and Cohen's *d~z~* / Hedges' *g*
- Sortable subject-level table
::: callout-note
The between-group effect size (Hedges' *g* ≈ −3.75) is implausibly large for a real antihypertensive trial — within-group variance is unusually compressed. Useful as a worked teaching example, but worth flagging if cited as evidence of effect magnitude.
:::
:::: {.dashboard-embed .aspect-tall data-url="https://lesslikely.com/dashboards/bp.html"}
::: dashboard-embed-toolbar
[BP TRIAL — INTERACTIVE]{.title} [[Open full screen ↗] · [Download bp.csv]{download}]{.actions}
:::
```{=html}
<iframe
src="dashboards/bp.html"
title="Diastolic blood pressure trial dashboard — paired pre/post analysis with ANCOVA"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
[Open full screen ↗]: dashboards/bp.html {target="_blank" rel="noopener"}
[Download bp.csv]: datasets/bp.csv
------------------------------------------------------------------------
## PUFA meta-analysis — forest plot {#pufa}
Pooled risk ratios from six classic trials of polyunsaturated fatty acid replacement vs. control diet for cardiovascular events: DARTS, LA Veterans, Minnesota Coronary Survey, MRC Soy, Oslo Diet Heart, STARS.
**What's in the dashboard**
- Per-study risk ratio with 95% CI and weight (random-effects)
- Pooled diamond at the bottom of the forest, model toggle (random-effects ↔ fixed-effect), scale toggle (log ↔ linear)
- Heterogeneity panel: Cochran's *Q*, df, *p*, I², τ²
- Event-rate bar chart by arm and study
- Study-weight bar chart
The pooled random-effects estimate sits right at the conventional significance threshold (RR 0.875, 95% CI 0.764 to 1.001, *p* ≈ 0.052) — heterogeneity is low (I² = 16%), so fixed-effect and random-effects estimates barely diverge.
:::: {.dashboard-embed .aspect-tall data-url="https://lesslikely.com/dashboards/pufa.html"}
::: dashboard-embed-toolbar
[PUFA META-ANALYSIS — INTERACTIVE]{.title} [[Open full screen ↗][5] · [Download pufa.csv]{download}]{.actions}
:::
```{=html}
<iframe
src="dashboards/pufa.html"
title="PUFA meta-analysis dashboard — random-effects forest plot with heterogeneity statistics"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
[5]: dashboards/pufa.html {target="_blank" rel="noopener"}
[Download pufa.csv]: datasets/pufa.csv
------------------------------------------------------------------------
## Atlantis Fresh Market — store uptime {#uptime}
Operational data from 70 c-store / fresh-market locations across five regions (Connecticut, Western MA, NYC Suburbs, New Jersey, New York City) over a seven-day window in April 2022. Records minutes Online, Offline, and Menu Available per store-day.
**What's in the dashboard**
- KPI cards for store count, aggregate uptime, total online/offline time, and date range
- Daily uptime line chart by region (with a network-average overlay)
- Bottom-15 stores by uptime, color-coded by health band
- Store × day uptime heatmap (real per-day variation, hover for cell-level detail)
- Region rollup table and full store-level table, both sortable
:::: {.dashboard-embed .aspect-tall data-url="https://lesslikely.com/dashboards/downtime.html"}
::: dashboard-embed-toolbar
[STORE UPTIME — INTERACTIVE]{.title} [[Open full screen ↗][6] · [Download downtime.csv]{download}]{.actions}
:::
```{=html}
<iframe
src="dashboards/downtime.html"
title="Atlantis Fresh Market store uptime dashboard — 70 stores × 7 days, by region"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
[6]: dashboards/downtime.html {target="_blank" rel="noopener"}
[Download downtime.csv]: datasets/downtime.csv
------------------------------------------------------------------------
## S-value adoption tracker {#svalues}
A live bibliometric view of who is actually using the S-value (Shannon-information / surprisal) transform of *p*-values. The dashboard queries the [OpenAlex] API on page load and counts works that cite at least one of three seed papers:
[OpenAlex]: https://openalex.org
- Greenland, *Valid P-values behave exactly as they should* (Am. Statistician, 2019)
- Rafi & Greenland, *Semantic and cognitive tools to aid statistical science* (BMC MRM, 2020)
- Cole, Edwards & Greenland, *Surprise!* (AJE, 2021)
**What's in the dashboard**
- Two tabs — **Cited** (deduplicated union of works citing any seed) and **Reported in text** (the subset that also mentions `"s-value"` or `surprisal` in OpenAlex-indexed full text)
- KPI cards for total cites, all-time reporters, and the most recent year on file
- Per-year, cumulative, and per-seed views of citation counts
- Cited-vs-reported comparison and a reporting-rate trend
- Recent papers list with year, title, venue, and DOI link
- Light/dark theme with a `?theme=dark` override
::: callout-note
The reported-in-text count is a **lower bound** — OpenAlex only indexes full text for a subset of works, so a paper that uses S-values in the Methods may still not match. Trust the trend, not the absolute integer; the strict Methods-only count from the Europe PMC open-access corpus is single digits and too sparse to chart. See the related post \[*S-values*\] for the underlying transform.
:::
:::: {.dashboard-embed .aspect-tall data-url="https://lesslikely.com/dashboards/svalues.html"}
::: dashboard-embed-toolbar
[S-VALUES — INTERACTIVE]{.title} [[Open full screen ↗][7] · [Read the explainer]]{.actions}
:::
```{=html}
<iframe
src="dashboards/svalues.html"
title="S-value adoption tracker — live OpenAlex citation and full-text counts for the surprisal transform"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
[7]: dashboards/svalues.html {target="_blank" rel="noopener"}
[Read the explainer]: statistics/s-values.html
------------------------------------------------------------------------
## PageSpeed / Lighthouse tracker {#pagespeed}
A live performance audit of the site itself. Pick any of eight representative pages and a device profile, and the dashboard calls the [Google PageSpeed Insights] API — which runs a full [Lighthouse] audit on Google's servers — then renders the result. It is the only dashboard here that measures *this website* rather than a teaching dataset.
[Google PageSpeed Insights]: https://developers.google.com/speed/docs/insights/v5/get-started
[Lighthouse]: https://developer.chrome.com/docs/lighthouse/overview/
**What's in the dashboard**
- Four Lighthouse category gauges — **Performance**, **Accessibility**, **Best Practices**, **SEO** — colored by Lighthouse's own 0–100 bands (green ≥ 90, amber 50–89, red \< 50)
- Lab Core Web Vitals and loading metrics as KPI cards: LCP, CLS, TBT, FCP, Speed Index, and Time to Interactive, each with its per-metric pass/fail band
- A **Mobile ↔ Desktop** toggle (the two strategies Lighthouse scores separately) and a page selector
- An **Opportunities** tab: the audits with the largest estimated load-time savings, as a ranked bar chart and table
- A **Field data** tab: real-user Core Web Vitals from the Chrome UX Report (28-day, 75th-percentile), switchable between this page and the whole origin — shown when CrUX has enough traffic for the URL
::: callout-note
The API is queried **keyless** by default, which shares a rate-limited anonymous quota — if an audit fails with a quota error, wait a moment and re-run, or append `?key=YOUR_PSI_KEY` to the dashboard URL to use a referrer-restricted [PageSpeed Insights API key]. Lab scores vary run-to-run (Lighthouse simulates a throttled network), so treat a single number as a snapshot, not a constant. Field data is absent for low-traffic pages — CrUX only reports URLs with enough real Chrome traffic.
:::
[PageSpeed Insights API key]: https://developers.google.com/speed/docs/insights/v5/get-started#APIKey
:::: {.dashboard-embed .aspect-tall data-url="https://lesslikely.com/dashboards/pagespeed.html"}
::: dashboard-embed-toolbar
[PAGESPEED — LIVE LIGHTHOUSE]{.title} [[Open full screen ↗][8] · [PageSpeed Insights API docs]]{.actions}
:::
```{=html}
<iframe
src="dashboards/pagespeed.html"
title="PageSpeed / Lighthouse tracker — live Google PageSpeed Insights audit of lesslikely.com with category scores, Core Web Vitals, and field data"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
[8]: dashboards/pagespeed.html {target="_blank" rel="noopener"}
[PageSpeed Insights API docs]: https://developers.google.com/speed/docs/insights/v5/get-started {target="_blank" rel="noopener"}
## UFC Fighter Database {#ufc-fighter-database}
:::: {.dashboard-embed .aspect-tall data-url="/UFC Fighter Database (standalone).html"}
::: dashboard-embed-toolbar
UFC Fighter Database[— INTERACTIVE]{.title} [\[Open full screen ↗\]\[9\]]{.actions}
:::
```{=html}
<iframe
src="/UFC Fighter Database (standalone).html"
title="UFC Fighter Database"
loading="lazy"
sandbox="allow-scripts allow-same-origin allow-popups"
referrerpolicy="no-referrer"
allow="fullscreen"></iframe>
```
::::
\[9\]: /UFC Fighter Database (standalone).html {target="\_blank" rel="noopener"}
------------------------------------------------------------------------
## Implementation notes
Each dashboard is a single self-contained HTML file. The chart library (Chart.js v4) loads from a CDN; everything else — data, layout, interactivity — is inline. To customize:
- **Update the data** — replace the `const DATA = {...}` blob near the top of the `<script>` tag.
- **Restyle** — the `:root` CSS variables at the top of each file control the color palette and spacing.
- **Add a chart** — Chart.js v4 is already loaded; new canvases can be appended without touching anything else.
The source CSVs live in [`datasets/`] and are downloadable directly.
[`datasets/`]: datasets.qmd
::: {.callout-tip collapse="true"}
## Why iframes instead of inlining the dashboards directly?
Three reasons. **First**, each dashboard ships its own `<script>` block with global variable names (`DATA`, `charts`, etc.) — inlining all four on one page would collide. **Second**, iframes give us a clean security boundary (`sandbox="allow-scripts allow-same-origin allow-popups"` blocks the embed from navigating the parent or accessing storage outside its own origin). **Third**, `loading="lazy"` defers the iframe payload until you scroll near it, so this page's Largest Contentful Paint stays fast even with four embeds. The cost is a fixed-height container per embed; the [`aspect-ratio` CSS] reservation prevents any layout shift (CLS) once they load.
:::
[`aspect-ratio` CSS]: https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
------------------------------------------------------------------------
## Related pages
- [Datasets] — source data and other teaching datasets
- [Projects] — statistical software and tools
- [All Posts] — tutorials and articles
[Datasets]: datasets.html
[Projects]: projects.html
[All Posts]: blog.html
Comments