A browser-based tool for exploring, filtering, and summarising
Breast Cancer Now Generations Study data.
Open the dashboard at https://uk-generations-study.github.io/data-dashboard-demo/.
- Drag-and-drop one or more
.jsondata files onto the Data File drop zone - Optionally drag-and-drop matching JSON Schema files onto the Schema File drop zone
- Click Continue to Dashboard
To try the dashboard with the included synthetic data, use the files in examples/ (e.g. synthetic_data.json + DerivedVariables_Schema.json).
When multiple data files are loaded, they are combined via a full outer join on participant ID (TCode). Participants not present in all files are retained. Each file must have exactly one row per TCode — files with duplicate TCodes are rejected with an error.
Note: Variable names must not overlap across schema files. If they do, an error is shown before loading.
| Tab | Description |
|---|---|
| Overview | Participant count, completeness, and variable group summary |
| Explore | Histogram, bar chart, violin plot, or pie chart per variable with summary stats and PNG download |
| Missingness | Horizontal bar chart showing null % and sentinel NA % across all variables |
| Stratified | Side-by-side distributions of a numeric variable split by a categorical grouping variable |
| Cohort Builder | AND/OR filter chains with live preview, attrition flow diagram, and JSON/PNG export |
| Descriptive | Table 1 — summary statistics for the active cohort with optional stratification and CSV export |
- Search — filter variables by name or description
- Group buttons — filter by variable group (Demographics, Anthropometry, Reproductive, Lifestyle, etc.)
- Click any variable — jumps to the Explore tab with that variable selected
- Mobile — tap the ☰ button to open the sidebar as an overlay
Loading a JSON Schema file (Draft 2020-12) enriches the dashboard with human-readable labels, correct variable types, code lookups (e.g. 0 = No, 1 = Yes), units on chart axes, variable groupings, and sentinel value definitions.
All data handling occurs entirely within your browser via the FileReader API.
No participant data is uploaded, transmitted, or stored anywhere outside your device.
All vendor libraries are bundled locally — no CDN or external network requests are made.
index.html Main dashboard page
js/
main.js Entry point and event wiring
state.js Shared mutable application state
utils.js DOM utilities, escaping, statistics helpers
schema.js Schema parsing, inference, and merging
data-loader.js File loading, dataset merging, drag-drop
exports.js Branded PNG and JSON export helpers
views/
tabs.js Tab switching
sidebar.js Variable list and selection
overview.js Overview tab
explore.js Variable detail panel and chart drawing
missingness.js Missingness chart
stratified.js Stratified comparison
cohort.js Cohort builder, filters, and attrition flow
table1.js Descriptive statistics table and CSV export
vendor/
chart.umd.min.js Chart.js
chartjs-chart-boxplot.umd.min.js Chart.js box plot plugin
html2canvas.min.js HTML-to-canvas for PNG export
fonts/nunito.css Nunito web font
assets/
logo-g.png Logo icon
logo-white.png Logo wordmark
examples/
synthetic_data.json 1,000-participant synthetic dataset
synthetic_cancer_data.json Synthetic cancer summary (231 records)
DerivedVariables_Schema.json JSON Schema for derived variables
CancerSummary_Schema.json JSON Schema for cancer summary
sample_cohort.json Example cohort definition
generate_data.py Script that produced synthetic_data.json
generate_cancer_data.py Script that produced synthetic_cancer_data.json
- 1,000 participants with fields drawn from the Generations Study variable schema
- Realistic epidemiological distributions (BMI ~N(24.5, 4.5), smoking ~16%, etc.)
- Logical coherence: BMI derived from height/weight; parity consistent with
R0_Parous; HRT confined to older/postmenopausal participants - Plausible missingness (~3--15% per variable; higher for age-conditional fields)
- Sentinel values (999 / 9999) preserved as defined in the schema
- No real participant data — all values are synthetic
python3 examples/generate_data.py- 231 tumour records across 220 participants (~22% of the cohort)
- 11 participants have two records (second primary cancer)
- 85% breast cancer (ICD-10 C50.x); remainder colorectal, lung, cervical, ovarian
- Realistic stage, grade, ER/PR/HER2, Ki-67, and tumour size distributions
- Joins to
synthetic_data.jsononTCode
python3 examples/generate_cancer_data.py| Type | Meaning |
|---|---|
numeric |
Continuous measurement (e.g. BMI, physical activity) |
integer |
Whole-number count or age |
categorical |
Coded value with labelled categories |
binary |
0 / 1 flag |
Some variables use 999 or 9999 to mean Not Applicable — distinct from null (missing / unknown):
| Sentinel | Example | Meaning |
|---|---|---|
999 |
R0_BMI |
Pregnant at study entry — BMI not calculated |
999 |
R0_AgeBirthFirst |
No live birth |
9999 |
R0_BreastfeedingDuration |
No live birth |
examples/sample_cohort.json defines:
Premenopausal + Parous + BMI > 25 + Current alcohol drinker
{
"filters": [
{ "field": "R0_Menopause", "operator": "in", "value": "2", "logic": "AND" },
{ "field": "R0_Parous", "operator": "in", "value": "1", "logic": "AND" },
{ "field": "R0_BMI", "operator": ">", "value": "25","logic": "AND" },
{ "field": "R0_AlcoholStatus", "operator": "in", "value": "2", "logic": "AND" }
]
}R:
df_cohort <- df[df$R0_Menopause == 2 & df$R0_Parous == 1 & df$R0_BMI > 25 & df$R0_AlcoholStatus == 2, ]Python:
mask = (df.R0_Menopause == 2) & (df.R0_Parous == 1) & (df.R0_BMI > 25) & (df.R0_AlcoholStatus == 2)
df_cohort = df[mask]Schema: Generations Study variable definitions (JSON Schema Draft 2020-12).
