@zukhruf/diagram 0.3.33 → 0.3.34

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 (117) hide show
  1. package/README.md +98 -52
  2. package/dist/index.d.ts +5 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/compiler/diagram-compile.d.ts +3 -4
  7. package/dist/lib/compiler/diagram-compile.d.ts.map +1 -1
  8. package/dist/lib/compiler/diagram-compile.js +85 -370
  9. package/dist/lib/compiler/diagram-compile.js.map +1 -1
  10. package/dist/lib/layouts/graph/attach.d.ts.map +1 -1
  11. package/dist/lib/layouts/graph/attach.js +64 -8
  12. package/dist/lib/layouts/graph/attach.js.map +1 -1
  13. package/dist/lib/layouts/graph/connections.d.ts +11 -4
  14. package/dist/lib/layouts/graph/connections.d.ts.map +1 -1
  15. package/dist/lib/layouts/graph/connections.js +43 -17
  16. package/dist/lib/layouts/graph/connections.js.map +1 -1
  17. package/dist/lib/layouts/graph/graph-layout-result.d.ts +4 -2
  18. package/dist/lib/layouts/graph/graph-layout-result.d.ts.map +1 -1
  19. package/dist/lib/layouts/graph/graph-layout-result.js.map +1 -1
  20. package/dist/lib/layouts/graph/gutters.js +40 -21
  21. package/dist/lib/layouts/graph/gutters.js.map +1 -1
  22. package/dist/lib/layouts/graph/labels.d.ts +16 -9
  23. package/dist/lib/layouts/graph/labels.d.ts.map +1 -1
  24. package/dist/lib/layouts/graph/labels.js +62 -18
  25. package/dist/lib/layouts/graph/labels.js.map +1 -1
  26. package/dist/lib/layouts/graph/layout.d.ts +1 -1
  27. package/dist/lib/layouts/graph/layout.d.ts.map +1 -1
  28. package/dist/lib/layouts/graph/layout.js +6 -3
  29. package/dist/lib/layouts/graph/layout.js.map +1 -1
  30. package/dist/lib/layouts/graph/measure.d.ts +8 -5
  31. package/dist/lib/layouts/graph/measure.d.ts.map +1 -1
  32. package/dist/lib/layouts/graph/measure.js +47 -9
  33. package/dist/lib/layouts/graph/measure.js.map +1 -1
  34. package/dist/lib/layouts/graph/min-heap.d.ts +1 -5
  35. package/dist/lib/layouts/graph/min-heap.d.ts.map +1 -1
  36. package/dist/lib/layouts/graph/min-heap.js +1 -5
  37. package/dist/lib/layouts/graph/min-heap.js.map +1 -1
  38. package/dist/lib/layouts/graph/node-content.d.ts +1 -1
  39. package/dist/lib/layouts/graph/node-content.d.ts.map +1 -1
  40. package/dist/lib/layouts/graph/node-content.js +26 -7
  41. package/dist/lib/layouts/graph/node-content.js.map +1 -1
  42. package/dist/lib/layouts/graph/path.d.ts +2 -10
  43. package/dist/lib/layouts/graph/path.d.ts.map +1 -1
  44. package/dist/lib/layouts/graph/path.js +11 -13
  45. package/dist/lib/layouts/graph/path.js.map +1 -1
  46. package/dist/lib/layouts/graph/round.d.ts +11 -0
  47. package/dist/lib/layouts/graph/round.d.ts.map +1 -0
  48. package/dist/lib/layouts/graph/round.js +181 -0
  49. package/dist/lib/layouts/graph/round.js.map +1 -0
  50. package/dist/lib/layouts/graph/route.d.ts +10 -6
  51. package/dist/lib/layouts/graph/route.d.ts.map +1 -1
  52. package/dist/lib/layouts/graph/route.js +68 -33
  53. package/dist/lib/layouts/graph/route.js.map +1 -1
  54. package/dist/lib/layouts/graph/sides.d.ts +10 -5
  55. package/dist/lib/layouts/graph/sides.d.ts.map +1 -1
  56. package/dist/lib/layouts/graph/sides.js +14 -7
  57. package/dist/lib/layouts/graph/sides.js.map +1 -1
  58. package/dist/lib/layouts/timeline/timeline-layout.d.ts +2 -1
  59. package/dist/lib/layouts/timeline/timeline-layout.d.ts.map +1 -1
  60. package/dist/lib/layouts/timeline/timeline-layout.js +9 -4
  61. package/dist/lib/layouts/timeline/timeline-layout.js.map +1 -1
  62. package/dist/lib/model/diagram-ir.d.ts +19 -156
  63. package/dist/lib/model/diagram-ir.d.ts.map +1 -1
  64. package/dist/lib/model/diagram-ir.js.map +1 -1
  65. package/dist/lib/model/validate-graph.d.ts +7 -0
  66. package/dist/lib/model/validate-graph.d.ts.map +1 -0
  67. package/dist/lib/model/validate-graph.js +54 -0
  68. package/dist/lib/model/validate-graph.js.map +1 -0
  69. package/dist/lib/react/Diagram.d.ts +3 -9
  70. package/dist/lib/react/Diagram.d.ts.map +1 -1
  71. package/dist/lib/react/Diagram.js +1 -13
  72. package/dist/lib/react/Diagram.js.map +1 -1
  73. package/dist/lib/react/diagram-types.d.ts +17 -46
  74. package/dist/lib/react/diagram-types.d.ts.map +1 -1
  75. package/dist/lib/react/diagram-types.js.map +1 -1
  76. package/dist/lib/renderers/canvas/graph-canvas.d.ts +2 -5
  77. package/dist/lib/renderers/canvas/graph-canvas.d.ts.map +1 -1
  78. package/dist/lib/renderers/canvas/graph-canvas.js +68 -43
  79. package/dist/lib/renderers/canvas/graph-canvas.js.map +1 -1
  80. package/dist/lib/renderers/html/graph-html.d.ts +2 -3
  81. package/dist/lib/renderers/html/graph-html.d.ts.map +1 -1
  82. package/dist/lib/renderers/html/graph-html.js +298 -289
  83. package/dist/lib/renderers/html/graph-html.js.map +1 -1
  84. package/dist/lib/renderers/shared/graph-parts.d.ts +3 -1
  85. package/dist/lib/renderers/shared/graph-parts.d.ts.map +1 -1
  86. package/dist/lib/renderers/shared/graph-parts.js +350 -418
  87. package/dist/lib/renderers/shared/graph-parts.js.map +1 -1
  88. package/dist/lib/renderers/shared/node-parts.d.ts +5 -6
  89. package/dist/lib/renderers/shared/node-parts.d.ts.map +1 -1
  90. package/dist/lib/renderers/shared/node-parts.js +112 -190
  91. package/dist/lib/renderers/shared/node-parts.js.map +1 -1
  92. package/dist/lib/renderers/shared/run-spans.js +2 -2
  93. package/dist/lib/renderers/shared/run-spans.js.map +1 -1
  94. package/dist/lib/renderers/shared/text-runs.d.ts +0 -6
  95. package/dist/lib/renderers/shared/text-runs.d.ts.map +1 -1
  96. package/dist/lib/renderers/shared/text-runs.js +0 -12
  97. package/dist/lib/renderers/shared/text-runs.js.map +1 -1
  98. package/dist/lib/renderers/svg/graph-svg.d.ts +1 -3
  99. package/dist/lib/renderers/svg/graph-svg.d.ts.map +1 -1
  100. package/dist/lib/renderers/svg/graph-svg.js +66 -80
  101. package/dist/lib/renderers/svg/graph-svg.js.map +1 -1
  102. package/dist/lib/renderers/svg/timeline-svg.d.ts.map +1 -1
  103. package/dist/lib/renderers/svg/timeline-svg.js +7 -5
  104. package/dist/lib/renderers/svg/timeline-svg.js.map +1 -1
  105. package/package.json +1 -1
  106. package/dist/lib/layouts/graph/graph-layout.d.ts +0 -154
  107. package/dist/lib/layouts/graph/graph-layout.d.ts.map +0 -1
  108. package/dist/lib/layouts/graph/graph-layout.js +0 -2340
  109. package/dist/lib/layouts/graph/graph-layout.js.map +0 -1
  110. package/dist/lib/layouts/graph/legacy-graph-layout.d.ts +0 -6
  111. package/dist/lib/layouts/graph/legacy-graph-layout.d.ts.map +0 -1
  112. package/dist/lib/layouts/graph/legacy-graph-layout.js +0 -542
  113. package/dist/lib/layouts/graph/legacy-graph-layout.js.map +0 -1
  114. package/dist/lib/layouts/text-metrics.d.ts +0 -7
  115. package/dist/lib/layouts/text-metrics.d.ts.map +0 -1
  116. package/dist/lib/layouts/text-metrics.js +0 -40
  117. package/dist/lib/layouts/text-metrics.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","names":["attachConnections","graphConnections","tagPosition","measureEdgeBadge","measureEdgeLabel","pathToSvg","simplifyPath","searchRoute","OPPOSITE","OUTWARD","LAYOUT_TOKENS","ROUTING_MARGIN","NODE_CLEARANCE","routeGraph","ir","nodes","groups","areas","searchMargin","connections","length","edges","leaders","groupLabels","flatMap","group","label","map","run","id","box","inflate","bounds","LABEL_GAP","attachments","content","union","nodeLayout","visual","groupLayout","rect","solid","filter","w","h","routed","tags","paths","Map","labels","order","connection","index","sort","a","b","Number","edge","undefined","cellDistance","from","to","ends","Set","shape","junctions","end","kind","walls","node","frames","caption","has","tag","runs","route","overlaps","segments","points","start","startStub","endStub","stubs","stubsClear","every","wall","crosses","search","window","lines","x","y","borders","band","startHeading","side","goal","goalHeading","near","intersection","spanOf","found","advice","Error","name","endName","set","isFree","ownSegments","intersects","contains","placed","measured","position","join","Math","ceil","text","place","push","badgeIcon","badgeLabel","badge","get","note","target","d","exitSide","entrySide","port","slice","point","min","abs","span","outer","inner","by","max","boxes","left","top","right","bottom"],"sources":["../../../../src/lib/layouts/graph/route.ts"],"sourcesContent":["import type { Box, DiagramGraphIR, Point } from '../../model/diagram-ir.ts';\nimport type { GridAreas } from './areas.ts';\nimport { attachConnections } from './attach.ts';\nimport {\n type Connection,\n type ConnectionEnd,\n graphConnections,\n} from './connections.ts';\nimport type {\n EdgeLayout,\n GroupLayout,\n LeaderLayout,\n NodeLayout,\n} from './graph-layout-result.ts';\nimport { tagPosition } from './labels.ts';\nimport { measureEdgeBadge, measureEdgeLabel } from './measure.ts';\nimport { pathToSvg, simplifyPath } from './path.ts';\nimport { searchRoute } from './route-search.ts';\nimport { OPPOSITE, OUTWARD } from './sides.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\n/** How far around the content a route may detour. */\nconst ROUTING_MARGIN = 64;\n/** How far a route keeps from a node that it does not connect. */\nconst NODE_CLEARANCE = 8;\n\ntype Routed = {\n points: Point[];\n /** The junctions the route ends at: routes that share one may run together into it. */\n junctions: Set<string>;\n};\n\n/**\n * Routes every edge and note leader orthogonally, nearest cells first, and\n * places each edge's label and badge before the next edge routes around\n * them. It throws when a route or a label has no room; it never draws a\n * diagonal or straight line through what is in the way.\n */\nexport function routeGraph(\n ir: DiagramGraphIR,\n nodes: NodeLayout[],\n groups: GroupLayout[],\n areas: GridAreas,\n /** How far beyond the bounding box of its two shapes a route first searches. */\n searchMargin: number,\n): { edges: EdgeLayout[]; leaders: LeaderLayout[] } {\n const connections = graphConnections(ir, nodes, groups, areas);\n if (connections.length === 0) return { edges: [], leaders: [] };\n const groupLabels = groups.flatMap(({ group, label }) =>\n label.map((run) => ({\n group: group.id,\n box: inflate(run.bounds, LAYOUT_TOKENS.LABEL_GAP),\n })),\n );\n const attachments = attachConnections(connections, groupLabels);\n const content = union([\n ...nodes.map((nodeLayout) => nodeLayout.visual),\n ...groups.map((groupLayout) => groupLayout.rect),\n ]);\n const bounds = inflate(content, ROUTING_MARGIN);\n const solid = nodes.filter(({ box }) => box.w > 0 && box.h > 0);\n\n const routed: Routed[] = [];\n const tags: Box[] = [];\n const paths = new Map<Connection, Point[]>();\n const labels = new Map<Connection, Pick<EdgeLayout, 'label' | 'badge'>>();\n\n const order = connections\n .map((connection, index) => ({ connection, index }))\n .sort(\n (a, b) =>\n Number(a.connection.edge === undefined) -\n Number(b.connection.edge === undefined) ||\n a.connection.cellDistance - b.connection.cellDistance ||\n a.index - b.index,\n );\n\n for (const { connection, index } of order) {\n const { from, to } = connection;\n const ends = new Set([from.shape.id, to.shape.id]);\n const junctions = new Set(\n [from, to]\n .filter((end) => end.shape.kind === 'junction')\n .map((end) => end.shape.id),\n );\n const walls = [\n ...solid.flatMap(({ node, box, visual, frames, caption }) => {\n if (!ends.has(node.id)) return [inflate(visual, NODE_CLEARANCE)];\n if (node.kind === 'junction') return [];\n // Its own parts, not their bounding box: a caption wider than the frame leaves room beside the frame.\n return [box, ...frames, ...(caption ? [caption.box] : [])];\n }),\n ...groupLabels.flatMap(({ group, box }) =>\n ends.has(group) ? [] : [box],\n ),\n ...tags.map((tag) => inflate(tag, LAYOUT_TOKENS.LABEL_GAP)),\n ];\n const runs = routed\n .filter((route) => !overlaps(route.junctions, junctions))\n .flatMap((route) => segments(route.points));\n const { start, startStub, end, endStub } = attachments[index]!;\n const stubs: [Point, Point][] = [\n [start, startStub],\n [endStub, end],\n ];\n const stubsClear = stubs.every(([a, b]) =>\n walls.every((wall) => !crosses(a, b, wall)),\n );\n\n const search = (window: Box): Point[] | undefined =>\n searchRoute({\n window,\n lines: {\n x: [startStub.x, endStub.x],\n y: [startStub.y, endStub.y],\n },\n walls,\n runs,\n borders: groups.flatMap(({ rect, band }) =>\n band ? [rect, band] : [rect],\n ),\n start: startStub,\n startHeading: OUTWARD[from.side],\n goal: endStub,\n goalHeading: OUTWARD[OPPOSITE[to.side]],\n });\n const near = intersection(\n inflate(\n union([from.shape.box, to.shape.box, spanOf(startStub, endStub)]),\n searchMargin,\n ),\n bounds,\n );\n const found = stubsClear ? (search(near) ?? search(bounds)) : undefined;\n if (!found) {\n const advice =\n connection.edge === undefined\n ? 'Move the note or its target.'\n : 'Change exitSide/entrySide or move a node.';\n throw new Error(\n `Diagram ${connection.name}: no orthogonal route from ${endName(from)} to ${endName(to)} avoids the nodes and labels. ${advice}`,\n );\n }\n const points = simplifyPath([start, ...found, end]);\n paths.set(connection, points);\n\n if (connection.edge !== undefined) {\n const edge = ir.edges[connection.edge]!;\n const isFree = (box: Box, ownSegments: boolean) =>\n solid.every(({ visual }) => !intersects(box, visual)) &&\n groups.every(\n ({ rect, band, label }) =>\n !(band && intersects(box, band)) &&\n label.every((run) => !intersects(box, run.bounds)) &&\n !(intersects(box, rect) && !contains(rect, box)),\n ) &&\n tags.every((tag) => !intersects(box, tag)) &&\n [\n ...routed.flatMap((route) => segments(route.points)),\n ...(ownSegments ? segments(points) : []),\n ].every(([a, b]) => !crosses(a, b, box));\n const placed: Pick<EdgeLayout, 'label' | 'badge'> = {};\n if (edge.label?.length) {\n const measured = measureEdgeLabel(edge);\n const position = tagPosition(measured, points, 'beside', (box) =>\n isFree(box, true),\n );\n if (!position) {\n throw new Error(\n `Diagram ${connection.name}: label \"${edge.label.join(' / ')}\" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position beside its route.`,\n );\n }\n placed.label = { ...position, text: measured.place(position.box) };\n tags.push(position.box);\n }\n if (edge.badgeIcon || edge.badgeLabel?.length) {\n const measured = measureEdgeBadge(edge);\n const position = tagPosition(measured, points, 'on', (box) =>\n isFree(box, false),\n );\n if (!position) {\n throw new Error(\n `Diagram ${connection.name}: badge \"${(edge.badgeLabel ?? []).join(' / ')}\" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position on its route.`,\n );\n }\n placed.badge = { box: position.box, ...measured.place(position.box) };\n tags.push(position.box);\n }\n labels.set(connection, placed);\n }\n routed.push({ points, junctions });\n }\n\n const edges: EdgeLayout[] = [];\n const leaders: LeaderLayout[] = [];\n for (const connection of connections) {\n const points = paths.get(connection)!;\n if (connection.edge === undefined) {\n leaders.push({\n note: connection.from.shape.id,\n target: connection.to.shape.id,\n points,\n d: pathToSvg(points),\n });\n continue;\n }\n edges.push({\n edge: ir.edges[connection.edge]!,\n exitSide: connection.from.side,\n entrySide: connection.to.side,\n points,\n d: pathToSvg(points),\n ...labels.get(connection),\n });\n }\n return { edges, leaders };\n}\n\nfunction endName({ shape, side, port }: ConnectionEnd): string {\n if (port) return `port \"${shape.id}:${port.id}\"`;\n if (shape.kind === 'junction') return `the centre of \"${shape.id}\"`;\n return `${side} of \"${shape.id}\"`;\n}\n\nfunction segments(points: Point[]): [Point, Point][] {\n return points.slice(1).map((point, index) => [points[index]!, point]);\n}\n\nfunction overlaps(a: Set<string>, b: Set<string>): boolean {\n for (const id of a) if (b.has(id)) return true;\n return false;\n}\n\nfunction spanOf(a: Point, b: Point): Box {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n w: Math.abs(a.x - b.x),\n h: Math.abs(a.y - b.y),\n };\n}\n\n/** Whether the segment enters the box's interior, not only its border. */\nfunction crosses(a: Point, b: Point, box: Box): boolean {\n const span = spanOf(a, b);\n return (\n span.x + span.w > box.x &&\n span.x < box.x + box.w &&\n span.y + span.h > box.y &&\n span.y < box.y + box.h\n );\n}\n\nfunction intersects(a: Box, b: Box): boolean {\n return (\n a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h\n );\n}\n\nfunction contains(outer: Box, inner: Box): boolean {\n return (\n inner.x >= outer.x &&\n inner.y >= outer.y &&\n inner.x + inner.w <= outer.x + outer.w &&\n inner.y + inner.h <= outer.y + outer.h\n );\n}\n\nfunction inflate(box: Box, by: number): Box {\n return { x: box.x - by, y: box.y - by, w: box.w + 2 * by, h: box.h + 2 * by };\n}\n\nfunction intersection(a: Box, b: Box): Box {\n const x = Math.max(a.x, b.x);\n const y = Math.max(a.y, b.y);\n return {\n x,\n y,\n w: Math.min(a.x + a.w, b.x + b.w) - x,\n h: Math.min(a.y + a.h, b.y + b.h) - y,\n };\n}\n\nfunction union(boxes: Box[]): Box {\n const left = Math.min(...boxes.map((box) => box.x));\n const top = Math.min(...boxes.map((box) => box.y));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n return { x: left, y: top, w: right - left, h: bottom - top };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"route.js","names":["attachConnections","graphConnections","tagPosition","measureEdgeTags","simplifyPath","searchRoute","OPPOSITE","OUTWARD","LAYOUT_TOKENS","ROUTING_MARGIN","NODE_CLEARANCE","routeGraph","ir","nodes","groups","areas","searchMargin","candidates","choices","map","routed","routeConnections","options","index","unrouted","next","length","noRoute","connections","edges","leaders","groupLabels","flatMap","group","label","run","id","box","inflate","bounds","LABEL_GAP","attachments","content","union","nodeLayout","visual","groupLayout","rect","solid","filter","w","h","tags","paths","Map","labels","order","connection","sort","a","b","Number","edge","undefined","cellDistance","from","to","ends","Set","shape","junctions","end","kind","walls","node","frames","caption","has","tag","runs","route","overlaps","segments","points","start","startStub","endStub","stubs","stubsClear","every","wall","crosses","search","window","lines","x","y","borders","band","startHeading","side","goal","goalHeading","near","intersection","spanOf","found","set","isFree","ownSegments","intersects","contains","measured","badge","placed","boxes","candidate","named","push","join","Math","ceil","badgeLabel","Error","name","text","place","get","note","target","exitSide","entrySide","advice","endName","port","slice","point","min","abs","span","outer","inner","by","max","left","top","right","bottom"],"sources":["../../../../src/lib/layouts/graph/route.ts"],"sourcesContent":["import type { Box, DiagramGraphIR, Point } from '../../model/diagram-ir.ts';\nimport type { GridAreas } from './areas.ts';\nimport { attachConnections } from './attach.ts';\nimport {\n type Connection,\n type ConnectionEnd,\n graphConnections,\n} from './connections.ts';\nimport type {\n EdgeLayout,\n GroupLayout,\n LeaderLayout,\n NodeLayout,\n} from './graph-layout-result.ts';\nimport { tagPosition } from './labels.ts';\nimport { measureEdgeTags } from './measure.ts';\nimport { simplifyPath } from './path.ts';\nimport { searchRoute } from './route-search.ts';\nimport { OPPOSITE, OUTWARD } from './sides.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\n/** How far around the content a route may detour. */\nconst ROUTING_MARGIN = 64;\n/** How far a route keeps from a node that it does not connect. */\nconst NODE_CLEARANCE = 8;\n\n/** The routes, before the layout rounds them and draws their paths. */\nexport type RoutedGraph = {\n edges: Omit<EdgeLayout, 'd'>[];\n leaders: Omit<LeaderLayout, 'd'>[];\n};\n\ntype Routed = {\n points: Point[];\n /** The junctions the route ends at: routes that share one may run together into it. */\n junctions: Set<string>;\n};\n\n/**\n * Routes every edge and note leader orthogonally, nearest cells first, and\n * places each edge's label and badge before the next edge routes around\n * them. A connection with no route takes its next choice of sides, and\n * everything routes again. It throws when a connection has no choice left,\n * or a label has no room; it never draws a diagonal or straight line\n * through what is in the way.\n */\nexport function routeGraph(\n ir: DiagramGraphIR,\n nodes: NodeLayout[],\n groups: GroupLayout[],\n areas: GridAreas,\n /** How far beyond the bounding box of its two shapes a route first searches. */\n searchMargin: number,\n): RoutedGraph {\n const candidates = graphConnections(ir, nodes, groups, areas);\n const choices = candidates.map(() => 0);\n for (;;) {\n const routed = routeConnections(\n ir,\n candidates.map((options, index) => options[choices[index]!]!),\n nodes,\n groups,\n searchMargin,\n );\n if (!('unrouted' in routed)) return routed;\n const options = candidates[routed.unrouted]!;\n const next = choices[routed.unrouted]! + 1;\n if (next === options.length) throw noRoute(options[0]!);\n choices[routed.unrouted] = next;\n }\n}\n\n/**\n * Routes one choice of sides for every connection, or names the first\n * connection, in routing order, that has no route.\n */\nfunction routeConnections(\n ir: DiagramGraphIR,\n connections: Connection[],\n nodes: NodeLayout[],\n groups: GroupLayout[],\n searchMargin: number,\n): RoutedGraph | { unrouted: number } {\n if (connections.length === 0) return { edges: [], leaders: [] };\n const groupLabels = groups.flatMap(({ group, label }) =>\n label.map((run) => ({\n group: group.id,\n box: inflate(run.bounds, LAYOUT_TOKENS.LABEL_GAP),\n })),\n );\n const attachments = attachConnections(connections, groupLabels);\n const content = union([\n ...nodes.map((nodeLayout) => nodeLayout.visual),\n ...groups.map((groupLayout) => groupLayout.rect),\n ]);\n const bounds = inflate(content, ROUTING_MARGIN);\n const solid = nodes.filter(({ box }) => box.w > 0 && box.h > 0);\n\n const routed: Routed[] = [];\n const tags: Box[] = [];\n const paths = new Map<Connection, Point[]>();\n const labels = new Map<Connection, Pick<EdgeLayout, 'label' | 'badge'>>();\n\n const order = connections\n .map((connection, index) => ({ connection, index }))\n .sort(\n (a, b) =>\n Number(a.connection.edge === undefined) -\n Number(b.connection.edge === undefined) ||\n a.connection.cellDistance - b.connection.cellDistance ||\n a.index - b.index,\n );\n\n for (const { connection, index } of order) {\n const { from, to } = connection;\n const ends = new Set([from.shape.id, to.shape.id]);\n const junctions = new Set(\n [from, to]\n .filter((end) => end.shape.kind === 'junction')\n .map((end) => end.shape.id),\n );\n const walls = [\n ...solid.flatMap(({ node, box, visual, frames, caption }) => {\n if (!ends.has(node.id)) return [inflate(visual, NODE_CLEARANCE)];\n if (node.kind === 'junction') return [];\n // Its own parts, not their bounding box: a caption wider than the frame leaves room beside the frame.\n return [box, ...frames, ...(caption ? [caption.box] : [])];\n }),\n ...groupLabels.flatMap(({ group, box }) =>\n ends.has(group) ? [] : [box],\n ),\n ...tags.map((tag) => inflate(tag, LAYOUT_TOKENS.LABEL_GAP)),\n ];\n const runs = routed\n .filter((route) => !overlaps(route.junctions, junctions))\n .flatMap((route) => segments(route.points));\n const { start, startStub, end, endStub } = attachments[index]!;\n const stubs: [Point, Point][] = [\n [start, startStub],\n [endStub, end],\n ];\n const stubsClear = stubs.every(([a, b]) =>\n walls.every((wall) => !crosses(a, b, wall)),\n );\n\n const search = (window: Box): Point[] | undefined =>\n searchRoute({\n window,\n lines: {\n x: [startStub.x, endStub.x],\n y: [startStub.y, endStub.y],\n },\n walls,\n runs,\n borders: groups.flatMap(({ rect, band }) =>\n band ? [rect, band] : [rect],\n ),\n start: startStub,\n startHeading: OUTWARD[from.side],\n goal: endStub,\n goalHeading: OUTWARD[OPPOSITE[to.side]],\n });\n const near = intersection(\n inflate(\n union([from.shape.box, to.shape.box, spanOf(startStub, endStub)]),\n searchMargin,\n ),\n bounds,\n );\n const found = stubsClear ? (search(near) ?? search(bounds)) : undefined;\n if (!found) return { unrouted: index };\n const points = simplifyPath([start, ...found, end]);\n paths.set(connection, points);\n\n if (connection.edge !== undefined) {\n const edge = ir.edges[connection.edge]!;\n const isFree = (box: Box, ownSegments: boolean) =>\n solid.every(({ visual }) => !intersects(box, visual)) &&\n groups.every(\n ({ rect, band, label }) =>\n !(band && intersects(box, band)) &&\n label.every((run) => !intersects(box, run.bounds)) &&\n !(intersects(box, rect) && !contains(rect, box)),\n ) &&\n tags.every((tag) => !intersects(box, tag)) &&\n [\n ...routed.flatMap((route) => segments(route.points)),\n ...(ownSegments ? segments(points) : []),\n ].every(([a, b]) => !crosses(a, b, box));\n const measured = measureEdgeTags(edge);\n const { label, badge } = measured;\n const placed: Pick<EdgeLayout, 'label' | 'badge'> = {};\n if (label || badge) {\n const boxes = tagPosition(measured, points, (candidate, kind) =>\n isFree(candidate, kind === 'label'),\n );\n if (!boxes) {\n const named: string[] = [];\n if (label) {\n named.push(\n `label \"${edge.label!.join(' / ')}\" (${Math.ceil(label.w)}×${Math.ceil(label.h)})`,\n );\n }\n if (badge) {\n named.push(\n `badge \"${(edge.badgeLabel ?? []).join(' / ')}\" (${Math.ceil(badge.w)}×${Math.ceil(badge.h)})`,\n );\n }\n throw new Error(\n `Diagram ${connection.name}: ${named.join(' and ')} ${named.length > 1 ? 'have' : 'has'} no free position ${badge ? 'on' : 'beside'} its route.`,\n );\n }\n if (label && boxes.label) {\n placed.label = { box: boxes.label, text: label.place(boxes.label) };\n tags.push(boxes.label);\n }\n if (badge && boxes.badge) {\n placed.badge = { box: boxes.badge, ...badge.place(boxes.badge) };\n tags.push(boxes.badge);\n }\n }\n labels.set(connection, placed);\n }\n routed.push({ points, junctions });\n }\n\n const edges: RoutedGraph['edges'] = [];\n const leaders: RoutedGraph['leaders'] = [];\n for (const connection of connections) {\n const points = paths.get(connection)!;\n if (connection.edge === undefined) {\n leaders.push({\n note: connection.from.shape.id,\n target: connection.to.shape.id,\n points,\n });\n continue;\n }\n edges.push({\n edge: ir.edges[connection.edge]!,\n exitSide: connection.from.side,\n entrySide: connection.to.side,\n points,\n ...labels.get(connection),\n });\n }\n return { edges, leaders };\n}\n\nfunction noRoute({ name, edge, from, to }: Connection): Error {\n const advice =\n edge === undefined\n ? 'Move the note or its target.'\n : 'Change exitSide/entrySide or move a node.';\n return new Error(\n `Diagram ${name}: no orthogonal route from ${endName(from)} to ${endName(to)} avoids the nodes and labels. ${advice}`,\n );\n}\n\nfunction endName({ shape, side, port }: ConnectionEnd): string {\n if (port) return `port \"${shape.id}:${port.id}\"`;\n if (shape.kind === 'junction') return `the centre of \"${shape.id}\"`;\n return `${side} of \"${shape.id}\"`;\n}\n\nfunction segments(points: Point[]): [Point, Point][] {\n return points.slice(1).map((point, index) => [points[index]!, point]);\n}\n\nfunction overlaps(a: Set<string>, b: Set<string>): boolean {\n for (const id of a) if (b.has(id)) return true;\n return false;\n}\n\nfunction spanOf(a: Point, b: Point): Box {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n w: Math.abs(a.x - b.x),\n h: Math.abs(a.y - b.y),\n };\n}\n\n/** Whether the segment enters the box's interior, not only its border. */\nfunction crosses(a: Point, b: Point, box: Box): boolean {\n const span = spanOf(a, b);\n return (\n span.x + span.w > box.x &&\n span.x < box.x + box.w &&\n span.y + span.h > box.y &&\n span.y < box.y + box.h\n );\n}\n\nfunction intersects(a: Box, b: Box): boolean {\n return (\n a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h\n );\n}\n\nfunction contains(outer: Box, inner: Box): boolean {\n return (\n inner.x >= outer.x &&\n inner.y >= outer.y &&\n inner.x + inner.w <= outer.x + outer.w &&\n inner.y + inner.h <= outer.y + outer.h\n );\n}\n\nfunction inflate(box: Box, by: number): Box {\n return { x: box.x - by, y: box.y - by, w: box.w + 2 * by, h: box.h + 2 * by };\n}\n\nfunction intersection(a: Box, b: Box): Box {\n const x = Math.max(a.x, b.x);\n const y = Math.max(a.y, b.y);\n return {\n x,\n y,\n w: Math.min(a.x + a.w, b.x + b.w) - x,\n h: Math.min(a.y + a.h, b.y + b.h) - y,\n };\n}\n\nfunction union(boxes: Box[]): Box {\n const left = Math.min(...boxes.map((box) => box.x));\n const top = Math.min(...boxes.map((box) => box.y));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n return { x: left, y: top, w: right - left, h: bottom - top };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -5,13 +5,18 @@ export declare const OPPOSITE: Record<DiagramSide, DiagramSide>;
5
5
  /** The heading of a line that leaves a box through `side`. */
6
6
  export declare const OUTWARD: Record<DiagramSide, Heading>;
7
7
  export declare function isVertical(side: DiagramSide): boolean;
8
+ /** The side a connection leaves by, and the side it enters by. */
9
+ export type SidePair = [DiagramSide, DiagramSide];
8
10
  /**
9
- * The sides a connection leaves and enters by, read from the cells: areas
10
- * that share rows face left and right, areas that share columns face top
11
- * and bottom, and otherwise the axis with the larger cell delta wins, the
12
- * vertical one on a tie.
11
+ * The pairs of sides a connection may leave and enter by, read from the
12
+ * cells, in order of preference. First the facing pair: areas that share
13
+ * rows face left and right, areas that share columns face top and bottom,
14
+ * and otherwise the axis with the larger cell delta wins, the vertical one
15
+ * on a tie. Then the facing pair on the other axis, then the first pair's
16
+ * exit with the other pair's entry, then the other pair's exit with the
17
+ * first pair's entry.
13
18
  */
14
- export declare function facingSides(from: CellArea, to: CellArea): [DiagramSide, DiagramSide];
19
+ export declare function sidePairs(from: CellArea, to: CellArea): [SidePair, ...SidePair[]];
15
20
  /** The coordinate of the side's line: x for left and right, y for top and bottom. */
16
21
  export declare function sideLine(box: Box, side: DiagramSide): number;
17
22
  /** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */
@@ -1 +1 @@
1
- {"version":3,"file":"sides.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/sides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAKrD,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAKhD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,QAAQ,GACX,CAAC,WAAW,EAAE,WAAW,CAAC,CAa5B;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAW5D;AAED,yGAAyG;AACzG,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEtE;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAG7E;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,GACf,KAAK,CAWP"}
1
+ {"version":3,"file":"sides.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/sides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAKrD,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAKhD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAErD;AAED,kEAAkE;AAClE,MAAM,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,QAAQ,GACX,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC,CAe3B;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAW5D;AAED,yGAAyG;AACzG,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEtE;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAG7E;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,GACf,KAAK,CAWP"}
@@ -16,20 +16,27 @@ export function isVertical(side) {
16
16
  return side === 'top' || side === 'bottom';
17
17
  }
18
18
 
19
+ /** The side a connection leaves by, and the side it enters by. */
20
+
19
21
  /**
20
- * The sides a connection leaves and enters by, read from the cells: areas
21
- * that share rows face left and right, areas that share columns face top
22
- * and bottom, and otherwise the axis with the larger cell delta wins, the
23
- * vertical one on a tie.
22
+ * The pairs of sides a connection may leave and enter by, read from the
23
+ * cells, in order of preference. First the facing pair: areas that share
24
+ * rows face left and right, areas that share columns face top and bottom,
25
+ * and otherwise the axis with the larger cell delta wins, the vertical one
26
+ * on a tie. Then the facing pair on the other axis, then the first pair's
27
+ * exit with the other pair's entry, then the other pair's exit with the
28
+ * first pair's entry.
24
29
  */
25
- export function facingSides(from, to) {
30
+ export function sidePairs(from, to) {
26
31
  const shareRows = Math.max(from.row, to.row) < Math.min(from.row + from.rowSpan, to.row + to.rowSpan);
27
32
  const shareCols = Math.max(from.col, to.col) < Math.min(from.col + from.colSpan, to.col + to.colSpan);
28
33
  const dr = to.row + to.rowSpan / 2 - (from.row + from.rowSpan / 2);
29
34
  const dc = to.col + to.colSpan / 2 - (from.col + from.colSpan / 2);
35
+ const across = dc > 0 ? ['right', 'left'] : ['left', 'right'];
36
+ const down = dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];
30
37
  const horizontal = shareRows !== shareCols ? shareRows : Math.abs(dc) > Math.abs(dr);
31
- if (horizontal) return dc > 0 ? ['right', 'left'] : ['left', 'right'];
32
- return dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];
38
+ const [first, other] = horizontal ? [across, down] : [down, across];
39
+ return [first, other, [first[0], other[1]], [other[0], first[1]]];
33
40
  }
34
41
 
35
42
  /** The coordinate of the side's line: x for left and right, y for top and bottom. */
@@ -1 +1 @@
1
- {"version":3,"file":"sides.js","names":["OPPOSITE","top","bottom","left","right","OUTWARD","isVertical","side","facingSides","from","to","shareRows","Math","max","row","min","rowSpan","shareCols","col","colSpan","dr","dc","horizontal","abs","sideLine","box","y","h","x","w","sideSpan","pointOnSide","along","line","beyond","point","distance"],"sources":["../../../../src/lib/layouts/graph/sides.ts"],"sourcesContent":["import type { Box, DiagramSide, Point } from '../../model/diagram-ir.ts';\nimport type { CellArea } from './areas.ts';\nimport type { Heading } from './route-search.ts';\n\nexport const OPPOSITE: Record<DiagramSide, DiagramSide> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n};\n\n/** The heading of a line that leaves a box through `side`. */\nexport const OUTWARD: Record<DiagramSide, Heading> = {\n right: 0,\n left: 1,\n bottom: 2,\n top: 3,\n};\n\nexport function isVertical(side: DiagramSide): boolean {\n return side === 'top' || side === 'bottom';\n}\n\n/**\n * The sides a connection leaves and enters by, read from the cells: areas\n * that share rows face left and right, areas that share columns face top\n * and bottom, and otherwise the axis with the larger cell delta wins, the\n * vertical one on a tie.\n */\nexport function facingSides(\n from: CellArea,\n to: CellArea,\n): [DiagramSide, DiagramSide] {\n const shareRows =\n Math.max(from.row, to.row) <\n Math.min(from.row + from.rowSpan, to.row + to.rowSpan);\n const shareCols =\n Math.max(from.col, to.col) <\n Math.min(from.col + from.colSpan, to.col + to.colSpan);\n const dr = to.row + to.rowSpan / 2 - (from.row + from.rowSpan / 2);\n const dc = to.col + to.colSpan / 2 - (from.col + from.colSpan / 2);\n const horizontal =\n shareRows !== shareCols ? shareRows : Math.abs(dc) > Math.abs(dr);\n if (horizontal) return dc > 0 ? ['right', 'left'] : ['left', 'right'];\n return dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];\n}\n\n/** The coordinate of the side's line: x for left and right, y for top and bottom. */\nexport function sideLine(box: Box, side: DiagramSide): number {\n switch (side) {\n case 'top':\n return box.y;\n case 'bottom':\n return box.y + box.h;\n case 'left':\n return box.x;\n case 'right':\n return box.x + box.w;\n }\n}\n\n/** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */\nexport function sideSpan(box: Box, side: DiagramSide): [number, number] {\n return isVertical(side) ? [box.x, box.x + box.w] : [box.y, box.y + box.h];\n}\n\n/** The point on `side` of `box` at `along` on the side's span. */\nexport function pointOnSide(box: Box, side: DiagramSide, along: number): Point {\n const line = sideLine(box, side);\n return isVertical(side) ? { x: along, y: line } : { x: line, y: along };\n}\n\n/** The point `distance` beyond `point` out of `side`. */\nexport function beyond(\n point: Point,\n side: DiagramSide,\n distance: number,\n): Point {\n switch (side) {\n case 'top':\n return { x: point.x, y: point.y - distance };\n case 'bottom':\n return { x: point.x, y: point.y + distance };\n case 'left':\n return { x: point.x - distance, y: point.y };\n case 'right':\n return { x: point.x + distance, y: point.y };\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"sides.js","names":["OPPOSITE","top","bottom","left","right","OUTWARD","isVertical","side","sidePairs","from","to","shareRows","Math","max","row","min","rowSpan","shareCols","col","colSpan","dr","dc","across","down","horizontal","abs","first","other","sideLine","box","y","h","x","w","sideSpan","pointOnSide","along","line","beyond","point","distance"],"sources":["../../../../src/lib/layouts/graph/sides.ts"],"sourcesContent":["import type { Box, DiagramSide, Point } from '../../model/diagram-ir.ts';\nimport type { CellArea } from './areas.ts';\nimport type { Heading } from './route-search.ts';\n\nexport const OPPOSITE: Record<DiagramSide, DiagramSide> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n};\n\n/** The heading of a line that leaves a box through `side`. */\nexport const OUTWARD: Record<DiagramSide, Heading> = {\n right: 0,\n left: 1,\n bottom: 2,\n top: 3,\n};\n\nexport function isVertical(side: DiagramSide): boolean {\n return side === 'top' || side === 'bottom';\n}\n\n/** The side a connection leaves by, and the side it enters by. */\nexport type SidePair = [DiagramSide, DiagramSide];\n\n/**\n * The pairs of sides a connection may leave and enter by, read from the\n * cells, in order of preference. First the facing pair: areas that share\n * rows face left and right, areas that share columns face top and bottom,\n * and otherwise the axis with the larger cell delta wins, the vertical one\n * on a tie. Then the facing pair on the other axis, then the first pair's\n * exit with the other pair's entry, then the other pair's exit with the\n * first pair's entry.\n */\nexport function sidePairs(\n from: CellArea,\n to: CellArea,\n): [SidePair, ...SidePair[]] {\n const shareRows =\n Math.max(from.row, to.row) <\n Math.min(from.row + from.rowSpan, to.row + to.rowSpan);\n const shareCols =\n Math.max(from.col, to.col) <\n Math.min(from.col + from.colSpan, to.col + to.colSpan);\n const dr = to.row + to.rowSpan / 2 - (from.row + from.rowSpan / 2);\n const dc = to.col + to.colSpan / 2 - (from.col + from.colSpan / 2);\n const across: SidePair = dc > 0 ? ['right', 'left'] : ['left', 'right'];\n const down: SidePair = dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];\n const horizontal =\n shareRows !== shareCols ? shareRows : Math.abs(dc) > Math.abs(dr);\n const [first, other] = horizontal ? [across, down] : [down, across];\n return [first, other, [first[0], other[1]], [other[0], first[1]]];\n}\n\n/** The coordinate of the side's line: x for left and right, y for top and bottom. */\nexport function sideLine(box: Box, side: DiagramSide): number {\n switch (side) {\n case 'top':\n return box.y;\n case 'bottom':\n return box.y + box.h;\n case 'left':\n return box.x;\n case 'right':\n return box.x + box.w;\n }\n}\n\n/** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */\nexport function sideSpan(box: Box, side: DiagramSide): [number, number] {\n return isVertical(side) ? [box.x, box.x + box.w] : [box.y, box.y + box.h];\n}\n\n/** The point on `side` of `box` at `along` on the side's span. */\nexport function pointOnSide(box: Box, side: DiagramSide, along: number): Point {\n const line = sideLine(box, side);\n return isVertical(side) ? { x: along, y: line } : { x: line, y: along };\n}\n\n/** The point `distance` beyond `point` out of `side`. */\nexport function beyond(\n point: Point,\n side: DiagramSide,\n distance: number,\n): Point {\n switch (side) {\n case 'top':\n return { x: point.x, y: point.y - distance };\n case 'bottom':\n return { x: point.x, y: point.y + distance };\n case 'left':\n return { x: point.x - distance, y: point.y };\n case 'right':\n return { x: point.x + distance, y: point.y };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  import type { DiagramSignal, DiagramSignalBox, DiagramTimelineSpec } from '../../model/diagram-ir.ts';
2
+ import type { Font } from '../text/font.ts';
2
3
  export type { DiagramFrameElement, DiagramLane, DiagramSignal, DiagramSignalBox, } from '../../model/diagram-ir.ts';
3
4
  export type TimelineLayoutSpec = DiagramTimelineSpec & {
4
5
  title?: string[];
@@ -16,7 +17,7 @@ export declare const FRAME_HEADER_H = 22;
16
17
  export declare const FRAME_PAD = 12;
17
18
  export declare const BOTTOM_ACTOR_GAP = 50;
18
19
  export declare const DEFAULT_BOXED_STUB = 12;
19
- export declare const SIGNAL_LABEL_FONT_SIZE = 12;
20
+ export declare const SIGNAL_LABEL_FONT: Font;
20
21
  export declare const SIGNAL_LABEL_PAD_X = 14;
21
22
  export declare const SIGNAL_LABEL_PAD_Y = 10;
22
23
  export declare const SIGNAL_LABEL_LINE_H = 18;
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-layout.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/timeline/timeline-layout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline-layout.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/timeline/timeline-layout.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { textAscent, widestLine } from "../text-metrics.js";
1
+ import { fontAscent, measureText } from "../text/measure-text.js";
2
2
  export const SEQ_W = 1000;
3
3
  export const ACTOR_W = 190;
4
4
  export const ACTOR_H = 72;
@@ -12,7 +12,11 @@ export const FRAME_HEADER_H = 22;
12
12
  export const FRAME_PAD = 12;
13
13
  export const BOTTOM_ACTOR_GAP = 50;
14
14
  export const DEFAULT_BOXED_STUB = 12;
15
- export const SIGNAL_LABEL_FONT_SIZE = 12;
15
+ export const SIGNAL_LABEL_FONT = {
16
+ face: 'mono',
17
+ size: 12,
18
+ weight: 400
19
+ };
16
20
  export const SIGNAL_LABEL_PAD_X = 14;
17
21
  export const SIGNAL_LABEL_PAD_Y = 10;
18
22
  export const SIGNAL_LABEL_LINE_H = 18;
@@ -62,8 +66,9 @@ export function buildTimelineSegments(totalSignals, hasLoop, frameMsgs) {
62
66
  return segments;
63
67
  }
64
68
  export function measureSignalLabel(label) {
69
+ const widestLineW = Math.max(0, ...label.map(line => measureText(line, SIGNAL_LABEL_FONT)));
65
70
  return {
66
- boxW: Math.ceil(widestLine(label, SIGNAL_LABEL_FONT_SIZE, 'mono')) + SIGNAL_LABEL_PAD_X * 2,
71
+ boxW: Math.ceil(widestLineW) + SIGNAL_LABEL_PAD_X * 2,
67
72
  boxH: label.length * SIGNAL_LABEL_LINE_H + SIGNAL_LABEL_PAD_Y * 2
68
73
  };
69
74
  }
@@ -71,7 +76,7 @@ export function measureSignalLabel(label) {
71
76
  /** Distance from a signal's row up to the top of its label or label box. */
72
77
  export function signalLabelHeadroom(signal) {
73
78
  if (signal.boxed) return measureSignalLabel(signal.label).boxH / 2;
74
- return SIGNAL_LABEL_BASELINE_GAP + (signal.label.length - 1) * SIGNAL_LABEL_LINE_STEP + textAscent(SIGNAL_LABEL_FONT_SIZE, 'mono');
79
+ return SIGNAL_LABEL_BASELINE_GAP + (signal.label.length - 1) * SIGNAL_LABEL_LINE_STEP + fontAscent(SIGNAL_LABEL_FONT);
75
80
  }
76
81
 
77
82
  /** Distance from a signal's row down to the bottom of its label box. */
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-layout.js","names":["textAscent","widestLine","SEQ_W","ACTOR_W","ACTOR_H","ACTOR_RX","TOP_ACTOR_Y","ROW_H","FIRST_MSG_Y","LOOP_TOP_PAD","LOOP_X_PAD","FRAME_HEADER_H","FRAME_PAD","BOTTOM_ACTOR_GAP","DEFAULT_BOXED_STUB","SIGNAL_LABEL_FONT_SIZE","SIGNAL_LABEL_PAD_X","SIGNAL_LABEL_PAD_Y","SIGNAL_LABEL_LINE_H","SIGNAL_LABEL_BASELINE_GAP","SIGNAL_LABEL_LINE_STEP","buildTimelineSegments","totalSignals","hasLoop","frameMsgs","slotCount","step","i","segments","push","kind","index","start","end","m","measureSignalLabel","label","boxW","Math","ceil","boxH","length","signalLabelHeadroom","signal","boxed","signalLabelFootroom","computeBoxedSignal","args","fromX","toX","rowY","stub","position","headInset","direction","nearEdge","_exhaustive","Error","String","farEdge","stubA","x1","x2","stubB","stubALen","stubBLen","abs","boxLeft","min","boxRight","max","boxTop","boxBottom","laneCenterX","total","slot","computeTimelineLayout","spec","totalLanes","lanes","signals","frame","segOf","s","find","lifelineYStart","mainMsgY","lastMainMsgY","frameBottom","frameY","firstFrameSignal","lastFrameSignal","slice","firstRowOffset","lastRowOffset","frameH","seg","x","y","width","height","segmentStart","segmentEnd","map","ms","from","to","bottomActorY","lifelineYEnd","totalH","a","cx","id","centerX","rectX","topRectY","bottomRectY","accent","topLanesSegment","bottomLanesSegment"],"sources":["../../../../src/lib/layouts/timeline/timeline-layout.ts"],"sourcesContent":["import type {\n DiagramSignal,\n DiagramSignalBox,\n DiagramTimelineSpec,\n} from '../../model/diagram-ir.ts';\nimport { textAscent, widestLine } from '../text-metrics.ts';\n\nexport type {\n DiagramFrameElement,\n DiagramLane,\n DiagramSignal,\n DiagramSignalBox,\n} from '../../model/diagram-ir.ts';\n\nexport type TimelineLayoutSpec = DiagramTimelineSpec & { title?: string[] };\n\nexport const SEQ_W = 1000;\nexport const ACTOR_W = 190;\nexport const ACTOR_H = 72;\nexport const ACTOR_RX = 16;\nexport const TOP_ACTOR_Y = 30;\nexport const ROW_H = 70;\nexport const FIRST_MSG_Y = 200;\nexport const LOOP_TOP_PAD = 38;\nexport const LOOP_X_PAD = 24;\nexport const FRAME_HEADER_H = 22;\nexport const FRAME_PAD = 12;\nexport const BOTTOM_ACTOR_GAP = 50;\nexport const DEFAULT_BOXED_STUB = 12;\nexport const SIGNAL_LABEL_FONT_SIZE = 12;\nexport const SIGNAL_LABEL_PAD_X = 14;\nexport const SIGNAL_LABEL_PAD_Y = 10;\nexport const SIGNAL_LABEL_LINE_H = 18;\nexport const SIGNAL_LABEL_BASELINE_GAP = 12;\nexport const SIGNAL_LABEL_LINE_STEP = 15;\n\nexport type SegmentKind =\n 'top-lanes' | 'msg' | 'frame-frame' | 'frame-msg' | 'bottom-lanes';\n\nexport type LayoutSegment = {\n kind: SegmentKind;\n index: number;\n start: number;\n end: number;\n};\n\nexport function buildTimelineSegments(\n totalSignals: number,\n hasLoop: boolean,\n frameMsgs: number,\n): LayoutSegment[] {\n const slotCount = 1 + totalSignals + (hasLoop ? 1 + frameMsgs : 0) + 1;\n const step = 1 / slotCount;\n let i = 0;\n const segments: LayoutSegment[] = [];\n segments.push({\n kind: 'top-lanes',\n index: 0,\n start: i * step,\n end: ++i * step,\n });\n for (let m = 0; m < totalSignals; m++) {\n segments.push({ kind: 'msg', index: m, start: i * step, end: ++i * step });\n }\n if (hasLoop) {\n segments.push({\n kind: 'frame-frame',\n index: 0,\n start: i * step,\n end: ++i * step,\n });\n for (let m = 0; m < frameMsgs; m++) {\n segments.push({\n kind: 'frame-msg',\n index: m,\n start: i * step,\n end: ++i * step,\n });\n }\n }\n segments.push({\n kind: 'bottom-lanes',\n index: 0,\n start: i * step,\n end: (i + 1) * step,\n });\n return segments;\n}\n\nexport type BoxedSegment = {\n boxLeft: number;\n boxRight: number;\n boxTop: number;\n boxBottom: number;\n stubA: { x1: number; x2: number };\n stubB: { x1: number; x2: number };\n};\n\nexport function measureSignalLabel(label: string[]): {\n boxW: number;\n boxH: number;\n} {\n return {\n boxW:\n Math.ceil(widestLine(label, SIGNAL_LABEL_FONT_SIZE, 'mono')) +\n SIGNAL_LABEL_PAD_X * 2,\n boxH: label.length * SIGNAL_LABEL_LINE_H + SIGNAL_LABEL_PAD_Y * 2,\n };\n}\n\n/** Distance from a signal's row up to the top of its label or label box. */\nexport function signalLabelHeadroom(\n signal: Pick<DiagramSignal, 'label' | 'boxed'>,\n): number {\n if (signal.boxed) return measureSignalLabel(signal.label).boxH / 2;\n return (\n SIGNAL_LABEL_BASELINE_GAP +\n (signal.label.length - 1) * SIGNAL_LABEL_LINE_STEP +\n textAscent(SIGNAL_LABEL_FONT_SIZE, 'mono')\n );\n}\n\n/** Distance from a signal's row down to the bottom of its label box. */\nexport function signalLabelFootroom(\n signal: Pick<DiagramSignal, 'label' | 'boxed'>,\n): number {\n return signal.boxed ? measureSignalLabel(signal.label).boxH / 2 : 0;\n}\n\nexport function computeBoxedSignal(args: {\n fromX: number;\n toX: number;\n rowY: number;\n boxW: number;\n boxH: number;\n stub: number;\n position: DiagramSignalBox;\n headInset: number;\n}): BoxedSegment {\n const { fromX, toX, rowY, boxW, boxH, stub, position, headInset } = args;\n const direction = toX > fromX ? 1 : -1;\n\n let nearEdge: number;\n switch (position) {\n case 'source':\n nearEdge = fromX + stub * direction;\n break;\n case 'center':\n nearEdge = (fromX + toX) / 2 - (boxW / 2) * direction;\n break;\n case 'target':\n nearEdge = toX - (stub + boxW) * direction;\n break;\n default: {\n const _exhaustive: never = position;\n throw new Error(`invalid boxed signal position: ${String(_exhaustive)}`);\n }\n }\n const farEdge = nearEdge + boxW * direction;\n\n const stubA = { x1: fromX, x2: nearEdge };\n const stubB = { x1: farEdge, x2: toX - headInset * direction };\n\n const stubALen = (stubA.x2 - stubA.x1) * direction;\n const stubBLen = (stubB.x2 - stubB.x1) * direction;\n if (stubALen < 0 || stubBLen < 0) {\n throw new Error(\n `boxed signal label box (width=${boxW}) overflows the lane distance |toX-fromX|=${Math.abs(toX - fromX)} with stub=${stub}, position=${position}`,\n );\n }\n\n return {\n boxLeft: Math.min(nearEdge, farEdge),\n boxRight: Math.max(nearEdge, farEdge),\n boxTop: rowY - boxH / 2,\n boxBottom: rowY + boxH / 2,\n stubA,\n stubB,\n };\n}\n\nexport function laneCenterX(index: number, total: number): number {\n const slot = SEQ_W / total;\n return slot * index + slot / 2;\n}\n\nexport type LanePlacement = {\n id: string;\n centerX: number;\n rectX: number;\n topRectY: number;\n bottomRectY: number;\n accent: boolean;\n};\n\nexport type SignalPlacement = {\n index: number;\n from: string;\n to: string;\n rowY: number;\n segmentStart: number;\n segmentEnd: number;\n};\n\nexport type FramePlacement = {\n x: number;\n y: number;\n width: number;\n height: number;\n label: string;\n segmentStart: number;\n segmentEnd: number;\n signals: SignalPlacement[];\n};\n\nexport type TimelineLayout = {\n width: number;\n height: number;\n lanes: LanePlacement[];\n lifelineYStart: number;\n lifelineYEnd: number;\n signals: SignalPlacement[];\n frame: FramePlacement | null;\n topLanesSegment: { start: number; end: number };\n bottomLanesSegment: { start: number; end: number };\n};\n\nexport function computeTimelineLayout(\n spec: TimelineLayoutSpec,\n): TimelineLayout {\n const totalLanes = spec.lanes.length;\n const totalSignals = spec.signals.length;\n const hasLoop = !!spec.frame;\n const frameMsgs = spec.frame?.signals.length ?? 0;\n\n const segments = buildTimelineSegments(totalSignals, hasLoop, frameMsgs);\n const segOf = (kind: SegmentKind, index = 0) => {\n const s = segments.find((s) => s.kind === kind && s.index === index);\n if (!s) throw new Error(`segment ${kind}[${index}] missing`);\n return s;\n };\n\n const lifelineYStart = TOP_ACTOR_Y + ACTOR_H;\n const mainMsgY = (i: number) => FIRST_MSG_Y + i * ROW_H;\n const lastMainMsgY =\n spec.signals.length > 0 ? mainMsgY(spec.signals.length - 1) : FIRST_MSG_Y;\n\n let frame: FramePlacement | null = null;\n let frameBottom = lastMainMsgY;\n\n if (hasLoop && spec.frame) {\n const frameY = lastMainMsgY + LOOP_TOP_PAD;\n const [firstFrameSignal] = spec.frame.signals;\n const [lastFrameSignal] = spec.frame.signals.slice(-1);\n const firstRowOffset =\n FRAME_HEADER_H +\n FRAME_PAD +\n (firstFrameSignal ? signalLabelHeadroom(firstFrameSignal) : 0);\n const lastRowOffset = firstRowOffset + Math.max(0, frameMsgs - 1) * ROW_H;\n const frameH =\n lastRowOffset +\n (lastFrameSignal ? signalLabelFootroom(lastFrameSignal) : 0) +\n FRAME_PAD;\n frameBottom = frameY + frameH;\n const seg = segOf('frame-frame');\n frame = {\n x: LOOP_X_PAD,\n y: frameY,\n width: SEQ_W - 2 * LOOP_X_PAD,\n height: frameH,\n label: spec.frame.label,\n segmentStart: seg.start,\n segmentEnd: seg.end,\n signals: spec.frame.signals.map((m, i) => {\n const ms = segOf('frame-msg', i);\n return {\n index: i,\n from: m.from,\n to: m.to,\n rowY: frameY + firstRowOffset + i * ROW_H,\n segmentStart: ms.start,\n segmentEnd: ms.end,\n };\n }),\n };\n }\n\n const bottomActorY = frameBottom + BOTTOM_ACTOR_GAP;\n const lifelineYEnd = bottomActorY;\n const totalH = bottomActorY + ACTOR_H + 30;\n\n const lanes: LanePlacement[] = spec.lanes.map((a, i) => {\n const cx = laneCenterX(i, totalLanes);\n return {\n id: a.id,\n centerX: cx,\n rectX: cx - ACTOR_W / 2,\n topRectY: TOP_ACTOR_Y,\n bottomRectY: bottomActorY,\n accent: !!a.accent,\n };\n });\n\n const signals: SignalPlacement[] = spec.signals.map((m, i) => {\n const seg = segOf('msg', i);\n return {\n index: i,\n from: m.from,\n to: m.to,\n rowY: mainMsgY(i),\n segmentStart: seg.start,\n segmentEnd: seg.end,\n };\n });\n\n return {\n width: SEQ_W,\n height: totalH,\n lanes,\n lifelineYStart,\n lifelineYEnd,\n signals,\n frame,\n topLanesSegment: {\n start: segOf('top-lanes').start,\n end: segOf('top-lanes').end,\n },\n bottomLanesSegment: {\n start: segOf('bottom-lanes').start,\n end: segOf('bottom-lanes').end,\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"timeline-layout.js","names":["fontAscent","measureText","SEQ_W","ACTOR_W","ACTOR_H","ACTOR_RX","TOP_ACTOR_Y","ROW_H","FIRST_MSG_Y","LOOP_TOP_PAD","LOOP_X_PAD","FRAME_HEADER_H","FRAME_PAD","BOTTOM_ACTOR_GAP","DEFAULT_BOXED_STUB","SIGNAL_LABEL_FONT","face","size","weight","SIGNAL_LABEL_PAD_X","SIGNAL_LABEL_PAD_Y","SIGNAL_LABEL_LINE_H","SIGNAL_LABEL_BASELINE_GAP","SIGNAL_LABEL_LINE_STEP","buildTimelineSegments","totalSignals","hasLoop","frameMsgs","slotCount","step","i","segments","push","kind","index","start","end","m","measureSignalLabel","label","widestLineW","Math","max","map","line","boxW","ceil","boxH","length","signalLabelHeadroom","signal","boxed","signalLabelFootroom","computeBoxedSignal","args","fromX","toX","rowY","stub","position","headInset","direction","nearEdge","_exhaustive","Error","String","farEdge","stubA","x1","x2","stubB","stubALen","stubBLen","abs","boxLeft","min","boxRight","boxTop","boxBottom","laneCenterX","total","slot","computeTimelineLayout","spec","totalLanes","lanes","signals","frame","segOf","s","find","lifelineYStart","mainMsgY","lastMainMsgY","frameBottom","frameY","firstFrameSignal","lastFrameSignal","slice","firstRowOffset","lastRowOffset","frameH","seg","x","y","width","height","segmentStart","segmentEnd","ms","from","to","bottomActorY","lifelineYEnd","totalH","a","cx","id","centerX","rectX","topRectY","bottomRectY","accent","topLanesSegment","bottomLanesSegment"],"sources":["../../../../src/lib/layouts/timeline/timeline-layout.ts"],"sourcesContent":["import type {\n DiagramSignal,\n DiagramSignalBox,\n DiagramTimelineSpec,\n} from '../../model/diagram-ir.ts';\nimport type { Font } from '../text/font.ts';\nimport { fontAscent, measureText } from '../text/measure-text.ts';\n\nexport type {\n DiagramFrameElement,\n DiagramLane,\n DiagramSignal,\n DiagramSignalBox,\n} from '../../model/diagram-ir.ts';\n\nexport type TimelineLayoutSpec = DiagramTimelineSpec & { title?: string[] };\n\nexport const SEQ_W = 1000;\nexport const ACTOR_W = 190;\nexport const ACTOR_H = 72;\nexport const ACTOR_RX = 16;\nexport const TOP_ACTOR_Y = 30;\nexport const ROW_H = 70;\nexport const FIRST_MSG_Y = 200;\nexport const LOOP_TOP_PAD = 38;\nexport const LOOP_X_PAD = 24;\nexport const FRAME_HEADER_H = 22;\nexport const FRAME_PAD = 12;\nexport const BOTTOM_ACTOR_GAP = 50;\nexport const DEFAULT_BOXED_STUB = 12;\nexport const SIGNAL_LABEL_FONT: Font = { face: 'mono', size: 12, weight: 400 };\nexport const SIGNAL_LABEL_PAD_X = 14;\nexport const SIGNAL_LABEL_PAD_Y = 10;\nexport const SIGNAL_LABEL_LINE_H = 18;\nexport const SIGNAL_LABEL_BASELINE_GAP = 12;\nexport const SIGNAL_LABEL_LINE_STEP = 15;\n\nexport type SegmentKind =\n 'top-lanes' | 'msg' | 'frame-frame' | 'frame-msg' | 'bottom-lanes';\n\nexport type LayoutSegment = {\n kind: SegmentKind;\n index: number;\n start: number;\n end: number;\n};\n\nexport function buildTimelineSegments(\n totalSignals: number,\n hasLoop: boolean,\n frameMsgs: number,\n): LayoutSegment[] {\n const slotCount = 1 + totalSignals + (hasLoop ? 1 + frameMsgs : 0) + 1;\n const step = 1 / slotCount;\n let i = 0;\n const segments: LayoutSegment[] = [];\n segments.push({\n kind: 'top-lanes',\n index: 0,\n start: i * step,\n end: ++i * step,\n });\n for (let m = 0; m < totalSignals; m++) {\n segments.push({ kind: 'msg', index: m, start: i * step, end: ++i * step });\n }\n if (hasLoop) {\n segments.push({\n kind: 'frame-frame',\n index: 0,\n start: i * step,\n end: ++i * step,\n });\n for (let m = 0; m < frameMsgs; m++) {\n segments.push({\n kind: 'frame-msg',\n index: m,\n start: i * step,\n end: ++i * step,\n });\n }\n }\n segments.push({\n kind: 'bottom-lanes',\n index: 0,\n start: i * step,\n end: (i + 1) * step,\n });\n return segments;\n}\n\nexport type BoxedSegment = {\n boxLeft: number;\n boxRight: number;\n boxTop: number;\n boxBottom: number;\n stubA: { x1: number; x2: number };\n stubB: { x1: number; x2: number };\n};\n\nexport function measureSignalLabel(label: string[]): {\n boxW: number;\n boxH: number;\n} {\n const widestLineW = Math.max(\n 0,\n ...label.map((line) => measureText(line, SIGNAL_LABEL_FONT)),\n );\n return {\n boxW: Math.ceil(widestLineW) + SIGNAL_LABEL_PAD_X * 2,\n boxH: label.length * SIGNAL_LABEL_LINE_H + SIGNAL_LABEL_PAD_Y * 2,\n };\n}\n\n/** Distance from a signal's row up to the top of its label or label box. */\nexport function signalLabelHeadroom(\n signal: Pick<DiagramSignal, 'label' | 'boxed'>,\n): number {\n if (signal.boxed) return measureSignalLabel(signal.label).boxH / 2;\n return (\n SIGNAL_LABEL_BASELINE_GAP +\n (signal.label.length - 1) * SIGNAL_LABEL_LINE_STEP +\n fontAscent(SIGNAL_LABEL_FONT)\n );\n}\n\n/** Distance from a signal's row down to the bottom of its label box. */\nexport function signalLabelFootroom(\n signal: Pick<DiagramSignal, 'label' | 'boxed'>,\n): number {\n return signal.boxed ? measureSignalLabel(signal.label).boxH / 2 : 0;\n}\n\nexport function computeBoxedSignal(args: {\n fromX: number;\n toX: number;\n rowY: number;\n boxW: number;\n boxH: number;\n stub: number;\n position: DiagramSignalBox;\n headInset: number;\n}): BoxedSegment {\n const { fromX, toX, rowY, boxW, boxH, stub, position, headInset } = args;\n const direction = toX > fromX ? 1 : -1;\n\n let nearEdge: number;\n switch (position) {\n case 'source':\n nearEdge = fromX + stub * direction;\n break;\n case 'center':\n nearEdge = (fromX + toX) / 2 - (boxW / 2) * direction;\n break;\n case 'target':\n nearEdge = toX - (stub + boxW) * direction;\n break;\n default: {\n const _exhaustive: never = position;\n throw new Error(`invalid boxed signal position: ${String(_exhaustive)}`);\n }\n }\n const farEdge = nearEdge + boxW * direction;\n\n const stubA = { x1: fromX, x2: nearEdge };\n const stubB = { x1: farEdge, x2: toX - headInset * direction };\n\n const stubALen = (stubA.x2 - stubA.x1) * direction;\n const stubBLen = (stubB.x2 - stubB.x1) * direction;\n if (stubALen < 0 || stubBLen < 0) {\n throw new Error(\n `boxed signal label box (width=${boxW}) overflows the lane distance |toX-fromX|=${Math.abs(toX - fromX)} with stub=${stub}, position=${position}`,\n );\n }\n\n return {\n boxLeft: Math.min(nearEdge, farEdge),\n boxRight: Math.max(nearEdge, farEdge),\n boxTop: rowY - boxH / 2,\n boxBottom: rowY + boxH / 2,\n stubA,\n stubB,\n };\n}\n\nexport function laneCenterX(index: number, total: number): number {\n const slot = SEQ_W / total;\n return slot * index + slot / 2;\n}\n\nexport type LanePlacement = {\n id: string;\n centerX: number;\n rectX: number;\n topRectY: number;\n bottomRectY: number;\n accent: boolean;\n};\n\nexport type SignalPlacement = {\n index: number;\n from: string;\n to: string;\n rowY: number;\n segmentStart: number;\n segmentEnd: number;\n};\n\nexport type FramePlacement = {\n x: number;\n y: number;\n width: number;\n height: number;\n label: string;\n segmentStart: number;\n segmentEnd: number;\n signals: SignalPlacement[];\n};\n\nexport type TimelineLayout = {\n width: number;\n height: number;\n lanes: LanePlacement[];\n lifelineYStart: number;\n lifelineYEnd: number;\n signals: SignalPlacement[];\n frame: FramePlacement | null;\n topLanesSegment: { start: number; end: number };\n bottomLanesSegment: { start: number; end: number };\n};\n\nexport function computeTimelineLayout(\n spec: TimelineLayoutSpec,\n): TimelineLayout {\n const totalLanes = spec.lanes.length;\n const totalSignals = spec.signals.length;\n const hasLoop = !!spec.frame;\n const frameMsgs = spec.frame?.signals.length ?? 0;\n\n const segments = buildTimelineSegments(totalSignals, hasLoop, frameMsgs);\n const segOf = (kind: SegmentKind, index = 0) => {\n const s = segments.find((s) => s.kind === kind && s.index === index);\n if (!s) throw new Error(`segment ${kind}[${index}] missing`);\n return s;\n };\n\n const lifelineYStart = TOP_ACTOR_Y + ACTOR_H;\n const mainMsgY = (i: number) => FIRST_MSG_Y + i * ROW_H;\n const lastMainMsgY =\n spec.signals.length > 0 ? mainMsgY(spec.signals.length - 1) : FIRST_MSG_Y;\n\n let frame: FramePlacement | null = null;\n let frameBottom = lastMainMsgY;\n\n if (hasLoop && spec.frame) {\n const frameY = lastMainMsgY + LOOP_TOP_PAD;\n const [firstFrameSignal] = spec.frame.signals;\n const [lastFrameSignal] = spec.frame.signals.slice(-1);\n const firstRowOffset =\n FRAME_HEADER_H +\n FRAME_PAD +\n (firstFrameSignal ? signalLabelHeadroom(firstFrameSignal) : 0);\n const lastRowOffset = firstRowOffset + Math.max(0, frameMsgs - 1) * ROW_H;\n const frameH =\n lastRowOffset +\n (lastFrameSignal ? signalLabelFootroom(lastFrameSignal) : 0) +\n FRAME_PAD;\n frameBottom = frameY + frameH;\n const seg = segOf('frame-frame');\n frame = {\n x: LOOP_X_PAD,\n y: frameY,\n width: SEQ_W - 2 * LOOP_X_PAD,\n height: frameH,\n label: spec.frame.label,\n segmentStart: seg.start,\n segmentEnd: seg.end,\n signals: spec.frame.signals.map((m, i) => {\n const ms = segOf('frame-msg', i);\n return {\n index: i,\n from: m.from,\n to: m.to,\n rowY: frameY + firstRowOffset + i * ROW_H,\n segmentStart: ms.start,\n segmentEnd: ms.end,\n };\n }),\n };\n }\n\n const bottomActorY = frameBottom + BOTTOM_ACTOR_GAP;\n const lifelineYEnd = bottomActorY;\n const totalH = bottomActorY + ACTOR_H + 30;\n\n const lanes: LanePlacement[] = spec.lanes.map((a, i) => {\n const cx = laneCenterX(i, totalLanes);\n return {\n id: a.id,\n centerX: cx,\n rectX: cx - ACTOR_W / 2,\n topRectY: TOP_ACTOR_Y,\n bottomRectY: bottomActorY,\n accent: !!a.accent,\n };\n });\n\n const signals: SignalPlacement[] = spec.signals.map((m, i) => {\n const seg = segOf('msg', i);\n return {\n index: i,\n from: m.from,\n to: m.to,\n rowY: mainMsgY(i),\n segmentStart: seg.start,\n segmentEnd: seg.end,\n };\n });\n\n return {\n width: SEQ_W,\n height: totalH,\n lanes,\n lifelineYStart,\n lifelineYEnd,\n signals,\n frame,\n topLanesSegment: {\n start: segOf('top-lanes').start,\n end: segOf('top-lanes').end,\n },\n bottomLanesSegment: {\n start: segOf('bottom-lanes').start,\n end: segOf('bottom-lanes').end,\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}