Skill Tracer
Skills › Archify › archify › README.md

README.md

130 lines · archify/renderers/class/README.md at a406594

Open on GitHub
1# Class and Interface Renderer
2
3Render `diagram_type: "class"` JSON files into the standard Archify HTML template.
4
5```bash
6node archify/renderers/class/render-class.mjs input.class.json output.html
7```
8
9The renderer validates input against `archify/schemas/class.schema.json` with the
10bundled standalone validator. No dependency installation is required. If
11`output.html` is omitted, it uses `meta.output` or falls back to `class.html` in
12the current working directory. `--layout-json` prints the placed types and
13routes instead of writing HTML.

Class and Interface Renderer

Render diagram_type: "class" JSON files into the standard Archify HTML template.

node archify/renderers/class/render-class.mjs input.class.json output.html

The renderer validates input against archify/schemas/class.schema.json with the bundled standalone validator. No dependency installation is required. If output.html is omitted, it uses meta.output or falls back to class.html in the current working directory. --layout-json prints the placed types and routes instead of writing HTML.

Raw lines 1 to 14
15## Input
17```json
19 "schema_version": 1,
20 "diagram_type": "class",
21 "meta": { "title": "Payment module types" },
22 "types": [],
23 "relationships": [],
24 "cards": []
26```
28A type carries its name in `label`, its `kind`, a `row`/`col` grid cell (or an
29absolute `pos`), and optional `sublabel`, `attributes`, `methods`, and `sources`.
30Authors choose the members the explanation needs; a type may show none.
32| `kind` | Header | Colour family |
33| --- | --- | --- |
34| `class` | name only | backend |
35| `abstract` | `«abstract»`, italic name | backend |
36| `interface` | `«interface»` | frontend |
37| `enum` | `«enumeration»`; `attributes` are the constants | messagebus |
38| `record` | `«record»` | database |
40An attribute is `{ name, type?, visibility?, static? }` and draws as
41`+ name: Type`. A method is `{ name, parameters?, returns?, visibility?,
42static?, abstract? }` and draws as `+ name(parameters): Returns`. Visibility
43uses the UML glyphs `+` public, `#` protected, `~` package, `-` private; a
44static member is underlined and an abstract method is italic. Interface
45attributes describe property contracts (for example, TypeScript's
46`interface Person { name: string }`); they do not imply stored implementation
47state. Interfaces may also declare static constants.

Input

{
  "schema_version": 1,
  "diagram_type": "class",
  "meta": { "title": "Payment module types" },
  "types": [],
  "relationships": [],
  "cards": []
}

A type carries its name in label, its kind, a row/col grid cell (or an absolute pos), and optional sublabel, attributes, methods, and sources. Authors choose the members the explanation needs; a type may show none.

kindHeaderColour family
classname onlybackend
abstract«abstract», italic namebackend
interface«interface»frontend
enum«enumeration»; attributes are the constantsmessagebus
record«record»database

An attribute is { name, type?, visibility?, static? } and draws as + name: Type. A method is { name, parameters?, returns?, visibility?, static?, abstract? } and draws as + name(parameters): Returns. Visibility uses the UML glyphs + public, # protected, ~ package, - private; a static member is underlined and an abstract method is italic. Interface attributes describe property contracts (for example, TypeScript's interface Person { name: string }); they do not imply stored implementation state. Interfaces may also declare static constants.

Raw lines 15 to 48
49## Relationships
51Every relationship reads `from` -> `to`, and `kind` owns the whole notation, so
52an implementation can never look like a call arrow:
54| `kind` | Meaning | Line | Marker |
55| --- | --- | --- | --- |
56| `dependency` | `from` uses `to` | dashed | open arrow at `to` |
57| `association` | `from` holds a reference to `to` | solid | open arrow at `to` |
58| `inheritance` | `from` extends `to` | solid | hollow triangle at `to` |
59| `realization` | `from` implements interface `to` | dashed | hollow triangle at `to` |
60| `composition` | `from` owns `to` and its lifetime | solid | filled diamond at `from` |
61| `aggregation` | `from` groups `to` without owning it | solid | hollow diamond at `from` |
63Semantic checks: a realization runs from a non-interface to an interface
64(`class/realization-target`); inheritance never crosses the interface boundary
65(`class/inheritance-kind`); inheritance cannot form a cycle
66(`class/inheritance-cycle`); a relationship cannot connect a type to itself.

Relationships

Every relationship reads from -> to, and kind owns the whole notation, so an implementation can never look like a call arrow:

kindMeaningLineMarker
dependencyfrom uses todashedopen arrow at to
associationfrom holds a reference to tosolidopen arrow at to
inheritancefrom extends tosolidhollow triangle at to
realizationfrom implements interface todashedhollow triangle at to
compositionfrom owns to and its lifetimesolidfilled diamond at from
aggregationfrom groups to without owning itsolidhollow diamond at from

Semantic checks: a realization runs from a non-interface to an interface (class/realization-target); inheritance never crosses the interface boundary (class/inheritance-kind); inheritance cannot form a cycle (class/inheritance-cycle); a relationship cannot connect a type to itself.

Raw lines 49 to 67
68## Layout
70`layout.mode: "grid"` (the default) places types by `row`/`col` on the banded
71grid shared with the ERD renderer: each column takes its widest type and each
72row its tallest. Types are centred in their row band so a relationship between
73two types of one row is a straight line. A half-step `col` (e.g. `1.5`) centres
74a type between two columns without sizing either, which is how a supertype sits
75symmetrically over two subtypes; it occupies both neighbouring cells. `layout.gapX`/`gapY` (default 128/84)
76leave room for markers and labels; `layout.typeW` (180) is the minimum and
77`layout.typeMaxW` (300) the maximum automatic width.
79Members are never truncated. A type without `width` grows to its widest member
80up to `typeMaxW`; longer members wrap. A wrapped method is set like formatter
81output: `name(` ends the first line, parameters hang one step deeper (breaking
82after commas), and `): Return` closes it. Visibility glyphs and type
83annotations are set in the muted ink so member names carry the row. An authored `width` is
84authoritative, and only a title that does not fit it is an error
85(`class/title-text-capacity`).
87Generalizations are routed vertically whenever the two types are not side by
88side, so supertypes stand above their subtypes. Two or more automatic
89generalizations of one kind into one supertype, from subtypes placed below it
90with at least 40px of gap, draw as one hierarchy bus: a single triangle and
91trunk, a horizontal bus halfway down the gap, and a drop to each subtype. The
92bus is drawn from the supertype outward so a dashed realization bus keeps one
93dash phase. Its `data-motion-path` carries the source-to-target route so Viewer
94tokens and flow overlays follow the relationship's semantic direction. A bus
95that would cross another type falls back to ordinary routes.
97主干还会与完整场景中的其他关系共同检查:同一个主干组可以共享端口和线段。
98主干候选若与其他组或普通关系争用标记空间、重叠走廊或形成内部交叉,
99整组关系回退到现有路由器,以独立端口和走廊重新规划;无冲突的
100其他主干保留。每轮回退后重新检查剩余主干,且只删除冲突组,不反复恢复尝试。
101类型位置、关系种类和方向、显式 `via`、端口、路由及标签位置保持作者的控制。
102此检查决定是否保留自动主干,不承诺固定路线周围满足全部自动间距或任意布局都能成功。
103固定路线之间的冲突和无法绕开的复杂交叉仍遵循现有路由约束,不会修改作者指定的几何。
105All other relationships use the shared orthogonal router
106(`../architecture/routing.mjs`) and the shared Clean Flow, crossing, corridor,
107rhythm, and label-clearance gates.
109Labels sit on the segment with the most room: above a horizontal run, beside a
110vertical one. `labelAt`, `labelDx`/`labelDy`, and `labelSegment` override it.
112`via: []` 与省略 `via` 等价,在主干选择和回退路由前统一按无路径点处理。
113非空 `via` 仍是显式几何;其他路由与标签控制不变,原始 JSON 不会被改写。

Layout

layout.mode: "grid" (the default) places types by row/col on the banded grid shared with the ERD renderer: each column takes its widest type and each row its tallest. Types are centred in their row band so a relationship between two types of one row is a straight line. A half-step col (e.g. 1.5) centres a type between two columns without sizing either, which is how a supertype sits symmetrically over two subtypes; it occupies both neighbouring cells. layout.gapX/gapY (default 128/84) leave room for markers and labels; layout.typeW (180) is the minimum and layout.typeMaxW (300) the maximum automatic width.

Members are never truncated. A type without width grows to its widest member up to typeMaxW; longer members wrap. A wrapped method is set like formatter output: name( ends the first line, parameters hang one step deeper (breaking after commas), and ): Return closes it. Visibility glyphs and type annotations are set in the muted ink so member names carry the row. An authored width is authoritative, and only a title that does not fit it is an error (class/title-text-capacity).

Generalizations are routed vertically whenever the two types are not side by side, so supertypes stand above their subtypes. Two or more automatic generalizations of one kind into one supertype, from subtypes placed below it with at least 40px of gap, draw as one hierarchy bus: a single triangle and trunk, a horizontal bus halfway down the gap, and a drop to each subtype. The bus is drawn from the supertype outward so a dashed realization bus keeps one dash phase. Its data-motion-path carries the source-to-target route so Viewer tokens and flow overlays follow the relationship's semantic direction. A bus that would cross another type falls back to ordinary routes.

主干还会与完整场景中的其他关系共同检查:同一个主干组可以共享端口和线段。 主干候选若与其他组或普通关系争用标记空间、重叠走廊或形成内部交叉, 整组关系回退到现有路由器,以独立端口和走廊重新规划;无冲突的 其他主干保留。每轮回退后重新检查剩余主干,且只删除冲突组,不反复恢复尝试。 类型位置、关系种类和方向、显式 via、端口、路由及标签位置保持作者的控制。 此检查决定是否保留自动主干,不承诺固定路线周围满足全部自动间距或任意布局都能成功。 固定路线之间的冲突和无法绕开的复杂交叉仍遵循现有路由约束,不会修改作者指定的几何。

All other relationships use the shared orthogonal router (../architecture/routing.mjs) and the shared Clean Flow, crossing, corridor, rhythm, and label-clearance gates.

Labels sit on the segment with the most room: above a horizontal run, beside a vertical one. labelAt, labelDx/labelDy, and labelSegment override it.

via: [] 与省略 via 等价,在主干选择和回退路由前统一按无路径点处理。 非空 via 仍是显式几何;其他路由与标签控制不变,原始 JSON 不会被改写。

Raw lines 68 to 114
115## Reader and export
117An automatic canvas declares `data-reader-fit="intrinsic-height"` and a 7.5px
118reader text floor, like the ERD, so a tall model scrolls instead of shrinking
119members past legibility. The legend lists the relationship kinds present, drawn
120in their own notation; hovering or focusing an entry dims the other kinds. Every
121type is a focusable node whose passport shows its kind and `sublabel`; supplied
122`sources` appear as repository evidence. The notation lives in the SVG's own
123`<style>` and markers, so SVG/PNG export keeps it.

Reader and export

An automatic canvas declares data-reader-fit="intrinsic-height" and a 7.5px reader text floor, like the ERD, so a tall model scrolls instead of shrinking members past legibility. The legend lists the relationship kinds present, drawn in their own notation; hovering or focusing an entry dims the other kinds. Every type is a focusable node whose passport shows its kind and sublabel; supplied sources appear as repository evidence. The notation lives in the SVG's own <style> and markers, so SVG/PNG export keeps it.

Raw lines 115 to 124
125## Tested size
127`examples/payment-processors.class.json` (11 types, 10 relationships, long
128signatures) renders in about 0.2s and passes the showcase gates at a 7.5px
129projected text minimum in a 1440px desktop reader. Wider models need more rows
130rather than more columns to stay above that floor.

Tested size

examples/payment-processors.class.json (11 types, 10 relationships, long signatures) renders in about 0.2s and passes the showcase gates at a 7.5px projected text minimum in a 1440px desktop reader. Wider models need more rows rather than more columns to stay above that floor.

Raw lines 125 to 130