@yalehwang/plantuml-js 0.3.0 → 0.3.1
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/core.d.ts +7 -7
- package/dist/core.js +5 -5
- package/dist/{render → foundation}/labels.d.ts +3 -3
- package/dist/{render → foundation}/labels.js +3 -3
- package/dist/foundation/layout.d.ts +1 -1
- package/dist/foundation/layout.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/layout/compound.d.ts +15 -0
- package/dist/layout/compound.js +27 -1
- package/dist/layout/elk.d.ts +17 -0
- package/dist/layout/elk.js +22 -7
- package/dist/layout/fanout-trunk.js +1 -1
- package/dist/layout/trunk-lanes.js +1 -1
- package/dist/layout/viz.d.ts +1 -1
- package/dist/layout/viz.js +1 -1
- package/dist/{layout → metrics}/layout-metrics.js +1 -1
- package/dist/{parser.d.ts → parse/parser.d.ts} +1 -1
- package/dist/{parser.js → parse/parser.js} +1 -1
- package/dist/{serialize.d.ts → parse/serialize.d.ts} +1 -1
- package/dist/render/svg.js +1 -1
- package/dist/{transform.d.ts → transform/transform.d.ts} +1 -1
- package/dist/{transform.js → transform/transform.js} +1 -1
- package/package.json +1 -1
- /package/dist/{foundation → layout}/render-dot.d.ts +0 -0
- /package/dist/{foundation → layout}/render-dot.js +0 -0
- /package/dist/{layout → metrics}/layout-metrics.d.ts +0 -0
- /package/dist/{serialize.js → parse/serialize.js} +0 -0
package/dist/core.d.ts
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* engine + `renderDot`.
|
|
8
8
|
*/
|
|
9
9
|
import { PlantUmlModel } from './foundation/model.js';
|
|
10
|
-
import { parsePlantUml } from './parser.js';
|
|
10
|
+
import { parsePlantUml } from './parse/parser.js';
|
|
11
11
|
import { LayoutEngine, LayoutResult, DetailLevel } from './foundation/layout.js';
|
|
12
12
|
import { ThemeOverrides } from './render/theme.js';
|
|
13
13
|
import { ElkLayoutEngine, type ElkLayoutOptions } from './layout/elk.js';
|
|
14
14
|
import { renderSvg, RenderSvgOptions, RenderEngine, RenderFrameOptions, SvgRenderer, SvgRendererOptions } from './render/svg.js';
|
|
15
|
-
import { ViewSpec, TransformOptions } from './transform.js';
|
|
15
|
+
import { ViewSpec, TransformOptions } from './transform/transform.js';
|
|
16
16
|
export type { PlantUmlModel, PlantUmlEntity, PlantUmlMember, PlantUmlRelation, PlantUmlPackage, EntityKind, RelationType, } from './foundation/model.js';
|
|
17
17
|
export { defaultTheme, resolveTheme } from './render/theme.js';
|
|
18
18
|
export type { Theme, ThemeOverrides } from './render/theme.js';
|
|
@@ -191,11 +191,11 @@ export interface LineExplanation {
|
|
|
191
191
|
*/
|
|
192
192
|
export declare function explain(puml: string): LineExplanation[];
|
|
193
193
|
export { parsePlantUml, ElkLayoutEngine, renderSvg, SvgRenderer };
|
|
194
|
-
export { toPlantUml } from './serialize.js';
|
|
194
|
+
export { toPlantUml } from './parse/serialize.js';
|
|
195
195
|
export type { RenderSvgOptions, RenderEngine, RenderFrameOptions, SvgRendererOptions };
|
|
196
|
-
export { computeLayoutMetrics } from './
|
|
197
|
-
export type { LayoutMetrics } from './
|
|
198
|
-
export { applyView, transformModel, aggregateRelations, transitiveReduce, summarizeHubs, markCycles, groupByPathPrefix, } from './transform.js';
|
|
199
|
-
export type { ViewSpec, TransformOptions } from './transform.js';
|
|
196
|
+
export { computeLayoutMetrics } from './metrics/layout-metrics.js';
|
|
197
|
+
export type { LayoutMetrics } from './metrics/layout-metrics.js';
|
|
198
|
+
export { applyView, transformModel, aggregateRelations, transitiveReduce, summarizeHubs, markCycles, groupByPathPrefix, } from './transform/transform.js';
|
|
199
|
+
export type { ViewSpec, TransformOptions } from './transform/transform.js';
|
|
200
200
|
export { archguardToPlantUml, archguardAliasMap, pathName, displayName, ARCHGUARD_RELATION_ARROWS, } from './archguard.js';
|
|
201
201
|
export type { ArchguardNode, ArchguardEdge, ArchguardGraph, ArchguardBridgeOptions, ArchguardPlantUml, } from './archguard.js';
|
package/dist/core.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* `src/index.ts` is the full build: it re-exports this core and adds the viz
|
|
7
7
|
* engine + `renderDot`.
|
|
8
8
|
*/
|
|
9
|
-
import { parsePlantUml, parseWithDiagnostics, ENTITY_LINE, ENTITY_KEYWORD, extractDeclaredName, stripComment } from './parser.js';
|
|
9
|
+
import { parsePlantUml, parseWithDiagnostics, ENTITY_LINE, ENTITY_KEYWORD, extractDeclaredName, stripComment } from './parse/parser.js';
|
|
10
10
|
import { applyDetail } from './foundation/layout.js';
|
|
11
11
|
import { ElkLayoutEngine } from './layout/elk.js';
|
|
12
12
|
import { renderSvg, SvgRenderer, } from './render/svg.js';
|
|
13
|
-
import { applyView, transformModel, transformModelDetailed, shouldAutoReduce, INTER_PACKAGE_AGGREGATE_ENTITY_THRESHOLD } from './transform.js';
|
|
13
|
+
import { applyView, transformModel, transformModelDetailed, shouldAutoReduce, INTER_PACKAGE_AGGREGATE_ENTITY_THRESHOLD } from './transform/transform.js';
|
|
14
14
|
export { defaultTheme, resolveTheme } from './render/theme.js';
|
|
15
15
|
/** Error thrown by {@link createRenderer}'s `render` on structurally invalid puml. */
|
|
16
16
|
export class RenderError extends Error {
|
|
@@ -294,7 +294,7 @@ function classifyLine(raw) {
|
|
|
294
294
|
return { kind: 'unknown', explanation: 'unrecognised line (ignored)' };
|
|
295
295
|
}
|
|
296
296
|
export { parsePlantUml, ElkLayoutEngine, renderSvg, SvgRenderer };
|
|
297
|
-
export { toPlantUml } from './serialize.js';
|
|
298
|
-
export { computeLayoutMetrics } from './
|
|
299
|
-
export { applyView, transformModel, aggregateRelations, transitiveReduce, summarizeHubs, markCycles, groupByPathPrefix, } from './transform.js';
|
|
297
|
+
export { toPlantUml } from './parse/serialize.js';
|
|
298
|
+
export { computeLayoutMetrics } from './metrics/layout-metrics.js';
|
|
299
|
+
export { applyView, transformModel, aggregateRelations, transitiveReduce, summarizeHubs, markCycles, groupByPathPrefix, } from './transform/transform.js';
|
|
300
300
|
export { archguardToPlantUml, archguardAliasMap, pathName, displayName, ARCHGUARD_RELATION_ARROWS, } from './archguard.js';
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* candidate that collides with no node and no previously placed label wins, so
|
|
8
8
|
* labels of neighbouring edges do not pile onto each other.
|
|
9
9
|
*/
|
|
10
|
-
import { PlantUmlModel, PlantUmlEntity } from '
|
|
11
|
-
import { LayoutResult, NodeLayout, Point } from '
|
|
12
|
-
import { Rect } from '
|
|
10
|
+
import { PlantUmlModel, PlantUmlEntity } from './model.js';
|
|
11
|
+
import { LayoutResult, NodeLayout, Point } from './layout.js';
|
|
12
|
+
import { Rect } from './edge-router.js';
|
|
13
13
|
export declare const EDGE_LABEL_FONT_SIZE = 11;
|
|
14
14
|
export declare const HUB_BADGE_RADIUS = 9;
|
|
15
15
|
export interface EdgeLabelPlacement {
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* candidate that collides with no node and no previously placed label wins, so
|
|
8
8
|
* labels of neighbouring edges do not pile onto each other.
|
|
9
9
|
*/
|
|
10
|
-
import { METRICS, displayName } from '
|
|
11
|
-
import { nodeRect } from '
|
|
12
|
-
import { measureTextWidth } from '
|
|
10
|
+
import { METRICS, displayName } from './layout.js';
|
|
11
|
+
import { nodeRect } from './edge-router.js';
|
|
12
|
+
import { measureTextWidth } from './text-measure.js';
|
|
13
13
|
export const EDGE_LABEL_FONT_SIZE = 11;
|
|
14
14
|
const EDGE_LABEL_PAD_X = 3;
|
|
15
15
|
const EDGE_LABEL_HEIGHT = 14;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* LayoutEngine — the pluggable layout contract. A LayoutEngine is a pure
|
|
3
3
|
* function from PlantUmlModel to concrete positions; the parser never talks
|
|
4
4
|
* to a layout engine and the renderer never talks to the parser, so swapping
|
|
5
|
-
* engines (
|
|
5
|
+
* engines (ELK, Graphviz, a custom tuner) is an injection, not a rewrite.
|
|
6
6
|
*/
|
|
7
7
|
import { PlantUmlModel, PlantUmlEntity } from './model.js';
|
|
8
8
|
export interface Point {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* LayoutEngine — the pluggable layout contract. A LayoutEngine is a pure
|
|
3
3
|
* function from PlantUmlModel to concrete positions; the parser never talks
|
|
4
4
|
* to a layout engine and the renderer never talks to the parser, so swapping
|
|
5
|
-
* engines (
|
|
5
|
+
* engines (ELK, Graphviz, a custom tuner) is an injection, not a rewrite.
|
|
6
6
|
*/
|
|
7
7
|
import { measureTextWidth, MONOSPACE_FONT_SIZE } from './text-measure.js';
|
|
8
8
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* bundle stays free of the Graphviz WASM.
|
|
7
7
|
*/
|
|
8
8
|
import { VizLayoutEngine } from './layout/viz.js';
|
|
9
|
-
import { renderDot } from './
|
|
9
|
+
import { renderDot } from './layout/render-dot.js';
|
|
10
10
|
import { Renderer, RendererOptions } from './core.js';
|
|
11
11
|
export * from './core.js';
|
|
12
|
-
export type { GraphvizEngine } from './
|
|
12
|
+
export type { GraphvizEngine } from './layout/render-dot.js';
|
|
13
13
|
export { renderDot, VizLayoutEngine };
|
|
14
14
|
/**
|
|
15
15
|
* Build a renderer. `layout` is `'elk'` (default), `'viz'` (experimental), or a
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* bundle stays free of the Graphviz WASM.
|
|
7
7
|
*/
|
|
8
8
|
import { VizLayoutEngine } from './layout/viz.js';
|
|
9
|
-
import { renderDot } from './
|
|
9
|
+
import { renderDot } from './layout/render-dot.js';
|
|
10
10
|
import { createRenderer as createCoreRenderer, } from './core.js';
|
|
11
11
|
export * from './core.js';
|
|
12
12
|
export { renderDot, VizLayoutEngine };
|
|
@@ -15,10 +15,25 @@ import type { PlantUmlModel } from '../foundation/model.js';
|
|
|
15
15
|
import { type LayoutResult } from '../foundation/layout.js';
|
|
16
16
|
import { type BoxPlacementContext, type PlacementStrategy, type PlacementStrategyOptions, type StubOrbit } from './placement-strategy.js';
|
|
17
17
|
export type { StubOrbit } from './placement-strategy.js';
|
|
18
|
+
/**
|
|
19
|
+
* Entity count above which the compound layout switches to its cheaper
|
|
20
|
+
* large-graph mode (see [[CompoundOptions.largeGraphThreshold]]).
|
|
21
|
+
*
|
|
22
|
+
* The cross-block router's A* cost grows with the lattice area, i.e. with the
|
|
23
|
+
* canvas the compound pack produced — 0.3.0 measured a 2000-node nested graph
|
|
24
|
+
* at ~282 s against 1.2 s at 300 nodes. The 800-node point is the knee of that
|
|
25
|
+
* curve in the reported scale ladder (500 ≈ 1.4 s, 800 ≈ 4-7 s, 2000 ≈ 282 s).
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_LARGE_GRAPH_THRESHOLD = 800;
|
|
18
28
|
export interface CompoundOptions extends PlacementStrategyOptions {
|
|
19
29
|
edgeRouting?: string;
|
|
20
30
|
/** Rip-up passes of the cross-block router; its default when omitted. */
|
|
21
31
|
ripupPasses?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Entity count above which the cross-block router degrades to a coarser
|
|
34
|
+
* lattice with no rip-up passes. Default [[DEFAULT_LARGE_GRAPH_THRESHOLD]].
|
|
35
|
+
*/
|
|
36
|
+
largeGraphThreshold?: number;
|
|
22
37
|
/**
|
|
23
38
|
* Extra block-placement strategies tried, in order, before the built-in
|
|
24
39
|
* chain; the first to return a placement wins (see [[./placement-strategy]]).
|
package/dist/layout/compound.js
CHANGED
|
@@ -75,6 +75,27 @@ const HUB_RAIL_MIN_HEIGHT = 400;
|
|
|
75
75
|
const CANVAS_MARGIN = 40;
|
|
76
76
|
/** Node gap inside packed blocks of a dense (very large) graph; leaves one routing lane. */
|
|
77
77
|
const DENSE_NODE_SPACING = 36;
|
|
78
|
+
/**
|
|
79
|
+
* Entity count above which the compound layout switches to its cheaper
|
|
80
|
+
* large-graph mode (see [[CompoundOptions.largeGraphThreshold]]).
|
|
81
|
+
*
|
|
82
|
+
* The cross-block router's A* cost grows with the lattice area, i.e. with the
|
|
83
|
+
* canvas the compound pack produced — 0.3.0 measured a 2000-node nested graph
|
|
84
|
+
* at ~282 s against 1.2 s at 300 nodes. The 800-node point is the knee of that
|
|
85
|
+
* curve in the reported scale ladder (500 ≈ 1.4 s, 800 ≈ 4-7 s, 2000 ≈ 282 s).
|
|
86
|
+
*/
|
|
87
|
+
export const DEFAULT_LARGE_GRAPH_THRESHOLD = 800;
|
|
88
|
+
/**
|
|
89
|
+
* Lattice pitch of the large-graph router. The default pitch is tied to the
|
|
90
|
+
* canvas area and becomes very fine on a big canvas (one lattice vertex every
|
|
91
|
+
* ~9-20 px), which makes every A* search explore hundreds of thousands of
|
|
92
|
+
* states. A coarser lattice cuts that by roughly the square of the pitch ratio
|
|
93
|
+
* while still leaving the 64 px gutters between blocks routable. 22 px is the
|
|
94
|
+
* coarsest value that still finds a terminal vertex outside every node in the
|
|
95
|
+
* dense nested fixtures; at 24 px a small package can sit entirely between
|
|
96
|
+
* lattice rows and the router falls back to a node-crossing dog-leg.
|
|
97
|
+
*/
|
|
98
|
+
const LARGE_GRAPH_ROUTER_PITCH = 22;
|
|
78
99
|
/** Tightest gap between neighbouring stubs on the rail, px. */
|
|
79
100
|
const RAIL_MIN_GAP = 24;
|
|
80
101
|
/** Lattice cost of crossing a wire in a view with stub rails (their fans are crossing-prone), and elsewhere. */
|
|
@@ -198,12 +219,17 @@ export async function compoundLayout(elk, model, options) {
|
|
|
198
219
|
target: model.relations[index].target,
|
|
199
220
|
points,
|
|
200
221
|
}));
|
|
222
|
+
// Large graphs route on a coarser lattice and skip the rip-up refinement:
|
|
223
|
+
// the A* search is the superlinear term (see DEFAULT_LARGE_GRAPH_THRESHOLD),
|
|
224
|
+
// and both knobs trade routing polish for a bounded layout time.
|
|
225
|
+
const large = model.entities.length > (options.largeGraphThreshold ?? DEFAULT_LARGE_GRAPH_THRESHOLD);
|
|
201
226
|
const routed = routeOrthogonal(requests, nodes, {
|
|
202
227
|
width: placed.width,
|
|
203
228
|
height: placed.height,
|
|
204
229
|
frames: packagesOut,
|
|
205
230
|
existing: drawn,
|
|
206
|
-
ripupPasses: options.ripupPasses,
|
|
231
|
+
ripupPasses: large ? 0 : options.ripupPasses,
|
|
232
|
+
pitch: large ? LARGE_GRAPH_ROUTER_PITCH : undefined,
|
|
207
233
|
crossingCost: model.entities.some((e) => e.stub) ? STUB_CROSSING_COST : CROSSING_COST,
|
|
208
234
|
});
|
|
209
235
|
for (const [id, points] of routed)
|
package/dist/layout/elk.d.ts
CHANGED
|
@@ -61,6 +61,21 @@ export interface ElkLayoutOptions {
|
|
|
61
61
|
* desktop panel or 9/16 for a portrait phone. Default 1.6.
|
|
62
62
|
*/
|
|
63
63
|
aspectRatio?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Entity count above which the compound layout degrades to its cheaper
|
|
66
|
+
* large-graph mode: the cross-block router uses a coarser lattice with no
|
|
67
|
+
* rip-up passes, the dependency-ordered block packing is not retried with
|
|
68
|
+
* rect-packing, and the cosmetic edge-polishing passes (fan-out bundling,
|
|
69
|
+
* trunk straightening, un-coiling) are skipped. Those passes run A* and
|
|
70
|
+
* O(edges) crossing scans per candidate edge, which grows superlinearly with
|
|
71
|
+
* the canvas area — the 0.3.0 nested 2000-node graph measured ~282 s at the
|
|
72
|
+
* default and is bounded above this threshold.
|
|
73
|
+
*
|
|
74
|
+
* Default 800, the knee between the reported 800-node (~4-7 s) and
|
|
75
|
+
* 2000-node (~282 s) measurements. Set to `Infinity` to keep the full
|
|
76
|
+
* polishing pipeline at every scale.
|
|
77
|
+
*/
|
|
78
|
+
largeGraphThreshold?: number;
|
|
64
79
|
/**
|
|
65
80
|
* Extra layout strategies tried, in order, before the built-in decision
|
|
66
81
|
* chain; the first to return a result wins (see [[./strategy]]).
|
|
@@ -111,6 +126,8 @@ export declare class ElkLayoutEngine implements LayoutEngine {
|
|
|
111
126
|
*/
|
|
112
127
|
private layoutToward;
|
|
113
128
|
private compound;
|
|
129
|
+
/** Entity count above which the cheap large-graph pipeline is used. */
|
|
130
|
+
private isLargeGraph;
|
|
114
131
|
/** One ELK run over the whole nested graph (`INCLUDE_CHILDREN`). */
|
|
115
132
|
private hierarchicalLayout;
|
|
116
133
|
}
|
package/dist/layout/elk.js
CHANGED
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import ELKDefault from 'elkjs';
|
|
38
38
|
import { alignRows, alignIsolatedFrames } from '../foundation/layout.js';
|
|
39
|
-
import { compoundLayout } from './compound.js';
|
|
40
|
-
import { computeLayoutMetrics, computeMaxEmptyBlockRatio } from '
|
|
39
|
+
import { compoundLayout, DEFAULT_LARGE_GRAPH_THRESHOLD } from './compound.js';
|
|
40
|
+
import { computeLayoutMetrics, computeMaxEmptyBlockRatio } from '../metrics/layout-metrics.js';
|
|
41
41
|
import { resolveLayerOrder, assignPartitions } from '../foundation/layers.js';
|
|
42
42
|
import { buildElkGraph } from './elk-graph.js';
|
|
43
43
|
import { clipPackageEndpoints } from './package-endpoints.js';
|
|
@@ -148,9 +148,16 @@ export class ElkLayoutEngine {
|
|
|
148
148
|
this.options = options;
|
|
149
149
|
}
|
|
150
150
|
async layout(model) {
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
const large = this.isLargeGraph(model);
|
|
152
|
+
const spread = (raw) => spreadParallelLanes(clipPackageEndpoints(model, alignIsolatedFrames(model, alignRows(model, raw))));
|
|
153
|
+
// The edge-polishing passes are quadratic-ish in the canvas size (per-edge
|
|
154
|
+
// A* plus all-pairs crossing scans) and cannot be bounded by any budget on
|
|
155
|
+
// a 2000-node nested canvas, so a large graph keeps the raw compound
|
|
156
|
+
// geometry and only gets the cheap passes.
|
|
157
|
+
const finish = (raw) => fitCanvas(liftFlushSegments(large
|
|
158
|
+
? spread(raw)
|
|
159
|
+
: // stub views price crossings high on purpose: their rail edges are not un-coiled
|
|
160
|
+
(model.entities.some((e) => e.stub) ? (l) => l : uncoilWraps)(straightenTrunkDetours(mergeFanoutTrunks(model, spread(raw))))));
|
|
154
161
|
if (!model.entities.some((e) => e.stub))
|
|
155
162
|
return finish((await this.layoutRaw(model)).layout);
|
|
156
163
|
// Where the orbiting stubs sit decides how the router weaves their edges
|
|
@@ -239,6 +246,7 @@ export class ElkLayoutEngine {
|
|
|
239
246
|
}
|
|
240
247
|
async compound(model, layers, partitions, { orbit, quick }) {
|
|
241
248
|
const dense = model.entities.length > COMPOUND_ENTITY_THRESHOLD;
|
|
249
|
+
const large = this.isLargeGraph(model);
|
|
242
250
|
const run = (rectPackDense) => compoundLayout(this.elk, model, {
|
|
243
251
|
edgeRouting: this.options.edgeRouting,
|
|
244
252
|
aspectRatio: this.options.aspectRatio,
|
|
@@ -248,15 +256,22 @@ export class ElkLayoutEngine {
|
|
|
248
256
|
partitions: layers.length > 0 ? partitions : new Map(),
|
|
249
257
|
stubOrbit: orbit,
|
|
250
258
|
ripupPasses: quick ? 0 : undefined,
|
|
259
|
+
largeGraphThreshold: this.options.largeGraphThreshold,
|
|
251
260
|
});
|
|
252
261
|
const ordered = await run(false);
|
|
253
262
|
// Dependency-ordered rows cost canvas on very large graphs; past the budget
|
|
254
|
-
// fall back to the tighter (order-blind) rect packing.
|
|
255
|
-
|
|
263
|
+
// fall back to the tighter (order-blind) rect packing. A large graph skips
|
|
264
|
+
// the retry: laying every nested block out twice doubles the dominant cost
|
|
265
|
+
// for a canvas-area gain that the large-graph router no longer needs.
|
|
266
|
+
if (!large && dense && ordered.width * ordered.height > COMPOUND_AREA_BUDGET) {
|
|
256
267
|
return { layout: await run(true), orbited: true };
|
|
257
268
|
}
|
|
258
269
|
return { layout: ordered, orbited: true };
|
|
259
270
|
}
|
|
271
|
+
/** Entity count above which the cheap large-graph pipeline is used. */
|
|
272
|
+
isLargeGraph(model) {
|
|
273
|
+
return model.entities.length > (this.options.largeGraphThreshold ?? DEFAULT_LARGE_GRAPH_THRESHOLD);
|
|
274
|
+
}
|
|
260
275
|
/** One ELK run over the whole nested graph (`INCLUDE_CHILDREN`). */
|
|
261
276
|
async hierarchicalLayout(model, layers, partitions) {
|
|
262
277
|
const graph = buildElkGraph(model, layers, partitions, {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* same direction, the second across) take part — the shape both ELK and the
|
|
12
12
|
* grid router give a plain fan-out. Anything else in the group is left alone.
|
|
13
13
|
*/
|
|
14
|
-
import { findParallelBundles } from '
|
|
14
|
+
import { findParallelBundles } from '../metrics/layout-metrics.js';
|
|
15
15
|
import { routeOrthogonal } from './grid-router.js';
|
|
16
16
|
/** Edges leaving (or entering) one side that make a group worth merging. */
|
|
17
17
|
export const TRUNK_MIN_EDGES = 5;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* no unrelated node or package frame, and adds at most [[EXTRA_CROSSINGS]] crossings.
|
|
10
10
|
*/
|
|
11
11
|
import { routeOrthogonal } from './grid-router.js';
|
|
12
|
-
import { findParallelBundles } from '
|
|
12
|
+
import { findParallelBundles } from '../metrics/layout-metrics.js';
|
|
13
13
|
/** Path length ÷ Manhattan distance above which an edge is considered for a Z. */
|
|
14
14
|
const DETOUR_FACTOR = 2;
|
|
15
15
|
/** Clearance between a Z segment and an unrelated node box. */
|
package/dist/layout/viz.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { PlantUmlModel } from '../foundation/model.js';
|
|
15
15
|
import { LayoutEngine, LayoutResult } from '../foundation/layout.js';
|
|
16
|
-
import { GraphvizEngine } from '
|
|
16
|
+
import { GraphvizEngine } from './render-dot.js';
|
|
17
17
|
export declare class VizLayoutEngine implements LayoutEngine {
|
|
18
18
|
private readonly graphvizEngine;
|
|
19
19
|
constructor(graphvizEngine?: GraphvizEngine);
|
package/dist/layout/viz.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* engine and the SVG renderer already speak.
|
|
13
13
|
*/
|
|
14
14
|
import { PACKAGE_LABEL, displayName, estimateEntitySize, } from '../foundation/layout.js';
|
|
15
|
-
import { getViz } from '
|
|
15
|
+
import { getViz } from './render-dot.js';
|
|
16
16
|
import { measureTextWidth } from '../foundation/text-measure.js';
|
|
17
17
|
import { relationSemantics } from '../foundation/relation-semantics.js';
|
|
18
18
|
const POINTS_PER_INCH = 72;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { METRICS, PACKAGE_LABEL, displayName } from '../foundation/layout.js';
|
|
12
12
|
import { countEdgeBoxIntersections, countNonOrthogonalSegments, nodeRect } from '../foundation/edge-router.js';
|
|
13
13
|
import { measureTextWidth } from '../foundation/text-measure.js';
|
|
14
|
-
import { entityTextRects, hubBadgeRect, placeEdgeLabels, rectHitsOtherEdge, rectsIntersect, } from '../
|
|
14
|
+
import { entityTextRects, hubBadgeRect, placeEdgeLabels, rectHitsOtherEdge, rectsIntersect, } from '../foundation/labels.js';
|
|
15
15
|
const registry = [];
|
|
16
16
|
/** Register a metric; the next [[computeLayoutMetrics]] call reports it. */
|
|
17
17
|
export function registerMetric(metric) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* generics (`List~Item~`, `BaseEntity<T>`), package/namespace grouping,
|
|
8
8
|
* aliases, and tolerant skipping of skinparam/hide/note directives.
|
|
9
9
|
*/
|
|
10
|
-
import { PlantUmlModel } from '
|
|
10
|
+
import { PlantUmlModel } from '../foundation/model.js';
|
|
11
11
|
export declare const ENTITY_LINE: RegExp;
|
|
12
12
|
export declare const ENTITY_KEYWORD: RegExp;
|
|
13
13
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* generics (`List~Item~`, `BaseEntity<T>`), package/namespace grouping,
|
|
8
8
|
* aliases, and tolerant skipping of skinparam/hide/note directives.
|
|
9
9
|
*/
|
|
10
|
-
import { emptyModel, } from '
|
|
10
|
+
import { emptyModel, } from '../foundation/model.js';
|
|
11
11
|
export const ENTITY_LINE = /^(abstract\s+)?(class|interface|enum)\s+(.+)$/i;
|
|
12
12
|
export const ENTITY_KEYWORD = /^(?:abstract\s+)?(?:class|interface|enum)\b/i;
|
|
13
13
|
const ARROWS = {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* as n0`), so names carrying a stereotype prefix or `/` path separators survive
|
|
20
20
|
* the round trip as authored.
|
|
21
21
|
*/
|
|
22
|
-
import type { PlantUmlModel } from '
|
|
22
|
+
import type { PlantUmlModel } from '../foundation/model.js';
|
|
23
23
|
/**
|
|
24
24
|
* Serialize a model to `@startuml … @enduml` class-diagram source.
|
|
25
25
|
*
|
package/dist/render/svg.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { METRICS, PACKAGE_LABEL, displayName, } from '../foundation/layout.js';
|
|
7
7
|
import { measureTextWidth } from '../foundation/text-measure.js';
|
|
8
|
-
import { hubBadgeCircle, placeEdgeLabels, EDGE_LABEL_FONT_SIZE } from '
|
|
8
|
+
import { hubBadgeCircle, placeEdgeLabels, EDGE_LABEL_FONT_SIZE } from '../foundation/labels.js';
|
|
9
9
|
import { renderLegend, LEGEND_DEFAULT_NODE_THRESHOLD } from './legend.js';
|
|
10
10
|
import { resolveTheme } from './theme.js';
|
|
11
11
|
import { packageLayer } from '../foundation/layers.js';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* input and produces the same output for the same input, so a transformed
|
|
10
10
|
* render stays byte-for-byte reproducible.
|
|
11
11
|
*/
|
|
12
|
-
import { PlantUmlModel } from '
|
|
12
|
+
import { PlantUmlModel } from '../foundation/model.js';
|
|
13
13
|
/** Options driving the model-transform pipeline. */
|
|
14
14
|
export interface TransformOptions {
|
|
15
15
|
/**
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* input and produces the same output for the same input, so a transformed
|
|
10
10
|
* render stays byte-for-byte reproducible.
|
|
11
11
|
*/
|
|
12
|
-
import { relationSemantics } from '
|
|
12
|
+
import { relationSemantics } from '../foundation/relation-semantics.js';
|
|
13
13
|
/** Entity count above which inter-package edges aggregate into corridors by default. */
|
|
14
14
|
export const INTER_PACKAGE_AGGREGATE_ENTITY_THRESHOLD = 150;
|
|
15
15
|
/** Stub count above which a single-package view groups stubs by name prefix. */
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|