@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.
- 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.map +1 -1
- package/dist/lib/layouts/graph/attach.js +64 -8
- package/dist/lib/layouts/graph/attach.js.map +1 -1
- package/dist/lib/layouts/graph/connections.d.ts +11 -4
- package/dist/lib/layouts/graph/connections.d.ts.map +1 -1
- package/dist/lib/layouts/graph/connections.js +43 -17
- package/dist/lib/layouts/graph/connections.js.map +1 -1
- package/dist/lib/layouts/graph/graph-layout-result.d.ts +4 -2
- 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 +40 -21
- package/dist/lib/layouts/graph/gutters.js.map +1 -1
- package/dist/lib/layouts/graph/labels.d.ts +16 -9
- package/dist/lib/layouts/graph/labels.d.ts.map +1 -1
- package/dist/lib/layouts/graph/labels.js +62 -18
- package/dist/lib/layouts/graph/labels.js.map +1 -1
- 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 +6 -3
- package/dist/lib/layouts/graph/layout.js.map +1 -1
- package/dist/lib/layouts/graph/measure.d.ts +8 -5
- package/dist/lib/layouts/graph/measure.d.ts.map +1 -1
- package/dist/lib/layouts/graph/measure.js +47 -9
- package/dist/lib/layouts/graph/measure.js.map +1 -1
- package/dist/lib/layouts/graph/min-heap.d.ts +1 -5
- package/dist/lib/layouts/graph/min-heap.d.ts.map +1 -1
- package/dist/lib/layouts/graph/min-heap.js +1 -5
- package/dist/lib/layouts/graph/min-heap.js.map +1 -1
- package/dist/lib/layouts/graph/node-content.d.ts +1 -1
- package/dist/lib/layouts/graph/node-content.d.ts.map +1 -1
- package/dist/lib/layouts/graph/node-content.js +26 -7
- package/dist/lib/layouts/graph/node-content.js.map +1 -1
- package/dist/lib/layouts/graph/path.d.ts +2 -10
- package/dist/lib/layouts/graph/path.d.ts.map +1 -1
- package/dist/lib/layouts/graph/path.js +11 -13
- package/dist/lib/layouts/graph/path.js.map +1 -1
- 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.d.ts +10 -6
- package/dist/lib/layouts/graph/route.d.ts.map +1 -1
- package/dist/lib/layouts/graph/route.js +68 -33
- package/dist/lib/layouts/graph/route.js.map +1 -1
- package/dist/lib/layouts/graph/sides.d.ts +10 -5
- package/dist/lib/layouts/graph/sides.d.ts.map +1 -1
- package/dist/lib/layouts/graph/sides.js +14 -7
- package/dist/lib/layouts/graph/sides.js.map +1 -1
- 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,6 +1,8 @@
|
|
|
1
|
+
import { validateGraph } from "../../model/validate-graph.js";
|
|
1
2
|
import { gridAreas } from "./areas.js";
|
|
2
3
|
import { gridGutters } from "./gutters.js";
|
|
3
4
|
import { measureGroupTitle, measureNode, placeGroupPorts } from "./measure.js";
|
|
5
|
+
import { roundLayout } from "./round.js";
|
|
4
6
|
import { routeGraph } from "./route.js";
|
|
5
7
|
import { LAYOUT_TOKENS } from "./tokens.js";
|
|
6
8
|
import { sizeTracks } from "./tracks.js";
|
|
@@ -9,9 +11,10 @@ import { sizeTracks } from "./tracks.js";
|
|
|
9
11
|
* Lays out a graph on a content-sized grid: it measures every node, sizes
|
|
10
12
|
* each row and column to the content in it, and reserves the chrome of the
|
|
11
13
|
* groups in the gutters between them. It throws when the grid cannot be
|
|
12
|
-
* drawn without overlap.
|
|
14
|
+
* drawn without overlap, or when an id or an edge end is wrong.
|
|
13
15
|
*/
|
|
14
16
|
export function layoutGraph(ir) {
|
|
17
|
+
validateGraph(ir);
|
|
15
18
|
const measured = new Map(ir.nodes.map(node => [node.id, measureNode(node)]));
|
|
16
19
|
const titles = new Map(ir.groups.map(group => [group.id, measureGroupTitle(group)]));
|
|
17
20
|
const areas = gridAreas(ir);
|
|
@@ -51,13 +54,13 @@ export function layoutGraph(ir) {
|
|
|
51
54
|
edges,
|
|
52
55
|
leaders
|
|
53
56
|
} = routeGraph(ir, nodes, groups, areas, 2 * widestGutter);
|
|
54
|
-
return {
|
|
57
|
+
return roundLayout({
|
|
55
58
|
nodes,
|
|
56
59
|
groups,
|
|
57
60
|
edges,
|
|
58
61
|
leaders,
|
|
59
62
|
viewBox: viewBoxOf(nodes, groups, edges, leaders)
|
|
60
|
-
};
|
|
63
|
+
});
|
|
61
64
|
}
|
|
62
65
|
function areaBox(area, lines) {
|
|
63
66
|
const x = lines.col.trackStart(area.col);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","names":["gridAreas","gridGutters","measureGroupTitle","measureNode","placeGroupPorts","routeGraph","LAYOUT_TOKENS","sizeTracks","layoutGraph","ir","measured","Map","nodes","map","node","id","titles","groups","group","areas","gutters","title","height","edges","items","axis","area","get","frame","overhang","start","row","span","rowSpan","size","h","top","bottom","col","colSpan","w","left","right","line","count","gutter","lines","rows","cols","measuredNode","areaBox","place","nodeFrame","groupArea","placeGroup","widestGutter","Math","max","leaders","viewBox","viewBoxOf","x","trackStart","y","trackEnd","stretch","visualW","visualH","depth","border","boundary","side","gutterStart","rect","dividers","labelSide","ports","centre","titleAtBottom","inner","Array","from","length","_","index","pointBox","boxes","nodeLayout","visual","groupLayout","flatMap","points","label","badge","box","pad","CONTENT_PAD","min"],"sources":["../../../../src/lib/layouts/graph/layout.ts"],"sourcesContent":["import type { Box, DiagramGraphIR, Point } from '../../model/diagram-ir.ts';\nimport { type CellArea, type GroupArea, gridAreas } from './areas.ts';\nimport type {\n EdgeLayout,\n GraphLayout,\n GroupLayout,\n LeaderLayout,\n NodeLayout,\n} from './graph-layout-result.ts';\nimport { type Axis, type GridGutters, gridGutters } from './gutters.ts';\nimport {\n type MeasuredGroupTitle,\n type MeasuredNode,\n measureGroupTitle,\n measureNode,\n placeGroupPorts,\n} from './measure.ts';\nimport { routeGraph } from './route.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\nimport { type TrackLine, sizeTracks } from './tracks.ts';\n\n/**\n * Lays out a graph on a content-sized grid: it measures every node, sizes\n * each row and column to the content in it, and reserves the chrome of the\n * groups in the gutters between them. It throws when the grid cannot be\n * drawn without overlap.\n */\nexport function layoutGraph(ir: DiagramGraphIR): GraphLayout {\n const measured = new Map(\n ir.nodes.map((node) => [node.id, measureNode(node)] as const),\n );\n const titles = new Map(\n ir.groups.map((group) => [group.id, measureGroupTitle(group)] as const),\n );\n const areas = gridAreas(ir);\n const gutters = gridGutters(\n areas,\n new Map([...titles].map(([id, title]) => [id, title.height])),\n ir.edges,\n );\n\n const items = (axis: Axis) =>\n ir.nodes.map((node) => {\n const area = areas.nodes.get(node.id)!;\n const { frame, overhang } = measured.get(node.id)!;\n return axis === 'row'\n ? {\n start: area.row,\n span: area.rowSpan,\n size: frame.h + overhang.top + overhang.bottom,\n }\n : {\n start: area.col,\n span: area.colSpan,\n size: frame.w + overhang.left + overhang.right,\n };\n });\n const line = (axis: Axis, count: number) =>\n sizeTracks(\n count,\n items(axis),\n gutters[axis].map((gutter) => gutter.size),\n );\n const lines: Record<Axis, TrackLine> = {\n row: line('row', areas.rows),\n col: line('col', areas.cols),\n };\n\n const nodes: NodeLayout[] = ir.nodes.map((node) => {\n const measuredNode = measured.get(node.id)!;\n const area = areaBox(areas.nodes.get(node.id)!, lines);\n return { node, ...measuredNode.place(nodeFrame(measuredNode, area)) };\n });\n const groups = areas.groups.map((groupArea) =>\n placeGroup(groupArea, titles.get(groupArea.group.id)!, lines, gutters),\n );\n\n const widestGutter = Math.max(\n ...[...gutters.row, ...gutters.col].map((gutter) => gutter.size),\n );\n const { edges, leaders } = routeGraph(\n ir,\n nodes,\n groups,\n areas,\n 2 * widestGutter,\n );\n\n return {\n nodes,\n groups,\n edges,\n leaders,\n viewBox: viewBoxOf(nodes, groups, edges, leaders),\n };\n}\n\nfunction areaBox(area: CellArea, lines: Record<Axis, TrackLine>): Box {\n const x = lines.col.trackStart(area.col);\n const y = lines.row.trackStart(area.row);\n return {\n x,\n y,\n w: lines.col.trackEnd(area.col + area.colSpan - 1) - x,\n h: lines.row.trackEnd(area.row + area.rowSpan - 1) - y,\n };\n}\n\n/** A stretching node fills its area; any other node keeps its measured frame, centred in the area. */\nfunction nodeFrame(measured: MeasuredNode, area: Box): Box {\n const { frame, overhang, stretch } = measured;\n if (stretch) {\n return {\n x: area.x + overhang.left,\n y: area.y + overhang.top,\n w: area.w - overhang.left - overhang.right,\n h: area.h - overhang.top - overhang.bottom,\n };\n }\n const visualW = frame.w + overhang.left + overhang.right;\n const visualH = frame.h + overhang.top + overhang.bottom;\n return {\n x: area.x + (area.w - visualW) / 2 + overhang.left,\n y: area.y + (area.h - visualH) / 2 + overhang.top,\n ...frame,\n };\n}\n\n/** Each side of a group lies on the outer edge of its chrome slot in the gutter where the group opens or closes. */\nfunction placeGroup(\n { group, depth, area }: GroupArea,\n title: MeasuredGroupTitle,\n lines: Record<Axis, TrackLine>,\n gutters: GridGutters,\n): GroupLayout {\n const border = (axis: Axis, boundary: number, side: 'opening' | 'closing') =>\n lines[axis].gutterStart(boundary) +\n gutters[axis][boundary]![side].get(depth)!;\n const x = border('col', area.col, 'opening');\n const y = border('row', area.row, 'opening');\n const rect = {\n x,\n y,\n w: border('col', area.col + area.colSpan, 'closing') - x,\n h: border('row', area.row + area.rowSpan, 'closing') - y,\n };\n return {\n group,\n depth,\n rect,\n ...title.place(rect),\n dividers: group.dividers\n ? dividers(rect, area, title, group.labelSide, lines, gutters)\n : [],\n ports: placeGroupPorts(group.ports ?? [], rect),\n };\n}\n\n/** A line through the middle of every gutter inside the group, clear of its title. */\nfunction dividers(\n rect: Box,\n area: CellArea,\n title: MeasuredGroupTitle,\n labelSide: 'top' | 'bottom' | undefined,\n lines: Record<Axis, TrackLine>,\n gutters: GridGutters,\n): [Point, Point][] {\n const centre = (axis: Axis, boundary: number) =>\n lines[axis].gutterStart(boundary) + gutters[axis][boundary]!.size / 2;\n const titleAtBottom = labelSide === 'bottom';\n const top = rect.y + (titleAtBottom ? 0 : title.height);\n const bottom = rect.y + rect.h - (titleAtBottom ? title.height : 0);\n const inner = (start: number, span: number) =>\n Array.from({ length: span - 1 }, (_, index) => start + index + 1);\n return [\n ...inner(area.col, area.colSpan).map((boundary): [Point, Point] => {\n const x = centre('col', boundary);\n return [\n { x, y: top },\n { x, y: bottom },\n ];\n }),\n ...inner(area.row, area.rowSpan).map((boundary): [Point, Point] => {\n const y = centre('row', boundary);\n return [\n { x: rect.x, y },\n { x: rect.x + rect.w, y },\n ];\n }),\n ];\n}\n\nfunction viewBoxOf(\n nodes: NodeLayout[],\n groups: GroupLayout[],\n edges: EdgeLayout[],\n leaders: LeaderLayout[],\n): Box {\n const pointBox = ({ x, y }: Point): Box => ({ x, y, w: 0, h: 0 });\n const boxes = [\n ...nodes.map((nodeLayout) => nodeLayout.visual),\n ...groups.map((groupLayout) => groupLayout.rect),\n ...edges.flatMap(({ points, label, badge }) => [\n ...points.map(pointBox),\n ...(label ? [label.box] : []),\n ...(badge ? [badge.box] : []),\n ]),\n ...leaders.flatMap(({ points }) => points.map(pointBox)),\n ];\n const pad = LAYOUT_TOKENS.CONTENT_PAD;\n if (boxes.length === 0) return { x: -pad, y: -pad, w: 2 * pad, h: 2 * pad };\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 {\n x: left - pad,\n y: top - pad,\n w: right - left + 2 * pad,\n h: bottom - top + 2 * pad,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"layout.js","names":["validateGraph","gridAreas","gridGutters","measureGroupTitle","measureNode","placeGroupPorts","roundLayout","routeGraph","LAYOUT_TOKENS","sizeTracks","layoutGraph","ir","measured","Map","nodes","map","node","id","titles","groups","group","areas","gutters","title","height","edges","items","axis","area","get","frame","overhang","start","row","span","rowSpan","size","h","top","bottom","col","colSpan","w","left","right","line","count","gutter","lines","rows","cols","measuredNode","areaBox","place","nodeFrame","groupArea","placeGroup","widestGutter","Math","max","leaders","viewBox","viewBoxOf","x","trackStart","y","trackEnd","stretch","visualW","visualH","depth","border","boundary","side","gutterStart","rect","dividers","labelSide","ports","centre","titleAtBottom","inner","Array","from","length","_","index","pointBox","boxes","nodeLayout","visual","groupLayout","flatMap","points","label","badge","box","pad","CONTENT_PAD","min"],"sources":["../../../../src/lib/layouts/graph/layout.ts"],"sourcesContent":["import type { Box, DiagramGraphIR, Point } from '../../model/diagram-ir.ts';\nimport { validateGraph } from '../../model/validate-graph.ts';\nimport { type CellArea, type GroupArea, gridAreas } from './areas.ts';\nimport type {\n GraphLayout,\n GroupLayout,\n NodeLayout,\n} from './graph-layout-result.ts';\nimport { type Axis, type GridGutters, gridGutters } from './gutters.ts';\nimport {\n type MeasuredGroupTitle,\n type MeasuredNode,\n measureGroupTitle,\n measureNode,\n placeGroupPorts,\n} from './measure.ts';\nimport { roundLayout } from './round.ts';\nimport { type RoutedGraph, routeGraph } from './route.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\nimport { type TrackLine, sizeTracks } from './tracks.ts';\n\n/**\n * Lays out a graph on a content-sized grid: it measures every node, sizes\n * each row and column to the content in it, and reserves the chrome of the\n * groups in the gutters between them. It throws when the grid cannot be\n * drawn without overlap, or when an id or an edge end is wrong.\n */\nexport function layoutGraph(ir: DiagramGraphIR): GraphLayout {\n validateGraph(ir);\n const measured = new Map(\n ir.nodes.map((node) => [node.id, measureNode(node)] as const),\n );\n const titles = new Map(\n ir.groups.map((group) => [group.id, measureGroupTitle(group)] as const),\n );\n const areas = gridAreas(ir);\n const gutters = gridGutters(\n areas,\n new Map([...titles].map(([id, title]) => [id, title.height])),\n ir.edges,\n );\n\n const items = (axis: Axis) =>\n ir.nodes.map((node) => {\n const area = areas.nodes.get(node.id)!;\n const { frame, overhang } = measured.get(node.id)!;\n return axis === 'row'\n ? {\n start: area.row,\n span: area.rowSpan,\n size: frame.h + overhang.top + overhang.bottom,\n }\n : {\n start: area.col,\n span: area.colSpan,\n size: frame.w + overhang.left + overhang.right,\n };\n });\n const line = (axis: Axis, count: number) =>\n sizeTracks(\n count,\n items(axis),\n gutters[axis].map((gutter) => gutter.size),\n );\n const lines: Record<Axis, TrackLine> = {\n row: line('row', areas.rows),\n col: line('col', areas.cols),\n };\n\n const nodes: NodeLayout[] = ir.nodes.map((node) => {\n const measuredNode = measured.get(node.id)!;\n const area = areaBox(areas.nodes.get(node.id)!, lines);\n return { node, ...measuredNode.place(nodeFrame(measuredNode, area)) };\n });\n const groups = areas.groups.map((groupArea) =>\n placeGroup(groupArea, titles.get(groupArea.group.id)!, lines, gutters),\n );\n\n const widestGutter = Math.max(\n ...[...gutters.row, ...gutters.col].map((gutter) => gutter.size),\n );\n const { edges, leaders } = routeGraph(\n ir,\n nodes,\n groups,\n areas,\n 2 * widestGutter,\n );\n\n return roundLayout({\n nodes,\n groups,\n edges,\n leaders,\n viewBox: viewBoxOf(nodes, groups, edges, leaders),\n });\n}\n\nfunction areaBox(area: CellArea, lines: Record<Axis, TrackLine>): Box {\n const x = lines.col.trackStart(area.col);\n const y = lines.row.trackStart(area.row);\n return {\n x,\n y,\n w: lines.col.trackEnd(area.col + area.colSpan - 1) - x,\n h: lines.row.trackEnd(area.row + area.rowSpan - 1) - y,\n };\n}\n\n/** A stretching node fills its area; any other node keeps its measured frame, centred in the area. */\nfunction nodeFrame(measured: MeasuredNode, area: Box): Box {\n const { frame, overhang, stretch } = measured;\n if (stretch) {\n return {\n x: area.x + overhang.left,\n y: area.y + overhang.top,\n w: area.w - overhang.left - overhang.right,\n h: area.h - overhang.top - overhang.bottom,\n };\n }\n const visualW = frame.w + overhang.left + overhang.right;\n const visualH = frame.h + overhang.top + overhang.bottom;\n return {\n x: area.x + (area.w - visualW) / 2 + overhang.left,\n y: area.y + (area.h - visualH) / 2 + overhang.top,\n ...frame,\n };\n}\n\n/** Each side of a group lies on the outer edge of its chrome slot in the gutter where the group opens or closes. */\nfunction placeGroup(\n { group, depth, area }: GroupArea,\n title: MeasuredGroupTitle,\n lines: Record<Axis, TrackLine>,\n gutters: GridGutters,\n): GroupLayout {\n const border = (axis: Axis, boundary: number, side: 'opening' | 'closing') =>\n lines[axis].gutterStart(boundary) +\n gutters[axis][boundary]![side].get(depth)!;\n const x = border('col', area.col, 'opening');\n const y = border('row', area.row, 'opening');\n const rect = {\n x,\n y,\n w: border('col', area.col + area.colSpan, 'closing') - x,\n h: border('row', area.row + area.rowSpan, 'closing') - y,\n };\n return {\n group,\n depth,\n rect,\n ...title.place(rect),\n dividers: group.dividers\n ? dividers(rect, area, title, group.labelSide, lines, gutters)\n : [],\n ports: placeGroupPorts(group.ports ?? [], rect),\n };\n}\n\n/** A line through the middle of every gutter inside the group, clear of its title. */\nfunction dividers(\n rect: Box,\n area: CellArea,\n title: MeasuredGroupTitle,\n labelSide: 'top' | 'bottom' | undefined,\n lines: Record<Axis, TrackLine>,\n gutters: GridGutters,\n): [Point, Point][] {\n const centre = (axis: Axis, boundary: number) =>\n lines[axis].gutterStart(boundary) + gutters[axis][boundary]!.size / 2;\n const titleAtBottom = labelSide === 'bottom';\n const top = rect.y + (titleAtBottom ? 0 : title.height);\n const bottom = rect.y + rect.h - (titleAtBottom ? title.height : 0);\n const inner = (start: number, span: number) =>\n Array.from({ length: span - 1 }, (_, index) => start + index + 1);\n return [\n ...inner(area.col, area.colSpan).map((boundary): [Point, Point] => {\n const x = centre('col', boundary);\n return [\n { x, y: top },\n { x, y: bottom },\n ];\n }),\n ...inner(area.row, area.rowSpan).map((boundary): [Point, Point] => {\n const y = centre('row', boundary);\n return [\n { x: rect.x, y },\n { x: rect.x + rect.w, y },\n ];\n }),\n ];\n}\n\nfunction viewBoxOf(\n nodes: NodeLayout[],\n groups: GroupLayout[],\n edges: RoutedGraph['edges'],\n leaders: RoutedGraph['leaders'],\n): Box {\n const pointBox = ({ x, y }: Point): Box => ({ x, y, w: 0, h: 0 });\n const boxes = [\n ...nodes.map((nodeLayout) => nodeLayout.visual),\n ...groups.map((groupLayout) => groupLayout.rect),\n ...edges.flatMap(({ points, label, badge }) => [\n ...points.map(pointBox),\n ...(label ? [label.box] : []),\n ...(badge ? [badge.box] : []),\n ]),\n ...leaders.flatMap(({ points }) => points.map(pointBox)),\n ];\n const pad = LAYOUT_TOKENS.CONTENT_PAD;\n if (boxes.length === 0) return { x: -pad, y: -pad, w: 2 * pad, h: 2 * pad };\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 {\n x: left - pad,\n y: top - pad,\n w: right - left + 2 * pad,\n h: bottom - top + 2 * pad,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Box, DiagramEdge, DiagramGroup, DiagramNode, DiagramNodePort, DiagramSide } from '../../model/diagram-ir.ts';
|
|
2
|
-
import type { NodeLayout, TextRun } from './graph-layout-result.ts';
|
|
2
|
+
import type { GroupLayout, NodeLayout, TextRun } from './graph-layout-result.ts';
|
|
3
3
|
type Sides = Record<DiagramSide, number>;
|
|
4
4
|
export type MeasuredNode = {
|
|
5
5
|
/** The smallest frame that holds the node's content. */
|
|
@@ -20,10 +20,7 @@ export declare function placeGroupPorts(ports: DiagramNodePort[], rect: Box): No
|
|
|
20
20
|
export type MeasuredGroupTitle = {
|
|
21
21
|
/** The height the title reserves on its side, BAND_PAD above and below included; 0 without a label. */
|
|
22
22
|
height: number;
|
|
23
|
-
place(rect: Box):
|
|
24
|
-
band?: Box;
|
|
25
|
-
label: TextRun[];
|
|
26
|
-
};
|
|
23
|
+
place(rect: Box): Pick<GroupLayout, 'band' | 'separator' | 'label'>;
|
|
27
24
|
};
|
|
28
25
|
export declare function measureGroupTitle(group: DiagramGroup): MeasuredGroupTitle;
|
|
29
26
|
export type MeasuredEdgeLabel = {
|
|
@@ -41,5 +38,11 @@ export type MeasuredEdgeBadge = {
|
|
|
41
38
|
};
|
|
42
39
|
};
|
|
43
40
|
export declare function measureEdgeBadge(edge: DiagramEdge): MeasuredEdgeBadge;
|
|
41
|
+
export type MeasuredEdgeTags = {
|
|
42
|
+
label?: MeasuredEdgeLabel;
|
|
43
|
+
badge?: MeasuredEdgeBadge;
|
|
44
|
+
};
|
|
45
|
+
/** What an edge carries along its route: a label beside it and a badge on it, each only when the edge has one. */
|
|
46
|
+
export declare function measureEdgeTags(edge: DiagramEdge): MeasuredEdgeTags;
|
|
44
47
|
export {};
|
|
45
48
|
//# sourceMappingURL=measure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,WAAW,EACX,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,EACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,WAAW,EACX,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,EACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,OAAO,EACR,MAAM,0BAA0B,CAAC;AAKlC,KAAK,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,wDAAwD;IACxD,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,qFAAqF;IACrF,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CAC3C,CAAC;AAWF,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CA8D3D;AAsGD,oGAAoG;AACpG,wBAAgB,eAAe,CAC7B,KAAK,EAAE,eAAe,EAAE,EACxB,IAAI,EAAE,GAAG,GACR,UAAU,CAAC,OAAO,CAAC,CAErB;AAsGD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,uGAAuG;IACvG,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,CAAC;CACrE,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,kBAAkB,CAkCzE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,EAAE,CAAC;CAC5B,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,CAWrE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CAClD,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,CAoBrE;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B,CAAC;AAEF,kHAAkH;AAClH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB,CAOnE"}
|
|
@@ -40,25 +40,43 @@ export function measureNode(node) {
|
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
42
|
const {
|
|
43
|
-
visual
|
|
43
|
+
visual,
|
|
44
|
+
frames
|
|
44
45
|
} = place({
|
|
45
46
|
x: 0,
|
|
46
47
|
y: 0,
|
|
47
48
|
w,
|
|
48
49
|
h
|
|
49
50
|
});
|
|
51
|
+
const outside = outer => ({
|
|
52
|
+
top: 0 - outer.y,
|
|
53
|
+
left: 0 - outer.x,
|
|
54
|
+
bottom: outer.y + outer.h - h,
|
|
55
|
+
right: outer.x + outer.w - w
|
|
56
|
+
});
|
|
57
|
+
const stack = outside(union([{
|
|
58
|
+
x: 0,
|
|
59
|
+
y: 0,
|
|
60
|
+
w,
|
|
61
|
+
h
|
|
62
|
+
}, ...frames]));
|
|
63
|
+
const all = outside(visual);
|
|
64
|
+
// 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.
|
|
65
|
+
const caption = (a, b) => Math.max(all[a] - stack[a], all[b] - stack[b]);
|
|
66
|
+
const vertical = caption('top', 'bottom');
|
|
67
|
+
const horizontal = caption('left', 'right');
|
|
50
68
|
return {
|
|
51
69
|
frame: {
|
|
52
70
|
w,
|
|
53
71
|
h
|
|
54
72
|
},
|
|
55
73
|
overhang: {
|
|
56
|
-
top:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
right:
|
|
74
|
+
top: stack.top + vertical,
|
|
75
|
+
bottom: stack.bottom + vertical,
|
|
76
|
+
left: stack.left + horizontal,
|
|
77
|
+
right: stack.right + horizontal
|
|
60
78
|
},
|
|
61
|
-
stretch: kind === 'node'
|
|
79
|
+
stretch: kind === 'node',
|
|
62
80
|
place
|
|
63
81
|
};
|
|
64
82
|
}
|
|
@@ -298,15 +316,24 @@ export function measureGroupTitle(group) {
|
|
|
298
316
|
} else {
|
|
299
317
|
label = lines.place(rect.x + rect.w / 2, top, 'middle');
|
|
300
318
|
}
|
|
301
|
-
|
|
319
|
+
if (!group.titleBand) return {
|
|
320
|
+
label
|
|
321
|
+
};
|
|
322
|
+
const edge = group.labelSide === 'bottom' ? y : y + height;
|
|
323
|
+
return {
|
|
302
324
|
band: {
|
|
303
325
|
x: rect.x,
|
|
304
326
|
y,
|
|
305
327
|
w: rect.w,
|
|
306
328
|
h: height
|
|
307
329
|
},
|
|
308
|
-
|
|
309
|
-
|
|
330
|
+
separator: [{
|
|
331
|
+
x: rect.x,
|
|
332
|
+
y: edge
|
|
333
|
+
}, {
|
|
334
|
+
x: rect.x + rect.w,
|
|
335
|
+
y: edge
|
|
336
|
+
}],
|
|
310
337
|
label
|
|
311
338
|
};
|
|
312
339
|
}
|
|
@@ -347,6 +374,17 @@ export function measureEdgeBadge(edge) {
|
|
|
347
374
|
}
|
|
348
375
|
};
|
|
349
376
|
}
|
|
377
|
+
/** What an edge carries along its route: a label beside it and a badge on it, each only when the edge has one. */
|
|
378
|
+
export function measureEdgeTags(edge) {
|
|
379
|
+
return {
|
|
380
|
+
...(edge.label?.length ? {
|
|
381
|
+
label: measureEdgeLabel(edge)
|
|
382
|
+
} : {}),
|
|
383
|
+
...(edge.badgeIcon || edge.badgeLabel?.length ? {
|
|
384
|
+
badge: measureEdgeBadge(edge)
|
|
385
|
+
} : {})
|
|
386
|
+
};
|
|
387
|
+
}
|
|
350
388
|
function sidesOf(value) {
|
|
351
389
|
return {
|
|
352
390
|
top: value('top'),
|
|
@@ -1 +1 @@
|
|
|
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","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","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","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 { 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 } = 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(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): { band?: Box; label: TextRun[] };\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 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(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\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":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"min-heap.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/min-heap.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
|
@@ -1 +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":["
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import type { Box, DiagramNode } from '../../model/diagram-ir.ts';
|
|
2
2
|
import type { NodeLayout } from './graph-layout-result.ts';
|
|
3
|
-
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'>>;
|
|
4
4
|
/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */
|
|
5
5
|
export type NodeContent = {
|
|
6
6
|
w: number;
|
|
@@ -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;AAI3D,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,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"}
|
|
@@ -38,25 +38,44 @@ function boxContent(node) {
|
|
|
38
38
|
y: LAYOUT_TOKENS.PAD_Y
|
|
39
39
|
};
|
|
40
40
|
const isCard = node.textAlign === 'start' || node.description !== undefined || (node.items?.length ?? 0) > 0;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (node.icon) return {
|
|
46
|
-
...iconRowContent(node),
|
|
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),
|
|
47
45
|
pad
|
|
48
46
|
};
|
|
47
|
+
}
|
|
48
|
+
function labelContent(node) {
|
|
49
49
|
const lines = textBlock(labelLines(node.label, node.textColor), LAYOUT_TOKENS.fonts.boxLabel);
|
|
50
50
|
return {
|
|
51
51
|
w: lines.w,
|
|
52
52
|
h: lines.h,
|
|
53
|
-
pad,
|
|
54
53
|
place: inner => ({
|
|
55
54
|
text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),
|
|
56
55
|
bullets: []
|
|
57
56
|
})
|
|
58
57
|
};
|
|
59
58
|
}
|
|
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
|
+
}
|
|
60
79
|
function iconRowContent(node) {
|
|
61
80
|
const {
|
|
62
81
|
ICON,
|