@weasel-js/diagram 1.11.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-43LDZ6L4.js → chunk-2SYY4W3B.js} +18 -16
- package/dist/chunk-2SYY4W3B.js.map +1 -0
- package/dist/{chunk-QKSWZEJH.js → chunk-5GIP2LA6.js} +3 -3
- package/dist/{chunk-QKSWZEJH.js.map → chunk-5GIP2LA6.js.map} +1 -1
- package/dist/{chunk-CI3I3I6T.js → chunk-DYDX6EJC.js} +144 -91
- package/dist/chunk-DYDX6EJC.js.map +1 -0
- package/dist/{chunk-T6DQT553.js → chunk-GA4BX7SH.js} +3 -3
- package/dist/{chunk-T6DQT553.js.map → chunk-GA4BX7SH.js.map} +1 -1
- package/dist/{chunk-IM6DHWZO.js → chunk-R2XB6D32.js} +45 -20
- package/dist/chunk-R2XB6D32.js.map +1 -0
- package/dist/{dataTypes-B-iEwKZp.d.ts → dataTypes-DHdkzCL8.d.ts} +11 -6
- package/dist/effect-audio.d.ts +2 -1
- package/dist/effect-audio.js +12 -6
- package/dist/effect-audio.js.map +1 -1
- package/dist/effect.d.ts +2 -2
- package/dist/effect.js +40 -14
- package/dist/effect.js.map +1 -1
- package/dist/index.d.ts +24 -18
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +2 -2
- package/dist/{layout.entry-CH9gc0CY.d.ts → layout.entry-B-jJMc50.d.ts} +108 -3
- package/dist/layout.js +2 -2
- package/dist/{types-BbHunLXm.d.ts → types-M_ccNAlk.d.ts} +151 -252
- package/package.json +9 -9
- package/dist/chunk-43LDZ6L4.js.map +0 -1
- package/dist/chunk-CI3I3I6T.js.map +0 -1
- package/dist/chunk-IM6DHWZO.js.map +0 -1
package/dist/layout.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { t as BodyFloor,
|
|
2
|
-
export { e as AVOID_DEFAULTS, f as AvoidEdge, g as AvoidEnd, A as AvoidInput, h as AvoidLabel, i as AvoidObstacle, b as AvoidOptions, j as AvoidPort, a as AvoidRouter, c as AvoidRoutes, k as AvoidUpdateOptions, C as COMPASS, D as DEFAULT_PORTS,
|
|
1
|
+
export { t as BodyFloor, B as BodySpec, m as Bounds, w as DEFAULT_HOP_SIZE, x as DEFAULT_NODE_GAP, y as DEFAULT_RANK_GAP, c as DiagramLabel, f as DiagramNode, E as EdgeHop, H as EdgeLabelRoom, G as Graph, I as GraphEdge, J as GraphGroup, K as GraphNode, Q as HOPS_DOC_KEY, T as HopsDocValue, l as LabelSpot, V as LayoutAxes, q as LayoutDirection, d as LayoutFn, e as LayoutOptions, r as LayoutPlan, p as LayoutPlanner, L as LayoutPorts, n as LayoutResult, M as MeasureRowText, O as Outline, g as Port, P as PortAnchor, W as PortSite, b as PortSpec, a as Row, X as RowBox, Y as RowPort, Z as RowPortBox, R as RowTextStyle, _ as Slot, $ as anchorOffset, a0 as axesFor, a2 as bodyOutline, a4 as boxForContent, a6 as canvasMeasure, a7 as contentBox, ay as extent, ae as graphOrder, ai as layoutBody, aj as layoutRowPorts, ak as measureBody, al as outlinePath, am as packAcross, ao as pinnedSet, ap as planOf, aq as plannerPlan, as as seededOrder, at as settle, au as sizeToBody, aw as translated, ax as untilSettled } from './types-M_ccNAlk.js';
|
|
2
|
+
export { e as AVOID_DEFAULTS, f as AvoidEdge, g as AvoidEnd, A as AvoidInput, h as AvoidLabel, i as AvoidObstacle, b as AvoidOptions, j as AvoidPort, a as AvoidRouter, c as AvoidRoutes, k as AvoidUpdateOptions, B as BodyNodeSpec, l as BuildBodyOptions, C as COMPASS, D as DEFAULT_PORTS, m as ForceBody, F as ForceOptions, n as ForceRelaxation, L as LabelPlacements, p as LayeredPlan, q as PORT_LABEL_GAP, r as PerimeterPortLabelBox, s as PlaceLabel, t as PlaceLabelsInput, d as PlaceLabelsOptions, u as PlaceRoute, P as PortsOptions, R as RowNodeData, w as backEdges, x as buildBody, y as chain, z as createAvoidRouter, E as edgeHops, G as footprintNode, H as force, I as forceRelaxation, J as forestOf, K as labelCenter, M as layered, N as layeredPlan, O as marginOf, Q as outlinePolyline, S as placeLabels, T as portLabelBox, V as portOf, W as portSitesOf, X as portsOf, Y as portsOnOutline, Z as ranksByLength, _ as ranksOf, $ as rayHit, a0 as routeHolds, a1 as tree } from './layout.entry-B-jJMc50.js';
|
|
3
3
|
import '@weasel-js/core/math';
|
|
4
4
|
import '@weasel-js/geom';
|
|
5
5
|
import '@weasel-js/simulation';
|
|
@@ -1,6 +1,111 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { m as Bounds, b as PortSpec, g as Port, N as GroupInset, f as DiagramNode, M as MeasureRowText, X as RowBox, Z as RowPortBox, B as BodySpec, K as GraphNode, i as DiagramNodeReader, h as DiagramNodeLike, c as DiagramLabel, E as EdgeHop, l as LabelSpot, e as LayoutOptions, G as Graph, n as LayoutResult, d as LayoutFn, L as LayoutPorts, O as Outline } from './types-M_ccNAlk.js';
|
|
2
|
+
import { Vec2, PoseDescriptor, Path } from '@weasel-js/core/math';
|
|
2
3
|
import { SimulationNode, createSimulation } from '@weasel-js/simulation';
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Perimeter port labels: where the text naming a port is drawn, and how far
|
|
7
|
+
* past its node that reaches.
|
|
8
|
+
*
|
|
9
|
+
* A label sits outside the node, on the port's own face, and to one side of
|
|
10
|
+
* the line the port's wire leaves along, so the wire does not run through it.
|
|
11
|
+
* A port inside a row draws its label inside the box instead; that is a
|
|
12
|
+
* `ports` row's job, not this module's.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Between a port and the near sides of its label, in world units. */
|
|
16
|
+
declare const PORT_LABEL_GAP = 4;
|
|
17
|
+
/**
|
|
18
|
+
* Where a label `size` big goes for a port at `point` facing `normal`.
|
|
19
|
+
*
|
|
20
|
+
* A port on a left or right face gets its label outside that face, above its
|
|
21
|
+
* wire; one on a top or bottom face, outside that face, right of its wire; a
|
|
22
|
+
* corner port, off the corner. A port with no direction gets it centered
|
|
23
|
+
* above.
|
|
24
|
+
*/
|
|
25
|
+
declare function portLabelBox(port: {
|
|
26
|
+
point: Vec2;
|
|
27
|
+
normal: Vec2 | null;
|
|
28
|
+
}, size: {
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
}, gap?: number): Bounds;
|
|
32
|
+
/** Where a built body's perimeter port label sits, as `buildBody`'s
|
|
33
|
+
* `portLabel` is handed it. */
|
|
34
|
+
interface PerimeterPortLabelBox extends Bounds {
|
|
35
|
+
port: PortSpec;
|
|
36
|
+
side: 'outside';
|
|
37
|
+
}
|
|
38
|
+
/** A labeled port, resolved, and the box its label is drawn in. */
|
|
39
|
+
interface PortLabelPlacement {
|
|
40
|
+
port: Port & {
|
|
41
|
+
label: string;
|
|
42
|
+
};
|
|
43
|
+
box: Bounds;
|
|
44
|
+
}
|
|
45
|
+
/** Every labeled port of `trait` resolved against `bounds`, with its label's
|
|
46
|
+
* box. `size` measures one label. */
|
|
47
|
+
declare function portLabelsOf(trait: DiagramNode, bounds: Bounds, size: (text: string) => {
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
}): PortLabelPlacement[];
|
|
51
|
+
/** How far `boxes` reach past `bounds` on each side; `undefined` for none. */
|
|
52
|
+
declare function marginOf(bounds: Bounds, boxes: readonly Bounds[]): GroupInset | undefined;
|
|
53
|
+
|
|
54
|
+
/** What {@link buildBody} emits: the `AddNodeSpec` fields it fills in. Named
|
|
55
|
+
* structurally rather than imported so a consumer whose scene is typed
|
|
56
|
+
* differently can still spread one. */
|
|
57
|
+
interface BodyNodeSpec<TData, TLayer extends string, TPose> {
|
|
58
|
+
kind: 'container' | 'leaf';
|
|
59
|
+
layer: TLayer;
|
|
60
|
+
pose: TPose;
|
|
61
|
+
data: TData;
|
|
62
|
+
id?: string;
|
|
63
|
+
parent?: string;
|
|
64
|
+
/** Set on the container to {@link clipNothing}: a perimeter port label sits
|
|
65
|
+
* outside the body, and a container clips its children to its outline. */
|
|
66
|
+
clipFromPose?: () => null;
|
|
67
|
+
/** Set `false` on every leaf the builder emits: the innermost hit wins, so a
|
|
68
|
+
* row that answers a press is a body that cannot be dragged. */
|
|
69
|
+
pickable?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** What a built body's rows are handed to, one call per row.
|
|
72
|
+
*
|
|
73
|
+
* `text` is the row's content already formatted — a `label`'s own text, or a
|
|
74
|
+
* `field`'s `"label: value"` — so the common case needs no discrimination.
|
|
75
|
+
* Return `null` for a row the consumer paints itself; `ports` and `slot` rows
|
|
76
|
+
* arrive with `text` empty and are the usual ones to decline. */
|
|
77
|
+
type RowNodeData<TData> = (text: string, box: RowBox) => TData | null;
|
|
78
|
+
/** Options for {@link buildBody}: the layer and data of each node it emits.
|
|
79
|
+
* Without `measure`, rows are sized from a fallback line height rather than
|
|
80
|
+
* their text. */
|
|
81
|
+
interface BuildBodyOptions<TData, TLayer extends string, TPose extends Bounds> {
|
|
82
|
+
layer: TLayer;
|
|
83
|
+
/** The container's id. Edges name it, so pass one for anything an edge or a
|
|
84
|
+
* layout `pin` will refer to. */
|
|
85
|
+
id?: string;
|
|
86
|
+
measure?: MeasureRowText;
|
|
87
|
+
/** The container's own data, given the trait the builder computed and the
|
|
88
|
+
* pose it was computed against. */
|
|
89
|
+
body: (trait: DiagramNode, pose: TPose) => TData;
|
|
90
|
+
/** One row's data, or `null` to leave that row undrawn. */
|
|
91
|
+
row: RowNodeData<TData>;
|
|
92
|
+
/** One port's label — a row port's or a perimeter port's — or `null` to
|
|
93
|
+
* leave it undrawn. Ports with no label are never offered. Omit to draw none. */
|
|
94
|
+
portLabel?: (text: string, box: RowPortBox | PerimeterPortLabelBox) => TData | null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The scene nodes a built body is: one container carrying the trait, and one
|
|
98
|
+
* leaf per row that wants drawing.
|
|
99
|
+
*
|
|
100
|
+
* Rows are ordinary scene nodes rather than something this package paints, so
|
|
101
|
+
* the kit's own text painter draws them and text editing, styling, and
|
|
102
|
+
* selection work on them unchanged. The returned pose is `at` grown to fit the
|
|
103
|
+
* body, never shrunk.
|
|
104
|
+
*/
|
|
105
|
+
declare function buildBody<TData, TLayer extends string, TPose extends Bounds>(spec: BodySpec, at: TPose, opts: BuildBodyOptions<TData, TLayer, TPose>): {
|
|
106
|
+
pose: TPose;
|
|
107
|
+
specs: BodyNodeSpec<TData, TLayer, TPose>[];
|
|
108
|
+
};
|
|
4
109
|
|
|
5
110
|
/** `node` as layout sees it: bounds grown by its margin, ports where they were. */
|
|
6
111
|
declare function footprintNode(node: GraphNode): GraphNode;
|
|
@@ -509,4 +614,4 @@ declare function rayHit(poly: readonly number[], center: {
|
|
|
509
614
|
*/
|
|
510
615
|
declare function portsOnOutline(ports: readonly Port[], outline: Outline, bounds: Bounds): Port[];
|
|
511
616
|
|
|
512
|
-
export { type AvoidInput as A,
|
|
617
|
+
export { rayHit as $, type AvoidInput as A, type BodyNodeSpec as B, COMPASS as C, DEFAULT_PORTS as D, edgeHops as E, type ForceOptions as F, footprintNode as G, force as H, forceRelaxation as I, forestOf as J, labelCenter as K, type LabelPlacements as L, layered as M, layeredPlan as N, marginOf as O, type PortsOptions as P, outlinePolyline as Q, type RowNodeData as R, placeLabels as S, portLabelBox as T, portLabelsOf as U, portOf as V, portSitesOf as W, portsOf as X, portsOnOutline as Y, ranksByLength as Z, ranksOf as _, type AvoidRouter as a, routeHolds as a0, tree as a1, type AvoidOptions as b, type AvoidRoutes as c, type PlaceLabelsOptions as d, AVOID_DEFAULTS as e, type AvoidEdge as f, type AvoidEnd as g, type AvoidLabel as h, type AvoidObstacle as i, type AvoidPort as j, type AvoidUpdateOptions as k, type BuildBodyOptions as l, type ForceBody as m, type ForceRelaxation as n, type Forest as o, type LayeredPlan as p, PORT_LABEL_GAP as q, type PerimeterPortLabelBox as r, type PlaceLabel as s, type PlaceLabelsInput as t, type PlaceRoute as u, type PortLabelPlacement as v, backEdges as w, buildBody as x, chain as y, createAvoidRouter as z };
|
package/dist/layout.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './chunk-WDIE35AK.js';
|
|
2
|
-
export { AVOID_DEFAULTS, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, createAvoidRouter, edgeHops, placeLabels } from './chunk-
|
|
3
|
-
export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, PORT_LABEL_GAP, anchorOffset, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, chain, contentBox, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, labelCenter, layered, layeredPlan, layoutBody, layoutRowPorts, marginOf, measureBody, outlinePath, outlinePolyline, packAcross, pinnedSet, planOf, plannerPlan, portLabelBox, portOf, portSitesOf, portsOf, portsOnOutline, ranksByLength, ranksOf, rayHit, routeHolds, seededOrder, settle, sizeToBody, translated, tree, untilSettled } from './chunk-
|
|
2
|
+
export { AVOID_DEFAULTS, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, createAvoidRouter, edgeHops, placeLabels } from './chunk-GA4BX7SH.js';
|
|
3
|
+
export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, PORT_LABEL_GAP, anchorOffset, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, chain, contentBox, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, labelCenter, layered, layeredPlan, layoutBody, layoutRowPorts, marginOf, measureBody, outlinePath, outlinePolyline, packAcross, pinnedSet, planOf, plannerPlan, portLabelBox, portOf, portSitesOf, portsOf, portsOnOutline, ranksByLength, ranksOf, rayHit, routeHolds, seededOrder, settle, sizeToBody, translated, tree, untilSettled } from './chunk-R2XB6D32.js';
|
|
4
4
|
//# sourceMappingURL=layout.js.map
|
|
5
5
|
//# sourceMappingURL=layout.js.map
|
|
@@ -98,167 +98,6 @@ declare function diagramLabelOf(node: {
|
|
|
98
98
|
data: unknown;
|
|
99
99
|
}): DiagramLabel | null;
|
|
100
100
|
|
|
101
|
-
/**
|
|
102
|
-
* The container trait: what makes a core `ContainerNode` a diagram container,
|
|
103
|
-
* a pool, or one of a pool's lanes, and where its header is.
|
|
104
|
-
*
|
|
105
|
-
* A container's title is a text child in its header, named
|
|
106
|
-
* `<container id>/title`. The layouts find it by that name, because a layout
|
|
107
|
-
* strategy sees only ids and poses.
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
/** Which kind of region a container is. */
|
|
111
|
-
type ContainerRole = 'container' | 'pool' | 'lane';
|
|
112
|
-
/** The strip a container's title sits in, along one side. */
|
|
113
|
-
interface ContainerHeader {
|
|
114
|
-
side: 'top' | 'left';
|
|
115
|
-
/** Its depth into the container, in world units. */
|
|
116
|
-
size: number;
|
|
117
|
-
}
|
|
118
|
-
/** The container half of a diagram node's trait, under `data.diagram.container`. */
|
|
119
|
-
interface DiagramContainer {
|
|
120
|
-
role: ContainerRole;
|
|
121
|
-
header?: ContainerHeader;
|
|
122
|
-
/** Its box is fitted to its members each time the diagram is built from data
|
|
123
|
-
* (`DataContainer` with no `box`), so a move that carries it along is no edit of its own. */
|
|
124
|
-
fitted?: true;
|
|
125
|
-
}
|
|
126
|
-
type Box = {
|
|
127
|
-
x: number;
|
|
128
|
-
y: number;
|
|
129
|
-
width: number;
|
|
130
|
-
height: number;
|
|
131
|
-
};
|
|
132
|
-
/** The container trait on a node's data, or `null`. */
|
|
133
|
-
declare function diagramContainerOf(node: {
|
|
134
|
-
data: unknown;
|
|
135
|
-
}): DiagramContainer | null;
|
|
136
|
-
/** The id of a container's title node. */
|
|
137
|
-
declare const titleIdOf: (containerId: string) => string;
|
|
138
|
-
/** The header strip of a container at `bounds`; null with no header. */
|
|
139
|
-
declare function headerBox(bounds: Box, header: ContainerHeader | undefined): Box | null;
|
|
140
|
-
/** What a container at `bounds` holds members in: everything past its header. */
|
|
141
|
-
declare function bodyBox(bounds: Box, header: ContainerHeader | undefined): Box;
|
|
142
|
-
|
|
143
|
-
/** A color on a shape or connector that the author can set by hand, and a theme then leaves alone.
|
|
144
|
-
* On a connector, `text` is its label's color. */
|
|
145
|
-
type StyleField = 'fill' | 'stroke' | 'text';
|
|
146
|
-
/** A part of a shape's or connector's text face the author can set by hand, which a theme then
|
|
147
|
-
* leaves alone. Kept apart from {@link StyleField}, so choosing a role, which hands back the
|
|
148
|
-
* colors, keeps it. */
|
|
149
|
-
type FontField = 'size';
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Where a port sits on its node, in **normalized bounds coordinates**:
|
|
153
|
-
* `(0, 0)` is the top-left corner of the node's AABB and `(1, 1)` the
|
|
154
|
-
* bottom-right. `COMPASS` names the eight positions almost everything wants.
|
|
155
|
-
*
|
|
156
|
-
* Normalized rather than absolute because a node's size is authored data that
|
|
157
|
-
* resize, align and distribute all write — a port fixed at an offset would
|
|
158
|
-
* drift off the shape the first time one of them ran.
|
|
159
|
-
*/
|
|
160
|
-
interface PortAnchor {
|
|
161
|
-
u: number;
|
|
162
|
-
v: number;
|
|
163
|
-
}
|
|
164
|
-
/** One more place a port may sit, and optionally the direction it faces there. */
|
|
165
|
-
interface PortSite extends PortAnchor {
|
|
166
|
-
normal?: Vec2 | null;
|
|
167
|
-
}
|
|
168
|
-
/** One attachment point declared on a node. */
|
|
169
|
-
interface PortSpec {
|
|
170
|
-
/** Unique within the node. Edges name this, so it outlives a re-layout. */
|
|
171
|
-
id: string;
|
|
172
|
-
at: PortAnchor;
|
|
173
|
-
/** Other places the port may sit. An edge meeting the port takes whichever
|
|
174
|
-
* of `at` and these faces the edge's next point most directly, so a
|
|
175
|
-
* diamond's second exit can leave by its top or its bottom vertex, toward
|
|
176
|
-
* wherever its wire goes. Everything else that shows a port where it is —
|
|
177
|
-
* the connect affordance, `portsOf` — reads `at`. A site faces away from
|
|
178
|
-
* the node's center unless it gives a `normal` of its own. */
|
|
179
|
-
sites?: readonly PortSite[];
|
|
180
|
-
/** Consulted by a connect gesture's validity predicate. Uninterpreted here. */
|
|
181
|
-
type?: string;
|
|
182
|
-
/** What the port is for, drawn beside it outside the node: beside the
|
|
183
|
-
* wire rather than across it. A built body draws it and keeps it in its
|
|
184
|
-
* `margin`; any other participant gets it on its resolved `Port`. */
|
|
185
|
-
label?: string;
|
|
186
|
-
/** The direction an edge leaves along, overriding the one the anchor
|
|
187
|
-
* implies. `null` means "no preferred direction" — a router goes straight
|
|
188
|
-
* at it. Applies at `at`; each of `sites` says its own. */
|
|
189
|
-
normal?: Vec2 | null;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* The trait that makes an existing scene node a diagram participant.
|
|
193
|
-
*
|
|
194
|
-
* Attached to a node's `data`, not a node kind the plugin mints: a text block,
|
|
195
|
-
* an image, a path, a group or a plain rect all take part by carrying this,
|
|
196
|
-
* and nothing has to be authored through this package to be connectable.
|
|
197
|
-
*/
|
|
198
|
-
interface DiagramNode {
|
|
199
|
-
/** Defaults to {@link DEFAULT_PORTS} — the four edge midpoints of the
|
|
200
|
-
* node's own bounds, which every node has. */
|
|
201
|
-
ports?: readonly PortSpec[];
|
|
202
|
-
/** Layout must not move this node. */
|
|
203
|
-
pinned?: boolean;
|
|
204
|
-
/** What the node is *drawn* as. Present on a built body; absent on a
|
|
205
|
-
* participant that already had a look of its own — a text block, an image,
|
|
206
|
-
* a path — which keeps whatever painter it already matched. */
|
|
207
|
-
outline?: Outline;
|
|
208
|
-
/** Present on a group's box: a node drawn around the participants it
|
|
209
|
-
* depends on, which layout keeps together and leaves room for. The box
|
|
210
|
-
* itself is never laid out — it derives its pose from its members — but an
|
|
211
|
-
* edge can attach to it like any participant. */
|
|
212
|
-
group?: DiagramGroup;
|
|
213
|
-
/** Present on a container, a pool, or a lane: a `ContainerNode` holding
|
|
214
|
-
* members (`containers/trait.ts`). */
|
|
215
|
-
container?: DiagramContainer;
|
|
216
|
-
/** How far past its bounds something drawn with it reaches, on each side —
|
|
217
|
-
* a built body's port labels. Layout keeps neighbors that far off too. */
|
|
218
|
-
margin?: GroupInset;
|
|
219
|
-
/** The theme role it is drawn in. Unset, the theme's default role. */
|
|
220
|
-
style?: string;
|
|
221
|
-
/** The colors the author set by hand, which a theme leaves as they are. */
|
|
222
|
-
ownStyle?: readonly StyleField[];
|
|
223
|
-
/** The parts of its text face the author set by hand, which a theme leaves as they are. */
|
|
224
|
-
ownFont?: readonly FontField[];
|
|
225
|
-
/** On a built body whose rows are all text: how it stacks them, so it can be laid out again when
|
|
226
|
-
* their text changes size. Each row's text node carries its place as `bodyRow`. */
|
|
227
|
-
body?: BodyLayout;
|
|
228
|
-
}
|
|
229
|
-
/** How a built body stacks its text rows: the `BodySpec` fields its layout reads, and how many rows. */
|
|
230
|
-
interface BodyLayout {
|
|
231
|
-
padding: number;
|
|
232
|
-
gap: number;
|
|
233
|
-
verticalAlign: 'top' | 'center' | 'bottom';
|
|
234
|
-
rows: number;
|
|
235
|
-
}
|
|
236
|
-
/** The group half of a {@link DiagramNode}. */
|
|
237
|
-
interface DiagramGroup {
|
|
238
|
-
/** Room the box keeps around its members, in world units: one number for
|
|
239
|
-
* every side, or per side. Default 12 on each. */
|
|
240
|
-
inset?: number | Partial<GroupInset>;
|
|
241
|
-
/** The narrowest the box may be, in world units, as room for its label.
|
|
242
|
-
* A box its members leave narrower grows evenly on both sides. */
|
|
243
|
-
minWidth?: number;
|
|
244
|
-
/** The axis its members can be dragged along to change their order. */
|
|
245
|
-
reorder?: 'x' | 'y';
|
|
246
|
-
}
|
|
247
|
-
/** A port resolved against a node's current pose: where it is in world
|
|
248
|
-
* coordinates, and which way an edge leaves it. */
|
|
249
|
-
interface Port {
|
|
250
|
-
id: string;
|
|
251
|
-
/** The node this port belongs to. */
|
|
252
|
-
nodeId: string;
|
|
253
|
-
/** World point an edge attaches to. */
|
|
254
|
-
point: Vec2;
|
|
255
|
-
/** Unit vector pointing away from the node, or `null` when the port
|
|
256
|
-
* declared no direction. Rotated with the node. */
|
|
257
|
-
normal: Vec2 | null;
|
|
258
|
-
type?: string;
|
|
259
|
-
label?: string;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
101
|
/**
|
|
263
102
|
* Reading the `DiagramNode` trait off a scene node.
|
|
264
103
|
*
|
|
@@ -655,53 +494,165 @@ declare function packClusters(graph: Graph, rows: readonly (readonly GraphNode[]
|
|
|
655
494
|
declare function expandGroupEdges(edges: readonly GraphEdge[], groups: readonly GraphGroup[]): GraphEdge[];
|
|
656
495
|
|
|
657
496
|
/**
|
|
658
|
-
*
|
|
659
|
-
*
|
|
497
|
+
* The container trait: what makes a core `ContainerNode` a diagram container,
|
|
498
|
+
* a pool, or one of a pool's lanes, and where its header is.
|
|
660
499
|
*
|
|
661
|
-
* A
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
* `ports` row's job, not this module's.
|
|
500
|
+
* A container's title is a text child in its header, named
|
|
501
|
+
* `<container id>/title`. The layouts find it by that name, because a layout
|
|
502
|
+
* strategy sees only ids and poses.
|
|
665
503
|
*/
|
|
666
504
|
|
|
667
|
-
/**
|
|
668
|
-
|
|
505
|
+
/** Which kind of region a container is. */
|
|
506
|
+
type ContainerRole = 'container' | 'pool' | 'lane';
|
|
507
|
+
/** The strip a container's title sits in, along one side. */
|
|
508
|
+
interface ContainerHeader {
|
|
509
|
+
side: 'top' | 'left';
|
|
510
|
+
/** Its depth into the container, in world units. */
|
|
511
|
+
size: number;
|
|
512
|
+
}
|
|
513
|
+
/** The container half of a diagram node's trait, under `data.diagram.container`. */
|
|
514
|
+
interface DiagramContainer {
|
|
515
|
+
role: ContainerRole;
|
|
516
|
+
header?: ContainerHeader;
|
|
517
|
+
/** Its box is fitted to its members each time the diagram is built from data
|
|
518
|
+
* (`DataContainer` with no `box`), so a move that carries it along is no edit of its own. */
|
|
519
|
+
fitted?: true;
|
|
520
|
+
}
|
|
521
|
+
type Box = {
|
|
522
|
+
x: number;
|
|
523
|
+
y: number;
|
|
524
|
+
width: number;
|
|
525
|
+
height: number;
|
|
526
|
+
};
|
|
527
|
+
/** The container trait on a node's data, or `null`. */
|
|
528
|
+
declare function diagramContainerOf(node: {
|
|
529
|
+
data: unknown;
|
|
530
|
+
}): DiagramContainer | null;
|
|
531
|
+
/** The id of a container's title node. */
|
|
532
|
+
declare const titleIdOf: (containerId: string) => string;
|
|
533
|
+
/** The header strip of a container at `bounds`; null with no header. */
|
|
534
|
+
declare function headerBox(bounds: Box, header: ContainerHeader | undefined): Box | null;
|
|
535
|
+
/** What a container at `bounds` holds members in: everything past its header. */
|
|
536
|
+
declare function bodyBox(bounds: Box, header: ContainerHeader | undefined): Box;
|
|
537
|
+
|
|
538
|
+
/** A color on a shape or connector that the author can set by hand, and a theme then leaves alone.
|
|
539
|
+
* On a connector, `text` is its label's color. */
|
|
540
|
+
type StyleField = 'fill' | 'stroke' | 'text';
|
|
541
|
+
/** A part of a shape's or connector's text face the author can set by hand, which a theme then
|
|
542
|
+
* leaves alone. Kept apart from {@link StyleField}, so choosing a role, which hands back the
|
|
543
|
+
* colors, keeps it. */
|
|
544
|
+
type FontField = 'size';
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Where a port sits on its node, in **normalized bounds coordinates**:
|
|
548
|
+
* `(0, 0)` is the top-left corner of the node's AABB and `(1, 1)` the
|
|
549
|
+
* bottom-right. `COMPASS` names the eight positions almost everything wants.
|
|
550
|
+
*
|
|
551
|
+
* Normalized rather than absolute because a node's size is authored data that
|
|
552
|
+
* resize, align and distribute all write — a port fixed at an offset would
|
|
553
|
+
* drift off the shape the first time one of them ran.
|
|
554
|
+
*/
|
|
555
|
+
interface PortAnchor {
|
|
556
|
+
u: number;
|
|
557
|
+
v: number;
|
|
558
|
+
}
|
|
559
|
+
/** One more place a port may sit, and optionally the direction it faces there. */
|
|
560
|
+
interface PortSite extends PortAnchor {
|
|
561
|
+
normal?: Vec2 | null;
|
|
562
|
+
}
|
|
563
|
+
/** One attachment point declared on a node. */
|
|
564
|
+
interface PortSpec {
|
|
565
|
+
/** Unique within the node. Edges name this, so it outlives a re-layout. */
|
|
566
|
+
id: string;
|
|
567
|
+
at: PortAnchor;
|
|
568
|
+
/** Other places the port may sit. An edge meeting the port takes whichever
|
|
569
|
+
* of `at` and these faces the edge's next point most directly, so a
|
|
570
|
+
* diamond's second exit can leave by its top or its bottom vertex, toward
|
|
571
|
+
* wherever its wire goes. Everything else that shows a port where it is —
|
|
572
|
+
* the connect affordance, `portsOf` — reads `at`. A site faces away from
|
|
573
|
+
* the node's center unless it gives a `normal` of its own. */
|
|
574
|
+
sites?: readonly PortSite[];
|
|
575
|
+
/** Consulted by a connect gesture's validity predicate. Uninterpreted here. */
|
|
576
|
+
type?: string;
|
|
577
|
+
/** What the port is for, drawn beside it outside the node: beside the
|
|
578
|
+
* wire rather than across it. A built body draws it and keeps it in its
|
|
579
|
+
* `margin`; any other participant gets it on its resolved `Port`. */
|
|
580
|
+
label?: string;
|
|
581
|
+
/** The direction an edge leaves along, overriding the one the anchor
|
|
582
|
+
* implies. `null` means "no preferred direction" — a router goes straight
|
|
583
|
+
* at it. Applies at `at`; each of `sites` says its own. */
|
|
584
|
+
normal?: Vec2 | null;
|
|
585
|
+
}
|
|
669
586
|
/**
|
|
670
|
-
*
|
|
587
|
+
* The trait that makes an existing scene node a diagram participant.
|
|
671
588
|
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
* above.
|
|
589
|
+
* Attached to a node's `data`, not a node kind the plugin mints: a text block,
|
|
590
|
+
* an image, a path, a group or a plain rect all take part by carrying this,
|
|
591
|
+
* and nothing has to be authored through this package to be connectable.
|
|
676
592
|
*/
|
|
677
|
-
|
|
593
|
+
interface DiagramNode {
|
|
594
|
+
/** Defaults to {@link DEFAULT_PORTS} — the four edge midpoints of the
|
|
595
|
+
* node's own bounds, which every node has. */
|
|
596
|
+
ports?: readonly PortSpec[];
|
|
597
|
+
/** Layout must not move this node. */
|
|
598
|
+
pinned?: boolean;
|
|
599
|
+
/** What the node is *drawn* as. Present on a built body; absent on a
|
|
600
|
+
* participant that already had a look of its own — a text block, an image,
|
|
601
|
+
* a path — which keeps whatever painter it already matched. */
|
|
602
|
+
outline?: Outline;
|
|
603
|
+
/** Present on a group's box: a node drawn around the participants it
|
|
604
|
+
* depends on, which layout keeps together and leaves room for. The box
|
|
605
|
+
* itself is never laid out — it derives its pose from its members — but an
|
|
606
|
+
* edge can attach to it like any participant. */
|
|
607
|
+
group?: DiagramGroup;
|
|
608
|
+
/** Present on a container, a pool, or a lane: a `ContainerNode` holding
|
|
609
|
+
* members (`containers/trait.ts`). */
|
|
610
|
+
container?: DiagramContainer;
|
|
611
|
+
/** How far past its bounds something drawn with it reaches, on each side —
|
|
612
|
+
* a built body's port labels. Layout keeps neighbors that far off too. */
|
|
613
|
+
margin?: GroupInset;
|
|
614
|
+
/** The theme role it is drawn in. Unset, the theme's default role. */
|
|
615
|
+
style?: string;
|
|
616
|
+
/** The colors the author set by hand, which a theme leaves as they are. */
|
|
617
|
+
ownStyle?: readonly StyleField[];
|
|
618
|
+
/** The parts of its text face the author set by hand, which a theme leaves as they are. */
|
|
619
|
+
ownFont?: readonly FontField[];
|
|
620
|
+
/** On a built body whose rows are all text: how it stacks them, so it can be laid out again when
|
|
621
|
+
* their text changes size. Each row's text node carries its place as `bodyRow`. */
|
|
622
|
+
body?: BodyLayout;
|
|
623
|
+
}
|
|
624
|
+
/** How a built body stacks its text rows: the `BodySpec` fields its layout reads, and how many rows. */
|
|
625
|
+
interface BodyLayout {
|
|
626
|
+
padding: number;
|
|
627
|
+
gap: number;
|
|
628
|
+
verticalAlign: 'top' | 'center' | 'bottom';
|
|
629
|
+
rows: number;
|
|
630
|
+
}
|
|
631
|
+
/** The group half of a {@link DiagramNode}. */
|
|
632
|
+
interface DiagramGroup {
|
|
633
|
+
/** Room the box keeps around its members, in world units: one number for
|
|
634
|
+
* every side, or per side. Default 12 on each. */
|
|
635
|
+
inset?: number | Partial<GroupInset>;
|
|
636
|
+
/** The narrowest the box may be, in world units, as room for its label.
|
|
637
|
+
* A box its members leave narrower grows evenly on both sides. */
|
|
638
|
+
minWidth?: number;
|
|
639
|
+
/** The axis its members can be dragged along to change their order. */
|
|
640
|
+
reorder?: 'x' | 'y';
|
|
641
|
+
}
|
|
642
|
+
/** A port resolved against a node's current pose: where it is in world
|
|
643
|
+
* coordinates, and which way an edge leaves it. */
|
|
644
|
+
interface Port {
|
|
645
|
+
id: string;
|
|
646
|
+
/** The node this port belongs to. */
|
|
647
|
+
nodeId: string;
|
|
648
|
+
/** World point an edge attaches to. */
|
|
678
649
|
point: Vec2;
|
|
650
|
+
/** Unit vector pointing away from the node, or `null` when the port
|
|
651
|
+
* declared no direction. Rotated with the node. */
|
|
679
652
|
normal: Vec2 | null;
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
height: number;
|
|
683
|
-
}, gap?: number): Bounds;
|
|
684
|
-
/** Where a built body's perimeter port label sits, as `buildBody`'s
|
|
685
|
-
* `portLabel` is handed it. */
|
|
686
|
-
interface PerimeterPortLabelBox extends Bounds {
|
|
687
|
-
port: PortSpec;
|
|
688
|
-
side: 'outside';
|
|
689
|
-
}
|
|
690
|
-
/** A labeled port, resolved, and the box its label is drawn in. */
|
|
691
|
-
interface PortLabelPlacement {
|
|
692
|
-
port: Port & {
|
|
693
|
-
label: string;
|
|
694
|
-
};
|
|
695
|
-
box: Bounds;
|
|
653
|
+
type?: string;
|
|
654
|
+
label?: string;
|
|
696
655
|
}
|
|
697
|
-
/** Every labeled port of `trait` resolved against `bounds`, with its label's
|
|
698
|
-
* box. `size` measures one label. */
|
|
699
|
-
declare function portLabelsOf(trait: DiagramNode, bounds: Bounds, size: (text: string) => {
|
|
700
|
-
width: number;
|
|
701
|
-
height: number;
|
|
702
|
-
}): PortLabelPlacement[];
|
|
703
|
-
/** How far `boxes` reach past `bounds` on each side; `undefined` for none. */
|
|
704
|
-
declare function marginOf(bounds: Bounds, boxes: readonly Bounds[]): GroupInset | undefined;
|
|
705
656
|
|
|
706
657
|
/** One line of body content. */
|
|
707
658
|
type Row =
|
|
@@ -774,20 +725,6 @@ interface BodySpec {
|
|
|
774
725
|
/** Perimeter port labels by id, drawn outside the box; over a port's own `label`. */
|
|
775
726
|
portLabels?: Readonly<Record<string, string>>;
|
|
776
727
|
}
|
|
777
|
-
/** What {@link buildBody} emits: the `AddNodeSpec` fields it fills in. Named
|
|
778
|
-
* structurally rather than imported so a consumer whose scene is typed
|
|
779
|
-
* differently can still spread one. */
|
|
780
|
-
interface BodyNodeSpec<TData, TLayer extends string, TPose> {
|
|
781
|
-
kind: 'container' | 'leaf';
|
|
782
|
-
layer: TLayer;
|
|
783
|
-
pose: TPose;
|
|
784
|
-
data: TData;
|
|
785
|
-
id?: string;
|
|
786
|
-
parent?: string;
|
|
787
|
-
/** Set `false` on every leaf the builder emits: the innermost hit wins, so a
|
|
788
|
-
* row that answers a press is a body that cannot be dragged. */
|
|
789
|
-
pickable?: boolean;
|
|
790
|
-
}
|
|
791
728
|
/** The floor a body's content puts under its node's size. */
|
|
792
729
|
interface BodyFloor {
|
|
793
730
|
minWidth: number;
|
|
@@ -859,44 +796,6 @@ declare function bodyTrait(spec: BodySpec, bounds: Bounds, measure?: MeasureRowT
|
|
|
859
796
|
/** The outline path for a built body at `bounds` — what paints it, and what a
|
|
860
797
|
* perimeter-hugging port will eventually be placed on. */
|
|
861
798
|
declare function bodyOutline(spec: BodySpec, bounds: Bounds): _weasel_js_geom.Path;
|
|
862
|
-
/** What a built body's rows are handed to, one call per row.
|
|
863
|
-
*
|
|
864
|
-
* `text` is the row's content already formatted — a `label`'s own text, or a
|
|
865
|
-
* `field`'s `"label: value"` — so the common case needs no discrimination.
|
|
866
|
-
* Return `null` for a row the consumer paints itself; `ports` and `slot` rows
|
|
867
|
-
* arrive with `text` empty and are the usual ones to decline. */
|
|
868
|
-
type RowNodeData<TData> = (text: string, box: RowBox) => TData | null;
|
|
869
|
-
/** Options for {@link buildBody}: the layer and data of each node it emits.
|
|
870
|
-
* Without `measure`, rows are sized from a fallback line height rather than
|
|
871
|
-
* their text. */
|
|
872
|
-
interface BuildBodyOptions<TData, TLayer extends string, TPose extends Bounds> {
|
|
873
|
-
layer: TLayer;
|
|
874
|
-
/** The container's id. Edges name it, so pass one for anything an edge or a
|
|
875
|
-
* layout `pin` will refer to. */
|
|
876
|
-
id?: string;
|
|
877
|
-
measure?: MeasureRowText;
|
|
878
|
-
/** The container's own data, given the trait the builder computed and the
|
|
879
|
-
* pose it was computed against. */
|
|
880
|
-
body: (trait: DiagramNode, pose: TPose) => TData;
|
|
881
|
-
/** One row's data, or `null` to leave that row undrawn. */
|
|
882
|
-
row: RowNodeData<TData>;
|
|
883
|
-
/** One port's label — a row port's or a perimeter port's — or `null` to
|
|
884
|
-
* leave it undrawn. Ports with no label are never offered. Omit to draw none. */
|
|
885
|
-
portLabel?: (text: string, box: RowPortBox | PerimeterPortLabelBox) => TData | null;
|
|
886
|
-
}
|
|
887
|
-
/**
|
|
888
|
-
* The scene nodes a built body is: one container carrying the trait, and one
|
|
889
|
-
* leaf per row that wants drawing.
|
|
890
|
-
*
|
|
891
|
-
* Rows are ordinary scene nodes rather than something this package paints, so
|
|
892
|
-
* the kit's own text painter draws them and text editing, styling, and
|
|
893
|
-
* selection work on them unchanged. The returned pose is `at` grown to fit the
|
|
894
|
-
* body, never shrunk.
|
|
895
|
-
*/
|
|
896
|
-
declare function buildBody<TData, TLayer extends string, TPose extends Bounds>(spec: BodySpec, at: TPose, opts: BuildBodyOptions<TData, TLayer, TPose>): {
|
|
897
|
-
pose: TPose;
|
|
898
|
-
specs: BodyNodeSpec<TData, TLayer, TPose>[];
|
|
899
|
-
};
|
|
900
799
|
|
|
901
800
|
/**
|
|
902
801
|
* Line jumps as data: the document value that turns them on, and the hops a
|
|
@@ -923,4 +822,4 @@ interface EdgeHop {
|
|
|
923
822
|
r: number;
|
|
924
823
|
}
|
|
925
824
|
|
|
926
|
-
export {
|
|
825
|
+
export { anchorOffset as $, type DiagramNodeEntry as A, type BodySpec as B, type ContainerRole as C, type DiagramGroup as D, type EdgeHop as E, type FontField as F, type Graph as G, type EdgeLabelRoom as H, type GraphEdge as I, type GraphGroup as J, type GraphNode as K, type LayoutPorts as L, type MeasureRowText as M, type GroupInset as N, type Outline as O, type PortAnchor as P, HOPS_DOC_KEY as Q, type RowTextStyle as R, type StyleField as S, type HopsDocValue as T, LABEL_PLACEMENT as U, type LayoutAxes as V, type PortSite as W, type RowBox as X, type RowPort as Y, type RowPortBox as Z, type Slot as _, type Row as a, axesFor as a0, bodyBox as a1, bodyOutline as a2, bodyTrait as a3, boxForContent as a4, buildGraph as a5, canvasMeasure as a6, contentBox as a7, createDiagramNodes as a8, dataKeyReader as a9, diagramContainerOf as aa, diagramLabelOf as ab, diagramNodeOf as ac, expandGroupEdges as ad, graphOrder as ae, headerBox as af, insetOf as ag, isPinned as ah, layoutBody as ai, layoutRowPorts as aj, measureBody as ak, outlinePath as al, packAcross as am, packClusters as an, pinnedSet as ao, planOf as ap, plannerPlan as aq, rankGaps as ar, seededOrder as as, settle as at, sizeToBody as au, titleIdOf as av, translated as aw, untilSettled as ax, extent as ay, type PortSpec as b, type DiagramLabel as c, type LayoutFn as d, type LayoutOptions as e, type DiagramNode as f, type Port as g, type DiagramNodeLike as h, type DiagramNodeReader as i, type DiagramContainer as j, type ContainerHeader as k, type LabelSpot as l, type Bounds as m, type LayoutResult as n, type GraphSource as o, type LayoutPlanner as p, type LayoutDirection as q, type LayoutPlan as r, type GraphNodeLike as s, type BodyFloor as t, type BuildGraphOptions as u, DEFAULT_GROUP_INSET as v, DEFAULT_HOP_SIZE as w, DEFAULT_NODE_GAP as x, DEFAULT_RANK_GAP as y, DIAGRAM_TRAIT_KEY as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/diagram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Node-link diagramming for weasel: any scene node becomes a diagram participant, with ports on its perimeter and an optional body builder for flowchart-shaped boxes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=18",
|
|
36
|
-
"@weasel-js/animator": "1.
|
|
37
|
-
"@weasel-js/audio": "1.
|
|
38
|
-
"@weasel-js/core": "1.
|
|
39
|
-
"@weasel-js/font": "1.
|
|
40
|
-
"@weasel-js/geom": "1.
|
|
41
|
-
"@weasel-js/react": "1.
|
|
42
|
-
"@weasel-js/simulation": "1.
|
|
36
|
+
"@weasel-js/animator": "1.12.0",
|
|
37
|
+
"@weasel-js/audio": "1.12.0",
|
|
38
|
+
"@weasel-js/core": "1.12.0",
|
|
39
|
+
"@weasel-js/font": "1.12.0",
|
|
40
|
+
"@weasel-js/geom": "1.12.0",
|
|
41
|
+
"@weasel-js/react": "1.12.0",
|
|
42
|
+
"@weasel-js/simulation": "1.12.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
45
45
|
"@weasel-js/audio": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"table": "./dist/icons.table.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@weasel-js/icons": "1.
|
|
53
|
+
"@weasel-js/icons": "1.12.0"
|
|
54
54
|
},
|
|
55
55
|
"author": "orochi235",
|
|
56
56
|
"homepage": "https://orochi235.github.io/weasel/",
|