@zukhruf/diagram 0.3.32 → 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.
- package/README.md +98 -52
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/compiler/diagram-compile.d.ts +3 -4
- package/dist/lib/compiler/diagram-compile.d.ts.map +1 -1
- package/dist/lib/compiler/diagram-compile.js +85 -370
- package/dist/lib/compiler/diagram-compile.js.map +1 -1
- package/dist/lib/layouts/graph/attach.d.ts +25 -0
- package/dist/lib/layouts/graph/attach.d.ts.map +1 -0
- package/dist/lib/layouts/graph/attach.js +272 -0
- package/dist/lib/layouts/graph/attach.js.map +1 -0
- package/dist/lib/layouts/graph/connections.d.ts +45 -0
- package/dist/lib/layouts/graph/connections.d.ts.map +1 -0
- package/dist/lib/layouts/graph/connections.js +138 -0
- package/dist/lib/layouts/graph/connections.js.map +1 -0
- package/dist/lib/layouts/graph/graph-layout-result.d.ts +5 -3
- package/dist/lib/layouts/graph/graph-layout-result.d.ts.map +1 -1
- package/dist/lib/layouts/graph/graph-layout-result.js.map +1 -1
- package/dist/lib/layouts/graph/gutters.js +41 -22
- package/dist/lib/layouts/graph/gutters.js.map +1 -1
- package/dist/lib/layouts/graph/labels.d.ts +23 -0
- package/dist/lib/layouts/graph/labels.d.ts.map +1 -0
- package/dist/lib/layouts/graph/labels.js +120 -0
- package/dist/lib/layouts/graph/labels.js.map +1 -0
- package/dist/lib/layouts/graph/layout.d.ts +1 -1
- package/dist/lib/layouts/graph/layout.d.ts.map +1 -1
- package/dist/lib/layouts/graph/layout.js +37 -12
- package/dist/lib/layouts/graph/layout.js.map +1 -1
- package/dist/lib/layouts/graph/measure.d.ts +15 -11
- package/dist/lib/layouts/graph/measure.d.ts.map +1 -1
- package/dist/lib/layouts/graph/measure.js +82 -38
- package/dist/lib/layouts/graph/measure.js.map +1 -1
- package/dist/lib/layouts/graph/min-heap.d.ts +8 -0
- package/dist/lib/layouts/graph/min-heap.d.ts.map +1 -0
- package/dist/lib/layouts/graph/min-heap.js +56 -0
- package/dist/lib/layouts/graph/min-heap.js.map +1 -0
- package/dist/lib/layouts/graph/node-content.d.ts +2 -3
- package/dist/lib/layouts/graph/node-content.d.ts.map +1 -1
- package/dist/lib/layouts/graph/node-content.js +67 -47
- package/dist/lib/layouts/graph/node-content.js.map +1 -1
- package/dist/lib/layouts/graph/path.d.ts +6 -0
- package/dist/lib/layouts/graph/path.d.ts.map +1 -0
- package/dist/lib/layouts/graph/path.js +53 -0
- package/dist/lib/layouts/graph/path.js.map +1 -0
- package/dist/lib/layouts/graph/round.d.ts +11 -0
- package/dist/lib/layouts/graph/round.d.ts.map +1 -0
- package/dist/lib/layouts/graph/round.js +181 -0
- package/dist/lib/layouts/graph/round.js.map +1 -0
- package/dist/lib/layouts/graph/route-search.d.ts +34 -0
- package/dist/lib/layouts/graph/route-search.d.ts.map +1 -0
- package/dist/lib/layouts/graph/route-search.js +208 -0
- package/dist/lib/layouts/graph/route-search.js.map +1 -0
- package/dist/lib/layouts/graph/route.d.ts +20 -0
- package/dist/lib/layouts/graph/route.d.ts.map +1 -0
- package/dist/lib/layouts/graph/route.js +276 -0
- package/dist/lib/layouts/graph/route.js.map +1 -0
- package/dist/lib/layouts/graph/sides.d.ts +28 -0
- package/dist/lib/layouts/graph/sides.d.ts.map +1 -0
- package/dist/lib/layouts/graph/sides.js +98 -0
- package/dist/lib/layouts/graph/sides.js.map +1 -0
- package/dist/lib/layouts/timeline/timeline-layout.d.ts +2 -1
- package/dist/lib/layouts/timeline/timeline-layout.d.ts.map +1 -1
- package/dist/lib/layouts/timeline/timeline-layout.js +9 -4
- package/dist/lib/layouts/timeline/timeline-layout.js.map +1 -1
- package/dist/lib/model/diagram-ir.d.ts +19 -156
- package/dist/lib/model/diagram-ir.d.ts.map +1 -1
- package/dist/lib/model/diagram-ir.js.map +1 -1
- package/dist/lib/model/validate-graph.d.ts +7 -0
- package/dist/lib/model/validate-graph.d.ts.map +1 -0
- package/dist/lib/model/validate-graph.js +54 -0
- package/dist/lib/model/validate-graph.js.map +1 -0
- package/dist/lib/react/Diagram.d.ts +3 -9
- package/dist/lib/react/Diagram.d.ts.map +1 -1
- package/dist/lib/react/Diagram.js +1 -13
- package/dist/lib/react/Diagram.js.map +1 -1
- package/dist/lib/react/diagram-types.d.ts +17 -46
- package/dist/lib/react/diagram-types.d.ts.map +1 -1
- package/dist/lib/react/diagram-types.js.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.d.ts +2 -5
- package/dist/lib/renderers/canvas/graph-canvas.d.ts.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.js +68 -43
- package/dist/lib/renderers/canvas/graph-canvas.js.map +1 -1
- package/dist/lib/renderers/html/graph-html.d.ts +2 -3
- package/dist/lib/renderers/html/graph-html.d.ts.map +1 -1
- package/dist/lib/renderers/html/graph-html.js +298 -289
- package/dist/lib/renderers/html/graph-html.js.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.d.ts +3 -1
- package/dist/lib/renderers/shared/graph-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.js +350 -418
- package/dist/lib/renderers/shared/graph-parts.js.map +1 -1
- package/dist/lib/renderers/shared/node-parts.d.ts +5 -6
- package/dist/lib/renderers/shared/node-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/node-parts.js +112 -190
- package/dist/lib/renderers/shared/node-parts.js.map +1 -1
- package/dist/lib/renderers/shared/run-spans.js +2 -2
- package/dist/lib/renderers/shared/run-spans.js.map +1 -1
- package/dist/lib/renderers/shared/text-runs.d.ts +0 -6
- package/dist/lib/renderers/shared/text-runs.d.ts.map +1 -1
- package/dist/lib/renderers/shared/text-runs.js +0 -12
- package/dist/lib/renderers/shared/text-runs.js.map +1 -1
- package/dist/lib/renderers/svg/graph-svg.d.ts +1 -3
- package/dist/lib/renderers/svg/graph-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/graph-svg.js +66 -80
- package/dist/lib/renderers/svg/graph-svg.js.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.js +7 -5
- package/dist/lib/renderers/svg/timeline-svg.js.map +1 -1
- package/package.json +1 -1
- package/dist/lib/layouts/graph/graph-layout.d.ts +0 -154
- package/dist/lib/layouts/graph/graph-layout.d.ts.map +0 -1
- package/dist/lib/layouts/graph/graph-layout.js +0 -2340
- package/dist/lib/layouts/graph/graph-layout.js.map +0 -1
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts +0 -6
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts.map +0 -1
- package/dist/lib/layouts/graph/legacy-graph-layout.js +0 -542
- package/dist/lib/layouts/graph/legacy-graph-layout.js.map +0 -1
- package/dist/lib/layouts/text-metrics.d.ts +0 -7
- package/dist/lib/layouts/text-metrics.d.ts.map +0 -1
- package/dist/lib/layouts/text-metrics.js +0 -40
- package/dist/lib/layouts/text-metrics.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measure.js","names":["nodeContent","labelLines","textBlock","PORT_LABEL_OFFSET","EDGE_LABEL_FRAME_PAD","BADGE_PAD","x","y","BADGE_MIN_CONTENT","SIDES","measureNode","node","tokens","kind","hidden","hiddenNode","content","ports","portGeometry","w","Math","max","pad","inset","left","right","minLength","top","bottom","h","place","box","inner","frames","stackFrames","caption","placeCaption","union","visual","radius","frameRadius","frame","overhang","stretch","text","bullets","min","FLAT_RADIUS","RADIUS","font","fonts","portLabel","bySide","Map","map","side","filter","port","label","accent","undefined","widest","get","tallest","labelDepth","depth","sideLength","count","length","labelLength","pitch","PORT_SPACING","LABEL_GAP","sidesOf","flatMap","onSide","index","fraction","point","portPoint","run","placePortLabel","id","floor","stack","direction","stackDirection","dx","endsWith","STACK_STEP","dy","startsWith","Array","from","_","level","lines","flat","line","trim","captionColor","framed","captionFrame","size","gap","CAPTION_GAP","captionSide","centreX","centreY","captionBox","measureGroupTitle","group","groupLabel","height","BAND_PAD","rect","labelSide","align","labelAlign","PAD_X","titleBand","band","measureEdgeLabel","edge","edgeLabel","labelFrame","measureEdgeBadge","badgeLabel","badge","icon","badgeIcon","BADGE_ICON","BLOCK_GAP","rowW","cy","value","by","boxes"],"sources":["../../../../src/lib/layouts/graph/measure.ts"],"sourcesContent":["import type {\n Box,\n DiagramEdge,\n DiagramGroup,\n DiagramNode,\n DiagramNodePort,\n DiagramSide,\n} from '../../model/diagram-ir.ts';\nimport type { NodeLayout, TextRun } from './graph-layout-result.ts';\nimport { nodeContent } from './node-content.ts';\nimport { type TextBlock, labelLines, textBlock } from './text-block.ts';\nimport type { LayoutTokens } from './tokens.ts';\n\ntype Sides = Record<DiagramSide, number>;\n\nexport type MeasuredNode = {\n /** The smallest frame that holds the node's content. */\n frame: { w: number; h: number };\n /** How far the stacked frames and the caption reach outside the frame. */\n overhang: Sides;\n /** Whether the frame grows to fill its grid area. */\n stretch: boolean;\n /** Positions everything the node draws, given its final frame (at least `frame`). */\n place(box: Box): Omit<NodeLayout, 'node'>;\n};\n\n/** The distance from a port's point to its label: the port marker's radius plus a gap. */\nconst PORT_LABEL_OFFSET = 8;\nconst EDGE_LABEL_FRAME_PAD = 4;\n/** Mirrors the badge drawn before content sizing: 8px side inset, 6px above and below, 24px content at least. */\nconst BADGE_PAD = { x: 8, y: 6 };\nconst BADGE_MIN_CONTENT = 24;\n\nconst SIDES: DiagramSide[] = ['top', 'right', 'bottom', 'left'];\n\nexport function measureNode(\n node: DiagramNode,\n tokens: LayoutTokens,\n): MeasuredNode {\n const kind = node.kind ?? 'node';\n if (node.hidden && kind === 'node') return hiddenNode();\n\n const content = nodeContent(node, tokens);\n const ports = portGeometry(node.ports ?? [], tokens);\n const w = Math.max(\n content.w + 2 * content.pad.x + ports.inset.left + ports.inset.right,\n ports.minLength.top,\n ports.minLength.bottom,\n );\n const h = Math.max(\n content.h + 2 * content.pad.y + ports.inset.top + ports.inset.bottom,\n ports.minLength.left,\n ports.minLength.right,\n );\n\n const place = (box: Box): Omit<NodeLayout, 'node'> => {\n const inner = inset(inset(box, ports.inset), {\n top: content.pad.y,\n bottom: content.pad.y,\n left: content.pad.x,\n right: content.pad.x,\n });\n const frames = stackFrames(node, box, tokens);\n const caption = placeCaption(node, union([box, ...frames]), tokens);\n return {\n box,\n visual: union([box, ...frames, ...(caption ? [caption.box] : [])]),\n frames,\n radius: frameRadius(node, box, tokens),\n ...content.place(inner),\n ...(caption ? { caption } : {}),\n ports: ports.place(box),\n };\n };\n\n const { visual } = place({ x: 0, y: 0, w, h });\n return {\n frame: { w, h },\n overhang: {\n top: 0 - visual.y,\n left: 0 - visual.x,\n bottom: visual.y + visual.h - h,\n right: visual.x + visual.w - w,\n },\n stretch: kind === 'node' && (node.stretch ?? true),\n place,\n };\n}\n\nfunction hiddenNode(): MeasuredNode {\n return {\n frame: { w: 0, h: 0 },\n overhang: { top: 0, right: 0, bottom: 0, left: 0 },\n stretch: false,\n place: (box) => ({\n box,\n visual: box,\n frames: [],\n radius: 0,\n text: [],\n bullets: [],\n ports: [],\n }),\n };\n}\n\nfunction frameRadius(\n node: DiagramNode,\n box: Box,\n tokens: LayoutTokens,\n): number {\n switch (node.kind) {\n case 'connector':\n return box.h / 2;\n case 'junction':\n return Math.min(box.w, box.h) / 2;\n case 'marker':\n case 'appliance':\n case 'note':\n return 0;\n default:\n if (node.frame === 'none') return 0;\n return node.frame === 'flat' ? tokens.FLAT_RADIUS : tokens.RADIUS;\n }\n}\n\n/**\n * Ports sit evenly along their side, with their labels inside the frame. A\n * side's labels push the content inward, and a side with k ports is long\n * enough for k + 1 port spacings.\n */\nfunction portGeometry(ports: DiagramNodePort[], tokens: LayoutTokens) {\n const font = tokens.fonts.portLabel;\n const bySide = new Map(\n SIDES.map((side) => [\n side,\n ports\n .filter((port) => port.side === side)\n .map((port) => ({\n port,\n label: port.label\n ? textBlock(\n labelLines(port.label, port.accent ? 'accent' : undefined),\n font,\n )\n : undefined,\n })),\n ]),\n );\n const widest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.w ?? 0));\n const tallest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.h ?? 0));\n const labelDepth = (side: DiagramSide) => {\n const depth =\n side === 'left' || side === 'right' ? widest(side) : tallest(side);\n return depth > 0 ? PORT_LABEL_OFFSET + depth : 0;\n };\n const sideLength = (side: DiagramSide) => {\n const count = bySide.get(side)!.length;\n if (count === 0) return 0;\n const labelLength =\n side === 'top' || side === 'bottom' ? widest(side) : tallest(side);\n const pitch = Math.max(tokens.PORT_SPACING, labelLength + tokens.LABEL_GAP);\n return (count + 1) * pitch;\n };\n\n return {\n inset: sidesOf(labelDepth),\n minLength: sidesOf(sideLength),\n place: (box: Box): NodeLayout['ports'] =>\n SIDES.flatMap((side) => {\n const onSide = bySide.get(side)!;\n return onSide.map(({ port, label }, index) => {\n const fraction = (index + 1) / (onSide.length + 1);\n const point = portPoint(box, side, fraction);\n const run = label && placePortLabel(label, point, side)[0];\n return {\n id: port.id,\n side,\n point,\n ...(run ? { label: run } : {}),\n };\n });\n }),\n };\n}\n\n/** The point `fraction` of the way along `side` of `box`. */\nfunction portPoint(\n box: Box,\n side: DiagramSide,\n fraction: number,\n): { x: number; y: number } {\n switch (side) {\n case 'top':\n return { x: box.x + box.w * fraction, y: box.y };\n case 'bottom':\n return { x: box.x + box.w * fraction, y: box.y + box.h };\n case 'left':\n return { x: box.x, y: box.y + box.h * fraction };\n case 'right':\n return { x: box.x + box.w, y: box.y + box.h * fraction };\n }\n}\n\nfunction placePortLabel(\n label: TextBlock,\n point: { x: number; y: number },\n side: DiagramSide,\n): TextRun[] {\n switch (side) {\n case 'left':\n return label.place(\n point.x + PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'start',\n );\n case 'right':\n return label.place(\n point.x - PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'end',\n );\n case 'top':\n return label.place(point.x, point.y + PORT_LABEL_OFFSET, 'middle');\n case 'bottom':\n return label.place(\n point.x,\n point.y - PORT_LABEL_OFFSET - label.h,\n 'middle',\n );\n }\n}\n\n/** The back frames of a stack, farthest first, each one STACK_STEP further in the stack direction. */\nfunction stackFrames(node: DiagramNode, box: Box, tokens: LayoutTokens): Box[] {\n const count = Math.max(1, Math.floor(node.stack ?? 1));\n const kind = node.kind ?? 'node';\n if (count === 1 || kind !== 'node' || node.frame === 'none') return [];\n const direction = node.stackDirection ?? 'up-left';\n const dx = (direction.endsWith('left') ? -1 : 1) * tokens.STACK_STEP.x;\n const dy = (direction.startsWith('up') ? -1 : 1) * tokens.STACK_STEP.y;\n return Array.from({ length: count - 1 }, (_, index) => {\n const level = count - 1 - index;\n return { ...box, x: box.x + level * dx, y: box.y + level * dy };\n });\n}\n\n/** The caption sits beside `box`, the frame together with its stacked back frames. */\nfunction placeCaption(\n node: DiagramNode,\n box: Box,\n tokens: LayoutTokens,\n): NodeLayout['caption'] {\n const font = tokens.fonts.caption;\n const lines = textBlock(\n labelLines(\n [node.caption ?? []].flat().map((line) => line.trim()),\n node.captionColor,\n ),\n font,\n );\n if (lines.h === 0) return undefined;\n const framed = node.captionFrame ?? false;\n const pad = framed\n ? { x: 0.9 * font.size, y: 0.55 * font.size }\n : { x: 0, y: 0 };\n const w = lines.w + 2 * pad.x;\n const h = lines.h + 2 * pad.y;\n const gap = tokens.CAPTION_GAP;\n const side = node.captionSide ?? 'bottom';\n const centreX = box.x + (box.w - w) / 2;\n const centreY = box.y + (box.h - h) / 2;\n const captionBox: Box = {\n top: { x: centreX, y: box.y - gap - h, w, h },\n bottom: { x: centreX, y: box.y + box.h + gap, w, h },\n left: { x: box.x - gap - w, y: centreY, w, h },\n right: { x: box.x + box.w + gap, y: centreY, w, h },\n }[side];\n const top = captionBox.y + pad.y;\n let text: TextRun[];\n if (side === 'left') {\n text = lines.place(captionBox.x + w - pad.x, top, 'end');\n } else if (side === 'right') {\n text = lines.place(captionBox.x + pad.x, top, 'start');\n } else {\n text = lines.place(captionBox.x + w / 2, top, 'middle');\n }\n return { box: captionBox, framed, text };\n}\n\nexport type MeasuredGroupTitle = {\n /** The height the title reserves on its side, BAND_PAD above and below included; 0 without a label. */\n height: number;\n place(rect: Box): { band?: Box; label: TextRun[] };\n};\n\nexport function measureGroupTitle(\n group: DiagramGroup,\n tokens: LayoutTokens,\n): MeasuredGroupTitle {\n const lines = textBlock(labelLines(group.label), tokens.fonts.groupLabel);\n const height = lines.h > 0 ? lines.h + 2 * tokens.BAND_PAD : 0;\n return {\n height,\n place(rect) {\n if (height === 0) return { label: [] };\n const y =\n group.labelSide === 'bottom' ? rect.y + rect.h - height : rect.y;\n const top = y + tokens.BAND_PAD;\n const align = group.labelAlign ?? 'center';\n let label: TextRun[];\n if (align === 'start') {\n label = lines.place(rect.x + tokens.PAD_X, top, 'start');\n } else if (align === 'end') {\n label = lines.place(rect.x + rect.w - tokens.PAD_X, top, 'end');\n } else {\n label = lines.place(rect.x + rect.w / 2, top, 'middle');\n }\n return group.titleBand\n ? { band: { x: rect.x, y, w: rect.w, h: height }, label }\n : { label };\n },\n };\n}\n\nexport type MeasuredEdgeLabel = {\n w: number;\n h: number;\n place(box: Box): TextRun[];\n};\n\nexport function measureEdgeLabel(\n edge: DiagramEdge,\n tokens: LayoutTokens,\n): MeasuredEdgeLabel {\n const lines = textBlock(labelLines(edge.label), tokens.fonts.edgeLabel);\n const pad = edge.labelFrame ? EDGE_LABEL_FRAME_PAD : 0;\n return {\n w: lines.w + 2 * pad,\n h: lines.h + 2 * pad,\n place: (box) => lines.place(box.x + box.w / 2, box.y + pad, 'middle'),\n };\n}\n\nexport type MeasuredEdgeBadge = {\n w: number;\n h: number;\n place(box: Box): { icon?: Box; text: TextRun[] };\n};\n\nexport function measureEdgeBadge(\n edge: DiagramEdge,\n tokens: LayoutTokens,\n): MeasuredEdgeBadge {\n const lines = textBlock(labelLines(edge.badgeLabel), tokens.fonts.badge);\n const icon = edge.badgeIcon ? tokens.BADGE_ICON : 0;\n const gap = icon > 0 && lines.w > 0 ? tokens.BLOCK_GAP : 0;\n const rowW = icon + gap + lines.w;\n return {\n w: Math.max(BADGE_MIN_CONTENT, rowW) + 2 * BADGE_PAD.x,\n h: Math.max(BADGE_MIN_CONTENT, lines.h) + 2 * BADGE_PAD.y,\n place(box) {\n const x = box.x + (box.w - rowW) / 2;\n const cy = box.y + box.h / 2;\n const text = lines.place(x + icon + gap, cy - lines.h / 2, 'start');\n return icon > 0\n ? { icon: { x, y: cy - icon / 2, w: icon, h: icon }, text }\n : { text };\n },\n };\n}\n\nfunction sidesOf(value: (side: DiagramSide) => number): Sides {\n return {\n top: value('top'),\n right: value('right'),\n bottom: value('bottom'),\n left: value('left'),\n };\n}\n\nfunction inset(box: Box, by: Sides): Box {\n return {\n x: box.x + by.left,\n y: box.y + by.top,\n w: box.w - by.left - by.right,\n h: box.h - by.top - by.bottom,\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":"measure.js","names":["nodeContent","labelLines","textBlock","LAYOUT_TOKENS","PORT_LABEL_OFFSET","EDGE_LABEL_FRAME_PAD","BADGE_PAD","x","y","BADGE_MIN_CONTENT","SIDES","measureNode","node","kind","hidden","hiddenNode","content","ports","portGeometry","w","Math","max","pad","inset","left","right","minLength","top","bottom","h","place","box","inner","frames","stackFrames","caption","placeCaption","union","visual","radius","frameRadius","outside","outer","stack","all","a","b","vertical","horizontal","frame","overhang","stretch","text","bullets","min","FLAT_RADIUS","RADIUS","font","fonts","portLabel","bySide","Map","map","side","filter","port","label","accent","undefined","widest","get","tallest","labelDepth","depth","sideLength","count","length","labelLength","pitch","PORT_SPACING","LABEL_GAP","sidesOf","flatMap","onSide","index","fraction","point","portPoint","run","placePortLabel","id","placeGroupPorts","rect","floor","direction","stackDirection","dx","endsWith","STACK_STEP","dy","startsWith","Array","from","_","level","lines","flat","line","trim","captionColor","framed","captionFrame","size","gap","CAPTION_GAP","captionSide","centreX","centreY","captionBox","measureGroupTitle","group","groupLabel","height","BAND_PAD","labelSide","align","labelAlign","PAD_X","titleBand","edge","band","separator","measureEdgeLabel","edgeLabel","labelFrame","measureEdgeBadge","badgeLabel","badge","icon","badgeIcon","BADGE_ICON","BLOCK_GAP","rowW","cy","measureEdgeTags","value","by","boxes"],"sources":["../../../../src/lib/layouts/graph/measure.ts"],"sourcesContent":["import type {\n Box,\n DiagramEdge,\n DiagramGroup,\n DiagramNode,\n DiagramNodePort,\n DiagramSide,\n} from '../../model/diagram-ir.ts';\nimport type {\n GroupLayout,\n NodeLayout,\n TextRun,\n} from './graph-layout-result.ts';\nimport { nodeContent } from './node-content.ts';\nimport { type TextBlock, labelLines, textBlock } from './text-block.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\ntype Sides = Record<DiagramSide, number>;\n\nexport type MeasuredNode = {\n /** The smallest frame that holds the node's content. */\n frame: { w: number; h: number };\n /** How far the stacked frames and the caption reach outside the frame. */\n overhang: Sides;\n /** Whether the frame grows to fill its grid area. */\n stretch: boolean;\n /** Positions everything the node draws, given its final frame (at least `frame`). */\n place(box: Box): Omit<NodeLayout, 'node'>;\n};\n\n/** The distance from a port's point to its label: the port marker's radius plus a gap. */\nconst PORT_LABEL_OFFSET = 8;\nconst EDGE_LABEL_FRAME_PAD = 4;\n/** Mirrors the badge drawn before content sizing: 8px side inset, 6px above and below, 24px content at least. */\nconst BADGE_PAD = { x: 8, y: 6 };\nconst BADGE_MIN_CONTENT = 24;\n\nconst SIDES: DiagramSide[] = ['top', 'right', 'bottom', 'left'];\n\nexport function measureNode(node: DiagramNode): MeasuredNode {\n const kind = node.kind ?? 'node';\n if (node.hidden && kind === 'node') return hiddenNode();\n\n const content = nodeContent(node);\n const ports = portGeometry(node.ports ?? []);\n const w = Math.max(\n content.w + 2 * content.pad.x + ports.inset.left + ports.inset.right,\n ports.minLength.top,\n ports.minLength.bottom,\n );\n const h = Math.max(\n content.h + 2 * content.pad.y + ports.inset.top + ports.inset.bottom,\n ports.minLength.left,\n ports.minLength.right,\n );\n\n const place = (box: Box): Omit<NodeLayout, 'node'> => {\n const inner = inset(inset(box, ports.inset), {\n top: content.pad.y,\n bottom: content.pad.y,\n left: content.pad.x,\n right: content.pad.x,\n });\n const frames = stackFrames(node, box);\n const caption = placeCaption(node, union([box, ...frames]));\n return {\n box,\n visual: union([box, ...frames, ...(caption ? [caption.box] : [])]),\n frames,\n radius: frameRadius(node, box),\n ...content.place(inner),\n ...(caption ? { caption } : {}),\n ports: ports.place(box),\n };\n };\n\n const { visual, frames } = place({ x: 0, y: 0, w, h });\n const outside = (outer: Box): Sides => ({\n top: 0 - outer.y,\n left: 0 - outer.x,\n bottom: outer.y + outer.h - h,\n right: outer.x + outer.w - w,\n });\n const stack = outside(union([{ x: 0, y: 0, w, h }, ...frames]));\n const all = outside(visual);\n // A caption reserves its room on both sides of the frame, so the frames of a row (or column) stay on one centre line whichever side their captions hang.\n const caption = (a: DiagramSide, b: DiagramSide) =>\n Math.max(all[a] - stack[a], all[b] - stack[b]);\n const vertical = caption('top', 'bottom');\n const horizontal = caption('left', 'right');\n return {\n frame: { w, h },\n overhang: {\n top: stack.top + vertical,\n bottom: stack.bottom + vertical,\n left: stack.left + horizontal,\n right: stack.right + horizontal,\n },\n stretch: kind === 'node',\n place,\n };\n}\n\nfunction hiddenNode(): MeasuredNode {\n return {\n frame: { w: 0, h: 0 },\n overhang: { top: 0, right: 0, bottom: 0, left: 0 },\n stretch: false,\n place: (box) => ({\n box,\n visual: box,\n frames: [],\n radius: 0,\n text: [],\n bullets: [],\n ports: [],\n }),\n };\n}\n\nfunction frameRadius(node: DiagramNode, box: Box): number {\n switch (node.kind) {\n case 'connector':\n return box.h / 2;\n case 'junction':\n return Math.min(box.w, box.h) / 2;\n case 'marker':\n case 'appliance':\n case 'note':\n return 0;\n default:\n if (node.frame === 'none') return 0;\n return node.frame === 'flat'\n ? LAYOUT_TOKENS.FLAT_RADIUS\n : LAYOUT_TOKENS.RADIUS;\n }\n}\n\n/**\n * Ports sit evenly along their side, with their labels inside the frame. A\n * side's labels push the content inward, and a side with k ports is long\n * enough for k + 1 port spacings.\n */\nfunction portGeometry(ports: DiagramNodePort[]) {\n const font = LAYOUT_TOKENS.fonts.portLabel;\n const bySide = new Map(\n SIDES.map((side) => [\n side,\n ports\n .filter((port) => port.side === side)\n .map((port) => ({\n port,\n label: port.label\n ? textBlock(\n labelLines(port.label, port.accent ? 'accent' : undefined),\n font,\n )\n : undefined,\n })),\n ]),\n );\n const widest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.w ?? 0));\n const tallest = (side: DiagramSide) =>\n Math.max(0, ...bySide.get(side)!.map(({ label }) => label?.h ?? 0));\n const labelDepth = (side: DiagramSide) => {\n const depth =\n side === 'left' || side === 'right' ? widest(side) : tallest(side);\n return depth > 0 ? PORT_LABEL_OFFSET + depth : 0;\n };\n const sideLength = (side: DiagramSide) => {\n const count = bySide.get(side)!.length;\n if (count === 0) return 0;\n const labelLength =\n side === 'top' || side === 'bottom' ? widest(side) : tallest(side);\n const pitch = Math.max(\n LAYOUT_TOKENS.PORT_SPACING,\n labelLength + LAYOUT_TOKENS.LABEL_GAP,\n );\n return (count + 1) * pitch;\n };\n\n return {\n inset: sidesOf(labelDepth),\n minLength: sidesOf(sideLength),\n place: (box: Box): NodeLayout['ports'] =>\n SIDES.flatMap((side) => {\n const onSide = bySide.get(side)!;\n return onSide.map(({ port, label }, index) => {\n const fraction = (index + 1) / (onSide.length + 1);\n const point = portPoint(box, side, fraction);\n const run = label && placePortLabel(label, point, side)[0];\n return {\n id: port.id,\n side,\n point,\n ...(run ? { label: run } : {}),\n };\n });\n }),\n };\n}\n\n/** A group's ports sit evenly along their side of its rect, like a node's ports along its frame. */\nexport function placeGroupPorts(\n ports: DiagramNodePort[],\n rect: Box,\n): NodeLayout['ports'] {\n return portGeometry(ports).place(rect);\n}\n\n/** The point `fraction` of the way along `side` of `box`. */\nfunction portPoint(\n box: Box,\n side: DiagramSide,\n fraction: number,\n): { x: number; y: number } {\n switch (side) {\n case 'top':\n return { x: box.x + box.w * fraction, y: box.y };\n case 'bottom':\n return { x: box.x + box.w * fraction, y: box.y + box.h };\n case 'left':\n return { x: box.x, y: box.y + box.h * fraction };\n case 'right':\n return { x: box.x + box.w, y: box.y + box.h * fraction };\n }\n}\n\nfunction placePortLabel(\n label: TextBlock,\n point: { x: number; y: number },\n side: DiagramSide,\n): TextRun[] {\n switch (side) {\n case 'left':\n return label.place(\n point.x + PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'start',\n );\n case 'right':\n return label.place(\n point.x - PORT_LABEL_OFFSET,\n point.y - label.h / 2,\n 'end',\n );\n case 'top':\n return label.place(point.x, point.y + PORT_LABEL_OFFSET, 'middle');\n case 'bottom':\n return label.place(\n point.x,\n point.y - PORT_LABEL_OFFSET - label.h,\n 'middle',\n );\n }\n}\n\n/** The back frames of a stack, farthest first, each one STACK_STEP further in the stack direction. */\nfunction stackFrames(node: DiagramNode, box: Box): Box[] {\n const count = Math.max(1, Math.floor(node.stack ?? 1));\n const kind = node.kind ?? 'node';\n if (count === 1 || kind !== 'node' || node.frame === 'none') return [];\n const direction = node.stackDirection ?? 'up-left';\n const dx = (direction.endsWith('left') ? -1 : 1) * LAYOUT_TOKENS.STACK_STEP.x;\n const dy = (direction.startsWith('up') ? -1 : 1) * LAYOUT_TOKENS.STACK_STEP.y;\n return Array.from({ length: count - 1 }, (_, index) => {\n const level = count - 1 - index;\n return { ...box, x: box.x + level * dx, y: box.y + level * dy };\n });\n}\n\n/** The caption sits beside `box`, the frame together with its stacked back frames. */\nfunction placeCaption(node: DiagramNode, box: Box): NodeLayout['caption'] {\n const font = LAYOUT_TOKENS.fonts.caption;\n const lines = textBlock(\n labelLines(\n [node.caption ?? []].flat().map((line) => line.trim()),\n node.captionColor,\n ),\n font,\n );\n if (lines.h === 0) return undefined;\n const framed = node.captionFrame ?? false;\n const pad = framed\n ? { x: 0.9 * font.size, y: 0.55 * font.size }\n : { x: 0, y: 0 };\n const w = lines.w + 2 * pad.x;\n const h = lines.h + 2 * pad.y;\n const gap = LAYOUT_TOKENS.CAPTION_GAP;\n const side = node.captionSide ?? 'bottom';\n const centreX = box.x + (box.w - w) / 2;\n const centreY = box.y + (box.h - h) / 2;\n const captionBox: Box = {\n top: { x: centreX, y: box.y - gap - h, w, h },\n bottom: { x: centreX, y: box.y + box.h + gap, w, h },\n left: { x: box.x - gap - w, y: centreY, w, h },\n right: { x: box.x + box.w + gap, y: centreY, w, h },\n }[side];\n const top = captionBox.y + pad.y;\n let text: TextRun[];\n if (side === 'left') {\n text = lines.place(captionBox.x + w - pad.x, top, 'end');\n } else if (side === 'right') {\n text = lines.place(captionBox.x + pad.x, top, 'start');\n } else {\n text = lines.place(captionBox.x + w / 2, top, 'middle');\n }\n return { box: captionBox, framed, text };\n}\n\nexport type MeasuredGroupTitle = {\n /** The height the title reserves on its side, BAND_PAD above and below included; 0 without a label. */\n height: number;\n place(rect: Box): Pick<GroupLayout, 'band' | 'separator' | 'label'>;\n};\n\nexport function measureGroupTitle(group: DiagramGroup): MeasuredGroupTitle {\n const lines = textBlock(\n labelLines(group.label),\n LAYOUT_TOKENS.fonts.groupLabel,\n );\n const height = lines.h > 0 ? lines.h + 2 * LAYOUT_TOKENS.BAND_PAD : 0;\n return {\n height,\n place(rect) {\n if (height === 0) return { label: [] };\n const y =\n group.labelSide === 'bottom' ? rect.y + rect.h - height : rect.y;\n const top = y + LAYOUT_TOKENS.BAND_PAD;\n const align = group.labelAlign ?? 'center';\n let label: TextRun[];\n if (align === 'start') {\n label = lines.place(rect.x + LAYOUT_TOKENS.PAD_X, top, 'start');\n } else if (align === 'end') {\n label = lines.place(rect.x + rect.w - LAYOUT_TOKENS.PAD_X, top, 'end');\n } else {\n label = lines.place(rect.x + rect.w / 2, top, 'middle');\n }\n if (!group.titleBand) return { label };\n const edge = group.labelSide === 'bottom' ? y : y + height;\n return {\n band: { x: rect.x, y, w: rect.w, h: height },\n separator: [\n { x: rect.x, y: edge },\n { x: rect.x + rect.w, y: edge },\n ],\n label,\n };\n },\n };\n}\n\nexport type MeasuredEdgeLabel = {\n w: number;\n h: number;\n place(box: Box): TextRun[];\n};\n\nexport function measureEdgeLabel(edge: DiagramEdge): MeasuredEdgeLabel {\n const lines = textBlock(\n labelLines(edge.label),\n LAYOUT_TOKENS.fonts.edgeLabel,\n );\n const pad = edge.labelFrame ? EDGE_LABEL_FRAME_PAD : 0;\n return {\n w: lines.w + 2 * pad,\n h: lines.h + 2 * pad,\n place: (box) => lines.place(box.x + box.w / 2, box.y + pad, 'middle'),\n };\n}\n\nexport type MeasuredEdgeBadge = {\n w: number;\n h: number;\n place(box: Box): { icon?: Box; text: TextRun[] };\n};\n\nexport function measureEdgeBadge(edge: DiagramEdge): MeasuredEdgeBadge {\n const lines = textBlock(\n labelLines(edge.badgeLabel),\n LAYOUT_TOKENS.fonts.badge,\n );\n const icon = edge.badgeIcon ? LAYOUT_TOKENS.BADGE_ICON : 0;\n const gap = icon > 0 && lines.w > 0 ? LAYOUT_TOKENS.BLOCK_GAP : 0;\n const rowW = icon + gap + lines.w;\n return {\n w: Math.max(BADGE_MIN_CONTENT, rowW) + 2 * BADGE_PAD.x,\n h: Math.max(BADGE_MIN_CONTENT, lines.h) + 2 * BADGE_PAD.y,\n place(box) {\n const x = box.x + (box.w - rowW) / 2;\n const cy = box.y + box.h / 2;\n const text = lines.place(x + icon + gap, cy - lines.h / 2, 'start');\n return icon > 0\n ? { icon: { x, y: cy - icon / 2, w: icon, h: icon }, text }\n : { text };\n },\n };\n}\n\nexport type MeasuredEdgeTags = {\n label?: MeasuredEdgeLabel;\n badge?: MeasuredEdgeBadge;\n};\n\n/** What an edge carries along its route: a label beside it and a badge on it, each only when the edge has one. */\nexport function measureEdgeTags(edge: DiagramEdge): MeasuredEdgeTags {\n return {\n ...(edge.label?.length ? { label: measureEdgeLabel(edge) } : {}),\n ...(edge.badgeIcon || edge.badgeLabel?.length\n ? { badge: measureEdgeBadge(edge) }\n : {}),\n };\n}\n\nfunction sidesOf(value: (side: DiagramSide) => number): Sides {\n return {\n top: value('top'),\n right: value('right'),\n bottom: value('bottom'),\n left: value('left'),\n };\n}\n\nfunction inset(box: Box, by: Sides): Box {\n return {\n x: box.x + by.left,\n y: box.y + by.top,\n w: box.w - by.left - by.right,\n h: box.h - by.top - by.bottom,\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":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"min-heap.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/min-heap.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,qBAAa,OAAO,CAAC,CAAC;;IAGpB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKrC,GAAG,IAAI,CAAC,GAAG,SAAS;CA2CrB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** A binary min-heap of items by priority. */
|
|
2
|
+
export class MinHeap {
|
|
3
|
+
#data = [];
|
|
4
|
+
get size() {
|
|
5
|
+
return this.#data.length;
|
|
6
|
+
}
|
|
7
|
+
push(item, priority) {
|
|
8
|
+
this.#data.push({
|
|
9
|
+
item,
|
|
10
|
+
priority
|
|
11
|
+
});
|
|
12
|
+
this.#bubbleUp(this.#data.length - 1);
|
|
13
|
+
}
|
|
14
|
+
pop() {
|
|
15
|
+
const top = this.#data[0];
|
|
16
|
+
if (!top) return undefined;
|
|
17
|
+
const last = this.#data.pop();
|
|
18
|
+
if (this.#data.length > 0) {
|
|
19
|
+
this.#data[0] = last;
|
|
20
|
+
this.#bubbleDown(0);
|
|
21
|
+
}
|
|
22
|
+
return top.item;
|
|
23
|
+
}
|
|
24
|
+
#bubbleUp(index) {
|
|
25
|
+
let i = index;
|
|
26
|
+
while (i > 0) {
|
|
27
|
+
const parent = i - 1 >> 1;
|
|
28
|
+
const entry = this.#data[i];
|
|
29
|
+
const parentEntry = this.#data[parent];
|
|
30
|
+
if (entry.priority >= parentEntry.priority) break;
|
|
31
|
+
this.#data[i] = parentEntry;
|
|
32
|
+
this.#data[parent] = entry;
|
|
33
|
+
i = parent;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
#bubbleDown(index) {
|
|
37
|
+
let i = index;
|
|
38
|
+
for (;;) {
|
|
39
|
+
const entry = this.#data[i];
|
|
40
|
+
let smallest = i;
|
|
41
|
+
let smallestEntry = entry;
|
|
42
|
+
for (const child of [2 * i + 1, 2 * i + 2]) {
|
|
43
|
+
const candidate = this.#data[child];
|
|
44
|
+
if (candidate && candidate.priority < smallestEntry.priority) {
|
|
45
|
+
smallest = child;
|
|
46
|
+
smallestEntry = candidate;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (smallest === i) break;
|
|
50
|
+
this.#data[i] = smallestEntry;
|
|
51
|
+
this.#data[smallest] = entry;
|
|
52
|
+
i = smallest;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=min-heap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"min-heap.js","names":["MinHeap","data","size","length","push","item","priority","bubbleUp","pop","top","undefined","last","bubbleDown","#bubbleUp","index","i","parent","entry","parentEntry","#bubbleDown","smallest","smallestEntry","child","candidate"],"sources":["../../../../src/lib/layouts/graph/min-heap.ts"],"sourcesContent":["/** A binary min-heap of items by priority. */\nexport class MinHeap<T> {\n readonly #data: { item: T; priority: number }[] = [];\n\n get size(): number {\n return this.#data.length;\n }\n\n push(item: T, priority: number): void {\n this.#data.push({ item, priority });\n this.#bubbleUp(this.#data.length - 1);\n }\n\n pop(): T | undefined {\n const top = this.#data[0];\n if (!top) return undefined;\n const last = this.#data.pop()!;\n if (this.#data.length > 0) {\n this.#data[0] = last;\n this.#bubbleDown(0);\n }\n return top.item;\n }\n\n #bubbleUp(index: number): void {\n let i = index;\n while (i > 0) {\n const parent = (i - 1) >> 1;\n const entry = this.#data[i]!;\n const parentEntry = this.#data[parent]!;\n if (entry.priority >= parentEntry.priority) break;\n this.#data[i] = parentEntry;\n this.#data[parent] = entry;\n i = parent;\n }\n }\n\n #bubbleDown(index: number): void {\n let i = index;\n for (;;) {\n const entry = this.#data[i]!;\n let smallest = i;\n let smallestEntry = entry;\n for (const child of [2 * i + 1, 2 * i + 2]) {\n const candidate = this.#data[child];\n if (candidate && candidate.priority < smallestEntry.priority) {\n smallest = child;\n smallestEntry = candidate;\n }\n }\n if (smallest === i) break;\n this.#data[i] = smallestEntry;\n this.#data[smallest] = entry;\n i = smallest;\n }\n }\n}\n"],"mappings":"AAAA;AACA,OAAO,MAAMA,OAAO,CAAI;EACb,CAACC,IAAI,GAAoC,EAAE;EAEpD,IAAIC,IAAIA,CAAA,EAAW;IACjB,OAAO,IAAI,CAAC,CAACD,IAAI,CAACE,MAAM;EAC1B;EAEAC,IAAIA,CAACC,IAAO,EAAEC,QAAgB,EAAQ;IACpC,IAAI,CAAC,CAACL,IAAI,CAACG,IAAI,CAAC;MAAEC,IAAI;MAAEC;IAAS,CAAC,CAAC;IACnC,IAAI,CAAC,CAACC,QAAQ,CAAC,IAAI,CAAC,CAACN,IAAI,CAACE,MAAM,GAAG,CAAC,CAAC;EACvC;EAEAK,GAAGA,CAAA,EAAkB;IACnB,MAAMC,GAAG,GAAG,IAAI,CAAC,CAACR,IAAI,CAAC,CAAC,CAAC;IACzB,IAAI,CAACQ,GAAG,EAAE,OAAOC,SAAS;IAC1B,MAAMC,IAAI,GAAG,IAAI,CAAC,CAACV,IAAI,CAACO,GAAG,CAAC,CAAE;IAC9B,IAAI,IAAI,CAAC,CAACP,IAAI,CAACE,MAAM,GAAG,CAAC,EAAE;MACzB,IAAI,CAAC,CAACF,IAAI,CAAC,CAAC,CAAC,GAAGU,IAAI;MACpB,IAAI,CAAC,CAACC,UAAU,CAAC,CAAC,CAAC;IACrB;IACA,OAAOH,GAAG,CAACJ,IAAI;EACjB;EAEA,CAACE,QAAQM,CAACC,KAAa,EAAQ;IAC7B,IAAIC,CAAC,GAAGD,KAAK;IACb,OAAOC,CAAC,GAAG,CAAC,EAAE;MACZ,MAAMC,MAAM,GAAID,CAAC,GAAG,CAAC,IAAK,CAAC;MAC3B,MAAME,KAAK,GAAG,IAAI,CAAC,CAAChB,IAAI,CAACc,CAAC,CAAE;MAC5B,MAAMG,WAAW,GAAG,IAAI,CAAC,CAACjB,IAAI,CAACe,MAAM,CAAE;MACvC,IAAIC,KAAK,CAACX,QAAQ,IAAIY,WAAW,CAACZ,QAAQ,EAAE;MAC5C,IAAI,CAAC,CAACL,IAAI,CAACc,CAAC,CAAC,GAAGG,WAAW;MAC3B,IAAI,CAAC,CAACjB,IAAI,CAACe,MAAM,CAAC,GAAGC,KAAK;MAC1BF,CAAC,GAAGC,MAAM;IACZ;EACF;EAEA,CAACJ,UAAUO,CAACL,KAAa,EAAQ;IAC/B,IAAIC,CAAC,GAAGD,KAAK;IACb,SAAS;MACP,MAAMG,KAAK,GAAG,IAAI,CAAC,CAAChB,IAAI,CAACc,CAAC,CAAE;MAC5B,IAAIK,QAAQ,GAAGL,CAAC;MAChB,IAAIM,aAAa,GAAGJ,KAAK;MACzB,KAAK,MAAMK,KAAK,IAAI,CAAC,CAAC,GAAGP,CAAC,GAAG,CAAC,EAAE,CAAC,GAAGA,CAAC,GAAG,CAAC,CAAC,EAAE;QAC1C,MAAMQ,SAAS,GAAG,IAAI,CAAC,CAACtB,IAAI,CAACqB,KAAK,CAAC;QACnC,IAAIC,SAAS,IAAIA,SAAS,CAACjB,QAAQ,GAAGe,aAAa,CAACf,QAAQ,EAAE;UAC5Dc,QAAQ,GAAGE,KAAK;UAChBD,aAAa,GAAGE,SAAS;QAC3B;MACF;MACA,IAAIH,QAAQ,KAAKL,CAAC,EAAE;MACpB,IAAI,CAAC,CAACd,IAAI,CAACc,CAAC,CAAC,GAAGM,aAAa;MAC7B,IAAI,CAAC,CAACpB,IAAI,CAACmB,QAAQ,CAAC,GAAGH,KAAK;MAC5BF,CAAC,GAAGK,QAAQ;IACd;EACF;AACF","ignoreList":[]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Box, DiagramNode } from '../../model/diagram-ir.ts';
|
|
2
2
|
import type { NodeLayout } from './graph-layout-result.ts';
|
|
3
|
-
|
|
4
|
-
export type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> & Partial<Pick<NodeLayout, 'icon' | 'appliance'>>;
|
|
3
|
+
export type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> & Partial<Pick<NodeLayout, 'icon' | 'appliance' | 'contentBox'>>;
|
|
5
4
|
/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */
|
|
6
5
|
export type NodeContent = {
|
|
7
6
|
w: number;
|
|
@@ -12,5 +11,5 @@ export type NodeContent = {
|
|
|
12
11
|
};
|
|
13
12
|
place(inner: Box): ContentPlacement;
|
|
14
13
|
};
|
|
15
|
-
export declare function nodeContent(node: DiagramNode
|
|
14
|
+
export declare function nodeContent(node: DiagramNode): NodeContent;
|
|
16
15
|
//# sourceMappingURL=node-content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-content.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/node-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAS,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"node-content.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/node-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAS,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAI3D,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC;AAEjE,uGAAuG;AACvG,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,gBAAgB,CAAC;CACrC,CAAC;AAQF,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAe1D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { labelLines, textBlock } from "./text-block.js";
|
|
2
|
+
import { LAYOUT_TOKENS } from "./tokens.js";
|
|
2
3
|
|
|
3
4
|
/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */
|
|
4
5
|
|
|
@@ -12,56 +13,75 @@ const NOTHING = {
|
|
|
12
13
|
text: [],
|
|
13
14
|
bullets: []
|
|
14
15
|
};
|
|
15
|
-
export function nodeContent(node
|
|
16
|
+
export function nodeContent(node) {
|
|
16
17
|
switch (node.kind) {
|
|
17
18
|
case 'junction':
|
|
18
|
-
return junctionContent(
|
|
19
|
+
return junctionContent();
|
|
19
20
|
case 'marker':
|
|
20
|
-
return markerContent(node
|
|
21
|
+
return markerContent(node);
|
|
21
22
|
case 'connector':
|
|
22
|
-
return connectorContent(node
|
|
23
|
+
return connectorContent(node);
|
|
23
24
|
case 'appliance':
|
|
24
|
-
return applianceContent(node
|
|
25
|
+
return applianceContent(node);
|
|
25
26
|
case 'note':
|
|
26
|
-
return noteContent(node
|
|
27
|
+
return noteContent(node);
|
|
27
28
|
default:
|
|
28
|
-
return boxContent(node
|
|
29
|
+
return boxContent(node);
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
function boxContent(node
|
|
32
|
+
function boxContent(node) {
|
|
32
33
|
const pad = node.frame === 'none' ? {
|
|
33
|
-
x:
|
|
34
|
-
y:
|
|
34
|
+
x: LAYOUT_TOKENS.LABEL_GAP,
|
|
35
|
+
y: LAYOUT_TOKENS.LABEL_GAP
|
|
35
36
|
} : {
|
|
36
|
-
x:
|
|
37
|
-
y:
|
|
37
|
+
x: LAYOUT_TOKENS.PAD_X,
|
|
38
|
+
y: LAYOUT_TOKENS.PAD_Y
|
|
38
39
|
};
|
|
39
40
|
const isCard = node.textAlign === 'start' || node.description !== undefined || (node.items?.length ?? 0) > 0;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (node.icon) return {
|
|
45
|
-
...iconRowContent(node, tokens),
|
|
41
|
+
let text;
|
|
42
|
+
if (isCard) text = cardContent(node);else if (node.icon) text = iconRowContent(node);else text = labelContent(node);
|
|
43
|
+
return {
|
|
44
|
+
...(node.content ? withReactContent(text, node.content.size) : text),
|
|
46
45
|
pad
|
|
47
46
|
};
|
|
48
|
-
|
|
47
|
+
}
|
|
48
|
+
function labelContent(node) {
|
|
49
|
+
const lines = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.boxLabel);
|
|
49
50
|
return {
|
|
50
51
|
w: lines.w,
|
|
51
52
|
h: lines.h,
|
|
52
|
-
pad,
|
|
53
53
|
place: inner => ({
|
|
54
54
|
text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),
|
|
55
55
|
bullets: []
|
|
56
56
|
})
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
/** The author's React content goes under the text, centred, in a box of the size the author gives. */
|
|
61
|
+
function withReactContent(text, size) {
|
|
62
|
+
const gap = text.h > 0 ? LAYOUT_TOKENS.BLOCK_GAP : 0;
|
|
63
|
+
return {
|
|
64
|
+
w: Math.max(text.w, size.w),
|
|
65
|
+
h: text.h + gap + size.h,
|
|
66
|
+
place: inner => ({
|
|
67
|
+
...text.place({
|
|
68
|
+
...inner,
|
|
69
|
+
h: inner.h - gap - size.h
|
|
70
|
+
}),
|
|
71
|
+
contentBox: {
|
|
72
|
+
x: centreX(inner) - size.w / 2,
|
|
73
|
+
y: inner.y + inner.h - size.h,
|
|
74
|
+
...size
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function iconRowContent(node) {
|
|
60
80
|
const {
|
|
61
81
|
ICON,
|
|
62
82
|
ICON_GAP
|
|
63
|
-
} =
|
|
64
|
-
const title = textBlock(labelLines(node.label, node.textColor),
|
|
83
|
+
} = LAYOUT_TOKENS;
|
|
84
|
+
const title = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.title);
|
|
65
85
|
const w = title.w > 0 ? ICON + ICON_GAP + title.w : ICON;
|
|
66
86
|
const h = Math.max(ICON, title.h);
|
|
67
87
|
return {
|
|
@@ -82,16 +102,16 @@ function iconRowContent(node, tokens) {
|
|
|
82
102
|
}
|
|
83
103
|
};
|
|
84
104
|
}
|
|
85
|
-
function cardContent(node
|
|
105
|
+
function cardContent(node) {
|
|
86
106
|
const {
|
|
87
107
|
ICON,
|
|
88
108
|
ICON_GAP,
|
|
89
109
|
BLOCK_GAP,
|
|
90
110
|
BULLET_INDENT
|
|
91
|
-
} =
|
|
92
|
-
const title = textBlock(labelLines(node.label, node.textColor),
|
|
93
|
-
const description = textBlock(labelLines(node.description, node.textColor),
|
|
94
|
-
const items = textBlock(labelLines(node.items, node.textColor),
|
|
111
|
+
} = LAYOUT_TOKENS;
|
|
112
|
+
const title = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.title);
|
|
113
|
+
const description = textBlock(labelLines(node.description, node.textColor), LAYOUT_TOKENS.fonts.body);
|
|
114
|
+
const items = textBlock(labelLines(node.items, node.textColor), LAYOUT_TOKENS.fonts.body);
|
|
95
115
|
let iconW = 0;
|
|
96
116
|
if (node.icon) iconW = title.w > 0 ? ICON + ICON_GAP : ICON;
|
|
97
117
|
const headerH = Math.max(node.icon ? ICON : 0, title.h);
|
|
@@ -105,7 +125,7 @@ function cardContent(node, tokens) {
|
|
|
105
125
|
h: items.h,
|
|
106
126
|
w: items.h > 0 ? BULLET_INDENT + items.w : 0
|
|
107
127
|
}].filter(section => section.h > 0);
|
|
108
|
-
const bulletRise =
|
|
128
|
+
const bulletRise = LAYOUT_TOKENS.fonts.body.size * 0.3;
|
|
109
129
|
return {
|
|
110
130
|
w: Math.max(0, ...sections.map(section => section.w)),
|
|
111
131
|
h: sections.reduce((sum, section) => sum + section.h, 0) + Math.max(0, sections.length - 1) * BLOCK_GAP,
|
|
@@ -137,14 +157,14 @@ function cardContent(node, tokens) {
|
|
|
137
157
|
}
|
|
138
158
|
};
|
|
139
159
|
}
|
|
140
|
-
function noteContent(node
|
|
141
|
-
const lines = textBlock(labelLines(node.label, node.textColor ?? 'dim'),
|
|
160
|
+
function noteContent(node) {
|
|
161
|
+
const lines = textBlock(labelLines(node.label, node.textColor ?? 'dim'), LAYOUT_TOKENS.fonts.note);
|
|
142
162
|
return {
|
|
143
163
|
w: lines.w,
|
|
144
164
|
h: lines.h,
|
|
145
165
|
pad: {
|
|
146
|
-
x:
|
|
147
|
-
y:
|
|
166
|
+
x: LAYOUT_TOKENS.LABEL_GAP,
|
|
167
|
+
y: LAYOUT_TOKENS.LABEL_GAP
|
|
148
168
|
},
|
|
149
169
|
place: inner => ({
|
|
150
170
|
text: lines.place(inner.x, inner.y, 'start'),
|
|
@@ -152,20 +172,20 @@ function noteContent(node, tokens) {
|
|
|
152
172
|
})
|
|
153
173
|
};
|
|
154
174
|
}
|
|
155
|
-
function markerContent(node
|
|
175
|
+
function markerContent(node) {
|
|
156
176
|
const {
|
|
157
177
|
MARKER_ICON,
|
|
158
178
|
BLOCK_GAP
|
|
159
|
-
} =
|
|
160
|
-
const lines = textBlock(labelLines(node.label, node.textColor),
|
|
179
|
+
} = LAYOUT_TOKENS;
|
|
180
|
+
const lines = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.marker);
|
|
161
181
|
const gap = lines.h > 0 ? BLOCK_GAP : 0;
|
|
162
182
|
const h = MARKER_ICON + gap + lines.h;
|
|
163
183
|
return {
|
|
164
184
|
w: Math.max(MARKER_ICON, lines.w),
|
|
165
185
|
h,
|
|
166
186
|
pad: {
|
|
167
|
-
x:
|
|
168
|
-
y:
|
|
187
|
+
x: LAYOUT_TOKENS.LABEL_GAP,
|
|
188
|
+
y: LAYOUT_TOKENS.LABEL_GAP
|
|
169
189
|
},
|
|
170
190
|
place: inner => {
|
|
171
191
|
const top = centredTop(inner, h);
|
|
@@ -182,12 +202,12 @@ function markerContent(node, tokens) {
|
|
|
182
202
|
}
|
|
183
203
|
};
|
|
184
204
|
}
|
|
185
|
-
function connectorContent(node
|
|
205
|
+
function connectorContent(node) {
|
|
186
206
|
const {
|
|
187
207
|
CONNECTOR_ICON,
|
|
188
208
|
BLOCK_GAP
|
|
189
|
-
} =
|
|
190
|
-
const lines = textBlock(labelLines(node.label, node.textColor),
|
|
209
|
+
} = LAYOUT_TOKENS;
|
|
210
|
+
const lines = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.connector);
|
|
191
211
|
const iconW = node.icon ? CONNECTOR_ICON + (lines.w > 0 ? BLOCK_GAP : 0) : 0;
|
|
192
212
|
const h = Math.max(CONNECTOR_MIN_HEIGHT - 2 * CONNECTOR_PAD.y, lines.h);
|
|
193
213
|
return {
|
|
@@ -215,10 +235,10 @@ function connectorContent(node, tokens) {
|
|
|
215
235
|
}
|
|
216
236
|
};
|
|
217
237
|
}
|
|
218
|
-
function junctionContent(
|
|
238
|
+
function junctionContent() {
|
|
219
239
|
return {
|
|
220
|
-
w:
|
|
221
|
-
h:
|
|
240
|
+
w: LAYOUT_TOKENS.JUNCTION,
|
|
241
|
+
h: LAYOUT_TOKENS.JUNCTION,
|
|
222
242
|
pad: {
|
|
223
243
|
x: 0,
|
|
224
244
|
y: 0
|
|
@@ -226,12 +246,12 @@ function junctionContent(tokens) {
|
|
|
226
246
|
place: () => NOTHING
|
|
227
247
|
};
|
|
228
248
|
}
|
|
229
|
-
function applianceContent(node
|
|
249
|
+
function applianceContent(node) {
|
|
230
250
|
const {
|
|
231
251
|
APPLIANCE,
|
|
232
252
|
LABEL_GAP
|
|
233
|
-
} =
|
|
234
|
-
const lines = textBlock(labelLines(node.label, node.textColor),
|
|
253
|
+
} = LAYOUT_TOKENS;
|
|
254
|
+
const lines = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.appliance);
|
|
235
255
|
return {
|
|
236
256
|
w: Math.max(APPLIANCE.w, lines.w + 2 * LABEL_GAP),
|
|
237
257
|
h: APPLIANCE.h + (lines.h > 0 ? lines.h + LABEL_GAP : 0),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-content.js","names":["labelLines","textBlock","CONNECTOR_PAD","x","y","CONNECTOR_MIN_HEIGHT","NOTHING","text","bullets","nodeContent","node","tokens","kind","junctionContent","markerContent","connectorContent","applianceContent","noteContent","boxContent","pad","frame","LABEL_GAP","PAD_X","PAD_Y","isCard","textAlign","description","undefined","items","length","cardContent","icon","iconRowContent","lines","label","textColor","fonts","boxLabel","w","h","place","inner","centreX","centredTop","ICON","ICON_GAP","title","Math","max","size","BLOCK_GAP","BULLET_INDENT","body","iconW","headerH","sections","filter","section","bulletRise","map","reduce","sum","top","next","at","headerTop","descriptionTop","itemsTop","itemRuns","run","note","MARKER_ICON","marker","gap","cx","CONNECTOR_ICON","connector","cy","JUNCTION","APPLIANCE","appliance","glyph","applianceGlyph","bodyX","bodyY","min","bodyW","bodyH","slant","mastX","antenna","jackCount","floor","appliancePorts","jackSpacing","jacks","Array","from","_","index","face","parts","box"],"sources":["../../../../src/lib/layouts/graph/node-content.ts"],"sourcesContent":["import type { Box, DiagramNode, Point } from '../../model/diagram-ir.ts';\nimport type { NodeLayout } from './graph-layout-result.ts';\nimport { labelLines, textBlock } from './text-block.ts';\nimport type { LayoutTokens } from './tokens.ts';\n\nexport type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> &\n Partial<Pick<NodeLayout, 'icon' | 'appliance'>>;\n\n/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */\nexport type NodeContent = {\n w: number;\n h: number;\n pad: { x: number; y: number };\n place(inner: Box): ContentPlacement;\n};\n\n/** Mirrors the connector pill drawn before content sizing: 10px side inset, 4px above and below the text, 28px tall at least. */\nconst CONNECTOR_PAD = { x: 10, y: 4 };\nconst CONNECTOR_MIN_HEIGHT = 28;\n\nconst NOTHING: ContentPlacement = { text: [], bullets: [] };\n\nexport function nodeContent(\n node: DiagramNode,\n tokens: LayoutTokens,\n): NodeContent {\n switch (node.kind) {\n case 'junction':\n return junctionContent(tokens);\n case 'marker':\n return markerContent(node, tokens);\n case 'connector':\n return connectorContent(node, tokens);\n case 'appliance':\n return applianceContent(node, tokens);\n case 'note':\n return noteContent(node, tokens);\n default:\n return boxContent(node, tokens);\n }\n}\n\nfunction boxContent(node: DiagramNode, tokens: LayoutTokens): NodeContent {\n const pad =\n node.frame === 'none'\n ? { x: tokens.LABEL_GAP, y: tokens.LABEL_GAP }\n : { x: tokens.PAD_X, y: tokens.PAD_Y };\n const isCard =\n node.textAlign === 'start' ||\n node.description !== undefined ||\n (node.items?.length ?? 0) > 0;\n if (isCard) return { ...cardContent(node, tokens), pad };\n if (node.icon) return { ...iconRowContent(node, tokens), pad };\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.boxLabel,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad,\n place: (inner) => ({\n text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),\n bullets: [],\n }),\n };\n}\n\nfunction iconRowContent(\n node: DiagramNode,\n tokens: LayoutTokens,\n): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP } = tokens;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.title,\n );\n const w = title.w > 0 ? ICON + ICON_GAP + title.w : ICON;\n const h = Math.max(ICON, title.h);\n return {\n w,\n h,\n place: (inner) => {\n const x = inner.x + (inner.w - w) / 2;\n const y = centredTop(inner, h);\n return {\n icon: { x, y: y + (h - ICON) / 2, size: ICON },\n text: title.place(x + ICON + ICON_GAP, y + (h - title.h) / 2, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction cardContent(\n node: DiagramNode,\n tokens: LayoutTokens,\n): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP, BLOCK_GAP, BULLET_INDENT } = tokens;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.title,\n );\n const description = textBlock(\n labelLines(node.description, node.textColor),\n tokens.fonts.body,\n );\n const items = textBlock(\n labelLines(node.items, node.textColor),\n tokens.fonts.body,\n );\n let iconW = 0;\n if (node.icon) iconW = title.w > 0 ? ICON + ICON_GAP : ICON;\n const headerH = Math.max(node.icon ? ICON : 0, title.h);\n const sections = [\n { h: headerH, w: iconW + title.w },\n { h: description.h, w: description.w },\n { h: items.h, w: items.h > 0 ? BULLET_INDENT + items.w : 0 },\n ].filter((section) => section.h > 0);\n const bulletRise = tokens.fonts.body.size * 0.3;\n return {\n w: Math.max(0, ...sections.map((section) => section.w)),\n h:\n sections.reduce((sum, section) => sum + section.h, 0) +\n Math.max(0, sections.length - 1) * BLOCK_GAP,\n place: (inner) => {\n let top = inner.y;\n const next = (h: number) => {\n const at = top;\n if (h > 0) top += h + BLOCK_GAP;\n return at;\n };\n const headerTop = next(headerH);\n const descriptionTop = next(description.h);\n const itemsTop = next(items.h);\n const itemRuns = items.place(inner.x + BULLET_INDENT, itemsTop, 'start');\n return {\n ...(node.icon\n ? {\n icon: {\n x: inner.x,\n y: headerTop + (headerH - ICON) / 2,\n size: ICON,\n },\n }\n : {}),\n text: [\n ...title.place(\n inner.x + iconW,\n headerTop + (headerH - title.h) / 2,\n 'start',\n ),\n ...description.place(inner.x, descriptionTop, 'start'),\n ...itemRuns,\n ],\n bullets: itemRuns.map((run) => ({\n x: inner.x + BULLET_INDENT / 4,\n y: run.y - bulletRise,\n })),\n };\n },\n };\n}\n\nfunction noteContent(node: DiagramNode, tokens: LayoutTokens): NodeContent {\n const lines = textBlock(\n labelLines(node.label, node.textColor ?? 'dim'),\n tokens.fonts.note,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad: { x: tokens.LABEL_GAP, y: tokens.LABEL_GAP },\n place: (inner) => ({\n text: lines.place(inner.x, inner.y, 'start'),\n bullets: [],\n }),\n };\n}\n\nfunction markerContent(node: DiagramNode, tokens: LayoutTokens): NodeContent {\n const { MARKER_ICON, BLOCK_GAP } = tokens;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.marker,\n );\n const gap = lines.h > 0 ? BLOCK_GAP : 0;\n const h = MARKER_ICON + gap + lines.h;\n return {\n w: Math.max(MARKER_ICON, lines.w),\n h,\n pad: { x: tokens.LABEL_GAP, y: tokens.LABEL_GAP },\n place: (inner) => {\n const top = centredTop(inner, h);\n const cx = centreX(inner);\n return {\n icon: { x: cx - MARKER_ICON / 2, y: top, size: MARKER_ICON },\n text: lines.place(cx, top + MARKER_ICON + gap, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\nfunction connectorContent(\n node: DiagramNode,\n tokens: LayoutTokens,\n): NodeContent {\n const { CONNECTOR_ICON, BLOCK_GAP } = tokens;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.connector,\n );\n const iconW = node.icon ? CONNECTOR_ICON + (lines.w > 0 ? BLOCK_GAP : 0) : 0;\n const h = Math.max(CONNECTOR_MIN_HEIGHT - 2 * CONNECTOR_PAD.y, lines.h);\n return {\n w: iconW + lines.w,\n h,\n pad: CONNECTOR_PAD,\n place: (inner) => {\n const cy = inner.y + inner.h / 2;\n const top = cy - lines.h / 2;\n if (!node.icon) {\n return {\n text: lines.place(centreX(inner), top, 'middle'),\n bullets: [],\n };\n }\n return {\n icon: { x: inner.x, y: cy - CONNECTOR_ICON / 2, size: CONNECTOR_ICON },\n text: lines.place(inner.x + iconW, top, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction junctionContent(tokens: LayoutTokens): NodeContent {\n return {\n w: tokens.JUNCTION,\n h: tokens.JUNCTION,\n pad: { x: 0, y: 0 },\n place: () => NOTHING,\n };\n}\n\nfunction applianceContent(\n node: DiagramNode,\n tokens: LayoutTokens,\n): NodeContent {\n const { APPLIANCE, LABEL_GAP } = tokens;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n tokens.fonts.appliance,\n );\n return {\n w: Math.max(APPLIANCE.w, lines.w + 2 * LABEL_GAP),\n h: APPLIANCE.h + (lines.h > 0 ? lines.h + LABEL_GAP : 0),\n pad: { x: 0, y: 0 },\n place: (inner) => {\n const glyph = {\n x: centreX(inner) - APPLIANCE.w / 2,\n y: inner.y,\n ...APPLIANCE,\n };\n return {\n appliance: applianceGlyph(node, glyph),\n text: lines.place(centreX(inner), glyph.y + glyph.h, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\n/** The router glyph: a slanted body, an optional antenna and a row of jacks, as the renderers drew it before content sizing. */\nfunction applianceGlyph(\n node: DiagramNode,\n glyph: Box,\n): NonNullable<NodeLayout['appliance']> {\n const bodyX = glyph.x + 4;\n const bodyY = glyph.y + Math.max(12, Math.min(22, glyph.h * 0.28));\n const bodyW = glyph.w - 8;\n const bodyH = glyph.h - (bodyY - glyph.y) - 12;\n const slant = Math.max(4, Math.min(16, bodyW * 0.28, bodyH * 0.75));\n const body: Point[] = [\n { x: bodyX + slant, y: bodyY },\n { x: bodyX + bodyW, y: bodyY + 6 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH },\n { x: bodyX, y: bodyY + bodyH - 6 },\n ];\n const mastX = bodyX + slant + bodyW * 0.2;\n const antenna: [Point, Point][] =\n (node.antenna ?? true)\n ? [\n [\n { x: bodyX + slant + bodyW * 0.18, y: bodyY + 1 },\n { x: mastX - 3, y: glyph.y + 3 },\n ],\n [\n { x: mastX + 1, y: bodyY + 2 },\n { x: mastX + 1, y: glyph.y + 8 },\n ],\n ]\n : [];\n const jackCount = Math.max(0, Math.floor(node.appliancePorts ?? 4));\n const jackSpacing = Math.min(\n 13,\n Math.max(8, (bodyW - slant - 42) / Math.max(jackCount, 1)),\n );\n const jacks = Array.from({ length: jackCount }, (_, index) => ({\n x: bodyX + slant + 16 + index * jackSpacing,\n y: bodyY + bodyH - 15,\n w: 5,\n h: 12,\n }));\n const face: [Point, Point] = [\n { x: bodyX + slant, y: bodyY + bodyH - 1 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH + 3 },\n ];\n // Through a variable, not a literal, so the return skips the excess-property check against NodeLayout['appliance'].\n const parts = { body, face, antenna, jacks };\n return parts;\n}\n\nfunction centreX(box: Box): number {\n return box.x + box.w / 2;\n}\n\nfunction centredTop(box: Box, h: number): number {\n return box.y + (box.h - h) / 2;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"node-content.js","names":["labelLines","textBlock","LAYOUT_TOKENS","CONNECTOR_PAD","x","y","CONNECTOR_MIN_HEIGHT","NOTHING","text","bullets","nodeContent","node","kind","junctionContent","markerContent","connectorContent","applianceContent","noteContent","boxContent","pad","frame","LABEL_GAP","PAD_X","PAD_Y","isCard","textAlign","description","undefined","items","length","cardContent","icon","iconRowContent","labelContent","content","withReactContent","size","lines","label","textColor","fonts","boxLabel","w","h","place","inner","centreX","centredTop","gap","BLOCK_GAP","Math","max","contentBox","ICON","ICON_GAP","title","BULLET_INDENT","body","iconW","headerH","sections","filter","section","bulletRise","map","reduce","sum","top","next","at","headerTop","descriptionTop","itemsTop","itemRuns","run","note","MARKER_ICON","marker","cx","CONNECTOR_ICON","connector","cy","JUNCTION","APPLIANCE","appliance","glyph","applianceGlyph","bodyX","bodyY","min","bodyW","bodyH","slant","mastX","antenna","jackCount","floor","appliancePorts","jackSpacing","jacks","Array","from","_","index","face","parts","box"],"sources":["../../../../src/lib/layouts/graph/node-content.ts"],"sourcesContent":["import type { Box, DiagramNode, Point } from '../../model/diagram-ir.ts';\nimport type { NodeLayout } from './graph-layout-result.ts';\nimport { labelLines, textBlock } from './text-block.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\nexport type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> &\n Partial<Pick<NodeLayout, 'icon' | 'appliance' | 'contentBox'>>;\n\n/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */\nexport type NodeContent = {\n w: number;\n h: number;\n pad: { x: number; y: number };\n place(inner: Box): ContentPlacement;\n};\n\n/** Mirrors the connector pill drawn before content sizing: 10px side inset, 4px above and below the text, 28px tall at least. */\nconst CONNECTOR_PAD = { x: 10, y: 4 };\nconst CONNECTOR_MIN_HEIGHT = 28;\n\nconst NOTHING: ContentPlacement = { text: [], bullets: [] };\n\nexport function nodeContent(node: DiagramNode): NodeContent {\n switch (node.kind) {\n case 'junction':\n return junctionContent();\n case 'marker':\n return markerContent(node);\n case 'connector':\n return connectorContent(node);\n case 'appliance':\n return applianceContent(node);\n case 'note':\n return noteContent(node);\n default:\n return boxContent(node);\n }\n}\n\nfunction boxContent(node: DiagramNode): NodeContent {\n const pad =\n node.frame === 'none'\n ? { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP }\n : { x: LAYOUT_TOKENS.PAD_X, y: LAYOUT_TOKENS.PAD_Y };\n const isCard =\n node.textAlign === 'start' ||\n node.description !== undefined ||\n (node.items?.length ?? 0) > 0;\n let text: Omit<NodeContent, 'pad'>;\n if (isCard) text = cardContent(node);\n else if (node.icon) text = iconRowContent(node);\n else text = labelContent(node);\n return {\n ...(node.content ? withReactContent(text, node.content.size) : text),\n pad,\n };\n}\n\nfunction labelContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.boxLabel,\n );\n return {\n w: lines.w,\n h: lines.h,\n place: (inner) => ({\n text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),\n bullets: [],\n }),\n };\n}\n\n/** The author's React content goes under the text, centred, in a box of the size the author gives. */\nfunction withReactContent(\n text: Omit<NodeContent, 'pad'>,\n size: { w: number; h: number },\n): Omit<NodeContent, 'pad'> {\n const gap = text.h > 0 ? LAYOUT_TOKENS.BLOCK_GAP : 0;\n return {\n w: Math.max(text.w, size.w),\n h: text.h + gap + size.h,\n place: (inner) => ({\n ...text.place({ ...inner, h: inner.h - gap - size.h }),\n contentBox: {\n x: centreX(inner) - size.w / 2,\n y: inner.y + inner.h - size.h,\n ...size,\n },\n }),\n };\n}\n\nfunction iconRowContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const w = title.w > 0 ? ICON + ICON_GAP + title.w : ICON;\n const h = Math.max(ICON, title.h);\n return {\n w,\n h,\n place: (inner) => {\n const x = inner.x + (inner.w - w) / 2;\n const y = centredTop(inner, h);\n return {\n icon: { x, y: y + (h - ICON) / 2, size: ICON },\n text: title.place(x + ICON + ICON_GAP, y + (h - title.h) / 2, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction cardContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP, BLOCK_GAP, BULLET_INDENT } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const description = textBlock(\n labelLines(node.description, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n const items = textBlock(\n labelLines(node.items, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n let iconW = 0;\n if (node.icon) iconW = title.w > 0 ? ICON + ICON_GAP : ICON;\n const headerH = Math.max(node.icon ? ICON : 0, title.h);\n const sections = [\n { h: headerH, w: iconW + title.w },\n { h: description.h, w: description.w },\n { h: items.h, w: items.h > 0 ? BULLET_INDENT + items.w : 0 },\n ].filter((section) => section.h > 0);\n const bulletRise = LAYOUT_TOKENS.fonts.body.size * 0.3;\n return {\n w: Math.max(0, ...sections.map((section) => section.w)),\n h:\n sections.reduce((sum, section) => sum + section.h, 0) +\n Math.max(0, sections.length - 1) * BLOCK_GAP,\n place: (inner) => {\n let top = inner.y;\n const next = (h: number) => {\n const at = top;\n if (h > 0) top += h + BLOCK_GAP;\n return at;\n };\n const headerTop = next(headerH);\n const descriptionTop = next(description.h);\n const itemsTop = next(items.h);\n const itemRuns = items.place(inner.x + BULLET_INDENT, itemsTop, 'start');\n return {\n ...(node.icon\n ? {\n icon: {\n x: inner.x,\n y: headerTop + (headerH - ICON) / 2,\n size: ICON,\n },\n }\n : {}),\n text: [\n ...title.place(\n inner.x + iconW,\n headerTop + (headerH - title.h) / 2,\n 'start',\n ),\n ...description.place(inner.x, descriptionTop, 'start'),\n ...itemRuns,\n ],\n bullets: itemRuns.map((run) => ({\n x: inner.x + BULLET_INDENT / 4,\n y: run.y - bulletRise,\n })),\n };\n },\n };\n}\n\nfunction noteContent(node: DiagramNode): NodeContent {\n const lines = textBlock(\n labelLines(node.label, node.textColor ?? 'dim'),\n LAYOUT_TOKENS.fonts.note,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => ({\n text: lines.place(inner.x, inner.y, 'start'),\n bullets: [],\n }),\n };\n}\n\nfunction markerContent(node: DiagramNode): NodeContent {\n const { MARKER_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.marker,\n );\n const gap = lines.h > 0 ? BLOCK_GAP : 0;\n const h = MARKER_ICON + gap + lines.h;\n return {\n w: Math.max(MARKER_ICON, lines.w),\n h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => {\n const top = centredTop(inner, h);\n const cx = centreX(inner);\n return {\n icon: { x: cx - MARKER_ICON / 2, y: top, size: MARKER_ICON },\n text: lines.place(cx, top + MARKER_ICON + gap, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\nfunction connectorContent(node: DiagramNode): NodeContent {\n const { CONNECTOR_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.connector,\n );\n const iconW = node.icon ? CONNECTOR_ICON + (lines.w > 0 ? BLOCK_GAP : 0) : 0;\n const h = Math.max(CONNECTOR_MIN_HEIGHT - 2 * CONNECTOR_PAD.y, lines.h);\n return {\n w: iconW + lines.w,\n h,\n pad: CONNECTOR_PAD,\n place: (inner) => {\n const cy = inner.y + inner.h / 2;\n const top = cy - lines.h / 2;\n if (!node.icon) {\n return {\n text: lines.place(centreX(inner), top, 'middle'),\n bullets: [],\n };\n }\n return {\n icon: { x: inner.x, y: cy - CONNECTOR_ICON / 2, size: CONNECTOR_ICON },\n text: lines.place(inner.x + iconW, top, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction junctionContent(): NodeContent {\n return {\n w: LAYOUT_TOKENS.JUNCTION,\n h: LAYOUT_TOKENS.JUNCTION,\n pad: { x: 0, y: 0 },\n place: () => NOTHING,\n };\n}\n\nfunction applianceContent(node: DiagramNode): NodeContent {\n const { APPLIANCE, LABEL_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.appliance,\n );\n return {\n w: Math.max(APPLIANCE.w, lines.w + 2 * LABEL_GAP),\n h: APPLIANCE.h + (lines.h > 0 ? lines.h + LABEL_GAP : 0),\n pad: { x: 0, y: 0 },\n place: (inner) => {\n const glyph = {\n x: centreX(inner) - APPLIANCE.w / 2,\n y: inner.y,\n ...APPLIANCE,\n };\n return {\n appliance: applianceGlyph(node, glyph),\n text: lines.place(centreX(inner), glyph.y + glyph.h, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\n/** The router glyph: a slanted body, an optional antenna and a row of jacks, as the renderers drew it before content sizing. */\nfunction applianceGlyph(\n node: DiagramNode,\n glyph: Box,\n): NonNullable<NodeLayout['appliance']> {\n const bodyX = glyph.x + 4;\n const bodyY = glyph.y + Math.max(12, Math.min(22, glyph.h * 0.28));\n const bodyW = glyph.w - 8;\n const bodyH = glyph.h - (bodyY - glyph.y) - 12;\n const slant = Math.max(4, Math.min(16, bodyW * 0.28, bodyH * 0.75));\n const body: Point[] = [\n { x: bodyX + slant, y: bodyY },\n { x: bodyX + bodyW, y: bodyY + 6 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH },\n { x: bodyX, y: bodyY + bodyH - 6 },\n ];\n const mastX = bodyX + slant + bodyW * 0.2;\n const antenna: [Point, Point][] =\n (node.antenna ?? true)\n ? [\n [\n { x: bodyX + slant + bodyW * 0.18, y: bodyY + 1 },\n { x: mastX - 3, y: glyph.y + 3 },\n ],\n [\n { x: mastX + 1, y: bodyY + 2 },\n { x: mastX + 1, y: glyph.y + 8 },\n ],\n ]\n : [];\n const jackCount = Math.max(0, Math.floor(node.appliancePorts ?? 4));\n const jackSpacing = Math.min(\n 13,\n Math.max(8, (bodyW - slant - 42) / Math.max(jackCount, 1)),\n );\n const jacks = Array.from({ length: jackCount }, (_, index) => ({\n x: bodyX + slant + 16 + index * jackSpacing,\n y: bodyY + bodyH - 15,\n w: 5,\n h: 12,\n }));\n const face: [Point, Point] = [\n { x: bodyX + slant, y: bodyY + bodyH - 1 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH + 3 },\n ];\n // Through a variable, not a literal, so the return skips the excess-property check against NodeLayout['appliance'].\n const parts = { body, face, antenna, jacks };\n return parts;\n}\n\nfunction centreX(box: Box): number {\n return box.x + box.w / 2;\n}\n\nfunction centredTop(box: Box, h: number): number {\n return box.y + (box.h - h) / 2;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Point } from '../../model/diagram-ir.ts';
|
|
2
|
+
/** Drops every point that lies on the straight line through its neighbours. */
|
|
3
|
+
export declare function simplifyPath(path: Point[]): Point[];
|
|
4
|
+
/** An SVG path through the points, with each bend rounded, and each number to the layout's precision. */
|
|
5
|
+
export declare function pathToSvg(points: Point[]): string;
|
|
6
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAMvD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAanD;AAED,yGAAyG;AACzG,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAsBjD"}
|