Skip to content

feat(vocabulary): the word cloud as SVG (M19b) - #31

Open
jgrodziski wants to merge 5 commits into
feat/m19a-vocabulary-coveragefrom
feat/m19b-vocabulary-cloud
Open

jgrodziski wants to merge 5 commits into
feat/m19a-vocabulary-coveragefrom
feat/m19b-vocabulary-cloud

Conversation

@jgrodziski

@jgrodziski jgrodziski commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

First step of milestone M19b in PLAN.md §20 (word cloud / glossary, #6). Stacked on #30 (itself on #29, #28, #27 and #26): review those first; this PR's diff is the five commits after #30.

It draws the word cloud: codegraph vocabulary --svg FILE writes one scope's words as an SVG image, beside the usual report.

Broadleaf's corpus cloud

The layout (cloud.ts)

  • Size reads as weight. The font size is interpolated on the square root of the weight, between 12 and 56 px, so a word's area follows its weight.
  • No randomness. Words go by weight descending, ties by text then class. Each takes the first point of an Archimedean spiral from the centre where its padded box overlaps nothing placed before it. The same words give the same layout in any order.
  • No fixed canvas. The canvas is whatever the words cover, shifted to start at (0, 0).
  • The measurer is handed in. The CLI uses a monospace one (0.6 em per cell; a combining mark takes no cell, a CJK or Hangul character takes two). The navigator's tab will hand it the browser's measureText and run the same function. The module imports types only, so a page can load it without the Node pipeline.

The SVG (svg.ts)

  • Colour is the class and nothing else. Each word carries one class attribute and a stylesheet colours it: domain in ink, technical muted, keyword and short faint. A prefers-color-scheme: dark palette applies on a dark page. No word has an inline fill.
  • The legend says what was counted: the scope, the class filter, how many words are shown out of how many, the role weights, the view, and the technical list with its digest. When more than one class is drawn, a key line names the colours.
  • The bytes are the same on every run. Coordinates round to 1/100 px. The Java fixture's cloud is a committed snapshot, fixtures/java/expected/vocabulary.svg.

The flag

  • --svg draws the scope the report shows: the corpus by default, or the one --scope names, an operation included. --class and --top choose the words.
  • It is refused with --level module|type and with --drift (exit 2), since a cloud shows one scope.
  • stderr says what was written: wrote 3794 bytes to F (cloud of corpus src: 40 of 73 domain terms).

The demo image

docs/vocabulary-broadleaf.svg is Broadleaf's corpus cloud at --top 80 (6.7 KB). It reads as commerce: order item customer product offer fulfillment payment sku cart catalog…. docs/cli.md and the website's vocabulary page link it and describe the flag.

Worth a look in review:

  • Padding is 4 px per side. I rendered the Java and Broadleaf clouds with headless Chrome, light and dark. At 2 px neighbouring words nearly touched.
  • The city's demo will use --height vocabulary:order, not --color. PLAN §20.2 asked for colour, but the city has no numeric colour channel. That's the last M19b PR; PLAN notes it.

Verification

  • pnpm -r build and pnpm -r typecheck green; eslint clean on every changed file; pnpm run gen:schemas leaves schemas/ unchanged; the Hugo site builds.
  • vocabulary 308 tests, cli 977, core 544; every other package passes except the Node 26 node:sqlite warning test noted on feat(core): language lexicons on profiles (M19a) #26.
  • Properties of the layout: no two padded boxes overlap, every box lies inside the reported canvas, any input order gives the same layout, and a heavier word is placed first and never drawn smaller.
  • Ten deliberate mutations of the layout, the SVG and the flag, one at a time; the tests caught each.
  • The bundled CLI (codegraph.cjs) reproduces the Java snapshot byte for byte. The single-executable build fails on this machine because Homebrew's Node lacks SEA support.

PLAN §20.4's first M19b item is checked.

Part of #6.

🤖 Generated with Claude Code

Jérémie Grodziski and others added 5 commits October 26, 2026 10:42
layoutCloud (PLAN.md §20.2): pure geometry, no randomness. Words by
weight, ties by text then class, so any order of the same words lays
out the same; the font size on the square root of the weight (area
reads as magnitude); each padded box at the first point of a 2:1
Archimedean spiral where it overlaps nothing placed. The measurer is
injected: a monospace default that counts a mark as no cell and a wide
character as two, or a page's measureText. Type imports only, so the
navigator's tab can run the same function.

Properties: no overlap, every box inside the canvas, order-independent,
weight order with sizes never inverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vocabularyCloudSvg draws one scope's words: size by weight, colour by
class and nothing else (a stylesheet keyed by class, light and dark;
no inline fill), a key when more than one class is drawn, and a legend
stating the scope, counts, weights, view and technical list. The font
is monospace, so the bytes are the same on every run:
fixtures/java/expected/vocabulary.svg is a snapshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--svg FILE draws the cloud of the one scope reported, the corpus or the
--scope one (an operation counted on demand too), from the words
--class and --top pick, and confirms on stderr. A cloud is one scope's,
so --svg with --level module|type or --drift is a usage error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/cli.md and the website's vocabulary page describe --svg: what
size, colour and the legend say, and when the flag is refused.
docs/vocabulary-broadleaf.svg is BroadleafCommerce's corpus cloud,
drawn by the command with --top 80.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
§20.1's command paragraph states when --svg is refused; §20.2 records
the layout's settings, the measurer's cells and the SVG's palette as
built, and the Broadleaf demo. The first M19b item is checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
codegraph 9ba26fa Commit Preview URL

Branch Preview URL
Oct 26 2026, 11:40 AM

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.

1 participant