Two proposals for the eDISH renderer, off the back of PR #44: a triage of every open issue in the original SafetyGraphics/hep-explorer against our port — with a short list to land this release — and a design for a Clinical guide section on the renderer site, grounded in the DIA-ASA working group's evaluation-workflow manual.
All 35 open upstream issues triaged against our Chart.js port. Most are already delivered, deferred (sv#45–51), or not-applicable to a non-Webcharts renderer — leaving a thin, coherent slice of new value.
10 small, in-scope wins in two themes — a clinical-guide cluster and control/legend completeness. Each is S–M effort and closes a visible gap without expanding the chart's surface.
A new per-renderer Clinical guide tab that teaches the eDISH evaluation workflow and links to the authoritative manual — copyright-safe, and it satisfies upstream #328 outright.
Nothing here is filed or built yet — this is a proposal for your review. On your go I'll file the sub-issues and open a small PR for the clinical-guide section and the add-this-release cluster.
Part 1 · the upstream backlog
The 35 upstream hep-explorer issues cluster into five bands: legend/grouping UX, axis and display controls, clinical-guide linking and messaging, data-handling edge cases, and a handful of large visualization features. A large share is already behind us — 12 are out-of-scope because our Chart.js port already ships the behavior (click-to-filter legend, settings schema, subset-aware legend) or because they are upstream-only Webcharts/D3, IE, build, or code-style defects that share none of our rendering path. Another 6 map cleanly onto our existing sv#45–51 defers (animation, box-plots, sparklines, P_ALT footnote, CSV export) or the known population-profile gap, so they need no new tracking. That leaves 10 small, genuine, in-scope wins we can credibly land this release and 7 real gaps worth new sub-issues (two of which — #207/#248 — collapse into a single display-logic issue). Net: the upstream backlog is mostly either delivered, deferred, or not-applicable, with a thin, coherent slice of new value concentrated in control/legend completeness and clinical-guide linking.
All small, all reinforcing the Clinical guide section below. #328 is a wiring task, not a feature build — the guide section satisfies it outright.
| Issue | Title | Effort | Why it makes the release |
|---|---|---|---|
| #328 | Add a link to the clinical workflow as part of the UI | S | Header link from the chart to the clinical workflow/guide — the anchor deliverable of the clinical-guide section being scoped in parallel. |
| #335 | Link to R/nR reference | S | We derive and show R-Ratio but offer no link to its clinical rationale; a small in-widget reference link, same clinical-guide surface as #328. |
| #240 | Allow some messages to be permanent | S | Add a persistent 'not validated for clinical use' caution alongside the existing data-cleaning note; ties directly into the clinical-guide messaging work. |
| #107 | Add explanatory labels or footnotes for quadrant labels | S | HEP-QUAD names each quadrant but explains none; a tooltip/caption on clinical meaning is a small, self-contained clinical win. |
Each closes a visible gap in a control or legend we already ship — self-contained, no new chart surface.
| Issue | Title | Effort | Why it makes the release |
|---|---|---|---|
| #106 | Make Quadrant labels optional | S | Quadrant labels are always-on; adding a show/hide control is a contained control tweak not covered by any sv# defer. |
| #290 | Annotate measures in spaghetti plot | S | The HEP-SELECT line chart labels measures with abbreviations only; adding full measure names (or a clearer legend) is a small labeling clarity win. |
| #274 | Make legend for point size | S | We ship the Uniform/rRatio point-size control but no legend explaining the size encoding; a size legend is a small completeness win. |
| #108 | Add frequencies and percentages for grouping variable | S | The group legend shows swatch+value only; adding per-group n/% to the legend or a small group table is a genuine in-scope gap. |
| #112 | Support different base value for log axis | S | HEP-CTRL ships a linear/log toggle with a hard-coded base; exposing a log2/log10 base option is a small in-scope control tweak. |
| #238 | Allow user to manually adjust axes | M | Controls offer a linear/log toggle but no manual axis min/max; a pair of axis-range inputs is a small in-scope control addition (also largely satisfies #209's simpler intent). |
These need no new tracking — they belong to a v1.3.0 sub-issue we already filed, or the known population-profile gap.
| Issue | Title | Maps to | Note |
|---|---|---|---|
| #84 | Update ParticipantProfileURL setting | population-profile | We ship no external participant profile link at all — this per-participant/templated profile-URL request IS the documented population-profile known gap. |
| #273 | Only use unique study day values in animation | sv#46 | A tween refinement of the study-day animation we deferred wholesale as sv#46 (play/stop + motion trails). |
| #262 | New view for quadrant comparison | sv#47 | Box/violin plots by visit comparing a quadrant vs the normal quadrant — box-plot rendering is already deferred under sv#47; a large view beyond v1.3. |
| #296 | Keep x-axis domain constant across raw lab values summary table charts | sv#48 | A rendering detail of the summary-table sparklines deferred as sv#48; our drill-down currently ships one line chart plus a numeric table, so the mini-charts don't exist yet. |
| #327 | Update wording for Palt footnote | sv#49 | The Palt footnote only surfaces with the P_ALT estimate, deferred under sv#49; its 'refer to clinical workflow' aspect is already covered by #328/#335, so it is not a separate release item. |
| #212 | Is there a way to download a set of cases? | sv#50 | Downloading data for a chosen set of cases (e.g. the Temple's Corollary cases) is the CSV-export work already deferred under sv#50; we have selection + linked listing but no export. |
Real gaps not covered by any existing defer — but larger or more ambiguous than a this-release win. #207 and #248 collapse into one display-logic sub-issue.
| Issue | Title | Effort | Why a follow-up (not this release) |
|---|---|---|---|
| #248 | Improve default display logic | M | Hide eDISH when no ULN, hide mDISH when no baseline, error when neither — conditional display gating we don't do. Superset of #207; file ONE display-logic sub-issue covering both. |
| #207 | Update baseline behavour | M | Suppress the mDISH toggle unless valid user-specified baseline values exist — same display-logic theme as #248; combine into the single display-logic sub-issue, do not file separately. |
| #140 | Add option for static ULNs (not from user data) | M | We derive ULN/cutpoints data-driven only; no data-driven-vs-user-defined ULN-method control or per-measure numeric ULN entry — a genuine gap not in any sv# defer. |
| #229 | Deal with unscheduled visits | M | HEP-DATA derives day/visit ordering when studyday is absent but has no explicit handling for unscheduled visits (which lack a scheduled study day). |
| #209 | Is there an interactive way to adjust the axes? | M | Interactive axis-range/zoom/pan, distinct from sv#45's draggable cut-lines and richer than #238's numeric min/max inputs; a real if low-priority gap worth its own followup. |
| #111 | Improve ordering of legend for group variable | S | We render the group legend in data/alpha order with no ordering by a numeric companion column (e.g. TRTN), so Placebo/Low/High can't be forced into rank order. |
| #236 | Don't repeat colors after n=9 | S | The fixed categorical palette repeats colors once groups exceed its length; extending/deduplicating for n>9 is a narrow robustness fix, better as a small followup than forced into this release. |
| Issue | Title | Reason | Detail |
|---|---|---|---|
| #21 | Click legend to filter groups | already shipped | SHIPPED — Group color-by legend exists and Chart.js legends natively toggle series visibility on click. |
| #302 | Add a settings schema | already shipped | SHIPPED — the port already ships src/data/schema/hep-explorer.json validating required columns plus a structured controls/settings surface. |
| #160 | treatment group after subset | already shipped | SHIPPED/fixed — an upstream Webcharts legend bug; our port derives groupValues from filteredPoints() so the legend already reflects only the current subset. |
| #164 | apply labels to group drowdown | already addressable | Minor polish — the Group color-by picker exists and the JSON schema can already carry display labels; not a distinct release win. |
| #115 | Add filter for baseline ALP? | already addressable | Achievable today via HEP-CTRL generic categorical filters on any configured column; the issue itself is an unresolved clinical-workflow decision, not a port gap. |
| #237 | Add option to minimize messages after expanding | already addressable | Our port already surfaces a concise on-page note plus console warning rather than a verbose expandable panel; a collapse affordance adds little. |
| #198 | Consider adding a "Highlight" functionality | out of v1.3 scope | A configurable ALT/TB/AST/ALP decision-rule builder that grays/highlights points — a large new feature (L) beyond v1.3 scope. |
| #239 | Optimize code for improved performance in very large data sets | out of v1.3 scope | Binning/hexbin/decluttering for large data is a substantial new feature (L) beyond v1.3; we draw one point per participant. |
| #228 | Add SEND example | not applicable (upstream-only) | Upstream demo-content work (wrangling a no-ULN SEND dataset), not a behavior gap; our port validates a long-format data contract via schema. |
| #325 | oninit/cleanData/dropRows isn't running | not applicable (upstream-only) | Not applicable — an internal Webcharts variable-name bug (imputedData vs imputed_data); our port already removes missing/non-numeric records with a reported count. |
| #251 | Use `export default` for all functions | not applicable (upstream-only) | Not applicable — an upstream Webcharts/D3 module code-style convention irrelevant to our Chart.js architecture. |
| #299 | hep-explorer not rendering any data in IE | not applicable (upstream-only) | Not applicable — an Internet Explorer bug in the upstream Webcharts/D3 build; our Chart.js reimplementation does not target IE and shares none of that path. |
Part 2 · a clinical-guide section
The manual is the DIA-ASA Biopharm Working Group's user guide for the Hepatic Safety Explorer, an interactive successor to FDA's static eDISH plot (peak transaminase versus peak total bilirubin, in fold-change from ULN). Beyond describing the tool's controls, its clinical core is a structured hepatotoxicity evaluation workflow: a reviewer starts from a case sitting in one of three quadrants of interest (possible Hy's Law, Temple's Corollary, isolated hyperbilirubinemia) and walks a series of decision steps that gather evidence for or against a drug-caused injury, since drug-induced liver injury is a diagnosis of exclusion. This matters for our renderer because every clinical concept the workflow leans on — the named quadrants, movable cut-lines, the R-Ratio, the eDISH/mDISH toggle, timing windows, and per-participant lab-over-time drill-down — is already a live control in our Chart.js port, so a guide can teach the reasoning and point directly at the demo. Publishing that reasoning alongside the demo turns the renderer from a plotting widget into a review aid a clinician can actually act on.
source · cited, not reproducedLocate each case in one of four regions split by the ALT (3x ULN) and total-bilirubin (2x ULN) cut-lines: normal (lower-left), isolated hyperbilirubinemia (upper-left), Temple's Corollary / isolated ALT (lower-right), and possible Hy's Law (upper-right). Maps to our Quadrants feature (HEP-QUAD): named corners, live per-quadrant %, and the summary table.
If the default ULN plot shows no upper-right cases, re-run against baseline to avoid missing low-starting patients; if cases appear, ask whether the population (e.g. oncology with liver metastases) explains them and raise the thresholds accordingly. Maps to the eDISH/mDISH Display toggle (HEP-DISPLAY) and the X/Y reference-line inputs (HEP-QUAD/HEP-CTRL).
Switch the axes from fold-change-over-ULN to fold-change-over-baseline to gain sensitivity to drug effects and consistency across labs, especially with abnormal pre-dose chemistry; suggested boundaries are ~3.8x baseline ALT and ~4.8x baseline TB. Maps directly to our mDISH Display Type.
Check that the ALT and bilirubin peaks (or qualifying elevations) fall within about 2-4 weeks of each other with bilirubin rising after ALT, and that alkaline phosphatase stays below 2x ULN so the bilirubin is not cholestatic. Maps to the timing-window days input (filled vs hollow points, HEP-CTRL) and the per-participant lab-over-time drill-down (HEP-SELECT).
Compute R = (ALT/ULN)/(ALP/ULN) to characterize injury type — roughly >5 hepatocellular, 2-5 mixed, <2 cholestatic — with the newer nR variant also considering AST. Maps to our derived R-Ratio (shown in the point tooltip) and the R-Ratio range filter (HEP-CTRL).
Confirm the ALT peak falls within the first ~12 weeks of dosing (the highest-risk window) and read how quickly ALT crosses 3x/5x/10x/20x ULN, since a steeper rise suggests a more acute, drug-related insult. Maps to the standardized lab-values-by-study-day line chart and study-day tooltips in the drill-down (HEP-SELECT).
Use a peak-ALT/AUC-derived estimate of hepatocyte loss to grade severity (mild vs moderate vs sufficient to produce Hy's Law vs likely fatal), giving a magnitude read beyond raw peak ALT. Not yet in our port — deferred as the exposure track + P_ALT estimate (sv#49).
Cross-check the AST time course and the AST:ALT ratio to separate hepatocellular injury from mitochondrial, muscle, alcohol, or hemolysis-artifact sources, and confirm resolution after (or despite continued) dosing. Maps to the ALT/AST/TB/ALP measure pickers (HEP-DISPLAY) and the drill-down lab panels.
For isolated ALT elevation without qualifying bilirubin (lower-right), evaluate whether the case reflects real hepatocellular injury that could later progress into the Hy's Law quadrant, running the analogous timing/rate/AST checks. Maps to the named Temple's Corollary quadrant and the reference-line inputs that reclassify points live (HEP-QUAD).
For isolated bilirubin elevation without ALT (upper-left), consider non-hepatocellular causes (e.g. cholestasis, hemolysis, or benign unconjugated hyperbilirubinemia) that place a patient in this quadrant without drug injury. Maps to the named Hyperbilirubinemia quadrant and the ALP/measure controls used to probe the pattern.
A minimal, incremental add that mirrors the existing evidence/api tabs and the conditional Matrix link — a good start, with room for a richer framework later.
A per-renderer authored Markdown file at docs/guides/<module>.md (e.g. docs/guides/hep-explorer.md) — versioned and reviewable in-repo like the evidence JSON, rendered through the existing shell with no new runtime dependency.
An optional "guide": "hep-explorer.md" key on the renderer's config.json entry. Because it is optional, only renderers that ship a guide get the tab — degrading gracefully exactly like the existing matrixUrl handling.
A conditional tab('guide', 'guide.html', 'Clinical guide') in scripts/site-lib.mjs pageTabs(), slotted between Live demo and Test evidence so the review-oriented reading sits next to the demo.
A block in scripts/site.mjs that reads the guide Markdown, converts to HTML, and writes site/<module>/guide.html through the same renderShell path used for evidence/api — a pure function of the repo tree, no test run or network.
Page title ("Clinical guide: reading the Hepatic Safety Explorer") and a short, prominent caution — in our own words — that this graphic is an exploratory review aid, not a validated diagnostic tool, and that a drug-induced-liver-injury conclusion requires exclusion work (e.g. serology) beyond what the plot shows. Sets expectations before any workflow.
Original-worded explanation that each point is one participant plotted at their peak transaminase (x) against peak total bilirubin (y) in fold-change units, and that two cut-lines carve the plane into four regions. Names the four quadrants and what each implies (normal; isolated hyperbilirubinemia; Temple's Corollary / isolated ALT; possible Hy's Law), with a one-line note that upper-right cases are only 'potential' until further evaluated.
Brief framing that the workflow forks by quadrant of interest — possible Hy's Law, Temple's Corollary, isolated hyperbilirubinemia — each a short decision path that gathers evidence for or against a drug cause. Prepares the reader for the step list without reproducing the manual's step text.
Our ordered, paraphrased rendering of the workflowSteps: quadrant orientation; Step 1 population/oncology confounders and when to switch to mDISH; Step 2a timing coincidence + alkaline-phosphatase/cholestasis screen; R-Ratio/nR pattern interpretation; Step 2b onset window and rate of rise; Step 2c hepatocyte-loss (PALT) magnitude; Steps 2d-2f AST corroboration and resolution; and the parallel Temple's Corollary and hyperbilirubinemia branches. Each item is a short rationale, not a transcription, with the authoritative PDF cited for the underlying evidence.
A cross-reference table tying each clinical concept to the exact control in our demo: quadrants/cut-lines -> Quadrants + X/Y reference-line inputs; baseline reasoning -> eDISH/mDISH Display toggle; timing coincidence -> timing-window days (filled vs hollow points); injury pattern -> R-Ratio tooltip value + R-Ratio range filter; onset/rate-of-rise and AST checks -> click-to-drill-down lab-values-by-study-day chart and measure pickers. Flags PALT/hepatocyte-loss as not-yet-implemented (deferred, sv#49) so the guide never points at a missing control.
A few concrete 'do this' prompts that link back to the Live demo tab (later, deep-linked presets): switch to mDISH, nudge the ALT reference line to an oncology-adjusted value, filter by R-Ratio range, and click a Hy's-Law-quadrant point to inspect its lab trajectory. Turns passive reading into guided exploration.
A clearly separated block stating that the workflow structure and clinical rationale are adapted and summarized from the DIA-ASA working group's manual, with the exact attribution line and a link out to the authoritative PDF (see attribution field). Makes explicit that we summarize rather than reproduce and that the manual is the citable authority.
Directly satisfies upstream #328 (add a link to the clinical workflow in the UI): shipping a Clinical guide tab that summarizes the workflow and links out to the authoritative PDF is a stronger answer than a bare link, and its "Try it in the demo" cross-references put the workflow one click from the chart. Relates to #327 (P_ALT footnote wording): our Step 2c summary and the controls-map both mark hepatocyte-loss/PALT as not-yet-implemented and deferred (sv#49), so the guide's footnote wording should stay consistent with however #327 resolves the P_ALT language. Relates to #335 (R/nR reference link): the injury-pattern step explains R = (ALT/ULN)/(ALP/ULN) and the nR variant, and its attribution/source-link block is the natural home for the R/nR reference #335 asks for. Also touches the deferred obot.roadmap#30 sub-issues the guide should not over-promise against — sv#45 (draggable cut-lines), sv#49 (exposure track + P_ALT) — so the controls-map flags them as future rather than live.
Attribution shown on the page: Clinical workflow summarized and adapted, in our own words, from the Interactive Safety Graphic — Hepatic Safety Explorer User's Manual (v1.2.1), a product of the DIA-ASA Interactive Safety Graphics Working Group. See the authoritative manual for the full workflow, citations, and clinical detail.
What I'd do next
Add ten items to this release, organized around two coherent themes. The first is a clinical-guide cluster: #328 (link to the clinical workflow), #335 (R/nR reference link), #240 (permanent 'not validated for clinical use' caution), and #107 (explanatory footnotes on the quadrant labels) — all small, all reinforcing the clinical-guide section we are proposing in parallel. Crucially, #328 "Add a link to the clinical workflow as part of the UI" is not new scope: it is satisfied outright by that clinical-guide section, so shipping it is a wiring task, not a feature build. The second theme is control/legend completeness: #274 (point-size legend), #108 (per-group frequencies/percentages), #290 (full measure names in the detail chart), #106 (optional quadrant labels), #112 (log2/log10 base option), and #238 (manual axis min/max inputs). These make the release because each is S–M effort, self-contained, and closes a visible gap without expanding the chart's surface. I deliberately held back the larger or ambiguous asks: interactive zoom/pan (#209), user-defined static ULNs (#140), unscheduled-visit handling (#229), display-logic gating (#207/#248), legend ordering (#111), and the n>9 palette fix (#236) are real but warrant their own scoped sub-issues rather than being rushed in; the highlight rule-builder (#198), large-data performance (#239), and quadrant-comparison view (#262) are out of scope or already deferred.
On your go, I'll open a small safety.viz PR: the four-part framework above (config field + conditional tab + site.mjs gen + docs/guides/hep-explorer.md), populated with the copyright-safe guide content in the mockup.
Recommend: ship it — it satisfies #328, needs no new dependency, and is the anchor for the clinical-guide cluster.
The 10 items (or a trimmed subset). The 4 clinical-guide-cluster items fold into the PR above; the 6 completeness items are each S–M control/legend tweaks.
Recommend: take all four clinical items + #274/#108/#290 (the cheapest completeness wins) now; hold #106/#112/#238 if you want a tighter release.
Seven new sub-issues of obot.roadmap#30 (with #207+#248 merged into one display-logic issue), plus finally filing the population-profile gap (#84) as sv#52.
Recommend: file on approval so the backlog is tracked, tagged v1.3.0 alongside sv#45–51.
None of this is filed or built yet — each item is an approval gate. Say which of A/B/C to proceed with and I'll execute.