@diagrammo/dgmo 0.7.3 → 0.8.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/AGENTS.md +15 -20
- package/README.md +56 -58
- package/dist/cli.cjs +188 -181
- package/dist/index.cjs +3506 -1057
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -43
- package/dist/index.d.ts +196 -43
- package/dist/index.js +3493 -1057
- package/dist/index.js.map +1 -1
- package/docs/language-reference.md +629 -289
- package/package.json +1 -1
- package/src/c4/layout.ts +6 -9
- package/src/c4/parser.ts +189 -83
- package/src/c4/renderer.ts +8 -9
- package/src/chart.ts +296 -83
- package/src/class/parser.ts +54 -37
- package/src/class/renderer.ts +8 -8
- package/src/cli.ts +8 -8
- package/src/colors.ts +4 -1
- package/src/completion.ts +757 -10
- package/src/d3.ts +310 -73
- package/src/dgmo-router.ts +63 -8
- package/src/echarts.ts +726 -231
- package/src/er/parser.ts +94 -76
- package/src/er/renderer.ts +6 -5
- package/src/gantt/parser.ts +144 -69
- package/src/gantt/renderer.ts +50 -14
- package/src/gantt/types.ts +3 -3
- package/src/graph/flowchart-parser.ts +97 -37
- package/src/graph/flowchart-renderer.ts +4 -3
- package/src/graph/state-parser.ts +50 -31
- package/src/graph/state-renderer.ts +4 -3
- package/src/index.ts +14 -5
- package/src/infra/compute.ts +1 -0
- package/src/infra/layout.ts +3 -0
- package/src/infra/parser.ts +291 -92
- package/src/infra/renderer.ts +172 -30
- package/src/infra/types.ts +5 -0
- package/src/initiative-status/layout.ts +1 -1
- package/src/initiative-status/parser.ts +121 -47
- package/src/initiative-status/renderer.ts +42 -23
- package/src/initiative-status/types.ts +10 -2
- package/src/kanban/parser.ts +60 -37
- package/src/kanban/renderer.ts +2 -2
- package/src/kanban/types.ts +1 -0
- package/src/org/layout.ts +9 -9
- package/src/org/parser.ts +39 -40
- package/src/org/renderer.ts +5 -6
- package/src/org/resolver.ts +26 -19
- package/src/render.ts +1 -1
- package/src/sequence/parser.ts +304 -95
- package/src/sequence/renderer.ts +9 -9
- package/src/sitemap/layout.ts +3 -4
- package/src/sitemap/parser.ts +57 -49
- package/src/sitemap/renderer.ts +6 -7
- package/src/utils/arrows.ts +25 -6
- package/src/utils/duration.ts +43 -7
- package/src/utils/legend-constants.ts +26 -0
- package/src/utils/legend-svg.ts +167 -0
- package/src/utils/parsing.ts +247 -7
- package/src/utils/tag-groups.ts +160 -15
- package/src/utils/title-constants.ts +9 -0
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { resolveColor } from '../colors';
|
|
2
2
|
import type { PaletteColors } from '../palettes';
|
|
3
3
|
import { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
measureIndent,
|
|
6
|
+
extractColor,
|
|
7
|
+
normalizeDirection,
|
|
8
|
+
inferArrowColor,
|
|
9
|
+
parseFirstLine,
|
|
10
|
+
OPTION_NOCOLON_RE,
|
|
11
|
+
GROUP_HASH_RE,
|
|
12
|
+
DOUBLE_HASH_RE,
|
|
13
|
+
ALL_CHART_TYPES,
|
|
14
|
+
} from '../utils/parsing';
|
|
5
15
|
import type {
|
|
6
16
|
ParsedGraph,
|
|
7
17
|
GraphNode,
|
|
8
18
|
GraphEdge,
|
|
19
|
+
GraphGroup,
|
|
9
20
|
GraphShape,
|
|
10
21
|
GraphDirection,
|
|
11
22
|
} from './types';
|
|
@@ -177,22 +188,24 @@ function parseArrowToken(token: string, palette?: PaletteColors): ArrowInfo {
|
|
|
177
188
|
// Color-only: -(color)->
|
|
178
189
|
const colorOnly = token.match(/^-\(([^)]+)\)->$/);
|
|
179
190
|
if (colorOnly) {
|
|
180
|
-
return { color: resolveColor(colorOnly[1].trim(), palette) };
|
|
191
|
+
return { color: resolveColor(colorOnly[1].trim(), palette) ?? undefined };
|
|
181
192
|
}
|
|
182
193
|
// -label(color)-> or -label->
|
|
183
194
|
const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
|
|
184
195
|
if (m) {
|
|
185
196
|
const label = m[1]?.trim() || undefined;
|
|
186
|
-
|
|
197
|
+
let color = m[2] ? resolveColor(m[2].trim(), palette) ?? undefined : undefined;
|
|
198
|
+
if (label && !color) {
|
|
199
|
+
color = inferArrowColor(label);
|
|
200
|
+
}
|
|
187
201
|
return { label, color };
|
|
188
202
|
}
|
|
189
203
|
return {};
|
|
190
204
|
}
|
|
191
205
|
|
|
192
206
|
// ============================================================
|
|
193
|
-
//
|
|
207
|
+
// Group heading support
|
|
194
208
|
// ============================================================
|
|
195
|
-
const LEGACY_GROUP_RE = /^##\s+/;
|
|
196
209
|
|
|
197
210
|
// ============================================================
|
|
198
211
|
// Main parser
|
|
@@ -223,6 +236,12 @@ export function parseFlowchart(
|
|
|
223
236
|
const nodeMap = new Map<string, GraphNode>();
|
|
224
237
|
const indentStack: { nodeId: string; indent: number }[] = [];
|
|
225
238
|
let contentStarted = false;
|
|
239
|
+
let firstLineParsed = false;
|
|
240
|
+
|
|
241
|
+
// Group support
|
|
242
|
+
let currentGroup: GraphGroup | null = null;
|
|
243
|
+
let groupIndent = -1;
|
|
244
|
+
const groups: GraphGroup[] = [];
|
|
226
245
|
|
|
227
246
|
function getOrCreateNode(ref: NodeRef, lineNumber: number): GraphNode {
|
|
228
247
|
const existing = nodeMap.get(ref.id);
|
|
@@ -234,10 +253,15 @@ export function parseFlowchart(
|
|
|
234
253
|
shape: ref.shape,
|
|
235
254
|
lineNumber,
|
|
236
255
|
...(ref.color && { color: ref.color }),
|
|
256
|
+
...(currentGroup && { group: currentGroup.id }),
|
|
237
257
|
};
|
|
238
258
|
nodeMap.set(ref.id, node);
|
|
239
259
|
result.nodes.push(node);
|
|
240
260
|
|
|
261
|
+
if (currentGroup && !currentGroup.nodeIds.includes(ref.id)) {
|
|
262
|
+
currentGroup.nodeIds.push(ref.id);
|
|
263
|
+
}
|
|
264
|
+
|
|
241
265
|
return node;
|
|
242
266
|
}
|
|
243
267
|
|
|
@@ -374,54 +398,89 @@ export function parseFlowchart(
|
|
|
374
398
|
// Skip comments
|
|
375
399
|
if (trimmed.startsWith('//')) continue;
|
|
376
400
|
|
|
377
|
-
//
|
|
378
|
-
if (
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
if (!contentStarted && trimmed.includes(':') && !trimmed.includes('->')) {
|
|
387
|
-
const colonIdx = trimmed.indexOf(':');
|
|
388
|
-
const key = trimmed.substring(0, colonIdx).trim().toLowerCase();
|
|
389
|
-
const value = trimmed.substring(colonIdx + 1).trim();
|
|
390
|
-
|
|
391
|
-
if (key === 'chart') {
|
|
392
|
-
if (value.toLowerCase() !== 'flowchart') {
|
|
393
|
-
const allTypes = ['flowchart', 'sequence', 'class', 'er', 'org', 'bar', 'line', 'pie', 'scatter', 'sankey', 'venn', 'timeline', 'arc', 'slope'];
|
|
394
|
-
let msg = `Expected chart type "flowchart", got "${value}"`;
|
|
395
|
-
const hint = suggest(value.toLowerCase(), allTypes);
|
|
401
|
+
// First line: try parseFirstLine for `flowchart [Title]`
|
|
402
|
+
if (!firstLineParsed && !contentStarted) {
|
|
403
|
+
const firstLineResult = parseFirstLine(trimmed);
|
|
404
|
+
if (firstLineResult) {
|
|
405
|
+
firstLineParsed = true;
|
|
406
|
+
if (firstLineResult.chartType !== 'flowchart') {
|
|
407
|
+
const allTypes = Array.from(ALL_CHART_TYPES);
|
|
408
|
+
let msg = `Expected chart type "flowchart", got "${firstLineResult.chartType}"`;
|
|
409
|
+
const hint = suggest(firstLineResult.chartType, allTypes);
|
|
396
410
|
if (hint) msg += `. ${hint}`;
|
|
397
411
|
return fail(lineNumber, msg);
|
|
398
412
|
}
|
|
413
|
+
if (firstLineResult.title) {
|
|
414
|
+
result.title = firstLineResult.title;
|
|
415
|
+
result.titleLineNumber = lineNumber;
|
|
416
|
+
}
|
|
399
417
|
continue;
|
|
400
418
|
}
|
|
419
|
+
}
|
|
401
420
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
421
|
+
// ## group headings — emit helpful error
|
|
422
|
+
if (DOUBLE_HASH_RE.test(trimmed)) {
|
|
423
|
+
result.diagnostics.push(
|
|
424
|
+
makeDgmoError(lineNumber, 'Use `#` for groups \u2014 nesting is done with indentation.', 'error')
|
|
425
|
+
);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// # GroupName — alternate group notation
|
|
430
|
+
const hashGroupMatch = trimmed.match(GROUP_HASH_RE);
|
|
431
|
+
if (hashGroupMatch) {
|
|
432
|
+
const { label, color } = extractColor(hashGroupMatch[1].trim(), palette);
|
|
433
|
+
currentGroup = {
|
|
434
|
+
id: `group:${label.toLowerCase()}`,
|
|
435
|
+
label,
|
|
436
|
+
nodeIds: [],
|
|
437
|
+
lineNumber,
|
|
438
|
+
...(color && { color }),
|
|
439
|
+
};
|
|
440
|
+
groupIndent = indent;
|
|
441
|
+
groups.push(currentGroup);
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
407
444
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
445
|
+
// Options (space-separated, before content)
|
|
446
|
+
if (!contentStarted) {
|
|
447
|
+
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
448
|
+
if (optMatch && !trimmed.includes('->')) {
|
|
449
|
+
const key = optMatch[1].toLowerCase();
|
|
450
|
+
const value = optMatch[2].trim();
|
|
451
|
+
|
|
452
|
+
if (key === 'direction' || key === 'orientation') {
|
|
453
|
+
const dir = normalizeDirection(value);
|
|
454
|
+
if (dir) {
|
|
455
|
+
result.direction = dir;
|
|
456
|
+
}
|
|
457
|
+
continue;
|
|
412
458
|
}
|
|
459
|
+
|
|
460
|
+
// Boolean: no-color = color off
|
|
461
|
+
if (key === 'no-color') {
|
|
462
|
+
result.options['color'] = 'off';
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Store other options (e.g., color off)
|
|
467
|
+
result.options[key] = value;
|
|
413
468
|
continue;
|
|
414
469
|
}
|
|
470
|
+
}
|
|
415
471
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
472
|
+
// Close current group when indent returns to or below the group level
|
|
473
|
+
if (currentGroup && indent <= groupIndent) {
|
|
474
|
+
currentGroup = null;
|
|
475
|
+
groupIndent = -1;
|
|
419
476
|
}
|
|
420
477
|
|
|
421
478
|
// Content line (nodes and edges)
|
|
422
479
|
processContentLine(trimmed, lineNumber, indent);
|
|
423
480
|
}
|
|
424
481
|
|
|
482
|
+
if (groups.length > 0) result.groups = groups;
|
|
483
|
+
|
|
425
484
|
// Validation: no nodes found
|
|
426
485
|
if (result.nodes.length === 0 && !result.error) {
|
|
427
486
|
const diag = makeDgmoError(1, 'No nodes found. Add flowchart content with shape syntax like [Process] or (Start).');
|
|
@@ -497,7 +556,8 @@ export function extractSymbols(docText: string): DiagramSymbols {
|
|
|
497
556
|
let inMetadata = true;
|
|
498
557
|
for (const rawLine of docText.split('\n')) {
|
|
499
558
|
const line = rawLine.trim();
|
|
500
|
-
|
|
559
|
+
// Skip old-style colon metadata and new-style space-separated options
|
|
560
|
+
if (inMetadata && (/^[a-z-]+\s*:/i.test(line) || /^[a-z-]+\s+\S/i.test(line))) continue;
|
|
501
561
|
inMetadata = false;
|
|
502
562
|
if (line.length === 0 || /^\s/.test(rawLine)) continue;
|
|
503
563
|
const m = NODE_ID_RE.exec(line);
|
|
@@ -11,6 +11,7 @@ import type { ParsedGraph, GraphShape } from './types';
|
|
|
11
11
|
import type { LayoutResult, LayoutNode } from './layout';
|
|
12
12
|
import { parseFlowchart } from './flowchart-parser';
|
|
13
13
|
import { layoutGraph } from './layout';
|
|
14
|
+
import { TITLE_FONT_SIZE, TITLE_FONT_WEIGHT, TITLE_Y } from '../utils/title-constants';
|
|
14
15
|
|
|
15
16
|
// ============================================================
|
|
16
17
|
// Constants
|
|
@@ -301,11 +302,11 @@ export function renderFlowchart(
|
|
|
301
302
|
.append('text')
|
|
302
303
|
.attr('class', 'chart-title')
|
|
303
304
|
.attr('x', width / 2)
|
|
304
|
-
.attr('y',
|
|
305
|
+
.attr('y', TITLE_Y)
|
|
305
306
|
.attr('text-anchor', 'middle')
|
|
306
307
|
.attr('fill', palette.text)
|
|
307
|
-
.attr('font-size',
|
|
308
|
-
.attr('font-weight',
|
|
308
|
+
.attr('font-size', TITLE_FONT_SIZE)
|
|
309
|
+
.attr('font-weight', TITLE_FONT_WEIGHT)
|
|
309
310
|
.style('cursor', onClickItem && graph.titleLineNumber ? 'pointer' : 'default')
|
|
310
311
|
.text(graph.title);
|
|
311
312
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { resolveColor } from '../colors';
|
|
2
2
|
import type { PaletteColors } from '../palettes';
|
|
3
3
|
import { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
measureIndent,
|
|
6
|
+
extractColor,
|
|
7
|
+
normalizeDirection,
|
|
8
|
+
parseFirstLine,
|
|
9
|
+
OPTION_NOCOLON_RE,
|
|
10
|
+
ALL_CHART_TYPES,
|
|
11
|
+
} from '../utils/parsing';
|
|
5
12
|
import type {
|
|
6
13
|
ParsedGraph,
|
|
7
14
|
GraphNode,
|
|
@@ -95,11 +102,11 @@ interface ArrowInfo {
|
|
|
95
102
|
function parseArrowToken(token: string, palette?: PaletteColors): ArrowInfo {
|
|
96
103
|
if (token === '->') return {};
|
|
97
104
|
const colorOnly = token.match(/^-\(([^)]+)\)->$/);
|
|
98
|
-
if (colorOnly) return { color: resolveColor(colorOnly[1].trim(), palette) };
|
|
105
|
+
if (colorOnly) return { color: resolveColor(colorOnly[1].trim(), palette) ?? undefined };
|
|
99
106
|
const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
|
|
100
107
|
if (m) {
|
|
101
108
|
const label = m[1]?.trim() || undefined;
|
|
102
|
-
const color = m[2] ? resolveColor(m[2].trim(), palette) : undefined;
|
|
109
|
+
const color = m[2] ? resolveColor(m[2].trim(), palette) ?? undefined : undefined;
|
|
103
110
|
return { label, color };
|
|
104
111
|
}
|
|
105
112
|
return {};
|
|
@@ -168,6 +175,7 @@ export function parseState(
|
|
|
168
175
|
let groupIndent = -1;
|
|
169
176
|
const groups: GraphGroup[] = [];
|
|
170
177
|
let contentStarted = false;
|
|
178
|
+
let firstLineParsed = false;
|
|
171
179
|
|
|
172
180
|
function getOrCreateNode(ref: NodeRef, lineNumber: number): GraphNode {
|
|
173
181
|
const existing = nodeMap.get(ref.id);
|
|
@@ -217,6 +225,26 @@ export function parseState(
|
|
|
217
225
|
if (!trimmed) continue;
|
|
218
226
|
if (trimmed.startsWith('//')) continue;
|
|
219
227
|
|
|
228
|
+
// First line: try parseFirstLine for `state [Title]`
|
|
229
|
+
if (!firstLineParsed && !contentStarted) {
|
|
230
|
+
const firstLineResult = parseFirstLine(trimmed);
|
|
231
|
+
if (firstLineResult) {
|
|
232
|
+
firstLineParsed = true;
|
|
233
|
+
if (firstLineResult.chartType !== 'state') {
|
|
234
|
+
const allTypes = Array.from(ALL_CHART_TYPES);
|
|
235
|
+
let msg = `Expected chart type "state", got "${firstLineResult.chartType}"`;
|
|
236
|
+
const hint = suggest(firstLineResult.chartType, allTypes);
|
|
237
|
+
if (hint) msg += `. ${hint}`;
|
|
238
|
+
return fail(lineNumber, msg);
|
|
239
|
+
}
|
|
240
|
+
if (firstLineResult.title) {
|
|
241
|
+
result.title = firstLineResult.title;
|
|
242
|
+
result.titleLineNumber = lineNumber;
|
|
243
|
+
}
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
220
248
|
// Group brackets: [Name] or [Name](color)
|
|
221
249
|
const groupMatch = trimmed.match(GROUP_BRACKET_RE);
|
|
222
250
|
if (groupMatch && groupMatch[1].trim() !== '*') {
|
|
@@ -238,39 +266,30 @@ export function parseState(
|
|
|
238
266
|
continue;
|
|
239
267
|
}
|
|
240
268
|
|
|
241
|
-
//
|
|
242
|
-
if (!contentStarted
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
269
|
+
// Options (space-separated, before content)
|
|
270
|
+
if (!contentStarted) {
|
|
271
|
+
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
272
|
+
if (optMatch && !trimmed.includes('->')) {
|
|
273
|
+
const key = optMatch[1].toLowerCase();
|
|
274
|
+
const value = optMatch[2].trim();
|
|
275
|
+
|
|
276
|
+
if (key === 'direction' || key === 'orientation') {
|
|
277
|
+
const dir = normalizeDirection(value);
|
|
278
|
+
if (dir) {
|
|
279
|
+
result.direction = dir;
|
|
280
|
+
}
|
|
281
|
+
continue;
|
|
254
282
|
}
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
283
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (key === 'direction') {
|
|
265
|
-
const dir = value.toUpperCase() as GraphDirection;
|
|
266
|
-
if (dir === 'TB' || dir === 'LR') {
|
|
267
|
-
result.direction = dir;
|
|
284
|
+
// Boolean: no-color = color off
|
|
285
|
+
if (key === 'no-color') {
|
|
286
|
+
result.options['color'] = 'off';
|
|
287
|
+
continue;
|
|
268
288
|
}
|
|
289
|
+
|
|
290
|
+
result.options[key] = value;
|
|
269
291
|
continue;
|
|
270
292
|
}
|
|
271
|
-
|
|
272
|
-
result.options[key] = value;
|
|
273
|
-
continue;
|
|
274
293
|
}
|
|
275
294
|
|
|
276
295
|
// Content line — nodes and edges
|
|
@@ -11,6 +11,7 @@ import type { ParsedGraph } from './types';
|
|
|
11
11
|
import type { LayoutResult, LayoutNode } from './layout';
|
|
12
12
|
import { parseState } from './state-parser';
|
|
13
13
|
import { layoutGraph } from './layout';
|
|
14
|
+
import { TITLE_FONT_SIZE, TITLE_FONT_WEIGHT, TITLE_Y } from '../utils/title-constants';
|
|
14
15
|
|
|
15
16
|
// ============================================================
|
|
16
17
|
// Constants
|
|
@@ -154,11 +155,11 @@ export function renderState(
|
|
|
154
155
|
.append('text')
|
|
155
156
|
.attr('class', 'chart-title')
|
|
156
157
|
.attr('x', width / 2)
|
|
157
|
-
.attr('y',
|
|
158
|
+
.attr('y', TITLE_Y)
|
|
158
159
|
.attr('text-anchor', 'middle')
|
|
159
160
|
.attr('fill', palette.text)
|
|
160
|
-
.attr('font-size',
|
|
161
|
-
.attr('font-weight',
|
|
161
|
+
.attr('font-size', TITLE_FONT_SIZE)
|
|
162
|
+
.attr('font-weight', TITLE_FONT_WEIGHT)
|
|
162
163
|
.style('cursor', onClickItem && graph.titleLineNumber ? 'pointer' : 'default')
|
|
163
164
|
.text(graph.title);
|
|
164
165
|
|
package/src/index.ts
CHANGED
|
@@ -139,8 +139,6 @@ export { parseOrg } from './org/parser';
|
|
|
139
139
|
export type {
|
|
140
140
|
ParsedOrg,
|
|
141
141
|
OrgNode,
|
|
142
|
-
OrgTagGroup,
|
|
143
|
-
OrgTagEntry,
|
|
144
142
|
} from './org/parser';
|
|
145
143
|
|
|
146
144
|
export { layoutOrg } from './org/layout';
|
|
@@ -259,7 +257,7 @@ export type { InfraRole } from './infra/roles';
|
|
|
259
257
|
export { layoutInfra } from './infra/layout';
|
|
260
258
|
export type { InfraLayoutResult, InfraLayoutNode, InfraLayoutEdge, InfraLayoutGroup } from './infra/layout';
|
|
261
259
|
export { renderInfra, parseAndLayoutInfra, computeInfraLegendGroups } from './infra/renderer';
|
|
262
|
-
export type { InfraLegendGroup } from './infra/renderer';
|
|
260
|
+
export type { InfraLegendGroup, InfraPlaybackState } from './infra/renderer';
|
|
263
261
|
export type { CollapsedSitemapResult } from './sitemap/collapse';
|
|
264
262
|
|
|
265
263
|
// ── Gantt Chart ───────────────────────────────────────────
|
|
@@ -306,7 +304,10 @@ export { renderFlowchart, renderFlowchartForExport } from './graph/flowchart-ren
|
|
|
306
304
|
// Config Builders (produce framework-specific config objects)
|
|
307
305
|
// ============================================================
|
|
308
306
|
|
|
309
|
-
export { buildExtendedChartOption, buildSimpleChartOption, renderExtendedChartForExport } from './echarts';
|
|
307
|
+
export { buildExtendedChartOption, buildSimpleChartOption, renderExtendedChartForExport, getExtendedChartLegendGroups, getSimpleChartLegendGroups, computeScatterLabelGraphics } from './echarts';
|
|
308
|
+
export type { ScatterLabelPoint } from './echarts';
|
|
309
|
+
export { renderLegendSvg, type LegendGroupData } from './utils/legend-svg';
|
|
310
|
+
export { LEGEND_HEIGHT } from './utils/legend-constants';
|
|
310
311
|
export { buildMermaidQuadrant } from './dgmo-mermaid';
|
|
311
312
|
|
|
312
313
|
// ============================================================
|
|
@@ -395,8 +396,16 @@ export type {
|
|
|
395
396
|
export {
|
|
396
397
|
registerExtractor,
|
|
397
398
|
extractDiagramSymbols,
|
|
399
|
+
COMPLETION_REGISTRY,
|
|
400
|
+
CHART_TYPES,
|
|
401
|
+
METADATA_KEY_SET,
|
|
402
|
+
ENTITY_TYPES,
|
|
403
|
+
PIPE_METADATA,
|
|
404
|
+
extractTagDeclarations,
|
|
398
405
|
} from './completion';
|
|
399
|
-
export type { DiagramSymbols, ExtractFn } from './completion';
|
|
406
|
+
export type { DiagramSymbols, ExtractFn, DirectiveSpec, DirectiveValueSpec, PipeKeySpec } from './completion';
|
|
407
|
+
|
|
408
|
+
export { parseFirstLine, ALL_CHART_TYPES } from './utils/parsing';
|
|
400
409
|
|
|
401
410
|
// ============================================================
|
|
402
411
|
// Branding
|
package/src/infra/compute.ts
CHANGED
package/src/infra/layout.ts
CHANGED
|
@@ -47,6 +47,7 @@ export interface InfraLayoutEdge {
|
|
|
47
47
|
sourceId: string;
|
|
48
48
|
targetId: string;
|
|
49
49
|
label: string;
|
|
50
|
+
async: boolean;
|
|
50
51
|
computedRps: number;
|
|
51
52
|
split: number;
|
|
52
53
|
fanout: number | null;
|
|
@@ -575,6 +576,7 @@ export function layoutInfra(computed: ComputedInfraModel, expandedNodeIds?: Set<
|
|
|
575
576
|
sourceId: edge.sourceId,
|
|
576
577
|
targetId: edge.targetId,
|
|
577
578
|
label: edge.label,
|
|
579
|
+
async: edge.async,
|
|
578
580
|
computedRps: edge.computedRps,
|
|
579
581
|
split: edge.split,
|
|
580
582
|
fanout: edge.fanout,
|
|
@@ -587,6 +589,7 @@ export function layoutInfra(computed: ComputedInfraModel, expandedNodeIds?: Set<
|
|
|
587
589
|
sourceId: edge.sourceId,
|
|
588
590
|
targetId: edge.targetId,
|
|
589
591
|
label: edge.label,
|
|
592
|
+
async: edge.async,
|
|
590
593
|
computedRps: edge.computedRps,
|
|
591
594
|
split: edge.split,
|
|
592
595
|
fanout: edge.fanout,
|