@diagrammo/dgmo 0.8.20 → 0.8.22
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/AGENTS.md +2 -1
- package/README.md +1 -0
- package/dist/cli.cjs +142 -90
- package/dist/editor.cjs +30 -4
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +30 -4
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +25 -3
- package/dist/highlight.cjs.map +1 -1
- package/dist/highlight.js +25 -3
- package/dist/highlight.js.map +1 -1
- package/dist/index.cjs +21201 -12886
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +646 -89
- package/dist/index.d.ts +646 -89
- package/dist/index.js +21178 -12889
- package/dist/index.js.map +1 -1
- package/docs/guide/chart-mindmap.md +198 -0
- package/docs/guide/chart-sequence.md +23 -1
- package/docs/guide/chart-sitemap.md +18 -1
- package/docs/guide/chart-tech-radar.md +219 -0
- package/docs/guide/chart-wireframe.md +100 -0
- package/docs/guide/index.md +8 -0
- package/docs/guide/registry.json +1 -0
- package/docs/language-reference.md +249 -4
- package/gallery/fixtures/boxes-and-lines.dgmo +10 -3
- package/gallery/fixtures/c4-full.dgmo +2 -2
- package/gallery/fixtures/cycle/ooda-loop.dgmo +25 -0
- package/gallery/fixtures/cycle/pdca-circle-nodes.dgmo +12 -0
- package/gallery/fixtures/cycle/pdca-minimal.dgmo +6 -0
- package/gallery/fixtures/cycle/sprint-cycle-span.dgmo +17 -0
- package/gallery/fixtures/gantt-full.dgmo +2 -2
- package/gallery/fixtures/gantt.dgmo +2 -2
- package/gallery/fixtures/infra-full.dgmo +2 -2
- package/gallery/fixtures/infra.dgmo +1 -1
- package/gallery/fixtures/sequence-tags-protocols.dgmo +2 -2
- package/gallery/fixtures/sequence-tags.dgmo +2 -2
- package/gallery/fixtures/tech-radar-dense.dgmo +77 -0
- package/gallery/fixtures/tech-radar.dgmo +36 -0
- package/gallery/fixtures/timeline.dgmo +1 -1
- package/package.json +1 -1
- package/src/boxes-and-lines/collapse.ts +21 -3
- package/src/boxes-and-lines/layout.ts +360 -42
- package/src/boxes-and-lines/parser.ts +94 -11
- package/src/boxes-and-lines/renderer.ts +371 -114
- package/src/boxes-and-lines/types.ts +2 -1
- package/src/c4/layout.ts +8 -8
- package/src/c4/parser.ts +35 -2
- package/src/c4/renderer.ts +19 -3
- package/src/c4/types.ts +1 -0
- package/src/chart.ts +14 -7
- package/src/completion.ts +253 -0
- package/src/cycle/layout.ts +732 -0
- package/src/cycle/parser.ts +352 -0
- package/src/cycle/renderer.ts +539 -0
- package/src/cycle/types.ts +77 -0
- package/src/d3.ts +240 -40
- package/src/dgmo-router.ts +15 -0
- package/src/echarts.ts +7 -4
- package/src/editor/dgmo.grammar +5 -1
- package/src/editor/dgmo.grammar.js +1 -1
- package/src/editor/keywords.ts +26 -0
- package/src/gantt/parser.ts +2 -8
- package/src/graph/flowchart-parser.ts +15 -21
- package/src/graph/layout.ts +73 -9
- package/src/graph/state-collapse.ts +78 -0
- package/src/graph/state-parser.ts +5 -10
- package/src/graph/state-renderer.ts +139 -34
- package/src/index.ts +78 -0
- package/src/infra/layout.ts +218 -74
- package/src/infra/parser.ts +30 -6
- package/src/infra/renderer.ts +14 -8
- package/src/infra/types.ts +10 -3
- package/src/journey-map/layout.ts +386 -0
- package/src/journey-map/parser.ts +540 -0
- package/src/journey-map/renderer.ts +1456 -0
- package/src/journey-map/types.ts +47 -0
- package/src/kanban/parser.ts +3 -10
- package/src/kanban/renderer.ts +325 -63
- package/src/mindmap/collapse.ts +88 -0
- package/src/mindmap/layout.ts +605 -0
- package/src/mindmap/parser.ts +373 -0
- package/src/mindmap/renderer.ts +544 -0
- package/src/mindmap/text-wrap.ts +217 -0
- package/src/mindmap/types.ts +55 -0
- package/src/org/parser.ts +2 -6
- package/src/render.ts +18 -21
- package/src/sequence/renderer.ts +273 -56
- package/src/sharing.ts +3 -0
- package/src/sitemap/layout.ts +56 -18
- package/src/sitemap/parser.ts +26 -17
- package/src/sitemap/renderer.ts +34 -0
- package/src/sitemap/types.ts +1 -0
- package/src/tech-radar/index.ts +14 -0
- package/src/tech-radar/interactive.ts +1058 -0
- package/src/tech-radar/layout.ts +190 -0
- package/src/tech-radar/parser.ts +385 -0
- package/src/tech-radar/renderer.ts +1159 -0
- package/src/tech-radar/shared.ts +187 -0
- package/src/tech-radar/types.ts +81 -0
- package/src/utils/description-helpers.ts +33 -0
- package/src/utils/export-container.ts +3 -2
- package/src/utils/legend-d3.ts +1 -0
- package/src/utils/legend-layout.ts +5 -3
- package/src/utils/parsing.ts +48 -7
- package/src/utils/tag-groups.ts +46 -60
- package/src/wireframe/layout.ts +460 -0
- package/src/wireframe/parser.ts +956 -0
- package/src/wireframe/renderer.ts +1293 -0
- package/src/wireframe/types.ts +110 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Mindmap Text Wrapping
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// Shared logic for wrapping node labels and descriptions into
|
|
6
|
+
// multiple lines. Used by both layout (for sizing) and renderer
|
|
7
|
+
// (for drawing). Ensures both agree on line breaks and font size.
|
|
8
|
+
|
|
9
|
+
import { preprocessDescriptionLine } from '../utils/description-helpers';
|
|
10
|
+
|
|
11
|
+
const CHAR_WIDTH_RATIO = 0.58; // avg char width / fontSize for Helvetica
|
|
12
|
+
const H_PAD = 16; // 8px padding each side
|
|
13
|
+
const MAX_LABEL_LINES = 3;
|
|
14
|
+
const MAX_DESC_LINES = 2;
|
|
15
|
+
|
|
16
|
+
/** Split text into tokens, keeping hyphens attached to the left word. */
|
|
17
|
+
function tokenize(text: string): string[] {
|
|
18
|
+
const tokens: string[] = [];
|
|
19
|
+
// Split on spaces, and after hyphens (keep hyphen with left token)
|
|
20
|
+
const parts = text.split(/(\s+)/);
|
|
21
|
+
for (const part of parts) {
|
|
22
|
+
if (/^\s+$/.test(part)) continue; // skip whitespace tokens
|
|
23
|
+
// Further split on hyphens: "well-known" → ["well-", "known"]
|
|
24
|
+
const hyphenParts = part.split(/(?<=-)(?=\S)/);
|
|
25
|
+
tokens.push(...hyphenParts);
|
|
26
|
+
}
|
|
27
|
+
return tokens;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Wrap text into lines that fit within maxWidth at the given fontSize.
|
|
32
|
+
* Returns null if the text doesn't fit within maxLines.
|
|
33
|
+
*/
|
|
34
|
+
function tryWrap(
|
|
35
|
+
tokens: string[],
|
|
36
|
+
maxWidth: number,
|
|
37
|
+
fontSize: number,
|
|
38
|
+
maxLines: number
|
|
39
|
+
): string[] | null {
|
|
40
|
+
const availWidth = maxWidth - H_PAD;
|
|
41
|
+
const charWidth = fontSize * CHAR_WIDTH_RATIO;
|
|
42
|
+
const maxChars = Math.max(1, Math.floor(availWidth / charWidth));
|
|
43
|
+
|
|
44
|
+
const lines: string[] = [];
|
|
45
|
+
let currentLine = '';
|
|
46
|
+
|
|
47
|
+
for (const token of tokens) {
|
|
48
|
+
// After a hyphen-ending token, don't add a space
|
|
49
|
+
const sep = currentLine && !currentLine.endsWith('-') ? ' ' : '';
|
|
50
|
+
const candidate = currentLine + sep + token;
|
|
51
|
+
|
|
52
|
+
if (candidate.length <= maxChars) {
|
|
53
|
+
currentLine = candidate;
|
|
54
|
+
} else if (!currentLine) {
|
|
55
|
+
// Single token exceeds line — force it onto this line (will be truncated later if needed)
|
|
56
|
+
currentLine = token;
|
|
57
|
+
} else {
|
|
58
|
+
// Push current line, start new one
|
|
59
|
+
lines.push(currentLine);
|
|
60
|
+
if (lines.length >= maxLines) {
|
|
61
|
+
// Can't fit — return null to signal overflow
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
currentLine = token;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (currentLine) {
|
|
68
|
+
lines.push(currentLine);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (lines.length > maxLines) return null;
|
|
72
|
+
return lines;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Truncate the last line of a lines array with ellipsis to fit maxChars. */
|
|
76
|
+
function truncateLastLine(
|
|
77
|
+
lines: string[],
|
|
78
|
+
maxWidth: number,
|
|
79
|
+
fontSize: number
|
|
80
|
+
): string[] {
|
|
81
|
+
const availWidth = maxWidth - H_PAD;
|
|
82
|
+
const charWidth = fontSize * CHAR_WIDTH_RATIO;
|
|
83
|
+
const maxChars = Math.max(1, Math.floor(availWidth / charWidth));
|
|
84
|
+
|
|
85
|
+
const result = [...lines];
|
|
86
|
+
const last = result[result.length - 1];
|
|
87
|
+
if (last.length > maxChars) {
|
|
88
|
+
result[result.length - 1] = last.substring(0, maxChars - 1) + '\u2026';
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface WrapResult {
|
|
94
|
+
lines: string[];
|
|
95
|
+
fontSize: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Wrap text to fit within a node of the given maxWidth.
|
|
100
|
+
* Tries wrapping at baseFontSize first. If text doesn't fit within
|
|
101
|
+
* maxLines, reduces font size by 1px at a time down to minFontSize.
|
|
102
|
+
* As a last resort, truncates the final line with ellipsis.
|
|
103
|
+
*/
|
|
104
|
+
export function wrapText(
|
|
105
|
+
text: string,
|
|
106
|
+
maxWidth: number,
|
|
107
|
+
baseFontSize: number,
|
|
108
|
+
minFontSize: number,
|
|
109
|
+
maxLines: number = MAX_LABEL_LINES
|
|
110
|
+
): WrapResult {
|
|
111
|
+
if (!text) return { lines: [''], fontSize: baseFontSize };
|
|
112
|
+
|
|
113
|
+
const tokens = tokenize(text);
|
|
114
|
+
|
|
115
|
+
// Try at each font size from base down to min
|
|
116
|
+
for (let fs = baseFontSize; fs >= minFontSize; fs--) {
|
|
117
|
+
const lines = tryWrap(tokens, maxWidth, fs, maxLines);
|
|
118
|
+
if (lines) {
|
|
119
|
+
// Ensure each line fits (truncate overly long single tokens)
|
|
120
|
+
return { lines: truncateLastLine(lines, maxWidth, fs), fontSize: fs };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Last resort: wrap at minFontSize with unlimited lines, then take first maxLines
|
|
125
|
+
const allLines = tryWrap(tokens, maxWidth, minFontSize, 999) ?? [text];
|
|
126
|
+
const capped = allLines.slice(0, maxLines);
|
|
127
|
+
const truncated = truncateLastLine(capped, maxWidth, minFontSize);
|
|
128
|
+
// If we dropped lines, append ellipsis to indicate overflow
|
|
129
|
+
if (allLines.length > maxLines) {
|
|
130
|
+
const last = truncated[truncated.length - 1];
|
|
131
|
+
if (!last.endsWith('\u2026')) {
|
|
132
|
+
const availWidth = maxWidth - H_PAD;
|
|
133
|
+
const charWidth = minFontSize * CHAR_WIDTH_RATIO;
|
|
134
|
+
const maxChars = Math.max(1, Math.floor(availWidth / charWidth));
|
|
135
|
+
if (last.length >= maxChars - 1) {
|
|
136
|
+
truncated[truncated.length - 1] =
|
|
137
|
+
last.substring(0, maxChars - 1) + '\u2026';
|
|
138
|
+
} else {
|
|
139
|
+
truncated[truncated.length - 1] = last + '\u2026';
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
lines: truncated,
|
|
145
|
+
fontSize: minFontSize,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ============================================================
|
|
150
|
+
// Compute full node text layout (shared between layout + renderer)
|
|
151
|
+
// ============================================================
|
|
152
|
+
|
|
153
|
+
const ROOT_FONT_SIZE = 17;
|
|
154
|
+
const MIN_FONT_SIZE = 9;
|
|
155
|
+
const FONT_STEP = 3;
|
|
156
|
+
const DESC_FONT_SIZE = 10;
|
|
157
|
+
|
|
158
|
+
function labelFontSize(depth: number): number {
|
|
159
|
+
return Math.max(MIN_FONT_SIZE, ROOT_FONT_SIZE - depth * FONT_STEP);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
interface NodeTextLayout {
|
|
163
|
+
labelLines: string[];
|
|
164
|
+
labelFontSize: number;
|
|
165
|
+
descLines: string[];
|
|
166
|
+
descFontSize: number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Compute wrapped text layout for a mindmap node.
|
|
171
|
+
* Called by both layout (for height) and renderer (for drawing).
|
|
172
|
+
*/
|
|
173
|
+
export function computeNodeText(
|
|
174
|
+
label: string,
|
|
175
|
+
description: string[] | undefined,
|
|
176
|
+
depth: number,
|
|
177
|
+
nodeWidth: number,
|
|
178
|
+
hideDescriptions: boolean
|
|
179
|
+
): NodeTextLayout {
|
|
180
|
+
const baseFontSize = labelFontSize(depth);
|
|
181
|
+
const labelResult = wrapText(
|
|
182
|
+
label,
|
|
183
|
+
nodeWidth,
|
|
184
|
+
baseFontSize,
|
|
185
|
+
MIN_FONT_SIZE,
|
|
186
|
+
MAX_LABEL_LINES
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const descLines: string[] = [];
|
|
190
|
+
let descFontSize = DESC_FONT_SIZE;
|
|
191
|
+
if (!hideDescriptions && description && description.length > 0) {
|
|
192
|
+
// Wrap each description line independently so bullets and line breaks are preserved.
|
|
193
|
+
// Cap total output lines at MAX_DESC_LINES across all input lines.
|
|
194
|
+
let remaining = MAX_DESC_LINES;
|
|
195
|
+
for (const rawLine of description) {
|
|
196
|
+
if (remaining <= 0) break;
|
|
197
|
+
const line = preprocessDescriptionLine(rawLine);
|
|
198
|
+
const lineResult = wrapText(
|
|
199
|
+
line,
|
|
200
|
+
nodeWidth,
|
|
201
|
+
DESC_FONT_SIZE,
|
|
202
|
+
DESC_FONT_SIZE,
|
|
203
|
+
remaining
|
|
204
|
+
);
|
|
205
|
+
descLines.push(...lineResult.lines);
|
|
206
|
+
remaining -= lineResult.lines.length;
|
|
207
|
+
descFontSize = lineResult.fontSize;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
labelLines: labelResult.lines,
|
|
213
|
+
labelFontSize: labelResult.fontSize,
|
|
214
|
+
descLines,
|
|
215
|
+
descFontSize,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { DgmoError } from '../diagnostics.js';
|
|
2
|
+
import type { TagGroup } from '../utils/tag-groups.js';
|
|
3
|
+
|
|
4
|
+
export interface MindmapNode {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string[];
|
|
8
|
+
metadata: Record<string, string>;
|
|
9
|
+
children: MindmapNode[];
|
|
10
|
+
parentId: string | null;
|
|
11
|
+
lineNumber: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
collapsed?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ParsedMindmap {
|
|
17
|
+
title: string | null;
|
|
18
|
+
titleLineNumber: number | null;
|
|
19
|
+
roots: MindmapNode[];
|
|
20
|
+
tagGroups: TagGroup[];
|
|
21
|
+
options: Record<string, string>;
|
|
22
|
+
diagnostics: DgmoError[];
|
|
23
|
+
error: string | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface MindmapLayoutNode {
|
|
27
|
+
id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
description?: string[];
|
|
30
|
+
metadata: Record<string, string>;
|
|
31
|
+
lineNumber: number;
|
|
32
|
+
color?: string;
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
depth: number;
|
|
38
|
+
angle: number;
|
|
39
|
+
radius: number;
|
|
40
|
+
hiddenCount?: number;
|
|
41
|
+
hasChildren?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface MindmapLayoutEdge {
|
|
45
|
+
sourceId: string;
|
|
46
|
+
targetId: string;
|
|
47
|
+
path: string; // SVG path d attribute
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface MindmapLayoutResult {
|
|
51
|
+
nodes: MindmapLayoutNode[];
|
|
52
|
+
edges: MindmapLayoutEdge[];
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
}
|
package/src/org/parser.ts
CHANGED
|
@@ -270,8 +270,7 @@ export function parseOrg(content: string, palette?: PaletteColors): ParsedOrg {
|
|
|
270
270
|
|
|
271
271
|
if (containerMatch) {
|
|
272
272
|
// It's a container node
|
|
273
|
-
const
|
|
274
|
-
const { label, color } = extractColor(rawLabel, palette);
|
|
273
|
+
const label = containerMatch[1].trim();
|
|
275
274
|
|
|
276
275
|
containerCounter++;
|
|
277
276
|
const node: OrgNode = {
|
|
@@ -282,7 +281,6 @@ export function parseOrg(content: string, palette?: PaletteColors): ParsedOrg {
|
|
|
282
281
|
parentId: null,
|
|
283
282
|
isContainer: true,
|
|
284
283
|
lineNumber,
|
|
285
|
-
color,
|
|
286
284
|
};
|
|
287
285
|
|
|
288
286
|
attachNode(node, indent, indentStack, result);
|
|
@@ -378,8 +376,7 @@ function parseNodeLabel(
|
|
|
378
376
|
// Check for single-line compact metadata: "Alice Park | role: Senior, location: NY"
|
|
379
377
|
const segments = trimmed.split('|').map((s) => s.trim());
|
|
380
378
|
|
|
381
|
-
const
|
|
382
|
-
const { label, color } = extractColor(rawLabel, palette);
|
|
379
|
+
const label = segments[0];
|
|
383
380
|
|
|
384
381
|
const metadata = parsePipeMetadata(
|
|
385
382
|
segments,
|
|
@@ -395,7 +392,6 @@ function parseNodeLabel(
|
|
|
395
392
|
parentId: null,
|
|
396
393
|
isContainer: false,
|
|
397
394
|
lineNumber,
|
|
398
|
-
color,
|
|
399
395
|
};
|
|
400
396
|
}
|
|
401
397
|
|
package/src/render.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from './dgmo-router';
|
|
8
8
|
import type { DgmoError } from './diagnostics';
|
|
9
9
|
import { getPalette } from './palettes/registry';
|
|
10
|
+
import type { CompactViewState } from './sharing';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Ensures DOM globals are available for D3 renderers.
|
|
@@ -73,6 +74,8 @@ export async function render(
|
|
|
73
74
|
tagGroup?: string;
|
|
74
75
|
/** Legend state for export — controls which tag group is shown in exported SVG. */
|
|
75
76
|
legendState?: { activeGroup?: string; hiddenAttributes?: string[] };
|
|
77
|
+
/** View state for export — controls interactive state (collapse, swimlanes, etc.) */
|
|
78
|
+
viewState?: CompactViewState;
|
|
76
79
|
}
|
|
77
80
|
): Promise<{ svg: string; diagnostics: DgmoError[] }> {
|
|
78
81
|
const theme = options?.theme ?? 'light';
|
|
@@ -86,15 +89,15 @@ export async function render(
|
|
|
86
89
|
const chartType = parseDgmoChartType(content);
|
|
87
90
|
const category = chartType ? getRenderCategory(chartType) : null;
|
|
88
91
|
|
|
89
|
-
// Build
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
:
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
// Build viewState from legendState (backwards compat) or use provided viewState
|
|
93
|
+
const viewState: CompactViewState | undefined =
|
|
94
|
+
options?.viewState ??
|
|
95
|
+
(options?.legendState
|
|
96
|
+
? {
|
|
97
|
+
tag: options.legendState.activeGroup ?? undefined,
|
|
98
|
+
ha: options.legendState.hiddenAttributes,
|
|
99
|
+
}
|
|
100
|
+
: undefined);
|
|
98
101
|
|
|
99
102
|
if (category === 'data-chart') {
|
|
100
103
|
const svg = await renderExtendedChartForExport(
|
|
@@ -107,17 +110,11 @@ export async function render(
|
|
|
107
110
|
|
|
108
111
|
// Visualization/diagram and unknown/null types all go through the unified renderer
|
|
109
112
|
await ensureDom();
|
|
110
|
-
const svg = await renderForExport(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
c4Level: options?.c4Level,
|
|
117
|
-
c4System: options?.c4System,
|
|
118
|
-
c4Container: options?.c4Container,
|
|
119
|
-
tagGroup: options?.tagGroup,
|
|
120
|
-
}
|
|
121
|
-
);
|
|
113
|
+
const svg = await renderForExport(content, theme, paletteColors, viewState, {
|
|
114
|
+
c4Level: options?.c4Level,
|
|
115
|
+
c4System: options?.c4System,
|
|
116
|
+
c4Container: options?.c4Container,
|
|
117
|
+
tagGroup: options?.tagGroup,
|
|
118
|
+
});
|
|
122
119
|
return { svg, diagnostics };
|
|
123
120
|
}
|