obot.roadmap · proposal · 2026-07-12

Hep-explorer: upstream backlog & a clinical-guide section

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.


Executive summary

The backlog

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.

This release

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.

Clinical guide

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.

35triaged
10add this release
6map to defers
7new follow-ups
12out of scope

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

What's worth migrating from SafetyGraphics/hep-explorer

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.

Add to this release — theme 1: clinical-guide cluster 4 items

All small, all reinforcing the Clinical guide section below. #328 is a wiring task, not a feature build — the guide section satisfies it outright.

IssueTitleEffortWhy it makes the release
#328Add a link to the clinical workflow as part of the UISHeader link from the chart to the clinical workflow/guide — the anchor deliverable of the clinical-guide section being scoped in parallel.
#335Link to R/nR referenceSWe 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.
#240Allow some messages to be permanentSAdd a persistent 'not validated for clinical use' caution alongside the existing data-cleaning note; ties directly into the clinical-guide messaging work.
#107Add explanatory labels or footnotes for quadrant labelsSHEP-QUAD names each quadrant but explains none; a tooltip/caption on clinical meaning is a small, self-contained clinical win.

Add to this release — theme 2: control & legend completeness 6 items

Each closes a visible gap in a control or legend we already ship — self-contained, no new chart surface.

IssueTitleEffortWhy it makes the release
#106Make Quadrant labels optionalSQuadrant labels are always-on; adding a show/hide control is a contained control tweak not covered by any sv# defer.
#290Annotate measures in spaghetti plotSThe HEP-SELECT line chart labels measures with abbreviations only; adding full measure names (or a clearer legend) is a small labeling clarity win.
#274Make legend for point sizeSWe ship the Uniform/rRatio point-size control but no legend explaining the size encoding; a size legend is a small completeness win.
#108Add frequencies and percentages for grouping variableSThe group legend shows swatch+value only; adding per-group n/% to the legend or a small group table is a genuine in-scope gap.
#112Support different base value for log axisSHEP-CTRL ships a linear/log toggle with a hard-coded base; exposing a log2/log10 base option is a small in-scope control tweak.
#238Allow user to manually adjust axesMControls 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).

Already tracked — maps to an existing defer 6 items

These need no new tracking — they belong to a v1.3.0 sub-issue we already filed, or the known population-profile gap.

IssueTitleMaps toNote
#84Update ParticipantProfileURL settingpopulation-profileWe ship no external participant profile link at all — this per-participant/templated profile-URL request IS the documented population-profile known gap.
#273Only use unique study day values in animationsv#46A tween refinement of the study-day animation we deferred wholesale as sv#46 (play/stop + motion trails).
#262New view for quadrant comparisonsv#47Box/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.
#296Keep x-axis domain constant across raw lab values summary table chartssv#48A 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.
#327Update wording for Palt footnotesv#49The 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.
#212Is there a way to download a set of cases?sv#50Downloading 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.

New follow-ups worth filing 7 items

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.

IssueTitleEffortWhy a follow-up (not this release)
#248Improve default display logicMHide 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.
#207Update baseline behavourMSuppress 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.
#140Add option for static ULNs (not from user data)MWe 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.
#229Deal with unscheduled visitsMHEP-DATA derives day/visit ordering when studyday is absent but has no explicit handling for unscheduled visits (which lack a scheduled study day).
#209Is there an interactive way to adjust the axes?MInteractive 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.
#111Improve ordering of legend for group variableSWe 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.
#236Don't repeat colors after n=9SThe 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.

Out of scope / already shipped 12 items

IssueTitleReasonDetail
#21Click legend to filter groupsalready shippedSHIPPED — Group color-by legend exists and Chart.js legends natively toggle series visibility on click.
#302Add a settings schemaalready shippedSHIPPED — the port already ships src/data/schema/hep-explorer.json validating required columns plus a structured controls/settings surface.
#160treatment group after subsetalready shippedSHIPPED/fixed — an upstream Webcharts legend bug; our port derives groupValues from filteredPoints() so the legend already reflects only the current subset.
#164apply labels to group drowdownalready addressableMinor polish — the Group color-by picker exists and the JSON schema can already carry display labels; not a distinct release win.
#115Add filter for baseline ALP?already addressableAchievable today via HEP-CTRL generic categorical filters on any configured column; the issue itself is an unresolved clinical-workflow decision, not a port gap.
#237Add option to minimize messages after expandingalready addressableOur port already surfaces a concise on-page note plus console warning rather than a verbose expandable panel; a collapse affordance adds little.
#198Consider adding a "Highlight" functionalityout of v1.3 scopeA configurable ALT/TB/AST/ALP decision-rule builder that grays/highlights points — a large new feature (L) beyond v1.3 scope.
#239Optimize code for improved performance in very large data setsout of v1.3 scopeBinning/hexbin/decluttering for large data is a substantial new feature (L) beyond v1.3; we draw one point per participant.
#228Add SEND examplenot 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.
#325oninit/cleanData/dropRows isn't runningnot 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.
#251Use `export default` for all functionsnot applicable (upstream-only)Not applicable — an upstream Webcharts/D3 module code-style convention irrelevant to our Chart.js architecture.
#299hep-explorer not rendering any data in IEnot 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

Turning the renderer into a review aid

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 reproduced
Hepatic Safety Explorer User's Manual v1.2.1
DIA-ASA Interactive Safety Graphics Working Group · 84 pp. · the guide summarizes its workflow structure and links here for the authoritative detail.

The eDISH evaluation workflow — and where each step already lives in our port

Read the eDISH quadrants (orientation)

Locate 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.

Step 1 — Any potential Hy's Law cases? / population confounders

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).

mDISH (baseline-corrected) reasoning

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.

Step 2a — Timing coincidence and cholestasis screen

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).

R-Ratio / nR — hepatocellular vs cholestatic pattern

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).

Step 2b — Onset window and rate of rise

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).

Step 2c — Hepatocyte-loss estimate (PALT)

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).

Steps 2d-2f — AST corroboration and AST/ALT ratio

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.

Temple's Corollary branch (Steps 4-6)

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).

Hyperbilirubinemia branch (Steps 7-9)

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.

How to include it in the package

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.

1

Content source

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.

2

Config field

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.

3

Tab entry

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.

4

Page generation

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.

Later (non-blocking): promote the guide from freeform Markdown to structured {stepId, quadrant, rationale, controlRefs[]} steps; deep-link each step into the live demo via query-param presets (e.g. ?display=mDISH&xref=4.8) so “try this” buttons drive the actual chart; add a printable one-page SOP export; and a cross-renderer guide index so the guides become a browsable library. refined framework — after the first guide ships

Mockup — the hep-explorer Clinical guide page

jwildfire.github.io/safety.viz/hep-explorer/guide.html
Live demoClinical guideTest evidenceAPI referenceRequirement matrix ↗

Clinical guide: reading the Hepatic Safety Explorer

⚠ Exploratory review aid, not a validated diagnostic tool — a drug-induced-liver-injury conclusion requires exclusion work beyond what this plot shows.

Header + non-diagnostic caution

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.

What eDISH shows (orientation)

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.

The three evaluation branches

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.

Step-by-step reasoning (summarized)

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.

How this maps to the controls on this page

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.

Try it in the demo

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.

Attribution and source link

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.

Ties to the upstream backlog & staying copyright-safe

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.

The manual is a copyrighted third-party document, so the guide never reproduces its text. Every workflow description is rewritten in our own original words as a paraphrase of the workflow STRUCTURE and clinical rationale, not a transcription of the steps. Any direct quotation is kept minimal (under ~15 words), clearly quoted, and attributed to the DIA-ASA Interactive Safety Graphics Working Group. We do not copy the manual's figures, appendix flow-diagrams, or step text into the repo; instead we link out to the authoritative published PDF as the citable source, and we credit the working group in a visible attribution block on the page. The guide's value-add — mapping the clinical reasoning onto our specific Chart.js controls — is original content we author, which keeps it transformative and clear of reproducing the source.copyright posture

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

Recommendation

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.

A

Approve the Clinical guide section (good start)

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.

B

Confirm the add-this-release short list

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.

C

File the follow-ups

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.