Skip to content

Algorithm result views: figures, coefficient views and chart fixes - #49

Open
KFilippopolitis wants to merge 43 commits into
masterfrom
refactor/algorithm-visualizations
Open

KFilippopolitis wants to merge 43 commits into
masterfrom
refactor/algorithm-visualizations

Conversation

@KFilippopolitis

Copy link
Copy Markdown
Contributor

Summary

This branch reworks how algorithm results are shown in Experiment Studio, the experiment detail page and compare mode. It is display-only: no /services calls, experiment payloads or stored result shapes change, and older experiments render through the same mappers.

New result views

  • Headline figures with effect sizes for hypothesis tests, two-group tests (with the groups named) and cross-validated classifiers, which are compared against their majority-class baseline.
  • A coefficient view for logistic regression (odds ratios with a likelihood-ratio test), LMM, binary and ordinal GLMM (with an ICC) and Cox regression (events and events per covariate). Linear regression moves into its own component.
  • A centres heatmap for k-means with three or more variables, and bubbles sized by cluster for two. Gaussian naive Bayes gets class profiles on one standardized scale; categorical naive Bayes shows counts with class-conditional shares.
  • PCA component weights on a diverging scale, with the variance explained. Pearson shows one correlation triangle plus a pairs table.

Tables and charts

  • A table is not repeated when the figures or charts above it already show it, and a "show every value as a table" toggle brings everything back. ECharts aria descriptions describe charts to screen readers.
  • One house style for chart text, titles and tooltips, and one series palette (8 colours, colour-blind checked). Heatmaps share one diverging scale and pick cell text that stays readable: white only on the deep-blue end.
  • Readable numbers: grouped thousands, one p-value style, terms shown as variable and level instead of model syntax, and created-column codes read as words. Charts and tables fit a 360px compare column.
  • Fixes: Cox follow-up time and event indicator were swapped; the positive class is named in binary models; per-fold n_obs is labelled as training rows.

DESIGN.md and docs/context/module-index.md describe the new views and the chart house style.

Testing

  • npm run typecheck, npm run check:dead-code and npm run build pass. The build shows two warnings that predate this branch: the algorithm-panel CSS budget and the non-ESM jszip module.
  • Focused specs (ng test --watch=false --browsers=ChromeHeadless, visualisations and core): 185/185 pass.
  • Not covered: a browser run of the latest commits against live results. Please run the result-view part of the Frontend Manual QA in docs/context/testing.md (k-means, PCA, Pearson, naive Bayes CV, logistic regression CV, Cox), including compare mode.

Risk

  • Low. All changes are in result rendering and labelling. Legacy algorithm aliases are kept.
  • The Cox time/event fix changes which column is shown as which for existing Cox experiments. The old display was wrong.

Follow-ups (exaflow, not in this PR)

  • Naive Bayes CV computes the SD after appending the average row (scorer_multiclass.py), which understates it by √((n−1)/n), about 0.89× at 5 folds.
  • K-means could send its exact overall_mean (and a pooled SD), so the centres heatmap matches the Profile column exactly and is shaded in SD units.

🤖 Generated with Claude Code

/** A raw snake_case code (a created column such as stroke_territory_cohort, or a level such as
* cluster_2) reads as words; labelled names pass through unchanged. */
export function readable(code: string): string {
if (!/^[a-z0-9]+(_[a-z0-9]+)+$/.test(code)) return code;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: false positive. [a-z0-9] cannot match _, so each underscore splits the code in exactly one way and there is no catastrophic backtracking. Adversarial 100,000-character inputs finish in about 2 ms. Leaving the alert for a maintainer to dismiss.

🤖 Addressed by Claude Code

Comment on lines +12 to +24
template: `
<div class="key-figures" role="group" aria-label="Key figures">
@for (figure of figures(); track figure.label) {
<div class="key-figure">
<span class="key-figure-label">{{ figure.label }}</span>
<span class="key-figure-value">{{ figure.value }}</span>
@if (figure.note) {
<span class="key-figure-note">{{ figure.note }}</span>
}
</div>
}
</div>
`,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: false positive. {{ figure.label }} and the other braces sit in the component's inline Angular template, where {{ }} is Angular interpolation, not a JavaScript placeholder. Leaving the alert for a maintainer to dismiss.

🤖 Addressed by Claude Code

Comment on lines +12 to +24
template: `
<div class="key-figures" role="group" aria-label="Key figures">
@for (figure of figures(); track figure.label) {
<div class="key-figure">
<span class="key-figure-label">{{ figure.label }}</span>
<span class="key-figure-value">{{ figure.value }}</span>
@if (figure.note) {
<span class="key-figure-note">{{ figure.note }}</span>
}
</div>
}
</div>
`,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: false positive. {{ figure.label }} and the other braces sit in the component's inline Angular template, where {{ }} is Angular interpolation, not a JavaScript placeholder. Leaving the alert for a maintainer to dismiss.

🤖 Addressed by Claude Code

@KFilippopolitis
KFilippopolitis force-pushed the refactor/algorithm-visualizations branch from 7e5167e to 556a6b5 Compare October 16, 2026 08:29
KFilippopolitis and others added 26 commits October 19, 2026 14:13
…nent

The key figures, coefficients card and model-fit details lived inline in
AlgorithmResultComponent. They now sit under visualisations/regression as a
pure view builder (buildRegressionView) plus a presentational component, and
the number formatting is shared from visualisations/result-format.ts so the
next summary views can reuse it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…R test

Logistic regression reused the raw coefficient table. It now gets the same
summary as linear regression: odds ratios with their 95% CI, an interval-vs-1
column drawn on the log-odds scale, McFadden pseudo R², AIC, and a model
likelihood-ratio test derived from ll and ll0 (chiSquarePValue). Log-odds,
standard error and z stay one click away under All columns and in the CSV.

The single-predictor regression line chart could no longer be reached for
either model, so it is removed with its registry entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
t-tests, Mann-Whitney U, chi-squared, Fisher's exact, one- and two-way ANOVA
and standardized mean difference opened on a metric/value table where p
showed as 0, 1.110e-16 or 3.873e-238. They now lead with a key-figures
strip: the p-value APA style with its test statistic, and an effect size
with its conventional magnitude (Cohen's d, P(A > B) from U, Cramér's V,
eta squared, partial eta squared per two-way term). The detailed tables stay
underneath unchanged.

KeyFiguresComponent is shared with the regression view and wraps on its
container's width, so it also fits 360px compare columns. The t-test
mean-difference chart repeated the first figure on an axis with duplicated
tick labels and no zero line, so it is removed. SMD comparisons now show
the grouping variable's enumeration labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every chart section was headed "Effect estimates" with a lead about
comparing factors, including k-means centres, histograms and PCA. The chart
registry now carries a section title per algorithm; its inputPath field and
default entry were never anything but empty and are gone.

The one-way ANOVA mean plot called its whiskers a 95% confidence interval,
but Exaflow's ci_info m-s/m+s are mean minus/plus one sample SD. The plot now
says so, drops the title and p-value the section heading and key figures
already give, and lets ECharts pick round axis bounds instead of colliding
90/92 labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lours

The 3-variable k-means centres chart used scatter3D from the echarts-gl UMD
bundle, which registers on a different ECharts instance than ngx-echarts, so
it logged "Unknown series scatter3D" and drew nothing. Three or more
variables now use the parallel-coordinates profile already used past three,
and k-means variables and centre keys carry their labels.

The series palette had four slots, the fourth (#dfefe4) nearly invisible, so
a fifth cluster reused the first cluster's blue. One 8-slot palette now lives
in chart-palette.ts: the three charter colours plus five hues validated for
colour-blind and normal-vision separation. The chart renderer also stops
forcing every line to primary blue with smoothing and an area fill, which
merged multi-line series and bent the elbow curve between points; the elbow
marks the selected k with a labelled point instead of a pin.

The echarts-gl dependency has no remaining import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… explained

Signed loadings were coloured on a one-hue scale, so -0.71 looked weaker
than +0.38, PC1 sat at the bottom and the colour legend was clipped. The
loadings heatmap now diverges red / grey / blue around zero, lists PC1
first with its share of variance in the row label, and names the variables
above the columns. The scree plot repeated the eigenvalues as a red line;
it now shows variance explained per component with the cumulative share.
The PCA table adds both percentages and an exact-value loadings table.

A saved experiment's own PCA variable names are no longer replaced by
whatever the studio has selected at the time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pearson drew four heatmaps: r on a one-hue scale, p-values that all read
0.00 on solid red, and the lower and upper CI bounds as two more grids, while
the table only gave the row count. It now draws one lower-triangle heatmap
(each pair once, no diagonal of 1s) on a diverging scale with r, the 95% CI
and p in the tooltip, and the table lists every pair with r, CI and p,
strongest first. A y-by-x correlation matrix still draws whole.

Columns named Variable* in result tables now left-align like Variable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Naive Bayes CV and logistic regression CV opened on a confusion matrix whose
colour was dominated by the majority class, that kept an unused "unknown"
class as an all-zero row and column, and that listed classes bottom-up. The
naive Bayes metrics table spread 13 columns (accuracy repeated per class,
zeros for the unused class) until fold names wrapped letter by letter.

Both now lead with key figures: fold accuracy with its spread, the
majority-class baseline it has to beat, balanced accuracy and macro F1 from
the pooled confusion matrix, and mean ROC AUC when folds report one. The
confusion matrix drops classes absent on both sides, reads top-down and
shades each cell by share of its actual class with count and percent. The
naive Bayes tables become per-class precision/recall/F1 with support,
accuracy per fold, and the combined matrix. ROC curves are no longer
smoothed, gain a chance diagonal, and the tooltip lists every fold.

Naive Bayes priors draw as one compact horizontal bar per class. The
key-figure summary module is renamed summary-figures since it now covers
more than hypothesis tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ixed-unit chart

The CV chart put RMSE, R², MAE and the F statistic on one axis with each
standard deviation as its own bar, so F (~3,900) flattened everything else
and the SD bars read as extra metrics. The result now leads with RMSE and
MAE in outcome units, out-of-fold R² with the share of variance it means,
each with its fold spread, and the fold count. F is left to the table: it
describes each training fit, not held-out prediction. The chart and its
renderer are removed; the [mean, sd], {mean, std} and legacy mean_sq_error
shapes are covered by the figure builder's specs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Cox summary table labelled event_var as the follow-up time and
dependent_var as the event indicator, so a run on days-to-follow-up with
death as the event read "Follow-up time: Death 3m". Exaflow takes the time
as y (dependent_var) and the event as event_var; the rows now follow that,
and the spec fixture that encoded the swap uses a real time/event pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Linear mixed models and binary GLMMs showed a raw fixed-effects table and a
13-row model summary. They now use the regression view: fixed effects in the
coefficients card (odds ratios with an interval-vs-1 column for the GLMM),
and key figures led by the ICC, the share of variance between groups of the
grouping variable (latent scale with pi^2/3 for the logit GLMM), then groups,
observations and AIC. A model that did not converge says so first, with its
iteration count. A grouping variable sent as a list is now labelled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The outlier report spread strategy, tail, fold and both bounds over five
narrow columns ("madboth 3"), showed variable codes, and interleaved
variables by dataset. It now reads Variable, Dataset, Rule ("IQR × 1.5,
both tails"), Kept range, Below, Above, Outliers and Outlier %, keeps each
variable's datasets together, and shows variable labels. Null counts still
read Unavailable, distinct from zero.

Result tables meant to left-align name columns (Variable, Role, Categories)
but the rule lost to the later right-align rule of equal specificity, so it
never applied; it now comes after it, covers the header cell, and includes
Dataset and Rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In 360px compare columns the coefficient rows wrapped "< 0.001" and each CI
onto two lines. The table now responds to its own container width rather
than the viewport: numbers never wrap, and below 620px the interval sketch
column drops out so variable, estimate, CI and p fit side by side; All
columns scrolls sideways there. The ICC note is shortened to fit the strip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The detail tables printed p as 0 (t-tests, Mann-Whitney), 1.110e-16 (both
ANOVAs), 3.873e-238 (chi-squared) or <0.001 (Cox), next to key figures that
already said < 0.001. Every table p-value now goes through formatPValue:
"< 0.001" below that, three decimals above, blank when missing.

Tukey p-values come from statsmodels' psturng, which limits its output to
[0.001, 0.9], so the ends now read "≤ 0.001" and "≥ 0.900" instead of
presenting the clip as a measured value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… CIs

The ordinal GLMM joins LMM and the binary GLMM in the coefficient view. Its
cumulative logit is P(Y <= j) = sigmoid(k_j - eta), so odds ratios read as
the odds of a higher outcome category; the category order and cutpoints go
into the model-fit details (integer categories Exaflow echoes as "2.0" show
as "2").

Ratios used a fixed 3 significant digits, so a tight interval printed as
"1.04 to 1.04". Each row now takes the fewest digits (3 to 6) at which its
CI bounds differ: "1.036, 1.035 to 1.036".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… syntax

Coefficient rows printed patsy names: "Sex[female]",
"kmeans_cluster[cluster_2]", "stroke_territory_cohort[PCS]". The
coefficient view now splits a dummy term into the variable and a muted
level ("Sex · female") and reads raw snake_case codes of created columns as
words ("K-means cluster · Cluster 2"). When any row is a category level the
note says it is compared with the level not listed. Only the on-screen view
changes; the CSV keeps the original term names, and the tables, PDF and Cox
forest plot keep their own parsing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A survival model's information comes from its events, not its rows, so Cox
results now open with the event count and rate, events per covariate
(flagged below the usual 10), a non-convergence warning when it applies, and
McFadden pseudo R² for the stacked model. The forest plot title drops its
one-off teal for the ink and size the other chart titles use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The two-variable centres chart repeated the section title, drew every
centre the same size and started both axes at zero, which pushed most
centres into a corner. Centres are now bubbles whose area follows the
cluster's size (midpoint of its privacy-safe interval), the axes fit the
centres with padding so no bubble sits on an axis, and the tooltip gives
the coordinates and approximate row count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… scale

Gaussian naive Bayes charted only its class priors; how the classes differ
was left to the theta and variance tables, in each feature's own units. A
class-profile chart now places each class mean in pooled within-class SDs
from the overall mean, one row per feature on a shared axis, so the
features that separate the classes stand out. Feature names in Gaussian
results carry their labels (categorical results keep codes, which their
category_count lookup needs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l shares

Categorical naive Bayes printed a counts table and a separate log-probability
table per feature, both carrying an all-zero row for unused enumerations, and
the class prior as a log. Each feature is now one table, category by class,
with the count and the model's P(category | class) as a percentage, unused
categories dropped; the class summary shows the prior as a percentage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The t-test and Mann-Whitney figures said "group A" / "group B" because the
groups live in the run's parameters, which the result view never received.
AlgorithmResultComponent now takes the run parameters (experiment detail,
studio execution panel and compare columns all pass them) and labels groupA
and groupB through the x variable's enumerations: "yes − no · 95% CI ...".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… chart plus table

Cox results drew a hazard-ratio forest plot and then listed the same hazard
ratios and CIs in a table below it. Cox now uses the coefficient view like
the other regression models: hazard ratios with their CI, an interval-vs-1
column and p in one card, events and events per covariate as key figures,
and the study summary (follow-up time, event indicator, ties, fit) under
model-fit details. The forest-plot renderer and its spec are removed, and
the coefficient note names the ratio it is drawn around.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… already show

Several results showed the same numbers twice: key figures and then a
metric/value table (t-tests, Mann-Whitney, chi-squared and Fisher summaries,
SMD, linear regression CV error metrics), or a chart and then the table it
was drawn from (k-means centres, PCA variance and loadings, naive Bayes class
priors, the CV confusion matrix).

Each summary declares the table titles it fully covers
(TABLES_SHOWN_AS_FIGURES, the chart registry's replaces), the result view
hides those tables only when that summary actually rendered, and the
"Detailed results" heading moves into the table renderer so it disappears
with the last table. The few values a covered table had beyond its summary
moved into it first: SE of the mean difference and the one-sample SD in the
t-test figures, training rows next to each naive Bayes prior, approximate
size in each k-means legend entry (exact centres in the tooltip), and the
eigenvalue under each PCA component. PDF and CSV exports still read every
table from the registry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Five results still repeated part of a table under their summary. A view can
now cover part of a table, not only all of it (TableTrim: columns by header,
rows by first cell), and the screen drops just that part; a table with
nothing left to read disappears. Exports keep every table whole.

- One- and two-way ANOVA: df, F and p leave the table (they are in the
  figures); sums and mean squares stay.
- Pearson: r leaves the pairs table (it is in the heatmap); CI and p stay.
- Naive Bayes CV: the Mean ± SD row leaves the per-fold accuracy table.
- Logistic regression CV: the average and stdev rows leave the per-fold
  table; their precision, recall and F1 moved into a positive-class F1
  figure first, so nothing is lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KFilippopolitis and others added 17 commits October 19, 2026 14:14
…harts to screen readers

Leaving out tables the summary covers made some values reachable only as
canvas pixels (k-means centres, PCA loadings, naive Bayes priors). A
"Show all values as tables" button under the result brings every covered
table back whole, and hides them again; it only appears when something was
left out. Charts also turn on ECharts aria, which writes a text description
of each chart for screen readers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Table cells printed counts without grouping (111854), switched to
scientific notation from a million (sums of squares as 1.066e+6, four
digits lost at the source) and used an ASCII hyphen for negatives next to
key figures that use a minus sign. On screen, cells now group thousands
(111,854; 1,065,587), keep whole numbers whole, and use a typographic
minus; scientific notation is left for values below 1e-4. The table CSV
keeps plain, ungrouped numbers for spreadsheets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Logistic regression and the binary GLMM read "effect on the odds of 3m mRS
good outcome" without saying which level, and logistic regression CV
labelled its confusion matrix and baseline "Positive" / "Negative". The
run's positive_class parameter, labelled through the outcome's
enumerations, now completes them: "the odds that 3m mRS good outcome is
yes", a yes / not yes matrix, "always predicting yes".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Canvas text cannot read CSS, so charts drew in ECharts' default sans-serif
next to Inter, and each renderer styled (or forgot to style) its own title
and tooltip. The chart renderer now applies one house style under every
chart's own settings: the app font, 13px ink titles with muted subtitles,
and a white tooltip card with a hairline border. Renderers drop the title
styles they duplicated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chi-squared and Fisher category tables named a created column by its
code ("stroke_territory_cohort", and "STROKE_TERRITORY_COHORT \ EVT" over
the expected counts) because created columns have no data-model label.
The coefficient view's readable() fallback now lives in result-format and
also serves the table labels: "Stroke territory cohort".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A classifier at 70.4% next to a 70.2% baseline read as two separate
numbers. The accuracy figure now ends with its gain over the
majority-class baseline ("+0.2 pts over the baseline"), computed from the
pooled confusion matrix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e columns

In 360px compare columns the PCA loadings and Pearson variable names ran
into each other and the confusion-matrix caption was cut at both ends.
PCA loadings now put variables in rows (names wrap on the left) and
components in columns with their variance share under each; Pearson's
column names are slanted; the confusion caption is two short lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
overflow-wrap: anywhere let a squeezed first column shrink to single
characters, so the k-means profiles table read "Cluste / r 0" and the
notes table "Priv / acy". break-word only breaks a word that cannot fit on
its own line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- K-means with three or more variables draws a centres heatmap shaded
  around the size-weighted mean instead of parallel coordinates, whose
  lines no palette keeps apart past four clusters. Profile lines name
  variables by label; the Interpretation column, which only restated the
  profile and compactness, is gone; the elbow measure moves to a subtitle.
- PCA "Loadings" are unit eigenvectors, so they are now "Component
  weights"; variance bars keep one decimal.
- Cross-validation tables call per-fold n_obs "Training rows". Logistic
  regression CV rows read Fold n / Mean / SD, and its positive-class F1
  stays in that table instead of wrapping the figure strip.
- Outlier report shows the share as a percentage ("8.9%"); the Pearson
  pairs table keeps r, the value it is sorted by.
- ROC legend reads "Fold 1 · 0.864"; Naive Bayes class profiles name the
  classes on the first row; confusion matrix labels get room to breathe.
- Result tables put a gap before every column and left-align prose.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns clusters

White text never reaches 4.5:1 on the red half of the diverging scale
(2.1:1 at the old 0.5 switch) and only beats ink on the blue end past
0.7. Correlation, PCA weights, confusion matrix and k-means centres now
share DIVERGING_COLORS and cellLabelColor from chart-palette.ts; the
worst cell goes from 2.1:1 to about 4.2:1.

A k-means cluster under the privacy threshold arrives as "<10". It did
not parse, so the centres heatmap fell back to an unweighted mean for
every cluster and the cluster lost its size. "<N" now weighs N/2 and
prints as sent; an empty cluster's "0" weighs nothing and prints "0".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ECharts renders a tooltip formatter's return value as HTML. Variable,
class, group, dataset and cluster labels come from data-model metadata,
created columns and stored results, and shared experiments render in
other users' browsers, so every custom tooltip now escapes them.
escapeHtml takes any value, so callers need no String() wrapper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ale"

The Playwright run from master looked for the row "Sex[Male]", the model
syntax this branch replaces with variable and level ("Sex · Male"). The
coefficient view's rows also sat outside any table role, which is
invalid ARIA: the container is now a labelled table with column headers
and cells.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer feedback from the result-views quiz:
- Large numbers group thousands with a narrow no-break space (27 308)
  instead of a comma; PDF cells use a plain space, the font has no
  glyph for it.
- Logistic regression key columns are Estimate, Std. error, z and
  p-value; the odds ratio, its CI and the interval column move to All
  columns. Coefficient tables call the p column "p-value".
- Linear mixed model key columns show Std. error instead of the 95% CI.
- Mann-Whitney goes back to the master-style table, with P(A > B) added.
- Gaussian naive Bayes explains how to read the class-profile chart;
  linear regression CV explains RMSE and MAE.
- Independent t-test brings back the interval chart, vertical: mean
  difference on x, value and 95% CI on y.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… after rebase

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inite

JSON drops Infinity and NaN, so a perfect fit or an undefined test only survives as Exaflow's display fields. The chart spec now renders through change detection.

Co-authored-by: Cursor <cursoragent@cursor.com>
@KFilippopolitis
KFilippopolitis force-pushed the refactor/algorithm-visualizations branch from 556a6b5 to b262246 Compare October 19, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants