Skip to content

feat(export): add zoom-html, a three-level architecture view - #57

Merged
alexwrite merged 2 commits into
mainfrom
feat/zoom-view
Oct 11, 2026
Merged

alexwrite merged 2 commits into
mainfrom
feat/zoom-view

Conversation

@alexwrite

Copy link
Copy Markdown
Owner

Context

Closes #50 on merge. graph.html stops being readable past a few dozen nodes: one point per community, tests and framework classes mixed in, a central hairball, colours without meaning. This adds a view that reads at a glance even on a large repository, following the C4 zoom levels (S. Brown) and "overview first, zoom and filter, details on demand" (B. Shneiderman, 1996).

What

graphify export zoom-html [--graph PATH] [--output HTML] [--label NAME] writes one self-contained, offline HTML file (default graphify-out/GRAPH_ZOOM.html):

Level Shows One thing highlighted
1 Domains First folder under the code root (src/, app/); inside a layer folder (src/Controller/Account/, app/Http/Controllers/Admin/) the folder below it. Bar length = classes. Rows: callers above callees (greedy feedback-arc-set order, Eades-Lin-Smyth 1993, then longest-path rows). The 15 largest domains, the rest folded; the 15 strongest links with their call count Domains that call back up and close a cycle: red "!" badge, red links on hover/focus
2 One domain Classes in columns by layer: Route, Controller, Service, Repository, Entity / Model, View, Other. Templates join only through renders edges. Layer-to-layer call counts as arcs Classes that call a layer to their left: red outline + triangle icon, arc with "!"
3 One class Methods sorted by callers (bar), each with callers and callees, file:line of every call site "forbidden direction" and "inferred" tags

Tests, framework/vendor classes and code outside the code root are hidden by default, each behind a checkbox that shows its class count.

Why not callflow-html or tree as the base

Both were evaluated first. Kept: the idea of aggregating edges per section, and the arc-direction contract (paths.restore_arc_direction). Not reused as renderers: both load their library from a CDN with a version range and no SRI (#52), so they break offline, and callflow-html groups by community, which is the very problem reported in #50. The new view needs no library.

Fail-closed boundaries

Accessibility

Native links and buttons, full keyboard path (Tab, Enter to zoom in, Escape to zoom out, focus moved to the level heading), visible 3px focus ring, table twin for levels 1 and 2, nothing carried by colour alone (badge, icon, text tags), prefers-color-scheme and prefers-reduced-motion honoured, no text under 12px, no horizontal page scroll at 320px. Contrast measured for every token pair in both themes (all text >= 4.5:1, graphics >= 3:1).

Verification (commands actually run)

  • uv run pytest tests/test_zoom_html.py -q: 22 passed. Mutation check: dropping the EXTRACTED-only rule, reading source/target instead of _src/_tgt, or disabling the domain back-edge flag each makes one test fail.
  • uv run pytest tests/ -q: 7641 passed, 14 skipped (run before the last label-placement tweaks to the page script; scoped tests re-run after them: 117 passed).
  • uv run ruff check .: all checks passed. uv run pyright on the touched files: no new error (the two remaining errors in cli.py and __main__.py exist on main).
  • Real repositories (two Symfony projects, ClientXCMS / Laravel 12), --code-only: generation 0.1 to 0.6 s, page 0.3 to 2.4 MB for 500 to 3,400 classes. axe-core 4.10.3 (WCAG 2.0/2.1 A and AA): 0 violations on the 3 levels x 2 themes x 3 projects; no console error.

Plan post-merge

Regenerate the view on a large repository after graphify update and check level 1 stays within 15 boxes.

alexwrite and others added 2 commits October 11, 2026 16:14
Domains, then one domain's classes in columns by layer, then one class
with its methods and call sites. Offline single file, light and dark.
Refs #50

Co-Authored-By: Claude <noreply@anthropic.com>
Refs #50

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Thanks for the pull request, @alexwrite. A maintainer will review it soon.

Want to talk it through while it is in review? Come join us on our Discord server. For longer-form discussion there is also GitHub Discussions.

A couple of things that speed up review: make sure the test suite passes on Python 3.10 and 3.13, and that the change keeps extraction deterministic.

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.

Vue du graphe compréhensible d'un coup d'œil, même sur un gros dépôt

1 participant