@diagrammo/dgmo 0.2.7 → 0.2.9
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/cli.cjs +87 -87
- package/dist/index.cjs +176 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +176 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/chart.ts +2 -0
- package/src/d3.ts +118 -9
- package/src/echarts.ts +2 -0
- package/src/graph/flowchart-parser.ts +1 -0
- package/src/graph/flowchart-renderer.ts +15 -4
- package/src/graph/types.ts +1 -0
- package/src/sequence/parser.ts +12 -17
- package/src/sequence/renderer.ts +64 -27
package/dist/index.d.cts
CHANGED
|
@@ -171,6 +171,7 @@ interface ChartDataPoint {
|
|
|
171
171
|
interface ParsedChart {
|
|
172
172
|
type: ChartType;
|
|
173
173
|
title?: string;
|
|
174
|
+
titleLineNumber?: number;
|
|
174
175
|
series?: string;
|
|
175
176
|
xlabel?: string;
|
|
176
177
|
ylabel?: string;
|
|
@@ -235,6 +236,7 @@ interface ParsedHeatmapRow {
|
|
|
235
236
|
interface ParsedEChart {
|
|
236
237
|
type: EChartsChartType;
|
|
237
238
|
title?: string;
|
|
239
|
+
titleLineNumber?: number;
|
|
238
240
|
series?: string;
|
|
239
241
|
seriesNames?: string[];
|
|
240
242
|
seriesNameColors?: (string | undefined)[];
|
|
@@ -384,6 +386,7 @@ interface D3ExportDimensions {
|
|
|
384
386
|
interface ParsedD3 {
|
|
385
387
|
type: D3ChartType | null;
|
|
386
388
|
title: string | null;
|
|
389
|
+
titleLineNumber: number | null;
|
|
387
390
|
orientation: 'horizontal' | 'vertical';
|
|
388
391
|
periods: string[];
|
|
389
392
|
data: D3DataItem[];
|
|
@@ -546,6 +549,7 @@ interface SequenceNote {
|
|
|
546
549
|
position: 'right' | 'left';
|
|
547
550
|
participantId: string;
|
|
548
551
|
lineNumber: number;
|
|
552
|
+
endLineNumber: number;
|
|
549
553
|
}
|
|
550
554
|
type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
|
|
551
555
|
declare function isSequenceBlock(el: SequenceElement): el is SequenceBlock;
|
|
@@ -564,6 +568,7 @@ interface SequenceGroup {
|
|
|
564
568
|
*/
|
|
565
569
|
interface ParsedSequenceDgmo {
|
|
566
570
|
title: string | null;
|
|
571
|
+
titleLineNumber: number | null;
|
|
567
572
|
participants: SequenceParticipant[];
|
|
568
573
|
messages: SequenceMessage[];
|
|
569
574
|
elements: SequenceElement[];
|
|
@@ -660,6 +665,7 @@ interface GraphGroup {
|
|
|
660
665
|
interface ParsedGraph {
|
|
661
666
|
type: 'flowchart';
|
|
662
667
|
title?: string;
|
|
668
|
+
titleLineNumber?: number;
|
|
663
669
|
direction: GraphDirection;
|
|
664
670
|
nodes: GraphNode[];
|
|
665
671
|
edges: GraphEdge[];
|
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ interface ChartDataPoint {
|
|
|
171
171
|
interface ParsedChart {
|
|
172
172
|
type: ChartType;
|
|
173
173
|
title?: string;
|
|
174
|
+
titleLineNumber?: number;
|
|
174
175
|
series?: string;
|
|
175
176
|
xlabel?: string;
|
|
176
177
|
ylabel?: string;
|
|
@@ -235,6 +236,7 @@ interface ParsedHeatmapRow {
|
|
|
235
236
|
interface ParsedEChart {
|
|
236
237
|
type: EChartsChartType;
|
|
237
238
|
title?: string;
|
|
239
|
+
titleLineNumber?: number;
|
|
238
240
|
series?: string;
|
|
239
241
|
seriesNames?: string[];
|
|
240
242
|
seriesNameColors?: (string | undefined)[];
|
|
@@ -384,6 +386,7 @@ interface D3ExportDimensions {
|
|
|
384
386
|
interface ParsedD3 {
|
|
385
387
|
type: D3ChartType | null;
|
|
386
388
|
title: string | null;
|
|
389
|
+
titleLineNumber: number | null;
|
|
387
390
|
orientation: 'horizontal' | 'vertical';
|
|
388
391
|
periods: string[];
|
|
389
392
|
data: D3DataItem[];
|
|
@@ -546,6 +549,7 @@ interface SequenceNote {
|
|
|
546
549
|
position: 'right' | 'left';
|
|
547
550
|
participantId: string;
|
|
548
551
|
lineNumber: number;
|
|
552
|
+
endLineNumber: number;
|
|
549
553
|
}
|
|
550
554
|
type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
|
|
551
555
|
declare function isSequenceBlock(el: SequenceElement): el is SequenceBlock;
|
|
@@ -564,6 +568,7 @@ interface SequenceGroup {
|
|
|
564
568
|
*/
|
|
565
569
|
interface ParsedSequenceDgmo {
|
|
566
570
|
title: string | null;
|
|
571
|
+
titleLineNumber: number | null;
|
|
567
572
|
participants: SequenceParticipant[];
|
|
568
573
|
messages: SequenceMessage[];
|
|
569
574
|
elements: SequenceElement[];
|
|
@@ -660,6 +665,7 @@ interface GraphGroup {
|
|
|
660
665
|
interface ParsedGraph {
|
|
661
666
|
type: 'flowchart';
|
|
662
667
|
title?: string;
|
|
668
|
+
titleLineNumber?: number;
|
|
663
669
|
direction: GraphDirection;
|
|
664
670
|
nodes: GraphNode[];
|
|
665
671
|
edges: GraphEdge[];
|
package/dist/index.js
CHANGED
|
@@ -196,6 +196,7 @@ function measureIndent(line3) {
|
|
|
196
196
|
function parseSequenceDgmo(content) {
|
|
197
197
|
const result = {
|
|
198
198
|
title: null,
|
|
199
|
+
titleLineNumber: null,
|
|
199
200
|
participants: [],
|
|
200
201
|
messages: [],
|
|
201
202
|
elements: [],
|
|
@@ -299,6 +300,7 @@ function parseSequenceDgmo(content) {
|
|
|
299
300
|
}
|
|
300
301
|
if (key === "title") {
|
|
301
302
|
result.title = value;
|
|
303
|
+
result.titleLineNumber = lineNumber;
|
|
302
304
|
continue;
|
|
303
305
|
}
|
|
304
306
|
result.options[key] = value;
|
|
@@ -528,22 +530,19 @@ function parseSequenceDgmo(content) {
|
|
|
528
530
|
const notePosition = noteSingleMatch[1]?.toLowerCase() || "right";
|
|
529
531
|
let noteParticipant = noteSingleMatch[2] || null;
|
|
530
532
|
if (!noteParticipant) {
|
|
531
|
-
if (!lastMsgFrom)
|
|
532
|
-
result.error = `Line ${lineNumber}: note requires a preceding message`;
|
|
533
|
-
return result;
|
|
534
|
-
}
|
|
533
|
+
if (!lastMsgFrom) continue;
|
|
535
534
|
noteParticipant = lastMsgFrom;
|
|
536
535
|
}
|
|
537
536
|
if (!result.participants.some((p) => p.id === noteParticipant)) {
|
|
538
|
-
|
|
539
|
-
return result;
|
|
537
|
+
continue;
|
|
540
538
|
}
|
|
541
539
|
const note = {
|
|
542
540
|
kind: "note",
|
|
543
541
|
text: noteSingleMatch[3].trim(),
|
|
544
542
|
position: notePosition,
|
|
545
543
|
participantId: noteParticipant,
|
|
546
|
-
lineNumber
|
|
544
|
+
lineNumber,
|
|
545
|
+
endLineNumber: lineNumber
|
|
547
546
|
};
|
|
548
547
|
currentContainer().push(note);
|
|
549
548
|
continue;
|
|
@@ -553,15 +552,11 @@ function parseSequenceDgmo(content) {
|
|
|
553
552
|
const notePosition = noteMultiMatch[1]?.toLowerCase() || "right";
|
|
554
553
|
let noteParticipant = noteMultiMatch[2] || null;
|
|
555
554
|
if (!noteParticipant) {
|
|
556
|
-
if (!lastMsgFrom)
|
|
557
|
-
result.error = `Line ${lineNumber}: note requires a preceding message`;
|
|
558
|
-
return result;
|
|
559
|
-
}
|
|
555
|
+
if (!lastMsgFrom) continue;
|
|
560
556
|
noteParticipant = lastMsgFrom;
|
|
561
557
|
}
|
|
562
558
|
if (!result.participants.some((p) => p.id === noteParticipant)) {
|
|
563
|
-
|
|
564
|
-
return result;
|
|
559
|
+
continue;
|
|
565
560
|
}
|
|
566
561
|
const noteLines = [];
|
|
567
562
|
while (i + 1 < lines.length) {
|
|
@@ -573,16 +568,15 @@ function parseSequenceDgmo(content) {
|
|
|
573
568
|
noteLines.push(nextTrimmed);
|
|
574
569
|
i++;
|
|
575
570
|
}
|
|
576
|
-
if (noteLines.length === 0)
|
|
577
|
-
result.error = `Line ${lineNumber}: multi-line note has no content \u2014 add indented lines or use 'note: text'`;
|
|
578
|
-
return result;
|
|
579
|
-
}
|
|
571
|
+
if (noteLines.length === 0) continue;
|
|
580
572
|
const note = {
|
|
581
573
|
kind: "note",
|
|
582
574
|
text: noteLines.join("\n"),
|
|
583
575
|
position: notePosition,
|
|
584
576
|
participantId: noteParticipant,
|
|
585
|
-
lineNumber
|
|
577
|
+
lineNumber,
|
|
578
|
+
endLineNumber: i + 1
|
|
579
|
+
// i has advanced past the body lines (1-based)
|
|
586
580
|
};
|
|
587
581
|
currentContainer().push(note);
|
|
588
582
|
continue;
|
|
@@ -630,7 +624,7 @@ var init_parser = __esm({
|
|
|
630
624
|
ARROW_RETURN_PATTERN = /^(.+?)\s*<-\s*(.+)$/;
|
|
631
625
|
UML_RETURN_PATTERN = /^(\w+\([^)]*\))\s*:\s*(.+)$/;
|
|
632
626
|
NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
|
|
633
|
-
NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+(
|
|
627
|
+
NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+([^\s:]+))?\s*:?\s*$/i;
|
|
634
628
|
}
|
|
635
629
|
});
|
|
636
630
|
|
|
@@ -975,6 +969,7 @@ function parseFlowchart(content, palette) {
|
|
|
975
969
|
}
|
|
976
970
|
if (key === "title") {
|
|
977
971
|
result.title = value;
|
|
972
|
+
result.titleLineNumber = lineNumber;
|
|
978
973
|
continue;
|
|
979
974
|
}
|
|
980
975
|
if (key === "direction") {
|
|
@@ -2413,7 +2408,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2413
2408
|
const scaledH = diagramH * scale;
|
|
2414
2409
|
const offsetX = (width - scaledW) / 2;
|
|
2415
2410
|
const offsetY = (height - scaledH) / 2;
|
|
2416
|
-
const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).style("
|
|
2411
|
+
const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
|
|
2417
2412
|
const defs = svg.append("defs");
|
|
2418
2413
|
defs.append("marker").attr("id", "fc-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`).attr("refX", ARROWHEAD_W).attr("refY", ARROWHEAD_H / 2).attr("markerWidth", ARROWHEAD_W).attr("markerHeight", ARROWHEAD_H).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`).attr("fill", palette.textMuted);
|
|
2419
2414
|
const edgeColors = /* @__PURE__ */ new Set();
|
|
@@ -2426,7 +2421,17 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2426
2421
|
}
|
|
2427
2422
|
const mainG = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY}) scale(${scale})`);
|
|
2428
2423
|
if (graph.title) {
|
|
2429
|
-
mainG.append("text").attr("x", diagramW / 2).attr("y", TITLE_FONT_SIZE).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", "bold").attr("class", "fc-title").text(graph.title);
|
|
2424
|
+
const titleEl = mainG.append("text").attr("x", diagramW / 2).attr("y", TITLE_FONT_SIZE).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", "bold").attr("class", "fc-title chart-title").style("cursor", onClickItem && graph.titleLineNumber ? "pointer" : "default").text(graph.title);
|
|
2425
|
+
if (graph.titleLineNumber) {
|
|
2426
|
+
titleEl.attr("data-line-number", graph.titleLineNumber);
|
|
2427
|
+
if (onClickItem) {
|
|
2428
|
+
titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
|
|
2429
|
+
d3Selection.select(this).attr("opacity", 0.7);
|
|
2430
|
+
}).on("mouseleave", function() {
|
|
2431
|
+
d3Selection.select(this).attr("opacity", 1);
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2430
2435
|
}
|
|
2431
2436
|
const contentG = mainG.append("g").attr("transform", `translate(0, ${titleOffset})`);
|
|
2432
2437
|
for (const group of layout.groups) {
|
|
@@ -2460,7 +2465,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2460
2465
|
}
|
|
2461
2466
|
}
|
|
2462
2467
|
for (const node of layout.nodes) {
|
|
2463
|
-
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber));
|
|
2468
|
+
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
2464
2469
|
if (onClickItem) {
|
|
2465
2470
|
nodeG.style("cursor", "pointer").on("click", () => {
|
|
2466
2471
|
onClickItem(node.lineNumber);
|
|
@@ -2543,14 +2548,16 @@ __export(renderer_exports, {
|
|
|
2543
2548
|
import * as d3Selection2 from "d3-selection";
|
|
2544
2549
|
function parseInlineMarkdown(text) {
|
|
2545
2550
|
const spans = [];
|
|
2546
|
-
const regex = /\*\*(.+?)
|
|
2551
|
+
const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|([^*_`[]+)/g;
|
|
2547
2552
|
let match;
|
|
2548
2553
|
while ((match = regex.exec(text)) !== null) {
|
|
2549
2554
|
if (match[1]) spans.push({ text: match[1], bold: true });
|
|
2550
|
-
else if (match[2]) spans.push({ text: match[2],
|
|
2551
|
-
else if (match[3]) spans.push({ text: match[3],
|
|
2552
|
-
else if (match[4]) spans.push({ text: match[4],
|
|
2553
|
-
else if (match[
|
|
2555
|
+
else if (match[2]) spans.push({ text: match[2], bold: true });
|
|
2556
|
+
else if (match[3]) spans.push({ text: match[3], italic: true });
|
|
2557
|
+
else if (match[4]) spans.push({ text: match[4], italic: true });
|
|
2558
|
+
else if (match[5]) spans.push({ text: match[5], code: true });
|
|
2559
|
+
else if (match[6]) spans.push({ text: match[6], href: match[7] });
|
|
2560
|
+
else if (match[8]) spans.push({ text: match[8] });
|
|
2554
2561
|
}
|
|
2555
2562
|
return spans;
|
|
2556
2563
|
}
|
|
@@ -2949,6 +2956,34 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
2949
2956
|
if (elements && elements.length > 0) {
|
|
2950
2957
|
markBlockSpacing(elements);
|
|
2951
2958
|
}
|
|
2959
|
+
const NOTE_OFFSET_BELOW = 16;
|
|
2960
|
+
const computeNoteHeight = (text) => {
|
|
2961
|
+
const lines = wrapTextLines(text, NOTE_CHARS_PER_LINE);
|
|
2962
|
+
return lines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
|
|
2963
|
+
};
|
|
2964
|
+
const markNoteSpacing = (els) => {
|
|
2965
|
+
for (let i = 0; i < els.length; i++) {
|
|
2966
|
+
const el = els[i];
|
|
2967
|
+
if (isSequenceNote(el)) {
|
|
2968
|
+
const noteH = computeNoteHeight(el.text);
|
|
2969
|
+
const nextIdx = i + 1 < els.length ? findFirstMsgIndex([els[i + 1]]) : -1;
|
|
2970
|
+
if (nextIdx >= 0) {
|
|
2971
|
+
addExtra(nextIdx, noteH + NOTE_OFFSET_BELOW);
|
|
2972
|
+
}
|
|
2973
|
+
} else if (isSequenceBlock(el)) {
|
|
2974
|
+
markNoteSpacing(el.children);
|
|
2975
|
+
if (el.elseIfBranches) {
|
|
2976
|
+
for (const branch of el.elseIfBranches) {
|
|
2977
|
+
markNoteSpacing(branch.children);
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
markNoteSpacing(el.elseChildren);
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
};
|
|
2984
|
+
if (elements && elements.length > 0) {
|
|
2985
|
+
markNoteSpacing(elements);
|
|
2986
|
+
}
|
|
2952
2987
|
const preSectionMsgIndices = [];
|
|
2953
2988
|
const sectionRegions = [];
|
|
2954
2989
|
{
|
|
@@ -3121,7 +3156,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3121
3156
|
`0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
|
|
3122
3157
|
).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
|
|
3123
3158
|
if (title) {
|
|
3124
|
-
svg.append("text").attr("x", svgWidth / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 20).attr("font-weight", "bold").text(title);
|
|
3159
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", svgWidth / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 20).attr("font-weight", "bold").text(title);
|
|
3160
|
+
if (parsed.titleLineNumber) {
|
|
3161
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
3162
|
+
}
|
|
3125
3163
|
}
|
|
3126
3164
|
for (const group of groups) {
|
|
3127
3165
|
if (group.participantIds.length === 0) continue;
|
|
@@ -3460,8 +3498,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3460
3498
|
);
|
|
3461
3499
|
const isRight = el.position === "right";
|
|
3462
3500
|
const noteX = isRight ? px + ACTIVATION_WIDTH + NOTE_GAP : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
|
|
3463
|
-
const noteTopY = noteY
|
|
3464
|
-
const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber));
|
|
3501
|
+
const noteTopY = noteY + NOTE_OFFSET_BELOW;
|
|
3502
|
+
const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
|
|
3465
3503
|
noteG.append("path").attr(
|
|
3466
3504
|
"d",
|
|
3467
3505
|
[
|
|
@@ -3481,13 +3519,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3481
3519
|
`L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
|
|
3482
3520
|
].join(" ")
|
|
3483
3521
|
).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
|
|
3484
|
-
const connectorNoteX = isRight ? noteX : noteX + noteW;
|
|
3485
|
-
const connectorLifeX = isRight ? px + ACTIVATION_WIDTH / 2 : px - ACTIVATION_WIDTH / 2;
|
|
3486
|
-
noteG.append("line").attr("x1", connectorNoteX).attr("y1", noteY).attr("x2", connectorLifeX).attr("y2", noteY).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("stroke-dasharray", "3 2").attr("class", "note-connector");
|
|
3487
3522
|
wrappedLines.forEach((line3, li) => {
|
|
3488
3523
|
const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
|
|
3489
|
-
const
|
|
3490
|
-
const
|
|
3524
|
+
const isBullet = line3.startsWith("- ");
|
|
3525
|
+
const bulletIndent = isBullet ? 10 : 0;
|
|
3526
|
+
const displayLine = isBullet ? line3.slice(2) : line3;
|
|
3527
|
+
const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
|
|
3528
|
+
if (isBullet) {
|
|
3529
|
+
noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
|
|
3530
|
+
}
|
|
3531
|
+
const spans = parseInlineMarkdown(displayLine);
|
|
3491
3532
|
for (const span of spans) {
|
|
3492
3533
|
if (span.href) {
|
|
3493
3534
|
const a = textEl.append("a").attr("href", span.href);
|
|
@@ -3637,6 +3678,7 @@ function parseChart(content, palette) {
|
|
|
3637
3678
|
}
|
|
3638
3679
|
if (key === "title") {
|
|
3639
3680
|
result.title = value;
|
|
3681
|
+
result.titleLineNumber = lineNumber;
|
|
3640
3682
|
continue;
|
|
3641
3683
|
}
|
|
3642
3684
|
if (key === "xlabel") {
|
|
@@ -3778,6 +3820,7 @@ function parseEChart(content, palette) {
|
|
|
3778
3820
|
}
|
|
3779
3821
|
if (key === "title") {
|
|
3780
3822
|
result.title = value;
|
|
3823
|
+
result.titleLineNumber = lineNumber;
|
|
3781
3824
|
continue;
|
|
3782
3825
|
}
|
|
3783
3826
|
if (key === "series") {
|
|
@@ -5139,6 +5182,7 @@ function parseD3(content, palette) {
|
|
|
5139
5182
|
const result = {
|
|
5140
5183
|
type: null,
|
|
5141
5184
|
title: null,
|
|
5185
|
+
titleLineNumber: null,
|
|
5142
5186
|
orientation: "horizontal",
|
|
5143
5187
|
periods: [],
|
|
5144
5188
|
data: [],
|
|
@@ -5400,6 +5444,7 @@ function parseD3(content, palette) {
|
|
|
5400
5444
|
}
|
|
5401
5445
|
if (key === "title") {
|
|
5402
5446
|
result.title = line3.substring(colonIndex + 1).trim();
|
|
5447
|
+
result.titleLineNumber = lineNumber;
|
|
5403
5448
|
if (result.type === "quadrant") {
|
|
5404
5449
|
result.quadrantTitleLineNumber = lineNumber;
|
|
5405
5450
|
}
|
|
@@ -5762,7 +5807,17 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
|
|
|
5762
5807
|
const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
|
|
5763
5808
|
const tooltip = createTooltip(container, palette, isDark);
|
|
5764
5809
|
if (title) {
|
|
5765
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
5810
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
5811
|
+
if (parsed.titleLineNumber) {
|
|
5812
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
5813
|
+
if (onClickItem) {
|
|
5814
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
5815
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
5816
|
+
}).on("mouseleave", function() {
|
|
5817
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
5818
|
+
});
|
|
5819
|
+
}
|
|
5820
|
+
}
|
|
5766
5821
|
}
|
|
5767
5822
|
for (const period of periods) {
|
|
5768
5823
|
const x = xScale(period);
|
|
@@ -5971,7 +6026,17 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
|
|
|
5971
6026
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
5972
6027
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
5973
6028
|
if (title) {
|
|
5974
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
6029
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
6030
|
+
if (parsed.titleLineNumber) {
|
|
6031
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6032
|
+
if (onClickItem) {
|
|
6033
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6034
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6035
|
+
}).on("mouseleave", function() {
|
|
6036
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6037
|
+
});
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
5975
6040
|
}
|
|
5976
6041
|
const neighbors = /* @__PURE__ */ new Map();
|
|
5977
6042
|
for (const node of nodes) neighbors.set(node, /* @__PURE__ */ new Set());
|
|
@@ -6523,7 +6588,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6523
6588
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6524
6589
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6525
6590
|
if (title) {
|
|
6526
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
6591
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
6592
|
+
if (parsed.titleLineNumber) {
|
|
6593
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6594
|
+
if (onClickItem) {
|
|
6595
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6596
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6597
|
+
}).on("mouseleave", function() {
|
|
6598
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6599
|
+
});
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6527
6602
|
}
|
|
6528
6603
|
renderEras(
|
|
6529
6604
|
g,
|
|
@@ -6617,7 +6692,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6617
6692
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6618
6693
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6619
6694
|
if (title) {
|
|
6620
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
6695
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
6696
|
+
if (parsed.titleLineNumber) {
|
|
6697
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6698
|
+
if (onClickItem) {
|
|
6699
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6700
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6701
|
+
}).on("mouseleave", function() {
|
|
6702
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6703
|
+
});
|
|
6704
|
+
}
|
|
6705
|
+
}
|
|
6621
6706
|
}
|
|
6622
6707
|
renderEras(
|
|
6623
6708
|
g,
|
|
@@ -6740,7 +6825,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6740
6825
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6741
6826
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6742
6827
|
if (title) {
|
|
6743
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
6828
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
6829
|
+
if (parsed.titleLineNumber) {
|
|
6830
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6831
|
+
if (onClickItem) {
|
|
6832
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6833
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6834
|
+
}).on("mouseleave", function() {
|
|
6835
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6836
|
+
});
|
|
6837
|
+
}
|
|
6838
|
+
}
|
|
6744
6839
|
}
|
|
6745
6840
|
renderEras(
|
|
6746
6841
|
g,
|
|
@@ -6885,7 +6980,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6885
6980
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6886
6981
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6887
6982
|
if (title) {
|
|
6888
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
6983
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
6984
|
+
if (parsed.titleLineNumber) {
|
|
6985
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6986
|
+
if (onClickItem) {
|
|
6987
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6988
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6989
|
+
}).on("mouseleave", function() {
|
|
6990
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6991
|
+
});
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6889
6994
|
}
|
|
6890
6995
|
renderEras(
|
|
6891
6996
|
g,
|
|
@@ -7036,7 +7141,17 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
|
|
|
7036
7141
|
const rotateFn = getRotateFn(cloudOptions.rotate);
|
|
7037
7142
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7038
7143
|
if (title) {
|
|
7039
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
7144
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
7145
|
+
if (parsed.titleLineNumber) {
|
|
7146
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7147
|
+
if (onClickItem) {
|
|
7148
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
7149
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
7150
|
+
}).on("mouseleave", function() {
|
|
7151
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
7152
|
+
});
|
|
7153
|
+
}
|
|
7154
|
+
}
|
|
7040
7155
|
}
|
|
7041
7156
|
const g = svg.append("g").attr(
|
|
7042
7157
|
"transform",
|
|
@@ -7086,7 +7201,10 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
|
|
|
7086
7201
|
const rotateFn = getRotateFn(cloudOptions.rotate);
|
|
7087
7202
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7088
7203
|
if (title) {
|
|
7089
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
7204
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
7205
|
+
if (parsed.titleLineNumber) {
|
|
7206
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7207
|
+
}
|
|
7090
7208
|
}
|
|
7091
7209
|
const g = svg.append("g").attr(
|
|
7092
7210
|
"transform",
|
|
@@ -7296,7 +7414,17 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
7296
7414
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7297
7415
|
const tooltip = createTooltip(container, palette, isDark);
|
|
7298
7416
|
if (title) {
|
|
7299
|
-
svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
|
|
7417
|
+
const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
|
|
7418
|
+
if (parsed.titleLineNumber) {
|
|
7419
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7420
|
+
if (onClickItem) {
|
|
7421
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
7422
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
7423
|
+
}).on("mouseleave", function() {
|
|
7424
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
7425
|
+
});
|
|
7426
|
+
}
|
|
7427
|
+
}
|
|
7300
7428
|
}
|
|
7301
7429
|
const defs = svg.append("defs");
|
|
7302
7430
|
const pad = 20;
|
|
@@ -7474,10 +7602,13 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
7474
7602
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7475
7603
|
const tooltip = createTooltip(container, palette, isDark);
|
|
7476
7604
|
if (title) {
|
|
7477
|
-
const titleText = svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style(
|
|
7605
|
+
const titleText = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style(
|
|
7478
7606
|
"cursor",
|
|
7479
7607
|
onClickItem && quadrantTitleLineNumber ? "pointer" : "default"
|
|
7480
7608
|
).text(title);
|
|
7609
|
+
if (quadrantTitleLineNumber) {
|
|
7610
|
+
titleText.attr("data-line-number", quadrantTitleLineNumber);
|
|
7611
|
+
}
|
|
7481
7612
|
if (onClickItem && quadrantTitleLineNumber) {
|
|
7482
7613
|
titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
|
|
7483
7614
|
d3Selection3.select(this).attr("opacity", 0.7);
|