@zukhruf/diagram 0.3.31 → 0.3.33
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/dist/lib/layouts/graph/areas.js +17 -8
- package/dist/lib/layouts/graph/areas.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 +216 -0
- package/dist/lib/layouts/graph/attach.js.map +1 -0
- package/dist/lib/layouts/graph/connections.d.ts +38 -0
- package/dist/lib/layouts/graph/connections.d.ts.map +1 -0
- package/dist/lib/layouts/graph/connections.js +112 -0
- package/dist/lib/layouts/graph/connections.js.map +1 -0
- package/dist/lib/layouts/graph/graph-layout-result.d.ts +1 -1
- 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.d.ts +1 -2
- package/dist/lib/layouts/graph/gutters.d.ts.map +1 -1
- package/dist/lib/layouts/graph/gutters.js +20 -19
- package/dist/lib/layouts/graph/gutters.js.map +1 -1
- package/dist/lib/layouts/graph/labels.d.ts +16 -0
- package/dist/lib/layouts/graph/labels.d.ts.map +1 -0
- package/dist/lib/layouts/graph/labels.js +76 -0
- package/dist/lib/layouts/graph/labels.js.map +1 -0
- package/dist/lib/layouts/graph/layout.d.ts.map +1 -1
- package/dist/lib/layouts/graph/layout.js +34 -13
- package/dist/lib/layouts/graph/layout.js.map +1 -1
- package/dist/lib/layouts/graph/measure.d.ts +7 -6
- package/dist/lib/layouts/graph/measure.d.ts.map +1 -1
- package/dist/lib/layouts/graph/measure.js +35 -29
- package/dist/lib/layouts/graph/measure.js.map +1 -1
- package/dist/lib/layouts/graph/min-heap.d.ts +12 -0
- package/dist/lib/layouts/graph/min-heap.d.ts.map +1 -0
- package/dist/lib/layouts/graph/min-heap.js +60 -0
- package/dist/lib/layouts/graph/min-heap.js.map +1 -0
- package/dist/lib/layouts/graph/node-content.d.ts +1 -2
- package/dist/lib/layouts/graph/node-content.d.ts.map +1 -1
- package/dist/lib/layouts/graph/node-content.js +43 -42
- package/dist/lib/layouts/graph/node-content.js.map +1 -1
- package/dist/lib/layouts/graph/path.d.ts +14 -0
- package/dist/lib/layouts/graph/path.d.ts.map +1 -0
- package/dist/lib/layouts/graph/path.js +55 -0
- package/dist/lib/layouts/graph/path.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 +16 -0
- package/dist/lib/layouts/graph/route.d.ts.map +1 -0
- package/dist/lib/layouts/graph/route.js +241 -0
- package/dist/lib/layouts/graph/route.js.map +1 -0
- package/dist/lib/layouts/graph/sides.d.ts +23 -0
- package/dist/lib/layouts/graph/sides.d.ts.map +1 -0
- package/dist/lib/layouts/graph/sides.js +91 -0
- package/dist/lib/layouts/graph/sides.js.map +1 -0
- package/dist/lib/layouts/graph/tokens.d.ts +2 -7
- package/dist/lib/layouts/graph/tokens.d.ts.map +1 -1
- package/dist/lib/layouts/graph/tokens.js +91 -104
- package/dist/lib/layouts/graph/tokens.js.map +1 -1
- package/dist/lib/model/diagram-ir.d.ts +0 -3
- package/dist/lib/model/diagram-ir.d.ts.map +1 -1
- package/dist/lib/model/diagram-ir.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { attachConnections } from "./attach.js";
|
|
2
|
+
import { graphConnections } from "./connections.js";
|
|
3
|
+
import { tagPosition } from "./labels.js";
|
|
4
|
+
import { measureEdgeBadge, measureEdgeLabel } from "./measure.js";
|
|
5
|
+
import { pathToSvg, simplifyPath } from "./path.js";
|
|
6
|
+
import { searchRoute } from "./route-search.js";
|
|
7
|
+
import { OPPOSITE, OUTWARD } from "./sides.js";
|
|
8
|
+
import { LAYOUT_TOKENS } from "./tokens.js";
|
|
9
|
+
|
|
10
|
+
/** How far around the content a route may detour. */
|
|
11
|
+
const ROUTING_MARGIN = 64;
|
|
12
|
+
/** How far a route keeps from a node that it does not connect. */
|
|
13
|
+
const NODE_CLEARANCE = 8;
|
|
14
|
+
/**
|
|
15
|
+
* Routes every edge and note leader orthogonally, nearest cells first, and
|
|
16
|
+
* places each edge's label and badge before the next edge routes around
|
|
17
|
+
* them. It throws when a route or a label has no room; it never draws a
|
|
18
|
+
* diagonal or straight line through what is in the way.
|
|
19
|
+
*/
|
|
20
|
+
export function routeGraph(ir, nodes, groups, areas, /** How far beyond the bounding box of its two shapes a route first searches. */
|
|
21
|
+
searchMargin) {
|
|
22
|
+
const connections = graphConnections(ir, nodes, groups, areas);
|
|
23
|
+
if (connections.length === 0) return {
|
|
24
|
+
edges: [],
|
|
25
|
+
leaders: []
|
|
26
|
+
};
|
|
27
|
+
const groupLabels = groups.flatMap(({
|
|
28
|
+
group,
|
|
29
|
+
label
|
|
30
|
+
}) => label.map(run => ({
|
|
31
|
+
group: group.id,
|
|
32
|
+
box: inflate(run.bounds, LAYOUT_TOKENS.LABEL_GAP)
|
|
33
|
+
})));
|
|
34
|
+
const attachments = attachConnections(connections, groupLabels);
|
|
35
|
+
const content = union([...nodes.map(nodeLayout => nodeLayout.visual), ...groups.map(groupLayout => groupLayout.rect)]);
|
|
36
|
+
const bounds = inflate(content, ROUTING_MARGIN);
|
|
37
|
+
const solid = nodes.filter(({
|
|
38
|
+
box
|
|
39
|
+
}) => box.w > 0 && box.h > 0);
|
|
40
|
+
const routed = [];
|
|
41
|
+
const tags = [];
|
|
42
|
+
const paths = new Map();
|
|
43
|
+
const labels = new Map();
|
|
44
|
+
const order = connections.map((connection, index) => ({
|
|
45
|
+
connection,
|
|
46
|
+
index
|
|
47
|
+
})).sort((a, b) => Number(a.connection.edge === undefined) - Number(b.connection.edge === undefined) || a.connection.cellDistance - b.connection.cellDistance || a.index - b.index);
|
|
48
|
+
for (const {
|
|
49
|
+
connection,
|
|
50
|
+
index
|
|
51
|
+
} of order) {
|
|
52
|
+
const {
|
|
53
|
+
from,
|
|
54
|
+
to
|
|
55
|
+
} = connection;
|
|
56
|
+
const ends = new Set([from.shape.id, to.shape.id]);
|
|
57
|
+
const junctions = new Set([from, to].filter(end => end.shape.kind === 'junction').map(end => end.shape.id));
|
|
58
|
+
const walls = [...solid.flatMap(({
|
|
59
|
+
node,
|
|
60
|
+
box,
|
|
61
|
+
visual,
|
|
62
|
+
frames,
|
|
63
|
+
caption
|
|
64
|
+
}) => {
|
|
65
|
+
if (!ends.has(node.id)) return [inflate(visual, NODE_CLEARANCE)];
|
|
66
|
+
if (node.kind === 'junction') return [];
|
|
67
|
+
// Its own parts, not their bounding box: a caption wider than the frame leaves room beside the frame.
|
|
68
|
+
return [box, ...frames, ...(caption ? [caption.box] : [])];
|
|
69
|
+
}), ...groupLabels.flatMap(({
|
|
70
|
+
group,
|
|
71
|
+
box
|
|
72
|
+
}) => ends.has(group) ? [] : [box]), ...tags.map(tag => inflate(tag, LAYOUT_TOKENS.LABEL_GAP))];
|
|
73
|
+
const runs = routed.filter(route => !overlaps(route.junctions, junctions)).flatMap(route => segments(route.points));
|
|
74
|
+
const {
|
|
75
|
+
start,
|
|
76
|
+
startStub,
|
|
77
|
+
end,
|
|
78
|
+
endStub
|
|
79
|
+
} = attachments[index];
|
|
80
|
+
const stubs = [[start, startStub], [endStub, end]];
|
|
81
|
+
const stubsClear = stubs.every(([a, b]) => walls.every(wall => !crosses(a, b, wall)));
|
|
82
|
+
const search = window => searchRoute({
|
|
83
|
+
window,
|
|
84
|
+
lines: {
|
|
85
|
+
x: [startStub.x, endStub.x],
|
|
86
|
+
y: [startStub.y, endStub.y]
|
|
87
|
+
},
|
|
88
|
+
walls,
|
|
89
|
+
runs,
|
|
90
|
+
borders: groups.flatMap(({
|
|
91
|
+
rect,
|
|
92
|
+
band
|
|
93
|
+
}) => band ? [rect, band] : [rect]),
|
|
94
|
+
start: startStub,
|
|
95
|
+
startHeading: OUTWARD[from.side],
|
|
96
|
+
goal: endStub,
|
|
97
|
+
goalHeading: OUTWARD[OPPOSITE[to.side]]
|
|
98
|
+
});
|
|
99
|
+
const near = intersection(inflate(union([from.shape.box, to.shape.box, spanOf(startStub, endStub)]), searchMargin), bounds);
|
|
100
|
+
const found = stubsClear ? search(near) ?? search(bounds) : undefined;
|
|
101
|
+
if (!found) {
|
|
102
|
+
const advice = connection.edge === undefined ? 'Move the note or its target.' : 'Change exitSide/entrySide or move a node.';
|
|
103
|
+
throw new Error(`Diagram ${connection.name}: no orthogonal route from ${endName(from)} to ${endName(to)} avoids the nodes and labels. ${advice}`);
|
|
104
|
+
}
|
|
105
|
+
const points = simplifyPath([start, ...found, end]);
|
|
106
|
+
paths.set(connection, points);
|
|
107
|
+
if (connection.edge !== undefined) {
|
|
108
|
+
const edge = ir.edges[connection.edge];
|
|
109
|
+
const isFree = (box, ownSegments) => solid.every(({
|
|
110
|
+
visual
|
|
111
|
+
}) => !intersects(box, visual)) && groups.every(({
|
|
112
|
+
rect,
|
|
113
|
+
band,
|
|
114
|
+
label
|
|
115
|
+
}) => !(band && intersects(box, band)) && label.every(run => !intersects(box, run.bounds)) && !(intersects(box, rect) && !contains(rect, box))) && tags.every(tag => !intersects(box, tag)) && [...routed.flatMap(route => segments(route.points)), ...(ownSegments ? segments(points) : [])].every(([a, b]) => !crosses(a, b, box));
|
|
116
|
+
const placed = {};
|
|
117
|
+
if (edge.label?.length) {
|
|
118
|
+
const measured = measureEdgeLabel(edge);
|
|
119
|
+
const position = tagPosition(measured, points, 'beside', box => isFree(box, true));
|
|
120
|
+
if (!position) {
|
|
121
|
+
throw new Error(`Diagram ${connection.name}: label "${edge.label.join(' / ')}" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position beside its route.`);
|
|
122
|
+
}
|
|
123
|
+
placed.label = {
|
|
124
|
+
...position,
|
|
125
|
+
text: measured.place(position.box)
|
|
126
|
+
};
|
|
127
|
+
tags.push(position.box);
|
|
128
|
+
}
|
|
129
|
+
if (edge.badgeIcon || edge.badgeLabel?.length) {
|
|
130
|
+
const measured = measureEdgeBadge(edge);
|
|
131
|
+
const position = tagPosition(measured, points, 'on', box => isFree(box, false));
|
|
132
|
+
if (!position) {
|
|
133
|
+
throw new Error(`Diagram ${connection.name}: badge "${(edge.badgeLabel ?? []).join(' / ')}" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position on its route.`);
|
|
134
|
+
}
|
|
135
|
+
placed.badge = {
|
|
136
|
+
box: position.box,
|
|
137
|
+
...measured.place(position.box)
|
|
138
|
+
};
|
|
139
|
+
tags.push(position.box);
|
|
140
|
+
}
|
|
141
|
+
labels.set(connection, placed);
|
|
142
|
+
}
|
|
143
|
+
routed.push({
|
|
144
|
+
points,
|
|
145
|
+
junctions
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const edges = [];
|
|
149
|
+
const leaders = [];
|
|
150
|
+
for (const connection of connections) {
|
|
151
|
+
const points = paths.get(connection);
|
|
152
|
+
if (connection.edge === undefined) {
|
|
153
|
+
leaders.push({
|
|
154
|
+
note: connection.from.shape.id,
|
|
155
|
+
target: connection.to.shape.id,
|
|
156
|
+
points,
|
|
157
|
+
d: pathToSvg(points)
|
|
158
|
+
});
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
edges.push({
|
|
162
|
+
edge: ir.edges[connection.edge],
|
|
163
|
+
exitSide: connection.from.side,
|
|
164
|
+
entrySide: connection.to.side,
|
|
165
|
+
points,
|
|
166
|
+
d: pathToSvg(points),
|
|
167
|
+
...labels.get(connection)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
edges,
|
|
172
|
+
leaders
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function endName({
|
|
176
|
+
shape,
|
|
177
|
+
side,
|
|
178
|
+
port
|
|
179
|
+
}) {
|
|
180
|
+
if (port) return `port "${shape.id}:${port.id}"`;
|
|
181
|
+
if (shape.kind === 'junction') return `the centre of "${shape.id}"`;
|
|
182
|
+
return `${side} of "${shape.id}"`;
|
|
183
|
+
}
|
|
184
|
+
function segments(points) {
|
|
185
|
+
return points.slice(1).map((point, index) => [points[index], point]);
|
|
186
|
+
}
|
|
187
|
+
function overlaps(a, b) {
|
|
188
|
+
for (const id of a) if (b.has(id)) return true;
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
function spanOf(a, b) {
|
|
192
|
+
return {
|
|
193
|
+
x: Math.min(a.x, b.x),
|
|
194
|
+
y: Math.min(a.y, b.y),
|
|
195
|
+
w: Math.abs(a.x - b.x),
|
|
196
|
+
h: Math.abs(a.y - b.y)
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Whether the segment enters the box's interior, not only its border. */
|
|
201
|
+
function crosses(a, b, box) {
|
|
202
|
+
const span = spanOf(a, b);
|
|
203
|
+
return span.x + span.w > box.x && span.x < box.x + box.w && span.y + span.h > box.y && span.y < box.y + box.h;
|
|
204
|
+
}
|
|
205
|
+
function intersects(a, b) {
|
|
206
|
+
return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
|
|
207
|
+
}
|
|
208
|
+
function contains(outer, inner) {
|
|
209
|
+
return inner.x >= outer.x && inner.y >= outer.y && inner.x + inner.w <= outer.x + outer.w && inner.y + inner.h <= outer.y + outer.h;
|
|
210
|
+
}
|
|
211
|
+
function inflate(box, by) {
|
|
212
|
+
return {
|
|
213
|
+
x: box.x - by,
|
|
214
|
+
y: box.y - by,
|
|
215
|
+
w: box.w + 2 * by,
|
|
216
|
+
h: box.h + 2 * by
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function intersection(a, b) {
|
|
220
|
+
const x = Math.max(a.x, b.x);
|
|
221
|
+
const y = Math.max(a.y, b.y);
|
|
222
|
+
return {
|
|
223
|
+
x,
|
|
224
|
+
y,
|
|
225
|
+
w: Math.min(a.x + a.w, b.x + b.w) - x,
|
|
226
|
+
h: Math.min(a.y + a.h, b.y + b.h) - y
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function union(boxes) {
|
|
230
|
+
const left = Math.min(...boxes.map(box => box.x));
|
|
231
|
+
const top = Math.min(...boxes.map(box => box.y));
|
|
232
|
+
const right = Math.max(...boxes.map(box => box.x + box.w));
|
|
233
|
+
const bottom = Math.max(...boxes.map(box => box.y + box.h));
|
|
234
|
+
return {
|
|
235
|
+
x: left,
|
|
236
|
+
y: top,
|
|
237
|
+
w: right - left,
|
|
238
|
+
h: bottom - top
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","names":["attachConnections","graphConnections","tagPosition","measureEdgeBadge","measureEdgeLabel","pathToSvg","simplifyPath","searchRoute","OPPOSITE","OUTWARD","LAYOUT_TOKENS","ROUTING_MARGIN","NODE_CLEARANCE","routeGraph","ir","nodes","groups","areas","searchMargin","connections","length","edges","leaders","groupLabels","flatMap","group","label","map","run","id","box","inflate","bounds","LABEL_GAP","attachments","content","union","nodeLayout","visual","groupLayout","rect","solid","filter","w","h","routed","tags","paths","Map","labels","order","connection","index","sort","a","b","Number","edge","undefined","cellDistance","from","to","ends","Set","shape","junctions","end","kind","walls","node","frames","caption","has","tag","runs","route","overlaps","segments","points","start","startStub","endStub","stubs","stubsClear","every","wall","crosses","search","window","lines","x","y","borders","band","startHeading","side","goal","goalHeading","near","intersection","spanOf","found","advice","Error","name","endName","set","isFree","ownSegments","intersects","contains","placed","measured","position","join","Math","ceil","text","place","push","badgeIcon","badgeLabel","badge","get","note","target","d","exitSide","entrySide","port","slice","point","min","abs","span","outer","inner","by","max","boxes","left","top","right","bottom"],"sources":["../../../../src/lib/layouts/graph/route.ts"],"sourcesContent":["import type { Box, DiagramGraphIR, Point } from '../../model/diagram-ir.ts';\nimport type { GridAreas } from './areas.ts';\nimport { attachConnections } from './attach.ts';\nimport {\n type Connection,\n type ConnectionEnd,\n graphConnections,\n} from './connections.ts';\nimport type {\n EdgeLayout,\n GroupLayout,\n LeaderLayout,\n NodeLayout,\n} from './graph-layout-result.ts';\nimport { tagPosition } from './labels.ts';\nimport { measureEdgeBadge, measureEdgeLabel } from './measure.ts';\nimport { pathToSvg, simplifyPath } from './path.ts';\nimport { searchRoute } from './route-search.ts';\nimport { OPPOSITE, OUTWARD } from './sides.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\n/** How far around the content a route may detour. */\nconst ROUTING_MARGIN = 64;\n/** How far a route keeps from a node that it does not connect. */\nconst NODE_CLEARANCE = 8;\n\ntype Routed = {\n points: Point[];\n /** The junctions the route ends at: routes that share one may run together into it. */\n junctions: Set<string>;\n};\n\n/**\n * Routes every edge and note leader orthogonally, nearest cells first, and\n * places each edge's label and badge before the next edge routes around\n * them. It throws when a route or a label has no room; it never draws a\n * diagonal or straight line through what is in the way.\n */\nexport function routeGraph(\n ir: DiagramGraphIR,\n nodes: NodeLayout[],\n groups: GroupLayout[],\n areas: GridAreas,\n /** How far beyond the bounding box of its two shapes a route first searches. */\n searchMargin: number,\n): { edges: EdgeLayout[]; leaders: LeaderLayout[] } {\n const connections = graphConnections(ir, nodes, groups, areas);\n if (connections.length === 0) return { edges: [], leaders: [] };\n const groupLabels = groups.flatMap(({ group, label }) =>\n label.map((run) => ({\n group: group.id,\n box: inflate(run.bounds, LAYOUT_TOKENS.LABEL_GAP),\n })),\n );\n const attachments = attachConnections(connections, groupLabels);\n const content = union([\n ...nodes.map((nodeLayout) => nodeLayout.visual),\n ...groups.map((groupLayout) => groupLayout.rect),\n ]);\n const bounds = inflate(content, ROUTING_MARGIN);\n const solid = nodes.filter(({ box }) => box.w > 0 && box.h > 0);\n\n const routed: Routed[] = [];\n const tags: Box[] = [];\n const paths = new Map<Connection, Point[]>();\n const labels = new Map<Connection, Pick<EdgeLayout, 'label' | 'badge'>>();\n\n const order = connections\n .map((connection, index) => ({ connection, index }))\n .sort(\n (a, b) =>\n Number(a.connection.edge === undefined) -\n Number(b.connection.edge === undefined) ||\n a.connection.cellDistance - b.connection.cellDistance ||\n a.index - b.index,\n );\n\n for (const { connection, index } of order) {\n const { from, to } = connection;\n const ends = new Set([from.shape.id, to.shape.id]);\n const junctions = new Set(\n [from, to]\n .filter((end) => end.shape.kind === 'junction')\n .map((end) => end.shape.id),\n );\n const walls = [\n ...solid.flatMap(({ node, box, visual, frames, caption }) => {\n if (!ends.has(node.id)) return [inflate(visual, NODE_CLEARANCE)];\n if (node.kind === 'junction') return [];\n // Its own parts, not their bounding box: a caption wider than the frame leaves room beside the frame.\n return [box, ...frames, ...(caption ? [caption.box] : [])];\n }),\n ...groupLabels.flatMap(({ group, box }) =>\n ends.has(group) ? [] : [box],\n ),\n ...tags.map((tag) => inflate(tag, LAYOUT_TOKENS.LABEL_GAP)),\n ];\n const runs = routed\n .filter((route) => !overlaps(route.junctions, junctions))\n .flatMap((route) => segments(route.points));\n const { start, startStub, end, endStub } = attachments[index]!;\n const stubs: [Point, Point][] = [\n [start, startStub],\n [endStub, end],\n ];\n const stubsClear = stubs.every(([a, b]) =>\n walls.every((wall) => !crosses(a, b, wall)),\n );\n\n const search = (window: Box): Point[] | undefined =>\n searchRoute({\n window,\n lines: {\n x: [startStub.x, endStub.x],\n y: [startStub.y, endStub.y],\n },\n walls,\n runs,\n borders: groups.flatMap(({ rect, band }) =>\n band ? [rect, band] : [rect],\n ),\n start: startStub,\n startHeading: OUTWARD[from.side],\n goal: endStub,\n goalHeading: OUTWARD[OPPOSITE[to.side]],\n });\n const near = intersection(\n inflate(\n union([from.shape.box, to.shape.box, spanOf(startStub, endStub)]),\n searchMargin,\n ),\n bounds,\n );\n const found = stubsClear ? (search(near) ?? search(bounds)) : undefined;\n if (!found) {\n const advice =\n connection.edge === undefined\n ? 'Move the note or its target.'\n : 'Change exitSide/entrySide or move a node.';\n throw new Error(\n `Diagram ${connection.name}: no orthogonal route from ${endName(from)} to ${endName(to)} avoids the nodes and labels. ${advice}`,\n );\n }\n const points = simplifyPath([start, ...found, end]);\n paths.set(connection, points);\n\n if (connection.edge !== undefined) {\n const edge = ir.edges[connection.edge]!;\n const isFree = (box: Box, ownSegments: boolean) =>\n solid.every(({ visual }) => !intersects(box, visual)) &&\n groups.every(\n ({ rect, band, label }) =>\n !(band && intersects(box, band)) &&\n label.every((run) => !intersects(box, run.bounds)) &&\n !(intersects(box, rect) && !contains(rect, box)),\n ) &&\n tags.every((tag) => !intersects(box, tag)) &&\n [\n ...routed.flatMap((route) => segments(route.points)),\n ...(ownSegments ? segments(points) : []),\n ].every(([a, b]) => !crosses(a, b, box));\n const placed: Pick<EdgeLayout, 'label' | 'badge'> = {};\n if (edge.label?.length) {\n const measured = measureEdgeLabel(edge);\n const position = tagPosition(measured, points, 'beside', (box) =>\n isFree(box, true),\n );\n if (!position) {\n throw new Error(\n `Diagram ${connection.name}: label \"${edge.label.join(' / ')}\" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position beside its route.`,\n );\n }\n placed.label = { ...position, text: measured.place(position.box) };\n tags.push(position.box);\n }\n if (edge.badgeIcon || edge.badgeLabel?.length) {\n const measured = measureEdgeBadge(edge);\n const position = tagPosition(measured, points, 'on', (box) =>\n isFree(box, false),\n );\n if (!position) {\n throw new Error(\n `Diagram ${connection.name}: badge \"${(edge.badgeLabel ?? []).join(' / ')}\" (${Math.ceil(measured.w)}×${Math.ceil(measured.h)}) has no free position on its route.`,\n );\n }\n placed.badge = { box: position.box, ...measured.place(position.box) };\n tags.push(position.box);\n }\n labels.set(connection, placed);\n }\n routed.push({ points, junctions });\n }\n\n const edges: EdgeLayout[] = [];\n const leaders: LeaderLayout[] = [];\n for (const connection of connections) {\n const points = paths.get(connection)!;\n if (connection.edge === undefined) {\n leaders.push({\n note: connection.from.shape.id,\n target: connection.to.shape.id,\n points,\n d: pathToSvg(points),\n });\n continue;\n }\n edges.push({\n edge: ir.edges[connection.edge]!,\n exitSide: connection.from.side,\n entrySide: connection.to.side,\n points,\n d: pathToSvg(points),\n ...labels.get(connection),\n });\n }\n return { edges, leaders };\n}\n\nfunction endName({ shape, side, port }: ConnectionEnd): string {\n if (port) return `port \"${shape.id}:${port.id}\"`;\n if (shape.kind === 'junction') return `the centre of \"${shape.id}\"`;\n return `${side} of \"${shape.id}\"`;\n}\n\nfunction segments(points: Point[]): [Point, Point][] {\n return points.slice(1).map((point, index) => [points[index]!, point]);\n}\n\nfunction overlaps(a: Set<string>, b: Set<string>): boolean {\n for (const id of a) if (b.has(id)) return true;\n return false;\n}\n\nfunction spanOf(a: Point, b: Point): Box {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n w: Math.abs(a.x - b.x),\n h: Math.abs(a.y - b.y),\n };\n}\n\n/** Whether the segment enters the box's interior, not only its border. */\nfunction crosses(a: Point, b: Point, box: Box): boolean {\n const span = spanOf(a, b);\n return (\n span.x + span.w > box.x &&\n span.x < box.x + box.w &&\n span.y + span.h > box.y &&\n span.y < box.y + box.h\n );\n}\n\nfunction intersects(a: Box, b: Box): boolean {\n return (\n a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h\n );\n}\n\nfunction contains(outer: Box, inner: Box): boolean {\n return (\n inner.x >= outer.x &&\n inner.y >= outer.y &&\n inner.x + inner.w <= outer.x + outer.w &&\n inner.y + inner.h <= outer.y + outer.h\n );\n}\n\nfunction inflate(box: Box, by: number): Box {\n return { x: box.x - by, y: box.y - by, w: box.w + 2 * by, h: box.h + 2 * by };\n}\n\nfunction intersection(a: Box, b: Box): Box {\n const x = Math.max(a.x, b.x);\n const y = Math.max(a.y, b.y);\n return {\n x,\n y,\n w: Math.min(a.x + a.w, b.x + b.w) - x,\n h: Math.min(a.y + a.h, b.y + b.h) - y,\n };\n}\n\nfunction union(boxes: Box[]): Box {\n const left = Math.min(...boxes.map((box) => box.x));\n const top = Math.min(...boxes.map((box) => box.y));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n return { x: left, y: top, w: right - left, h: bottom - top };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Box, DiagramSide, Point } from '../../model/diagram-ir.ts';
|
|
2
|
+
import type { CellArea } from './areas.ts';
|
|
3
|
+
import type { Heading } from './route-search.ts';
|
|
4
|
+
export declare const OPPOSITE: Record<DiagramSide, DiagramSide>;
|
|
5
|
+
/** The heading of a line that leaves a box through `side`. */
|
|
6
|
+
export declare const OUTWARD: Record<DiagramSide, Heading>;
|
|
7
|
+
export declare function isVertical(side: DiagramSide): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* The sides a connection leaves and enters by, read from the cells: areas
|
|
10
|
+
* that share rows face left and right, areas that share columns face top
|
|
11
|
+
* and bottom, and otherwise the axis with the larger cell delta wins, the
|
|
12
|
+
* vertical one on a tie.
|
|
13
|
+
*/
|
|
14
|
+
export declare function facingSides(from: CellArea, to: CellArea): [DiagramSide, DiagramSide];
|
|
15
|
+
/** The coordinate of the side's line: x for left and right, y for top and bottom. */
|
|
16
|
+
export declare function sideLine(box: Box, side: DiagramSide): number;
|
|
17
|
+
/** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */
|
|
18
|
+
export declare function sideSpan(box: Box, side: DiagramSide): [number, number];
|
|
19
|
+
/** The point on `side` of `box` at `along` on the side's span. */
|
|
20
|
+
export declare function pointOnSide(box: Box, side: DiagramSide, along: number): Point;
|
|
21
|
+
/** The point `distance` beyond `point` out of `side`. */
|
|
22
|
+
export declare function beyond(point: Point, side: DiagramSide, distance: number): Point;
|
|
23
|
+
//# sourceMappingURL=sides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sides.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/sides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAKrD,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAKhD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,QAAQ,GACX,CAAC,WAAW,EAAE,WAAW,CAAC,CAa5B;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAW5D;AAED,yGAAyG;AACzG,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEtE;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAG7E;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,GACf,KAAK,CAWP"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export const OPPOSITE = {
|
|
2
|
+
top: 'bottom',
|
|
3
|
+
bottom: 'top',
|
|
4
|
+
left: 'right',
|
|
5
|
+
right: 'left'
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/** The heading of a line that leaves a box through `side`. */
|
|
9
|
+
export const OUTWARD = {
|
|
10
|
+
right: 0,
|
|
11
|
+
left: 1,
|
|
12
|
+
bottom: 2,
|
|
13
|
+
top: 3
|
|
14
|
+
};
|
|
15
|
+
export function isVertical(side) {
|
|
16
|
+
return side === 'top' || side === 'bottom';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The sides a connection leaves and enters by, read from the cells: areas
|
|
21
|
+
* that share rows face left and right, areas that share columns face top
|
|
22
|
+
* and bottom, and otherwise the axis with the larger cell delta wins, the
|
|
23
|
+
* vertical one on a tie.
|
|
24
|
+
*/
|
|
25
|
+
export function facingSides(from, to) {
|
|
26
|
+
const shareRows = Math.max(from.row, to.row) < Math.min(from.row + from.rowSpan, to.row + to.rowSpan);
|
|
27
|
+
const shareCols = Math.max(from.col, to.col) < Math.min(from.col + from.colSpan, to.col + to.colSpan);
|
|
28
|
+
const dr = to.row + to.rowSpan / 2 - (from.row + from.rowSpan / 2);
|
|
29
|
+
const dc = to.col + to.colSpan / 2 - (from.col + from.colSpan / 2);
|
|
30
|
+
const horizontal = shareRows !== shareCols ? shareRows : Math.abs(dc) > Math.abs(dr);
|
|
31
|
+
if (horizontal) return dc > 0 ? ['right', 'left'] : ['left', 'right'];
|
|
32
|
+
return dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The coordinate of the side's line: x for left and right, y for top and bottom. */
|
|
36
|
+
export function sideLine(box, side) {
|
|
37
|
+
switch (side) {
|
|
38
|
+
case 'top':
|
|
39
|
+
return box.y;
|
|
40
|
+
case 'bottom':
|
|
41
|
+
return box.y + box.h;
|
|
42
|
+
case 'left':
|
|
43
|
+
return box.x;
|
|
44
|
+
case 'right':
|
|
45
|
+
return box.x + box.w;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */
|
|
50
|
+
export function sideSpan(box, side) {
|
|
51
|
+
return isVertical(side) ? [box.x, box.x + box.w] : [box.y, box.y + box.h];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The point on `side` of `box` at `along` on the side's span. */
|
|
55
|
+
export function pointOnSide(box, side, along) {
|
|
56
|
+
const line = sideLine(box, side);
|
|
57
|
+
return isVertical(side) ? {
|
|
58
|
+
x: along,
|
|
59
|
+
y: line
|
|
60
|
+
} : {
|
|
61
|
+
x: line,
|
|
62
|
+
y: along
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The point `distance` beyond `point` out of `side`. */
|
|
67
|
+
export function beyond(point, side, distance) {
|
|
68
|
+
switch (side) {
|
|
69
|
+
case 'top':
|
|
70
|
+
return {
|
|
71
|
+
x: point.x,
|
|
72
|
+
y: point.y - distance
|
|
73
|
+
};
|
|
74
|
+
case 'bottom':
|
|
75
|
+
return {
|
|
76
|
+
x: point.x,
|
|
77
|
+
y: point.y + distance
|
|
78
|
+
};
|
|
79
|
+
case 'left':
|
|
80
|
+
return {
|
|
81
|
+
x: point.x - distance,
|
|
82
|
+
y: point.y
|
|
83
|
+
};
|
|
84
|
+
case 'right':
|
|
85
|
+
return {
|
|
86
|
+
x: point.x + distance,
|
|
87
|
+
y: point.y
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=sides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sides.js","names":["OPPOSITE","top","bottom","left","right","OUTWARD","isVertical","side","facingSides","from","to","shareRows","Math","max","row","min","rowSpan","shareCols","col","colSpan","dr","dc","horizontal","abs","sideLine","box","y","h","x","w","sideSpan","pointOnSide","along","line","beyond","point","distance"],"sources":["../../../../src/lib/layouts/graph/sides.ts"],"sourcesContent":["import type { Box, DiagramSide, Point } from '../../model/diagram-ir.ts';\nimport type { CellArea } from './areas.ts';\nimport type { Heading } from './route-search.ts';\n\nexport const OPPOSITE: Record<DiagramSide, DiagramSide> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n};\n\n/** The heading of a line that leaves a box through `side`. */\nexport const OUTWARD: Record<DiagramSide, Heading> = {\n right: 0,\n left: 1,\n bottom: 2,\n top: 3,\n};\n\nexport function isVertical(side: DiagramSide): boolean {\n return side === 'top' || side === 'bottom';\n}\n\n/**\n * The sides a connection leaves and enters by, read from the cells: areas\n * that share rows face left and right, areas that share columns face top\n * and bottom, and otherwise the axis with the larger cell delta wins, the\n * vertical one on a tie.\n */\nexport function facingSides(\n from: CellArea,\n to: CellArea,\n): [DiagramSide, DiagramSide] {\n const shareRows =\n Math.max(from.row, to.row) <\n Math.min(from.row + from.rowSpan, to.row + to.rowSpan);\n const shareCols =\n Math.max(from.col, to.col) <\n Math.min(from.col + from.colSpan, to.col + to.colSpan);\n const dr = to.row + to.rowSpan / 2 - (from.row + from.rowSpan / 2);\n const dc = to.col + to.colSpan / 2 - (from.col + from.colSpan / 2);\n const horizontal =\n shareRows !== shareCols ? shareRows : Math.abs(dc) > Math.abs(dr);\n if (horizontal) return dc > 0 ? ['right', 'left'] : ['left', 'right'];\n return dr >= 0 ? ['bottom', 'top'] : ['top', 'bottom'];\n}\n\n/** The coordinate of the side's line: x for left and right, y for top and bottom. */\nexport function sideLine(box: Box, side: DiagramSide): number {\n switch (side) {\n case 'top':\n return box.y;\n case 'bottom':\n return box.y + box.h;\n case 'left':\n return box.x;\n case 'right':\n return box.x + box.w;\n }\n}\n\n/** Where the side runs along its line: [start, end] in x for top and bottom, in y for left and right. */\nexport function sideSpan(box: Box, side: DiagramSide): [number, number] {\n return isVertical(side) ? [box.x, box.x + box.w] : [box.y, box.y + box.h];\n}\n\n/** The point on `side` of `box` at `along` on the side's span. */\nexport function pointOnSide(box: Box, side: DiagramSide, along: number): Point {\n const line = sideLine(box, side);\n return isVertical(side) ? { x: along, y: line } : { x: line, y: along };\n}\n\n/** The point `distance` beyond `point` out of `side`. */\nexport function beyond(\n point: Point,\n side: DiagramSide,\n distance: number,\n): Point {\n switch (side) {\n case 'top':\n return { x: point.x, y: point.y - distance };\n case 'bottom':\n return { x: point.x, y: point.y + distance };\n case 'left':\n return { x: point.x - distance, y: point.y };\n case 'right':\n return { x: point.x + distance, y: point.y };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { DiagramDensity } from '../../model/diagram-ir.ts';
|
|
2
1
|
import type { Font } from '../text/font.ts';
|
|
3
2
|
export type LayoutFonts = {
|
|
4
3
|
/** The title of a Card, or of a Box with an icon. */
|
|
@@ -49,10 +48,6 @@ export type LayoutTokens = {
|
|
|
49
48
|
FLAT_RADIUS: number;
|
|
50
49
|
fonts: LayoutFonts;
|
|
51
50
|
};
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
* elements (gaps, channels, group and diagram padding); node content and
|
|
55
|
-
* fonts keep their size, so text never shrinks to fit.
|
|
56
|
-
*/
|
|
57
|
-
export declare function layoutTokens(density?: DiagramDensity): LayoutTokens;
|
|
51
|
+
/** The sizes the engine lays out with. */
|
|
52
|
+
export declare const LAYOUT_TOKENS: LayoutTokens;
|
|
58
53
|
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,WAAW,GAAG;IACxB,qDAAqD;IACrD,KAAK,EAAE,IAAI,CAAC;IACZ,sCAAsC;IACtC,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,IAAI,CAAC;IACd,2CAA2C;IAC3C,QAAQ,EAAE,IAAI,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC;IACZ,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,aAAa,EAAE,YAsC3B,CAAC"}
|
|
@@ -1,108 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
1
|
+
/** The sizes the engine lays out with. */
|
|
2
|
+
export const LAYOUT_TOKENS = {
|
|
3
|
+
PAD_X: 16,
|
|
4
|
+
PAD_Y: 12,
|
|
5
|
+
ICON: 28,
|
|
6
|
+
ICON_GAP: 12,
|
|
7
|
+
GAP: 24,
|
|
8
|
+
CHANNEL: 8,
|
|
9
|
+
STUB: 16,
|
|
10
|
+
LABEL_GAP: 4,
|
|
11
|
+
CONTENT_PAD: 40,
|
|
12
|
+
GROUP_PAD: 12,
|
|
13
|
+
BAND_PAD: 6,
|
|
14
|
+
BULLET_INDENT: 12,
|
|
15
|
+
BLOCK_GAP: 8,
|
|
16
|
+
CAPTION_GAP: 8,
|
|
17
|
+
PORT_SPACING: 24,
|
|
18
|
+
STACK_STEP: {
|
|
19
|
+
x: 12,
|
|
20
|
+
y: 8
|
|
21
|
+
},
|
|
22
|
+
MARKER_ICON: 34,
|
|
23
|
+
CONNECTOR_ICON: 16,
|
|
24
|
+
BADGE_ICON: 22,
|
|
25
|
+
JUNCTION: 16,
|
|
26
|
+
APPLIANCE: {
|
|
27
|
+
w: 112,
|
|
28
|
+
h: 72
|
|
29
|
+
},
|
|
30
|
+
RADIUS: 16,
|
|
31
|
+
FLAT_RADIUS: 4,
|
|
32
|
+
fonts: {
|
|
33
|
+
title: {
|
|
34
|
+
face: 'sans',
|
|
35
|
+
size: 14,
|
|
36
|
+
weight: 600
|
|
37
|
+
},
|
|
38
|
+
body: {
|
|
39
|
+
face: 'sans',
|
|
40
|
+
size: 11,
|
|
41
|
+
weight: 400
|
|
42
|
+
},
|
|
43
|
+
caption: {
|
|
44
|
+
face: 'sans',
|
|
45
|
+
size: 11,
|
|
46
|
+
weight: 500
|
|
47
|
+
},
|
|
48
|
+
boxLabel: {
|
|
49
|
+
face: 'mono',
|
|
50
|
+
size: 12,
|
|
51
|
+
weight: 500
|
|
52
|
+
},
|
|
53
|
+
note: {
|
|
54
|
+
face: 'sans',
|
|
55
|
+
size: 10,
|
|
56
|
+
weight: 600
|
|
57
|
+
},
|
|
58
|
+
marker: {
|
|
59
|
+
face: 'sans',
|
|
60
|
+
size: 11,
|
|
61
|
+
weight: 700
|
|
33
62
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
APPLIANCE: {
|
|
39
|
-
w: 112,
|
|
40
|
-
h: 72
|
|
63
|
+
connector: {
|
|
64
|
+
face: 'sans',
|
|
65
|
+
size: 10,
|
|
66
|
+
weight: 700
|
|
41
67
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
face: 'sans',
|
|
67
|
-
size: 10,
|
|
68
|
-
weight: 600
|
|
69
|
-
},
|
|
70
|
-
marker: {
|
|
71
|
-
face: 'sans',
|
|
72
|
-
size: 11,
|
|
73
|
-
weight: 700
|
|
74
|
-
},
|
|
75
|
-
connector: {
|
|
76
|
-
face: 'sans',
|
|
77
|
-
size: 10,
|
|
78
|
-
weight: 700
|
|
79
|
-
},
|
|
80
|
-
appliance: {
|
|
81
|
-
face: 'sans',
|
|
82
|
-
size: 12,
|
|
83
|
-
weight: 600
|
|
84
|
-
},
|
|
85
|
-
groupLabel: {
|
|
86
|
-
face: 'sans',
|
|
87
|
-
size: 12,
|
|
88
|
-
weight: 600
|
|
89
|
-
},
|
|
90
|
-
edgeLabel: {
|
|
91
|
-
face: 'mono',
|
|
92
|
-
size: 10,
|
|
93
|
-
weight: 400
|
|
94
|
-
},
|
|
95
|
-
badge: {
|
|
96
|
-
face: 'sans',
|
|
97
|
-
size: 10,
|
|
98
|
-
weight: 600
|
|
99
|
-
},
|
|
100
|
-
portLabel: {
|
|
101
|
-
face: 'sans',
|
|
102
|
-
size: 9,
|
|
103
|
-
weight: 600
|
|
104
|
-
}
|
|
68
|
+
appliance: {
|
|
69
|
+
face: 'sans',
|
|
70
|
+
size: 12,
|
|
71
|
+
weight: 600
|
|
72
|
+
},
|
|
73
|
+
groupLabel: {
|
|
74
|
+
face: 'sans',
|
|
75
|
+
size: 12,
|
|
76
|
+
weight: 600
|
|
77
|
+
},
|
|
78
|
+
edgeLabel: {
|
|
79
|
+
face: 'mono',
|
|
80
|
+
size: 10,
|
|
81
|
+
weight: 400
|
|
82
|
+
},
|
|
83
|
+
badge: {
|
|
84
|
+
face: 'sans',
|
|
85
|
+
size: 10,
|
|
86
|
+
weight: 600
|
|
87
|
+
},
|
|
88
|
+
portLabel: {
|
|
89
|
+
face: 'sans',
|
|
90
|
+
size: 9,
|
|
91
|
+
weight: 600
|
|
105
92
|
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
108
95
|
//# sourceMappingURL=tokens.js.map
|