@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.cjs
CHANGED
|
@@ -218,6 +218,7 @@ function measureIndent(line3) {
|
|
|
218
218
|
function parseSequenceDgmo(content) {
|
|
219
219
|
const result = {
|
|
220
220
|
title: null,
|
|
221
|
+
titleLineNumber: null,
|
|
221
222
|
participants: [],
|
|
222
223
|
messages: [],
|
|
223
224
|
elements: [],
|
|
@@ -321,6 +322,7 @@ function parseSequenceDgmo(content) {
|
|
|
321
322
|
}
|
|
322
323
|
if (key === "title") {
|
|
323
324
|
result.title = value;
|
|
325
|
+
result.titleLineNumber = lineNumber;
|
|
324
326
|
continue;
|
|
325
327
|
}
|
|
326
328
|
result.options[key] = value;
|
|
@@ -550,22 +552,19 @@ function parseSequenceDgmo(content) {
|
|
|
550
552
|
const notePosition = noteSingleMatch[1]?.toLowerCase() || "right";
|
|
551
553
|
let noteParticipant = noteSingleMatch[2] || null;
|
|
552
554
|
if (!noteParticipant) {
|
|
553
|
-
if (!lastMsgFrom)
|
|
554
|
-
result.error = `Line ${lineNumber}: note requires a preceding message`;
|
|
555
|
-
return result;
|
|
556
|
-
}
|
|
555
|
+
if (!lastMsgFrom) continue;
|
|
557
556
|
noteParticipant = lastMsgFrom;
|
|
558
557
|
}
|
|
559
558
|
if (!result.participants.some((p) => p.id === noteParticipant)) {
|
|
560
|
-
|
|
561
|
-
return result;
|
|
559
|
+
continue;
|
|
562
560
|
}
|
|
563
561
|
const note = {
|
|
564
562
|
kind: "note",
|
|
565
563
|
text: noteSingleMatch[3].trim(),
|
|
566
564
|
position: notePosition,
|
|
567
565
|
participantId: noteParticipant,
|
|
568
|
-
lineNumber
|
|
566
|
+
lineNumber,
|
|
567
|
+
endLineNumber: lineNumber
|
|
569
568
|
};
|
|
570
569
|
currentContainer().push(note);
|
|
571
570
|
continue;
|
|
@@ -575,15 +574,11 @@ function parseSequenceDgmo(content) {
|
|
|
575
574
|
const notePosition = noteMultiMatch[1]?.toLowerCase() || "right";
|
|
576
575
|
let noteParticipant = noteMultiMatch[2] || null;
|
|
577
576
|
if (!noteParticipant) {
|
|
578
|
-
if (!lastMsgFrom)
|
|
579
|
-
result.error = `Line ${lineNumber}: note requires a preceding message`;
|
|
580
|
-
return result;
|
|
581
|
-
}
|
|
577
|
+
if (!lastMsgFrom) continue;
|
|
582
578
|
noteParticipant = lastMsgFrom;
|
|
583
579
|
}
|
|
584
580
|
if (!result.participants.some((p) => p.id === noteParticipant)) {
|
|
585
|
-
|
|
586
|
-
return result;
|
|
581
|
+
continue;
|
|
587
582
|
}
|
|
588
583
|
const noteLines = [];
|
|
589
584
|
while (i + 1 < lines.length) {
|
|
@@ -595,16 +590,15 @@ function parseSequenceDgmo(content) {
|
|
|
595
590
|
noteLines.push(nextTrimmed);
|
|
596
591
|
i++;
|
|
597
592
|
}
|
|
598
|
-
if (noteLines.length === 0)
|
|
599
|
-
result.error = `Line ${lineNumber}: multi-line note has no content \u2014 add indented lines or use 'note: text'`;
|
|
600
|
-
return result;
|
|
601
|
-
}
|
|
593
|
+
if (noteLines.length === 0) continue;
|
|
602
594
|
const note = {
|
|
603
595
|
kind: "note",
|
|
604
596
|
text: noteLines.join("\n"),
|
|
605
597
|
position: notePosition,
|
|
606
598
|
participantId: noteParticipant,
|
|
607
|
-
lineNumber
|
|
599
|
+
lineNumber,
|
|
600
|
+
endLineNumber: i + 1
|
|
601
|
+
// i has advanced past the body lines (1-based)
|
|
608
602
|
};
|
|
609
603
|
currentContainer().push(note);
|
|
610
604
|
continue;
|
|
@@ -652,7 +646,7 @@ var init_parser = __esm({
|
|
|
652
646
|
ARROW_RETURN_PATTERN = /^(.+?)\s*<-\s*(.+)$/;
|
|
653
647
|
UML_RETURN_PATTERN = /^(\w+\([^)]*\))\s*:\s*(.+)$/;
|
|
654
648
|
NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
|
|
655
|
-
NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+(
|
|
649
|
+
NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+([^\s:]+))?\s*:?\s*$/i;
|
|
656
650
|
}
|
|
657
651
|
});
|
|
658
652
|
|
|
@@ -997,6 +991,7 @@ function parseFlowchart(content, palette) {
|
|
|
997
991
|
}
|
|
998
992
|
if (key === "title") {
|
|
999
993
|
result.title = value;
|
|
994
|
+
result.titleLineNumber = lineNumber;
|
|
1000
995
|
continue;
|
|
1001
996
|
}
|
|
1002
997
|
if (key === "direction") {
|
|
@@ -2433,7 +2428,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2433
2428
|
const scaledH = diagramH * scale;
|
|
2434
2429
|
const offsetX = (width - scaledW) / 2;
|
|
2435
2430
|
const offsetY = (height - scaledH) / 2;
|
|
2436
|
-
const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).style("
|
|
2431
|
+
const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
|
|
2437
2432
|
const defs = svg.append("defs");
|
|
2438
2433
|
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);
|
|
2439
2434
|
const edgeColors = /* @__PURE__ */ new Set();
|
|
@@ -2446,7 +2441,17 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2446
2441
|
}
|
|
2447
2442
|
const mainG = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY}) scale(${scale})`);
|
|
2448
2443
|
if (graph.title) {
|
|
2449
|
-
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);
|
|
2444
|
+
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);
|
|
2445
|
+
if (graph.titleLineNumber) {
|
|
2446
|
+
titleEl.attr("data-line-number", graph.titleLineNumber);
|
|
2447
|
+
if (onClickItem) {
|
|
2448
|
+
titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
|
|
2449
|
+
d3Selection.select(this).attr("opacity", 0.7);
|
|
2450
|
+
}).on("mouseleave", function() {
|
|
2451
|
+
d3Selection.select(this).attr("opacity", 1);
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2450
2455
|
}
|
|
2451
2456
|
const contentG = mainG.append("g").attr("transform", `translate(0, ${titleOffset})`);
|
|
2452
2457
|
for (const group of layout.groups) {
|
|
@@ -2480,7 +2485,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
2480
2485
|
}
|
|
2481
2486
|
}
|
|
2482
2487
|
for (const node of layout.nodes) {
|
|
2483
|
-
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber));
|
|
2488
|
+
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);
|
|
2484
2489
|
if (onClickItem) {
|
|
2485
2490
|
nodeG.style("cursor", "pointer").on("click", () => {
|
|
2486
2491
|
onClickItem(node.lineNumber);
|
|
@@ -2564,14 +2569,16 @@ __export(renderer_exports, {
|
|
|
2564
2569
|
});
|
|
2565
2570
|
function parseInlineMarkdown(text) {
|
|
2566
2571
|
const spans = [];
|
|
2567
|
-
const regex = /\*\*(.+?)
|
|
2572
|
+
const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|([^*_`[]+)/g;
|
|
2568
2573
|
let match;
|
|
2569
2574
|
while ((match = regex.exec(text)) !== null) {
|
|
2570
2575
|
if (match[1]) spans.push({ text: match[1], bold: true });
|
|
2571
|
-
else if (match[2]) spans.push({ text: match[2],
|
|
2572
|
-
else if (match[3]) spans.push({ text: match[3],
|
|
2573
|
-
else if (match[4]) spans.push({ text: match[4],
|
|
2574
|
-
else if (match[
|
|
2576
|
+
else if (match[2]) spans.push({ text: match[2], bold: true });
|
|
2577
|
+
else if (match[3]) spans.push({ text: match[3], italic: true });
|
|
2578
|
+
else if (match[4]) spans.push({ text: match[4], italic: true });
|
|
2579
|
+
else if (match[5]) spans.push({ text: match[5], code: true });
|
|
2580
|
+
else if (match[6]) spans.push({ text: match[6], href: match[7] });
|
|
2581
|
+
else if (match[8]) spans.push({ text: match[8] });
|
|
2575
2582
|
}
|
|
2576
2583
|
return spans;
|
|
2577
2584
|
}
|
|
@@ -2970,6 +2977,34 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
2970
2977
|
if (elements && elements.length > 0) {
|
|
2971
2978
|
markBlockSpacing(elements);
|
|
2972
2979
|
}
|
|
2980
|
+
const NOTE_OFFSET_BELOW = 16;
|
|
2981
|
+
const computeNoteHeight = (text) => {
|
|
2982
|
+
const lines = wrapTextLines(text, NOTE_CHARS_PER_LINE);
|
|
2983
|
+
return lines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
|
|
2984
|
+
};
|
|
2985
|
+
const markNoteSpacing = (els) => {
|
|
2986
|
+
for (let i = 0; i < els.length; i++) {
|
|
2987
|
+
const el = els[i];
|
|
2988
|
+
if (isSequenceNote(el)) {
|
|
2989
|
+
const noteH = computeNoteHeight(el.text);
|
|
2990
|
+
const nextIdx = i + 1 < els.length ? findFirstMsgIndex([els[i + 1]]) : -1;
|
|
2991
|
+
if (nextIdx >= 0) {
|
|
2992
|
+
addExtra(nextIdx, noteH + NOTE_OFFSET_BELOW);
|
|
2993
|
+
}
|
|
2994
|
+
} else if (isSequenceBlock(el)) {
|
|
2995
|
+
markNoteSpacing(el.children);
|
|
2996
|
+
if (el.elseIfBranches) {
|
|
2997
|
+
for (const branch of el.elseIfBranches) {
|
|
2998
|
+
markNoteSpacing(branch.children);
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
markNoteSpacing(el.elseChildren);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
};
|
|
3005
|
+
if (elements && elements.length > 0) {
|
|
3006
|
+
markNoteSpacing(elements);
|
|
3007
|
+
}
|
|
2973
3008
|
const preSectionMsgIndices = [];
|
|
2974
3009
|
const sectionRegions = [];
|
|
2975
3010
|
{
|
|
@@ -3142,7 +3177,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3142
3177
|
`0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
|
|
3143
3178
|
).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
|
|
3144
3179
|
if (title) {
|
|
3145
|
-
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);
|
|
3180
|
+
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);
|
|
3181
|
+
if (parsed.titleLineNumber) {
|
|
3182
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
3183
|
+
}
|
|
3146
3184
|
}
|
|
3147
3185
|
for (const group of groups) {
|
|
3148
3186
|
if (group.participantIds.length === 0) continue;
|
|
@@ -3481,8 +3519,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3481
3519
|
);
|
|
3482
3520
|
const isRight = el.position === "right";
|
|
3483
3521
|
const noteX = isRight ? px + ACTIVATION_WIDTH + NOTE_GAP : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
|
|
3484
|
-
const noteTopY = noteY
|
|
3485
|
-
const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber));
|
|
3522
|
+
const noteTopY = noteY + NOTE_OFFSET_BELOW;
|
|
3523
|
+
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));
|
|
3486
3524
|
noteG.append("path").attr(
|
|
3487
3525
|
"d",
|
|
3488
3526
|
[
|
|
@@ -3502,13 +3540,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
3502
3540
|
`L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
|
|
3503
3541
|
].join(" ")
|
|
3504
3542
|
).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
|
|
3505
|
-
const connectorNoteX = isRight ? noteX : noteX + noteW;
|
|
3506
|
-
const connectorLifeX = isRight ? px + ACTIVATION_WIDTH / 2 : px - ACTIVATION_WIDTH / 2;
|
|
3507
|
-
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");
|
|
3508
3543
|
wrappedLines.forEach((line3, li) => {
|
|
3509
3544
|
const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
|
|
3510
|
-
const
|
|
3511
|
-
const
|
|
3545
|
+
const isBullet = line3.startsWith("- ");
|
|
3546
|
+
const bulletIndent = isBullet ? 10 : 0;
|
|
3547
|
+
const displayLine = isBullet ? line3.slice(2) : line3;
|
|
3548
|
+
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");
|
|
3549
|
+
if (isBullet) {
|
|
3550
|
+
noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
|
|
3551
|
+
}
|
|
3552
|
+
const spans = parseInlineMarkdown(displayLine);
|
|
3512
3553
|
for (const span of spans) {
|
|
3513
3554
|
if (span.href) {
|
|
3514
3555
|
const a = textEl.append("a").attr("href", span.href);
|
|
@@ -3729,6 +3770,7 @@ function parseChart(content, palette) {
|
|
|
3729
3770
|
}
|
|
3730
3771
|
if (key === "title") {
|
|
3731
3772
|
result.title = value;
|
|
3773
|
+
result.titleLineNumber = lineNumber;
|
|
3732
3774
|
continue;
|
|
3733
3775
|
}
|
|
3734
3776
|
if (key === "xlabel") {
|
|
@@ -3870,6 +3912,7 @@ function parseEChart(content, palette) {
|
|
|
3870
3912
|
}
|
|
3871
3913
|
if (key === "title") {
|
|
3872
3914
|
result.title = value;
|
|
3915
|
+
result.titleLineNumber = lineNumber;
|
|
3873
3916
|
continue;
|
|
3874
3917
|
}
|
|
3875
3918
|
if (key === "series") {
|
|
@@ -5231,6 +5274,7 @@ function parseD3(content, palette) {
|
|
|
5231
5274
|
const result = {
|
|
5232
5275
|
type: null,
|
|
5233
5276
|
title: null,
|
|
5277
|
+
titleLineNumber: null,
|
|
5234
5278
|
orientation: "horizontal",
|
|
5235
5279
|
periods: [],
|
|
5236
5280
|
data: [],
|
|
@@ -5492,6 +5536,7 @@ function parseD3(content, palette) {
|
|
|
5492
5536
|
}
|
|
5493
5537
|
if (key === "title") {
|
|
5494
5538
|
result.title = line3.substring(colonIndex + 1).trim();
|
|
5539
|
+
result.titleLineNumber = lineNumber;
|
|
5495
5540
|
if (result.type === "quadrant") {
|
|
5496
5541
|
result.quadrantTitleLineNumber = lineNumber;
|
|
5497
5542
|
}
|
|
@@ -5854,7 +5899,17 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
|
|
|
5854
5899
|
const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
|
|
5855
5900
|
const tooltip = createTooltip(container, palette, isDark);
|
|
5856
5901
|
if (title) {
|
|
5857
|
-
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);
|
|
5902
|
+
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);
|
|
5903
|
+
if (parsed.titleLineNumber) {
|
|
5904
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
5905
|
+
if (onClickItem) {
|
|
5906
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
5907
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
5908
|
+
}).on("mouseleave", function() {
|
|
5909
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
5910
|
+
});
|
|
5911
|
+
}
|
|
5912
|
+
}
|
|
5858
5913
|
}
|
|
5859
5914
|
for (const period of periods) {
|
|
5860
5915
|
const x = xScale(period);
|
|
@@ -6063,7 +6118,17 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
|
|
|
6063
6118
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6064
6119
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6065
6120
|
if (title) {
|
|
6066
|
-
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);
|
|
6121
|
+
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);
|
|
6122
|
+
if (parsed.titleLineNumber) {
|
|
6123
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6124
|
+
if (onClickItem) {
|
|
6125
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6126
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6127
|
+
}).on("mouseleave", function() {
|
|
6128
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6129
|
+
});
|
|
6130
|
+
}
|
|
6131
|
+
}
|
|
6067
6132
|
}
|
|
6068
6133
|
const neighbors = /* @__PURE__ */ new Map();
|
|
6069
6134
|
for (const node of nodes) neighbors.set(node, /* @__PURE__ */ new Set());
|
|
@@ -6615,7 +6680,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6615
6680
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6616
6681
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6617
6682
|
if (title) {
|
|
6618
|
-
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);
|
|
6683
|
+
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);
|
|
6684
|
+
if (parsed.titleLineNumber) {
|
|
6685
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6686
|
+
if (onClickItem) {
|
|
6687
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6688
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6689
|
+
}).on("mouseleave", function() {
|
|
6690
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6691
|
+
});
|
|
6692
|
+
}
|
|
6693
|
+
}
|
|
6619
6694
|
}
|
|
6620
6695
|
renderEras(
|
|
6621
6696
|
g,
|
|
@@ -6709,7 +6784,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6709
6784
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6710
6785
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6711
6786
|
if (title) {
|
|
6712
|
-
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);
|
|
6787
|
+
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);
|
|
6788
|
+
if (parsed.titleLineNumber) {
|
|
6789
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6790
|
+
if (onClickItem) {
|
|
6791
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6792
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6793
|
+
}).on("mouseleave", function() {
|
|
6794
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6795
|
+
});
|
|
6796
|
+
}
|
|
6797
|
+
}
|
|
6713
6798
|
}
|
|
6714
6799
|
renderEras(
|
|
6715
6800
|
g,
|
|
@@ -6832,7 +6917,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6832
6917
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6833
6918
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6834
6919
|
if (title) {
|
|
6835
|
-
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);
|
|
6920
|
+
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);
|
|
6921
|
+
if (parsed.titleLineNumber) {
|
|
6922
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
6923
|
+
if (onClickItem) {
|
|
6924
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
6925
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
6926
|
+
}).on("mouseleave", function() {
|
|
6927
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
6928
|
+
});
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6836
6931
|
}
|
|
6837
6932
|
renderEras(
|
|
6838
6933
|
g,
|
|
@@ -6977,7 +7072,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
6977
7072
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
6978
7073
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
6979
7074
|
if (title) {
|
|
6980
|
-
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);
|
|
7075
|
+
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);
|
|
7076
|
+
if (parsed.titleLineNumber) {
|
|
7077
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7078
|
+
if (onClickItem) {
|
|
7079
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
7080
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
7081
|
+
}).on("mouseleave", function() {
|
|
7082
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
7083
|
+
});
|
|
7084
|
+
}
|
|
7085
|
+
}
|
|
6981
7086
|
}
|
|
6982
7087
|
renderEras(
|
|
6983
7088
|
g,
|
|
@@ -7128,7 +7233,17 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
|
|
|
7128
7233
|
const rotateFn = getRotateFn(cloudOptions.rotate);
|
|
7129
7234
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7130
7235
|
if (title) {
|
|
7131
|
-
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);
|
|
7236
|
+
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);
|
|
7237
|
+
if (parsed.titleLineNumber) {
|
|
7238
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7239
|
+
if (onClickItem) {
|
|
7240
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
7241
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
7242
|
+
}).on("mouseleave", function() {
|
|
7243
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
7244
|
+
});
|
|
7245
|
+
}
|
|
7246
|
+
}
|
|
7132
7247
|
}
|
|
7133
7248
|
const g = svg.append("g").attr(
|
|
7134
7249
|
"transform",
|
|
@@ -7178,7 +7293,10 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
|
|
|
7178
7293
|
const rotateFn = getRotateFn(cloudOptions.rotate);
|
|
7179
7294
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7180
7295
|
if (title) {
|
|
7181
|
-
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);
|
|
7296
|
+
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);
|
|
7297
|
+
if (parsed.titleLineNumber) {
|
|
7298
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7299
|
+
}
|
|
7182
7300
|
}
|
|
7183
7301
|
const g = svg.append("g").attr(
|
|
7184
7302
|
"transform",
|
|
@@ -7388,7 +7506,17 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
7388
7506
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7389
7507
|
const tooltip = createTooltip(container, palette, isDark);
|
|
7390
7508
|
if (title) {
|
|
7391
|
-
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);
|
|
7509
|
+
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);
|
|
7510
|
+
if (parsed.titleLineNumber) {
|
|
7511
|
+
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
7512
|
+
if (onClickItem) {
|
|
7513
|
+
titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
|
|
7514
|
+
d3Selection3.select(this).attr("opacity", 0.7);
|
|
7515
|
+
}).on("mouseleave", function() {
|
|
7516
|
+
d3Selection3.select(this).attr("opacity", 1);
|
|
7517
|
+
});
|
|
7518
|
+
}
|
|
7519
|
+
}
|
|
7392
7520
|
}
|
|
7393
7521
|
const defs = svg.append("defs");
|
|
7394
7522
|
const pad = 20;
|
|
@@ -7566,10 +7694,13 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
7566
7694
|
const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
7567
7695
|
const tooltip = createTooltip(container, palette, isDark);
|
|
7568
7696
|
if (title) {
|
|
7569
|
-
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(
|
|
7697
|
+
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(
|
|
7570
7698
|
"cursor",
|
|
7571
7699
|
onClickItem && quadrantTitleLineNumber ? "pointer" : "default"
|
|
7572
7700
|
).text(title);
|
|
7701
|
+
if (quadrantTitleLineNumber) {
|
|
7702
|
+
titleText.attr("data-line-number", quadrantTitleLineNumber);
|
|
7703
|
+
}
|
|
7573
7704
|
if (onClickItem && quadrantTitleLineNumber) {
|
|
7574
7705
|
titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
|
|
7575
7706
|
d3Selection3.select(this).attr("opacity", 0.7);
|