@zombie-mermaid/svg-renderer 4.2.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +15 -1
  2. package/dist/index.cjs +52 -52
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +23 -4
  5. package/dist/index.d.ts +23 -4
  6. package/dist/index.js +897 -849
  7. package/dist/index.js.map +1 -1
  8. package/package.json +14 -5
  9. package/src/__tests__/c4-label-clearance-1290.test.ts +0 -112
  10. package/src/__tests__/c4-line-ends-1208.test.ts +0 -52
  11. package/src/__tests__/c4-mermaid-reference.test.ts +0 -124
  12. package/src/__tests__/c4-svg.test.ts +0 -337
  13. package/src/__tests__/c4-text-width-1210.test.ts +0 -43
  14. package/src/__tests__/class-component-order-1249.test.ts +0 -40
  15. package/src/__tests__/class-diamond-markers-1232.test.ts +0 -59
  16. package/src/__tests__/class-member-right-padding-1238.test.ts +0 -43
  17. package/src/__tests__/class-namespace-1196.test.ts +0 -165
  18. package/src/__tests__/class-namespace-sparse-elk-1196.test.ts +0 -96
  19. package/src/__tests__/class-visibility-markers-1237.test.ts +0 -27
  20. package/src/__tests__/edge-jog-straightening-1388.test.ts +0 -57
  21. package/src/__tests__/elk-adapter-utils.test.ts +0 -166
  22. package/src/__tests__/er-attribute-right-padding-1262.test.ts +0 -47
  23. package/src/__tests__/er-cardinality-markers-1233.test.ts +0 -35
  24. package/src/__tests__/er-default-direction-1250.test.ts +0 -69
  25. package/src/__tests__/er-edge-label-contrast-1244.test.ts +0 -58
  26. package/src/__tests__/fixtures/c4-mermaid-reference.json +0 -626
  27. package/src/__tests__/flowchart-parallel-edge-lanes-1308.test.ts +0 -168
  28. package/src/__tests__/pie-layout.test.ts +0 -215
  29. package/src/__tests__/pie-svg.test.ts +0 -194
  30. package/src/__tests__/render-mermaid-svg.test.ts +0 -64
  31. package/src/__tests__/sequence-label-clearance-1242.test.ts +0 -162
  32. package/src/__tests__/sequence-nested-activation-1241.test.ts +0 -37
  33. package/src/__tests__/svg-edge-to-own-cluster-1310.test.ts +0 -32
  34. package/src/__tests__/xychart-smooth-curve.test.ts +0 -42
  35. package/src/__tests__/xychart-x-label-overlap-1243.test.ts +0 -62
  36. package/src/c4/arial-widths.ts +0 -59
  37. package/src/c4/layout.ts +0 -680
  38. package/src/c4/metrics.ts +0 -261
  39. package/src/c4/renderer.ts +0 -366
  40. package/src/class/layout.ts +0 -525
  41. package/src/class/renderer.ts +0 -669
  42. package/src/edge-curves.ts +0 -205
  43. package/src/elk-instance.ts +0 -292
  44. package/src/er/layout.ts +0 -216
  45. package/src/er/renderer.ts +0 -516
  46. package/src/generated/mono-font-subset.ts +0 -32
  47. package/src/index.ts +0 -277
  48. package/src/layout-engine/back-edges.ts +0 -73
  49. package/src/layout-engine/compound-flat.ts +0 -916
  50. package/src/layout-engine/constants.ts +0 -19
  51. package/src/layout-engine/edge-bundling.ts +0 -458
  52. package/src/layout-engine/elk-adapter-utils.ts +0 -81
  53. package/src/layout-engine/elk-graph-builder.ts +0 -245
  54. package/src/layout-engine/from-elk.ts +0 -767
  55. package/src/layout-engine/inner-edges.ts +0 -329
  56. package/src/layout-engine/jog-straightening.ts +0 -52
  57. package/src/layout-engine/layer-alignment.ts +0 -174
  58. package/src/layout-engine/layout-hints.ts +0 -27
  59. package/src/layout-engine/to-elk.ts +0 -855
  60. package/src/layout-engine.ts +0 -115
  61. package/src/pie/layout.ts +0 -234
  62. package/src/pie/renderer.ts +0 -161
  63. package/src/registry.ts +0 -441
  64. package/src/renderer.ts +0 -1510
  65. package/src/resolve-colors.ts +0 -339
  66. package/src/sequence/layout.ts +0 -766
  67. package/src/sequence/renderer.ts +0 -687
  68. package/src/shape-clipping.ts +0 -197
  69. package/src/styles.ts +0 -145
  70. package/src/title-gaps.ts +0 -161
  71. package/src/xychart/layout.ts +0 -727
  72. package/src/xychart/renderer.ts +0 -676
package/src/er/layout.ts DELETED
@@ -1,216 +0,0 @@
1
- /**
2
- * ER diagram layout engine (ELK.js).
3
- *
4
- * Each entity box has:
5
- * 1. Header (entity name)
6
- * 2. Attribute rows (type, name, keys)
7
- */
8
-
9
- import type { ElkNode, ElkExtendedEdge } from 'elkjs'
10
- import type {
11
- ErDiagram,
12
- ErEntity,
13
- PositionedErDiagram,
14
- PositionedErEntity,
15
- PositionedErRelationship,
16
- } from '@zombie-mermaid/mermaid-parser'
17
- import type { ErRenderOptions } from '@zombie-mermaid/core'
18
- import {
19
- estimateTextWidth,
20
- estimateMonoTextWidth,
21
- FONT_WEIGHTS,
22
- resolveFontSizes,
23
- } from '../styles.ts'
24
- import { elkLayoutSync } from '../elk-instance.ts'
25
- import { extractEdgePoints } from '../layout-engine/elk-adapter-utils.ts'
26
- import {
27
- ELK_DIRECTION_FALLBACK,
28
- baseElkLayoutOptions,
29
- buildElkEdge,
30
- buildElkLeafNode,
31
- directionToElk,
32
- } from '../layout-engine/elk-graph-builder.ts'
33
-
34
- /** Layout constants for ER diagrams */
35
- const ER = {
36
- padding: 40,
37
- boxPadX: 14,
38
- headerHeight: 34,
39
- rowHeight: 22,
40
- minWidth: 140,
41
- attrFontSize: 11,
42
- attrFontWeight: 400,
43
- nodeSpacing: 70,
44
- layerSpacing: 90,
45
- } as const
46
-
47
- type EntitySizeMap = Map<string, { width: number; height: number }>
48
-
49
- /** Build ELK graph and size map from an ER diagram. */
50
- /**
51
- * Width of an attribute row sized for the worst-case glyph advance.
52
- *
53
- * The mono face advances 0.6em per glyph (6.6px at the 11px attribute size),
54
- * but browsers that don't position glyphs at subpixel offsets (headless
55
- * Chromium on Linux) round each advance to a whole pixel, so a long row draws
56
- * wider than `estimateMonoTextWidth` says and the type runs into the
57
- * right-aligned name (#1262, same cause as class members in #1238).
58
- */
59
- function attrTextWidth(text: string): number {
60
- return text.length * Math.ceil(estimateMonoTextWidth('M', ER.attrFontSize))
61
- }
62
-
63
- function buildErElkGraph(
64
- diagram: ErDiagram,
65
- options: ErRenderOptions,
66
- ): { elkGraph: ElkNode; entitySizes: EntitySizeMap } {
67
- const entitySizes: EntitySizeMap = new Map()
68
- const fontSizes = resolveFontSizes(options.fontSizes)
69
-
70
- for (const entity of diagram.entities) {
71
- const headerTextW = estimateTextWidth(
72
- entity.label,
73
- fontSizes.nodeLabel,
74
- FONT_WEIGHTS.nodeLabel,
75
- )
76
- let maxAttrW = 0
77
- for (const attr of entity.attributes) {
78
- const attrText = `${attr.type} ${attr.name}${attr.keys.length > 0 ? ' ' + attr.keys.join(',') : ''}`
79
- const w = attrTextWidth(attrText)
80
- if (w > maxAttrW) maxAttrW = w
81
- }
82
- const width = Math.max(
83
- ER.minWidth,
84
- headerTextW + ER.boxPadX * 2,
85
- maxAttrW + ER.boxPadX * 2,
86
- )
87
- const height =
88
- ER.headerHeight + Math.max(entity.attributes.length, 1) * ER.rowHeight
89
- entitySizes.set(entity.id, { width, height })
90
- }
91
-
92
- // Iterate entitySizes directly (populated above, in diagram.entities order)
93
- // rather than looking each entity back up by id — sidesteps needing an
94
- // assertion or invariant check for a lookup that can't actually miss.
95
- const children: ElkNode[] = []
96
- for (const [id, size] of entitySizes) {
97
- children.push(buildElkLeafNode(id, size))
98
- }
99
-
100
- // ER edge labels carry no per-label layout options — placement is set
101
- // once on the root graph below (`elk.edgeLabels.placement: CENTER`).
102
- const labelStyle = { fontSize: fontSizes.edgeLabel }
103
-
104
- const edges: ElkExtendedEdge[] = []
105
- for (const [i, rel] of diagram.relationships.entries()) {
106
- edges.push(
107
- buildElkEdge({
108
- id: `e${i}`,
109
- source: rel.entity1,
110
- target: rel.entity2,
111
- label: rel.label,
112
- labelStyle,
113
- }),
114
- )
115
- }
116
-
117
- const elkGraph: ElkNode = {
118
- id: 'root',
119
- layoutOptions: {
120
- ...baseElkLayoutOptions({
121
- // A source with no `direction` statement lays out top-to-bottom,
122
- // as official Mermaid does (#1250). See ELK_DIRECTION_FALLBACK.
123
- direction: directionToElk(diagram.direction, ELK_DIRECTION_FALLBACK.er),
124
- nodeSpacing: ER.nodeSpacing,
125
- layerSpacing: ER.layerSpacing,
126
- padding: ER.padding,
127
- }),
128
- 'elk.edgeLabels.placement': 'CENTER',
129
- // Keep declaration order as the crossing-minimization tie-break and
130
- // center children under their parents, as official Mermaid does.
131
- 'elk.layered.considerModelOrder.strategy': 'NODES_AND_EDGES',
132
- 'elk.layered.nodePlacement.bk.fixedAlignment': 'BALANCED',
133
- },
134
- children,
135
- edges,
136
- }
137
-
138
- return { elkGraph, entitySizes }
139
- }
140
-
141
- /** Extract positioned entities and relationships from ELK result. */
142
- function extractErLayout(
143
- result: ElkNode,
144
- diagram: ErDiagram,
145
- entitySizes: EntitySizeMap,
146
- ): PositionedErDiagram {
147
- const entityLookup = new Map<string, ErEntity>()
148
- for (const entity of diagram.entities) entityLookup.set(entity.id, entity)
149
-
150
- const positionedEntities: PositionedErEntity[] = []
151
- for (const child of result.children ?? []) {
152
- const entity = entityLookup.get(child.id)
153
- if (entity) {
154
- const size = entitySizes.get(entity.id)
155
- if (!size) {
156
- // Unreachable — entitySizes is populated for every diagram.entities
157
- // entry, and entityLookup/entity.id come from that same list.
158
- /* v8 ignore next */
159
- throw new Error(`Missing computed size for entity "${entity.id}"`)
160
- }
161
- positionedEntities.push({
162
- id: entity.id,
163
- label: entity.label,
164
- attributes: entity.attributes,
165
- x: child.x ?? 0,
166
- y: child.y ?? 0,
167
- width: child.width ?? size.width,
168
- height: child.height ?? size.height,
169
- headerHeight: ER.headerHeight,
170
- rowHeight: ER.rowHeight,
171
- })
172
- }
173
- }
174
-
175
- const relationships: PositionedErRelationship[] = []
176
- for (const [i, elkEdge] of (result.edges ?? []).entries()) {
177
- // diagram.relationships[i] is guaranteed by construction: buildErElkGraph
178
- // creates exactly one ELK edge per relationship, in the same order.
179
- const rel = diagram.relationships[i]!
180
-
181
- const points = extractEdgePoints(elkEdge)
182
-
183
- relationships.push({
184
- entity1: rel.entity1,
185
- entity2: rel.entity2,
186
- cardinality1: rel.cardinality1,
187
- cardinality2: rel.cardinality2,
188
- label: rel.label,
189
- identifying: rel.identifying,
190
- points,
191
- })
192
- }
193
-
194
- return {
195
- width: result.width ?? 600,
196
- height: result.height ?? 400,
197
- entities: positionedEntities,
198
- relationships,
199
- }
200
- }
201
-
202
- /**
203
- * Lay out a parsed ER diagram using ELK.js (synchronous).
204
- */
205
- export function layoutErDiagramSync(
206
- diagram: ErDiagram,
207
- options: ErRenderOptions = {},
208
- ): PositionedErDiagram {
209
- if (diagram.entities.length === 0) {
210
- return { width: 0, height: 0, entities: [], relationships: [] }
211
- }
212
-
213
- const { elkGraph, entitySizes } = buildErElkGraph(diagram, options)
214
- const result = elkLayoutSync(elkGraph, options.layoutCache)
215
- return extractErLayout(result, diagram, entitySizes)
216
- }