@diagrammo/dgmo 0.3.1 → 0.4.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/dist/index.js CHANGED
@@ -1285,6 +1285,31 @@ function collectIndentedValues(lines, startIndex) {
1285
1285
  }
1286
1286
  return { values, newIndex: j - 1 };
1287
1287
  }
1288
+ function parseSeriesNames(value, lines, lineIndex, palette) {
1289
+ let rawNames;
1290
+ let series;
1291
+ let newIndex = lineIndex;
1292
+ if (value) {
1293
+ series = value;
1294
+ rawNames = value.split(",").map((s) => s.trim()).filter(Boolean);
1295
+ } else {
1296
+ const collected = collectIndentedValues(lines, lineIndex);
1297
+ newIndex = collected.newIndex;
1298
+ rawNames = collected.values;
1299
+ series = rawNames.join(", ");
1300
+ }
1301
+ const names = [];
1302
+ const nameColors = [];
1303
+ for (const raw of rawNames) {
1304
+ const extracted = extractColor(raw, palette);
1305
+ nameColors.push(extracted.color);
1306
+ names.push(extracted.label);
1307
+ }
1308
+ if (names.length === 1) {
1309
+ series = names[0];
1310
+ }
1311
+ return { series, names, nameColors, newIndex };
1312
+ }
1288
1313
  function parsePipeMetadata(segments, aliasMap = /* @__PURE__ */ new Map()) {
1289
1314
  const metadata = {};
1290
1315
  for (let j = 1; j < segments.length; j++) {
@@ -1590,13 +1615,18 @@ var init_participant_inference = __esm({
1590
1615
 
1591
1616
  // src/utils/arrows.ts
1592
1617
  function parseArrow(line7) {
1618
+ if (BIDI_SYNC_RE.test(line7) || BIDI_ASYNC_RE.test(line7)) {
1619
+ return {
1620
+ error: "Bidirectional arrows are no longer supported. Use two separate lines: 'A -msg-> B' and 'B -msg-> A'"
1621
+ };
1622
+ }
1593
1623
  const patterns = [
1594
- { re: BIDI_SYNC_LABELED_RE, async: false, bidirectional: true },
1595
- { re: BIDI_ASYNC_LABELED_RE, async: true, bidirectional: true },
1596
- { re: SYNC_LABELED_RE, async: false, bidirectional: false },
1597
- { re: ASYNC_LABELED_RE, async: true, bidirectional: false }
1624
+ { re: RETURN_SYNC_LABELED_RE, async: false, isReturn: true },
1625
+ { re: RETURN_ASYNC_LABELED_RE, async: true, isReturn: true },
1626
+ { re: SYNC_LABELED_RE, async: false, isReturn: false },
1627
+ { re: ASYNC_LABELED_RE, async: true, isReturn: false }
1598
1628
  ];
1599
- for (const { re, async: isAsync, bidirectional } of patterns) {
1629
+ for (const { re, async: isAsync, isReturn } of patterns) {
1600
1630
  const m = line7.match(re);
1601
1631
  if (!m) continue;
1602
1632
  const label = m[2].trim();
@@ -1604,29 +1634,40 @@ function parseArrow(line7) {
1604
1634
  for (const arrow of ARROW_CHARS) {
1605
1635
  if (label.includes(arrow)) {
1606
1636
  return {
1607
- error: "Arrow characters (->, ~>) are not allowed inside labels"
1637
+ error: "Arrow characters (->, ~>, <-, <~) are not allowed inside labels"
1608
1638
  };
1609
1639
  }
1610
1640
  }
1641
+ if (isReturn) {
1642
+ return {
1643
+ from: m[3],
1644
+ to: m[1],
1645
+ label,
1646
+ async: isAsync,
1647
+ isReturn: true
1648
+ };
1649
+ }
1611
1650
  return {
1612
1651
  from: m[1],
1613
1652
  to: m[3],
1614
1653
  label,
1615
1654
  async: isAsync,
1616
- bidirectional
1655
+ isReturn: false
1617
1656
  };
1618
1657
  }
1619
1658
  return null;
1620
1659
  }
1621
- var BIDI_SYNC_LABELED_RE, BIDI_ASYNC_LABELED_RE, SYNC_LABELED_RE, ASYNC_LABELED_RE, ARROW_CHARS;
1660
+ var SYNC_LABELED_RE, ASYNC_LABELED_RE, RETURN_SYNC_LABELED_RE, RETURN_ASYNC_LABELED_RE, BIDI_SYNC_RE, BIDI_ASYNC_RE, ARROW_CHARS;
1622
1661
  var init_arrows = __esm({
1623
1662
  "src/utils/arrows.ts"() {
1624
1663
  "use strict";
1625
- BIDI_SYNC_LABELED_RE = /^(\S+)\s+<-(.+)->\s+(\S+)$/;
1626
- BIDI_ASYNC_LABELED_RE = /^(\S+)\s+<~(.+)~>\s+(\S+)$/;
1627
1664
  SYNC_LABELED_RE = /^(\S+)\s+-(.+)->\s+(\S+)$/;
1628
1665
  ASYNC_LABELED_RE = /^(\S+)\s+~(.+)~>\s+(\S+)$/;
1629
- ARROW_CHARS = ["->", "~>", "<->", "<~>"];
1666
+ RETURN_SYNC_LABELED_RE = /^(\S+)\s+<-(.+)-\s+(\S+)$/;
1667
+ RETURN_ASYNC_LABELED_RE = /^(\S+)\s+<~(.+)~\s+(\S+)$/;
1668
+ BIDI_SYNC_RE = /^(\S+)\s+<-(.+)->\s+(\S+)$/;
1669
+ BIDI_ASYNC_RE = /^(\S+)\s+<~(.+)~>\s+(\S+)$/;
1670
+ ARROW_CHARS = ["->", "~>", "<-", "<~"];
1630
1671
  }
1631
1672
  });
1632
1673
 
@@ -1648,36 +1689,6 @@ function isSequenceSection(el) {
1648
1689
  function isSequenceNote(el) {
1649
1690
  return "kind" in el && el.kind === "note";
1650
1691
  }
1651
- function parseReturnLabel(rawLabel) {
1652
- if (!rawLabel) return { label: "" };
1653
- const standaloneMatch = rawLabel.match(/^<-\s*(.*)$/);
1654
- if (standaloneMatch) {
1655
- return {
1656
- label: standaloneMatch[1].trim(),
1657
- standaloneReturn: true
1658
- };
1659
- }
1660
- const arrowReturn = rawLabel.match(ARROW_RETURN_PATTERN);
1661
- if (arrowReturn) {
1662
- return { label: arrowReturn[1].trim(), returnLabel: arrowReturn[2].trim() };
1663
- }
1664
- const umlReturn = rawLabel.match(UML_RETURN_PATTERN);
1665
- if (umlReturn) {
1666
- return { label: umlReturn[1].trim(), returnLabel: umlReturn[2].trim() };
1667
- }
1668
- const lastColon = rawLabel.lastIndexOf(":");
1669
- if (lastColon > 0 && lastColon < rawLabel.length - 1) {
1670
- const afterColon = rawLabel.substring(lastColon + 1);
1671
- if (!afterColon.startsWith("//")) {
1672
- const reqPart = rawLabel.substring(0, lastColon).trim();
1673
- const resPart = afterColon.trim();
1674
- if (reqPart && resPart) {
1675
- return { label: reqPart, returnLabel: resPart };
1676
- }
1677
- }
1678
- }
1679
- return { label: rawLabel };
1680
- }
1681
1692
  function parseSequenceDgmo(content) {
1682
1693
  const result = {
1683
1694
  title: null,
@@ -1777,7 +1788,7 @@ function parseSequenceDgmo(content) {
1777
1788
  continue;
1778
1789
  }
1779
1790
  const colonIndex = trimmed.indexOf(":");
1780
- if (colonIndex > 0 && !trimmed.includes("->") && !trimmed.includes("~>")) {
1791
+ if (colonIndex > 0 && !trimmed.includes("->") && !trimmed.includes("~>") && !trimmed.includes("<-") && !trimmed.includes("<~")) {
1781
1792
  const key = trimmed.substring(0, colonIndex).trim().toLowerCase();
1782
1793
  if (key === "note" || key.startsWith("note ")) {
1783
1794
  } else {
@@ -1906,16 +1917,15 @@ function parseSequenceDgmo(content) {
1906
1917
  }
1907
1918
  if (labeledArrow) {
1908
1919
  contentStarted = true;
1909
- const { from, to, label, async: isAsync2, bidirectional } = labeledArrow;
1920
+ const { from, to, label, async: isAsync, isReturn } = labeledArrow;
1910
1921
  lastMsgFrom = from;
1911
1922
  const msg = {
1912
1923
  from,
1913
1924
  to,
1914
1925
  label,
1915
- returnLabel: void 0,
1916
1926
  lineNumber,
1917
- ...isAsync2 ? { async: true } : {},
1918
- ...bidirectional ? { bidirectional: true } : {}
1927
+ ...isAsync ? { async: true } : {},
1928
+ ...isReturn ? { standaloneReturn: true } : {}
1919
1929
  };
1920
1930
  result.messages.push(msg);
1921
1931
  currentContainer().push(msg);
@@ -1937,27 +1947,50 @@ function parseSequenceDgmo(content) {
1937
1947
  }
1938
1948
  continue;
1939
1949
  }
1940
- const bidiSyncMatch = trimmed.match(
1941
- /^(\S+)\s*<->\s*([^\s:]+)\s*(?::\s*(.+))?$/
1950
+ const colonPostfixSync = trimmed.match(
1951
+ /^(\S+)\s*->\s*([^\s:]+)\s*:\s*(.+)$/
1942
1952
  );
1943
- const bidiAsyncMatch = trimmed.match(
1944
- /^(\S+)\s*<~>\s*([^\s:]+)\s*(?::\s*(.+))?$/
1953
+ const colonPostfixAsync = trimmed.match(
1954
+ /^(\S+)\s*~>\s*([^\s:]+)\s*:\s*(.+)$/
1955
+ );
1956
+ const colonPostfix = colonPostfixSync || colonPostfixAsync;
1957
+ if (colonPostfix) {
1958
+ const a = colonPostfix[1];
1959
+ const b = colonPostfix[2];
1960
+ const msg = colonPostfix[3].trim();
1961
+ const arrowChar = colonPostfixAsync ? "~" : "-";
1962
+ const arrowEnd = colonPostfixAsync ? "~>" : "->";
1963
+ pushError(
1964
+ lineNumber,
1965
+ `Colon syntax is no longer supported. Use '${a} ${arrowChar}${msg}${arrowEnd} ${b}' instead`
1966
+ );
1967
+ continue;
1968
+ }
1969
+ const bidiPlainMatch = trimmed.match(
1970
+ /^(\S+)\s*(?:<->|<~>)\s*(\S+)/
1945
1971
  );
1946
- const bidiMatch = bidiSyncMatch || bidiAsyncMatch;
1947
- if (bidiMatch) {
1972
+ if (bidiPlainMatch) {
1973
+ pushError(
1974
+ lineNumber,
1975
+ "Bidirectional arrows are no longer supported. Use two separate lines: 'A -msg-> B' and 'B -msg-> A'"
1976
+ );
1977
+ continue;
1978
+ }
1979
+ const bareReturnSync = trimmed.match(/^(\S+)\s+<-\s+(\S+)$/);
1980
+ const bareReturnAsync = trimmed.match(/^(\S+)\s+<~\s+(\S+)$/);
1981
+ const bareReturn = bareReturnSync || bareReturnAsync;
1982
+ if (bareReturn) {
1948
1983
  contentStarted = true;
1949
- const from = bidiMatch[1];
1950
- const to = bidiMatch[2];
1984
+ const to = bareReturn[1];
1985
+ const from = bareReturn[2];
1951
1986
  lastMsgFrom = from;
1952
- const rawLabel = bidiMatch[3]?.trim() || "";
1953
- const isBidiAsync = !!bidiAsyncMatch;
1954
1987
  const msg = {
1955
1988
  from,
1956
1989
  to,
1957
- label: rawLabel,
1990
+ label: "",
1958
1991
  lineNumber,
1959
- bidirectional: true,
1960
- ...isBidiAsync ? { async: true } : {}
1992
+ standaloneReturn: true,
1993
+ ...bareReturnAsync ? { async: true } : {}
1961
1994
  };
1962
1995
  result.messages.push(msg);
1963
1996
  currentContainer().push(msg);
@@ -1979,30 +2012,20 @@ function parseSequenceDgmo(content) {
1979
2012
  }
1980
2013
  continue;
1981
2014
  }
1982
- let isAsync = false;
1983
- const asyncArrowMatch = trimmed.match(
1984
- /^(\S+)\s*~>\s*([^\s:]+)\s*(?::\s*(.+))?$/
1985
- );
1986
- const syncArrowMatch = trimmed.match(
1987
- /^(\S+)\s*->\s*([^\s:]+)\s*(?::\s*(.+))?$/
1988
- );
1989
- const arrowMatch = asyncArrowMatch || syncArrowMatch;
1990
- if (asyncArrowMatch) isAsync = true;
1991
- if (arrowMatch) {
2015
+ const bareCallSync = trimmed.match(/^(\S+)\s*->\s*(\S+)$/);
2016
+ const bareCallAsync = trimmed.match(/^(\S+)\s*~>\s*(\S+)$/);
2017
+ const bareCall = bareCallSync || bareCallAsync;
2018
+ if (bareCall) {
1992
2019
  contentStarted = true;
1993
- const from = arrowMatch[1];
1994
- const to = arrowMatch[2];
2020
+ const from = bareCall[1];
2021
+ const to = bareCall[2];
1995
2022
  lastMsgFrom = from;
1996
- const rawLabel = arrowMatch[3]?.trim() || "";
1997
- const { label, returnLabel, standaloneReturn } = isAsync ? { label: rawLabel, returnLabel: void 0, standaloneReturn: void 0 } : parseReturnLabel(rawLabel);
1998
2023
  const msg = {
1999
2024
  from,
2000
2025
  to,
2001
- label,
2002
- returnLabel,
2026
+ label: "",
2003
2027
  lineNumber,
2004
- ...isAsync ? { async: true } : {},
2005
- ...standaloneReturn ? { standaloneReturn: true } : {}
2028
+ ...bareCallAsync ? { async: true } : {}
2006
2029
  };
2007
2030
  result.messages.push(msg);
2008
2031
  currentContainer().push(msg);
@@ -2211,7 +2234,7 @@ function looksLikeSequence(content) {
2211
2234
  return ARROW_PATTERN.test(trimmed);
2212
2235
  });
2213
2236
  }
2214
- var VALID_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, GROUP_HEADING_PATTERN, SECTION_PATTERN, ARROW_PATTERN, ARROW_RETURN_PATTERN, UML_RETURN_PATTERN, NOTE_SINGLE, NOTE_MULTI;
2237
+ var VALID_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, GROUP_HEADING_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_SINGLE, NOTE_MULTI;
2215
2238
  var init_parser = __esm({
2216
2239
  "src/sequence/parser.ts"() {
2217
2240
  "use strict";
@@ -2234,9 +2257,7 @@ var init_parser = __esm({
2234
2257
  POSITION_ONLY_PATTERN = /^(\S+)\s+position\s+(-?\d+)$/i;
2235
2258
  GROUP_HEADING_PATTERN = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
2236
2259
  SECTION_PATTERN = /^==\s+(.+?)(?:\s*==)?\s*$/;
2237
- ARROW_PATTERN = /\S+\s*(?:<->|<~>|->|~>|-\S+->|~\S+~>|<-\S+->|<~\S+~>)\s*\S+/;
2238
- ARROW_RETURN_PATTERN = /^(.+?)\s*<-\s*(.+)$/;
2239
- UML_RETURN_PATTERN = /^(\w+\([^)]*\))\s*:\s*(.+)$/;
2260
+ ARROW_PATTERN = /\S+\s*(?:<-\S+-|<~\S+~|-\S+->|~\S+~>|->|~>|<-|<~)\s*\S+/;
2240
2261
  NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
2241
2262
  NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+([^\s:]+))?\s*:?\s*$/i;
2242
2263
  }
@@ -3142,49 +3163,19 @@ function parseChart(content, palette) {
3142
3163
  continue;
3143
3164
  }
3144
3165
  if (key === "series") {
3145
- let rawNames;
3146
- if (value) {
3147
- result.series = value;
3148
- rawNames = value.split(",").map((s) => s.trim()).filter(Boolean);
3149
- } else {
3150
- const collected = collectIndentedValues(lines, i);
3151
- i = collected.newIndex;
3152
- rawNames = collected.values;
3153
- result.series = rawNames.join(", ");
3154
- }
3155
- const names = [];
3156
- const nameColors = [];
3157
- for (const raw of rawNames) {
3158
- const colorMatch = raw.match(/\(([^)]+)\)\s*$/);
3159
- if (colorMatch) {
3160
- const resolved = resolveColor(colorMatch[1].trim(), palette);
3161
- nameColors.push(resolved);
3162
- names.push(raw.substring(0, colorMatch.index).trim());
3163
- } else {
3164
- nameColors.push(void 0);
3165
- names.push(raw);
3166
- }
3167
- }
3168
- if (names.length === 1) {
3169
- result.series = names[0];
3166
+ const parsed = parseSeriesNames(value, lines, i, palette);
3167
+ i = parsed.newIndex;
3168
+ result.series = parsed.series;
3169
+ if (parsed.names.length > 1) {
3170
+ result.seriesNames = parsed.names;
3170
3171
  }
3171
- if (names.length > 1) {
3172
- result.seriesNames = names;
3173
- }
3174
- if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;
3172
+ if (parsed.nameColors.some(Boolean)) result.seriesNameColors = parsed.nameColors;
3175
3173
  continue;
3176
3174
  }
3177
3175
  const parts = value.split(",").map((s) => s.trim());
3178
3176
  const numValue = parseFloat(parts[0]);
3179
3177
  if (!isNaN(numValue)) {
3180
- let rawLabel = trimmed.substring(0, colonIndex).trim();
3181
- let pointColor;
3182
- const colorMatch = rawLabel.match(/\(([^)]+)\)\s*$/);
3183
- if (colorMatch) {
3184
- const resolved = resolveColor(colorMatch[1].trim(), palette);
3185
- pointColor = resolved;
3186
- rawLabel = rawLabel.substring(0, colorMatch.index).trim();
3187
- }
3178
+ const { label: rawLabel, color: pointColor } = extractColor(trimmed.substring(0, colonIndex).trim(), palette);
3188
3179
  const extra = parts.slice(1).map((s) => parseFloat(s)).filter((n) => !isNaN(n));
3189
3180
  result.data.push({
3190
3181
  label: rawLabel,
@@ -3264,13 +3255,10 @@ function parseEChart(content, palette) {
3264
3255
  if (!trimmed) continue;
3265
3256
  const mdCategoryMatch = trimmed.match(/^#{2,}\s+(.+)$/);
3266
3257
  if (mdCategoryMatch) {
3267
- let catName = mdCategoryMatch[1].trim();
3268
- const catColorMatch = catName.match(/\(([^)]+)\)\s*$/);
3269
- if (catColorMatch) {
3270
- const resolved = resolveColor(catColorMatch[1].trim(), palette);
3258
+ const { label: catName, color: catColor } = extractColor(mdCategoryMatch[1].trim(), palette);
3259
+ if (catColor) {
3271
3260
  if (!result.categoryColors) result.categoryColors = {};
3272
- catName = catName.substring(0, catColorMatch.index).trim();
3273
- result.categoryColors[catName] = resolved;
3261
+ result.categoryColors[catName] = catColor;
3274
3262
  }
3275
3263
  currentCategory = catName;
3276
3264
  continue;
@@ -3307,32 +3295,13 @@ function parseEChart(content, palette) {
3307
3295
  continue;
3308
3296
  }
3309
3297
  if (key === "series") {
3310
- let rawNames;
3311
- if (value) {
3312
- result.series = value;
3313
- rawNames = value.split(",").map((s) => s.trim()).filter(Boolean);
3314
- } else {
3315
- const collected = collectIndentedValues(lines, i);
3316
- i = collected.newIndex;
3317
- rawNames = collected.values;
3318
- result.series = rawNames.join(", ");
3319
- }
3320
- const names = [];
3321
- const nameColors = [];
3322
- for (const raw of rawNames) {
3323
- const colorMatch = raw.match(/\(([^)]+)\)\s*$/);
3324
- if (colorMatch) {
3325
- nameColors.push(resolveColor(colorMatch[1].trim(), palette));
3326
- names.push(raw.substring(0, colorMatch.index).trim());
3327
- } else {
3328
- nameColors.push(void 0);
3329
- names.push(raw);
3330
- }
3331
- }
3332
- if (names.length === 1) {
3333
- result.series = names[0];
3298
+ const parsed = parseSeriesNames(value, lines, i, palette);
3299
+ i = parsed.newIndex;
3300
+ result.series = parsed.series;
3301
+ if (parsed.names.length > 1) {
3302
+ result.seriesNames = parsed.names;
3334
3303
  }
3335
- if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;
3304
+ if (parsed.nameColors.some(Boolean)) result.seriesNameColors = parsed.nameColors;
3336
3305
  continue;
3337
3306
  }
3338
3307
  if (key === "xlabel") {
@@ -3394,13 +3363,7 @@ function parseEChart(content, palette) {
3394
3363
  continue;
3395
3364
  }
3396
3365
  if (result.type === "function") {
3397
- let fnName = trimmed.substring(0, colonIndex).trim();
3398
- let fnColor;
3399
- const colorMatch = fnName.match(/\(([^)]+)\)\s*$/);
3400
- if (colorMatch) {
3401
- fnColor = resolveColor(colorMatch[1].trim(), palette);
3402
- fnName = fnName.substring(0, colorMatch.index).trim();
3403
- }
3366
+ const { label: fnName, color: fnColor } = extractColor(trimmed.substring(0, colonIndex).trim(), palette);
3404
3367
  if (!result.functions) result.functions = [];
3405
3368
  result.functions.push({
3406
3369
  name: fnName,
@@ -3415,13 +3378,7 @@ function parseEChart(content, palette) {
3415
3378
  /^(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+))?$/
3416
3379
  );
3417
3380
  if (scatterMatch) {
3418
- let scatterName = trimmed.substring(0, colonIndex).trim();
3419
- let scatterColor;
3420
- const colorMatch = scatterName.match(/\(([^)]+)\)\s*$/);
3421
- if (colorMatch) {
3422
- scatterColor = resolveColor(colorMatch[1].trim(), palette);
3423
- scatterName = scatterName.substring(0, colorMatch.index).trim();
3424
- }
3381
+ const { label: scatterName, color: scatterColor } = extractColor(trimmed.substring(0, colonIndex).trim(), palette);
3425
3382
  if (!result.scatterPoints) result.scatterPoints = [];
3426
3383
  result.scatterPoints.push({
3427
3384
  name: scatterName,
@@ -3446,13 +3403,7 @@ function parseEChart(content, palette) {
3446
3403
  }
3447
3404
  const numValue = parseFloat(value);
3448
3405
  if (!isNaN(numValue)) {
3449
- let rawLabel = trimmed.substring(0, colonIndex).trim();
3450
- let pointColor;
3451
- const colorMatch = rawLabel.match(/\(([^)]+)\)\s*$/);
3452
- if (colorMatch) {
3453
- pointColor = resolveColor(colorMatch[1].trim(), palette);
3454
- rawLabel = rawLabel.substring(0, colorMatch.index).trim();
3455
- }
3406
+ const { label: rawLabel, color: pointColor } = extractColor(trimmed.substring(0, colonIndex).trim(), palette);
3456
3407
  result.data.push({
3457
3408
  label: rawLabel,
3458
3409
  value: numValue,
@@ -3499,30 +3450,21 @@ function parseEChart(content, palette) {
3499
3450
  }
3500
3451
  return result;
3501
3452
  }
3502
- function buildEChartsOption(parsed, palette, isDark) {
3453
+ function buildChartCommons(parsed, palette, isDark) {
3503
3454
  const textColor = palette.text;
3504
3455
  const axisLineColor = palette.border;
3456
+ const splitLineColor = palette.border;
3505
3457
  const gridOpacity = isDark ? 0.7 : 0.55;
3506
3458
  const colors = getSeriesColors(palette);
3459
+ const titleConfig = parsed.title ? { text: parsed.title, left: "center", top: 8, textStyle: { color: textColor, fontSize: 20, fontWeight: "bold", fontFamily: FONT_FAMILY } } : void 0;
3460
+ const tooltipTheme = { backgroundColor: palette.surface, borderColor: palette.border, textStyle: { color: palette.text } };
3461
+ return { textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme };
3462
+ }
3463
+ function buildEChartsOption(parsed, palette, isDark) {
3507
3464
  if (parsed.error) {
3508
3465
  return {};
3509
3466
  }
3510
- const titleConfig = parsed.title ? {
3511
- text: parsed.title,
3512
- left: "center",
3513
- top: 8,
3514
- textStyle: {
3515
- color: textColor,
3516
- fontSize: 20,
3517
- fontWeight: "bold",
3518
- fontFamily: FONT_FAMILY
3519
- }
3520
- } : void 0;
3521
- const tooltipTheme = {
3522
- backgroundColor: palette.surface,
3523
- borderColor: palette.border,
3524
- textStyle: { color: palette.text }
3525
- };
3467
+ const { textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme } = buildChartCommons(parsed, palette, isDark);
3526
3468
  if (parsed.type === "sankey") {
3527
3469
  return buildSankeyOption(
3528
3470
  parsed,
@@ -3598,8 +3540,7 @@ function buildSankeyOption(parsed, textColor, colors, titleConfig, tooltipTheme)
3598
3540
  }
3599
3541
  }));
3600
3542
  return {
3601
- backgroundColor: "transparent",
3602
- animation: false,
3543
+ ...CHART_BASE,
3603
3544
  title: titleConfig,
3604
3545
  tooltip: {
3605
3546
  show: false,
@@ -3656,8 +3597,7 @@ function buildChordOption(parsed, textColor, colors, titleConfig, tooltipTheme)
3656
3597
  }
3657
3598
  }));
3658
3599
  return {
3659
- backgroundColor: "transparent",
3660
- animation: false,
3600
+ ...CHART_BASE,
3661
3601
  title: titleConfig,
3662
3602
  tooltip: {
3663
3603
  trigger: "item",
@@ -3759,15 +3699,11 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpac
3759
3699
  itemStyle: {
3760
3700
  color: fnColor
3761
3701
  },
3762
- emphasis: {
3763
- focus: "self",
3764
- blurScope: "global"
3765
- }
3702
+ emphasis: EMPHASIS_SELF
3766
3703
  };
3767
3704
  });
3768
3705
  return {
3769
- backgroundColor: "transparent",
3770
- animation: false,
3706
+ ...CHART_BASE,
3771
3707
  title: titleConfig,
3772
3708
  tooltip: {
3773
3709
  trigger: "axis",
@@ -3912,8 +3848,7 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
3912
3848
  const xPad = (xMax - xMin) * 0.1 || 1;
3913
3849
  const yPad = (yMax - yMin) * 0.1 || 1;
3914
3850
  return {
3915
- backgroundColor: "transparent",
3916
- animation: false,
3851
+ ...CHART_BASE,
3917
3852
  title: titleConfig,
3918
3853
  tooltip,
3919
3854
  ...legendData && {
@@ -3998,8 +3933,7 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3998
3933
  });
3999
3934
  });
4000
3935
  return {
4001
- backgroundColor: "transparent",
4002
- animation: false,
3936
+ ...CHART_BASE,
4003
3937
  title: titleConfig,
4004
3938
  tooltip: {
4005
3939
  trigger: "item",
@@ -4076,8 +4010,7 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4076
4010
  fontWeight: "bold"
4077
4011
  },
4078
4012
  emphasis: {
4079
- focus: "self",
4080
- blurScope: "global",
4013
+ ...EMPHASIS_SELF,
4081
4014
  itemStyle: {
4082
4015
  shadowBlur: 10,
4083
4016
  shadowColor: "rgba(0, 0, 0, 0.5)"
@@ -4116,8 +4049,7 @@ function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4116
4049
  minSize: "8%"
4117
4050
  };
4118
4051
  return {
4119
- backgroundColor: "transparent",
4120
- animation: false,
4052
+ ...CHART_BASE,
4121
4053
  title: titleConfig,
4122
4054
  tooltip: {
4123
4055
  trigger: "item",
@@ -4155,8 +4087,7 @@ function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4155
4087
  lineStyle: { color: textColor, opacity: 0.3 }
4156
4088
  },
4157
4089
  emphasis: {
4158
- focus: "self",
4159
- blurScope: "global",
4090
+ ...EMPHASIS_SELF,
4160
4091
  label: {
4161
4092
  fontSize: 15
4162
4093
  }
@@ -4196,19 +4127,36 @@ function resolveAxisLabels(parsed) {
4196
4127
  yLabel: parsed.ylabel ?? (isHorizontal ? void 0 : parsed.label)
4197
4128
  };
4198
4129
  }
4199
- function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data, nameGapOverride) {
4130
+ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data, nameGapOverride, chartWidthHint) {
4200
4131
  const defaultGap = type === "value" ? 75 : 40;
4132
+ let catFontSize = 16;
4133
+ let catLabelExtras = {};
4134
+ if (type === "category" && data && data.length > 0) {
4135
+ const maxLabelLen = Math.max(...data.map((l) => l.length));
4136
+ const count = data.length;
4137
+ if (count > 10 || maxLabelLen > 20) catFontSize = 10;
4138
+ else if (count > 5 || maxLabelLen > 14) catFontSize = 11;
4139
+ else if (maxLabelLen > 8) catFontSize = 12;
4140
+ if (chartWidthHint && count > 0) {
4141
+ const availPerLabel = Math.floor(chartWidthHint * 0.85 / count);
4142
+ catLabelExtras = {
4143
+ width: availPerLabel,
4144
+ overflow: "break"
4145
+ };
4146
+ }
4147
+ }
4201
4148
  return {
4202
4149
  type,
4203
4150
  ...data && { data },
4204
4151
  axisLine: { lineStyle: { color: axisLineColor } },
4205
4152
  axisLabel: {
4206
4153
  color: textColor,
4207
- fontSize: type === "category" && data ? data.length > 10 ? 11 : data.length > 5 ? 12 : 16 : 16,
4154
+ fontSize: type === "category" && data ? catFontSize : 16,
4208
4155
  fontFamily: FONT_FAMILY,
4209
4156
  ...type === "category" && {
4210
4157
  interval: 0,
4211
- formatter: (value) => value.replace(/([a-z])([A-Z])/g, "$1\n$2").replace(/ /g, "\n")
4158
+ formatter: (value) => value.replace(/([a-z])([A-Z])/g, "$1\n$2"),
4159
+ ...catLabelExtras
4212
4160
  }
4213
4161
  },
4214
4162
  splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },
@@ -4220,38 +4168,18 @@ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacit
4220
4168
  }
4221
4169
  };
4222
4170
  }
4223
- function buildEChartsOptionFromChart(parsed, palette, isDark) {
4171
+ function buildEChartsOptionFromChart(parsed, palette, isDark, chartWidth) {
4224
4172
  if (parsed.error) return {};
4225
- const textColor = palette.text;
4226
- const axisLineColor = palette.border;
4227
- const splitLineColor = palette.border;
4228
- const gridOpacity = isDark ? 0.7 : 0.55;
4229
- const colors = getSeriesColors(palette);
4230
- const titleConfig = parsed.title ? {
4231
- text: parsed.title,
4232
- left: "center",
4233
- top: 8,
4234
- textStyle: {
4235
- color: textColor,
4236
- fontSize: 20,
4237
- fontWeight: "bold",
4238
- fontFamily: FONT_FAMILY
4239
- }
4240
- } : void 0;
4241
- const tooltipTheme = {
4242
- backgroundColor: palette.surface,
4243
- borderColor: palette.border,
4244
- textStyle: { color: palette.text }
4245
- };
4173
+ const { textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme } = buildChartCommons(parsed, palette, isDark);
4246
4174
  switch (parsed.type) {
4247
4175
  case "bar":
4248
- return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
4176
+ return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4249
4177
  case "bar-stacked":
4250
- return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
4178
+ return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4251
4179
  case "line":
4252
- return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
4180
+ return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4253
4181
  case "area":
4254
- return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
4182
+ return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4255
4183
  case "pie":
4256
4184
  return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);
4257
4185
  case "doughnut":
@@ -4262,7 +4190,16 @@ function buildEChartsOptionFromChart(parsed, palette, isDark) {
4262
4190
  return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);
4263
4191
  }
4264
4192
  }
4265
- function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
4193
+ function makeChartGrid(options) {
4194
+ return {
4195
+ left: options.yLabel ? "12%" : "3%",
4196
+ right: "4%",
4197
+ bottom: options.hasLegend ? "15%" : options.xLabel ? "10%" : "3%",
4198
+ top: options.hasTitle ? "15%" : "5%",
4199
+ containLabel: true
4200
+ };
4201
+ }
4202
+ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
4266
4203
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4267
4204
  const isHorizontal = parsed.orientation === "horizontal";
4268
4205
  const labels = parsed.data.map((d) => d.label);
@@ -4271,60 +4208,43 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
4271
4208
  itemStyle: { color: d.color ?? colors[i % colors.length] }
4272
4209
  }));
4273
4210
  const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
4274
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
4211
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
4275
4212
  const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
4276
4213
  return {
4277
- backgroundColor: "transparent",
4278
- animation: false,
4214
+ ...CHART_BASE,
4279
4215
  title: titleConfig,
4280
4216
  tooltip: {
4281
4217
  trigger: "axis",
4282
4218
  ...tooltipTheme,
4283
4219
  axisPointer: { type: "shadow" }
4284
4220
  },
4285
- grid: {
4286
- left: yLabel ? "12%" : "3%",
4287
- right: "4%",
4288
- bottom: xLabel ? "10%" : "3%",
4289
- top: parsed.title ? "15%" : "5%",
4290
- containLabel: true
4291
- },
4221
+ grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
4292
4222
  xAxis: isHorizontal ? valueAxis : categoryAxis,
4293
4223
  yAxis: isHorizontal ? categoryAxis : valueAxis,
4294
4224
  series: [
4295
4225
  {
4296
4226
  type: "bar",
4297
4227
  data,
4298
- emphasis: {
4299
- focus: "self",
4300
- blurScope: "global"
4301
- }
4228
+ emphasis: EMPHASIS_SELF
4302
4229
  }
4303
4230
  ]
4304
4231
  };
4305
4232
  }
4306
- function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
4233
+ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth) {
4307
4234
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4308
4235
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
4309
4236
  const labels = parsed.data.map((d) => d.label);
4310
4237
  const values = parsed.data.map((d) => d.value);
4311
4238
  return {
4312
- backgroundColor: "transparent",
4313
- animation: false,
4239
+ ...CHART_BASE,
4314
4240
  title: titleConfig,
4315
4241
  tooltip: {
4316
4242
  trigger: "axis",
4317
4243
  ...tooltipTheme,
4318
4244
  axisPointer: { type: "line" }
4319
4245
  },
4320
- grid: {
4321
- left: yLabel ? "12%" : "3%",
4322
- right: "4%",
4323
- bottom: xLabel ? "10%" : "3%",
4324
- top: parsed.title ? "15%" : "5%",
4325
- containLabel: true
4326
- },
4327
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
4246
+ grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
4247
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
4328
4248
  yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
4329
4249
  series: [
4330
4250
  {
@@ -4334,15 +4254,12 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
4334
4254
  symbolSize: 8,
4335
4255
  lineStyle: { color: lineColor, width: 3 },
4336
4256
  itemStyle: { color: lineColor },
4337
- emphasis: {
4338
- focus: "self",
4339
- blurScope: "global"
4340
- }
4257
+ emphasis: EMPHASIS_SELF
4341
4258
  }
4342
4259
  ]
4343
4260
  };
4344
4261
  }
4345
- function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
4262
+ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
4346
4263
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4347
4264
  const seriesNames = parsed.seriesNames ?? [];
4348
4265
  const labels = parsed.data.map((d) => d.label);
@@ -4359,15 +4276,11 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
4359
4276
  symbolSize: 8,
4360
4277
  lineStyle: { color, width: 3 },
4361
4278
  itemStyle: { color },
4362
- emphasis: {
4363
- focus: "self",
4364
- blurScope: "global"
4365
- }
4279
+ emphasis: EMPHASIS_SELF
4366
4280
  };
4367
4281
  });
4368
4282
  return {
4369
- backgroundColor: "transparent",
4370
- animation: false,
4283
+ ...CHART_BASE,
4371
4284
  title: titleConfig,
4372
4285
  tooltip: {
4373
4286
  trigger: "axis",
@@ -4379,40 +4292,27 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
4379
4292
  bottom: 10,
4380
4293
  textStyle: { color: textColor }
4381
4294
  },
4382
- grid: {
4383
- left: yLabel ? "12%" : "3%",
4384
- right: "4%",
4385
- bottom: "15%",
4386
- top: parsed.title ? "15%" : "5%",
4387
- containLabel: true
4388
- },
4389
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
4295
+ grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title, hasLegend: true }),
4296
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
4390
4297
  yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
4391
4298
  series
4392
4299
  };
4393
4300
  }
4394
- function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
4301
+ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth) {
4395
4302
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4396
4303
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
4397
4304
  const labels = parsed.data.map((d) => d.label);
4398
4305
  const values = parsed.data.map((d) => d.value);
4399
4306
  return {
4400
- backgroundColor: "transparent",
4401
- animation: false,
4307
+ ...CHART_BASE,
4402
4308
  title: titleConfig,
4403
4309
  tooltip: {
4404
4310
  trigger: "axis",
4405
4311
  ...tooltipTheme,
4406
4312
  axisPointer: { type: "line" }
4407
4313
  },
4408
- grid: {
4409
- left: yLabel ? "12%" : "3%",
4410
- right: "4%",
4411
- bottom: xLabel ? "10%" : "3%",
4412
- top: parsed.title ? "15%" : "5%",
4413
- containLabel: true
4414
- },
4415
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
4314
+ grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
4315
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels, void 0, chartWidth),
4416
4316
  yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
4417
4317
  series: [
4418
4318
  {
@@ -4423,10 +4323,7 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
4423
4323
  lineStyle: { color: lineColor, width: 3 },
4424
4324
  itemStyle: { color: lineColor },
4425
4325
  areaStyle: { opacity: 0.25 },
4426
- emphasis: {
4427
- focus: "self",
4428
- blurScope: "global"
4429
- }
4326
+ emphasis: EMPHASIS_SELF
4430
4327
  }
4431
4328
  ]
4432
4329
  };
@@ -4450,8 +4347,7 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
4450
4347
  itemStyle: { color: d.color ?? colors[i % colors.length] }
4451
4348
  }));
4452
4349
  return {
4453
- backgroundColor: "transparent",
4454
- animation: false,
4350
+ ...CHART_BASE,
4455
4351
  title: titleConfig,
4456
4352
  tooltip: {
4457
4353
  trigger: "item",
@@ -4469,10 +4365,7 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
4469
4365
  fontFamily: FONT_FAMILY
4470
4366
  },
4471
4367
  labelLine: { show: true },
4472
- emphasis: {
4473
- focus: "self",
4474
- blurScope: "global"
4475
- }
4368
+ emphasis: EMPHASIS_SELF
4476
4369
  }
4477
4370
  ]
4478
4371
  };
@@ -4486,8 +4379,7 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
4486
4379
  max: maxValue
4487
4380
  }));
4488
4381
  return {
4489
- backgroundColor: "transparent",
4490
- animation: false,
4382
+ ...CHART_BASE,
4491
4383
  title: titleConfig,
4492
4384
  tooltip: {
4493
4385
  trigger: "item",
@@ -4529,10 +4421,7 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
4529
4421
  }
4530
4422
  }
4531
4423
  ],
4532
- emphasis: {
4533
- focus: "self",
4534
- blurScope: "global"
4535
- }
4424
+ emphasis: EMPHASIS_SELF
4536
4425
  }
4537
4426
  ]
4538
4427
  };
@@ -4544,8 +4433,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
4544
4433
  itemStyle: { color: d.color ?? colors[i % colors.length] }
4545
4434
  }));
4546
4435
  return {
4547
- backgroundColor: "transparent",
4548
- animation: false,
4436
+ ...CHART_BASE,
4549
4437
  title: titleConfig,
4550
4438
  tooltip: {
4551
4439
  trigger: "item",
@@ -4564,15 +4452,12 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
4564
4452
  fontFamily: FONT_FAMILY
4565
4453
  },
4566
4454
  labelLine: { show: true },
4567
- emphasis: {
4568
- focus: "self",
4569
- blurScope: "global"
4570
- }
4455
+ emphasis: EMPHASIS_SELF
4571
4456
  }
4572
4457
  ]
4573
4458
  };
4574
4459
  }
4575
- function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
4460
+ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
4576
4461
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4577
4462
  const isHorizontal = parsed.orientation === "horizontal";
4578
4463
  const seriesNames = parsed.seriesNames ?? [];
@@ -4597,18 +4482,15 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
4597
4482
  fontWeight: "bold",
4598
4483
  fontFamily: FONT_FAMILY
4599
4484
  },
4600
- emphasis: {
4601
- focus: "self",
4602
- blurScope: "global"
4603
- }
4485
+ emphasis: EMPHASIS_SELF
4604
4486
  };
4605
4487
  });
4606
4488
  const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
4607
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap);
4608
- const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
4489
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
4490
+ const hValueGap = isHorizontal && xLabel ? 40 : void 0;
4491
+ const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel, void 0, hValueGap);
4609
4492
  return {
4610
- backgroundColor: "transparent",
4611
- animation: false,
4493
+ ...CHART_BASE,
4612
4494
  title: titleConfig,
4613
4495
  tooltip: {
4614
4496
  trigger: "axis",
@@ -4620,13 +4502,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
4620
4502
  bottom: 10,
4621
4503
  textStyle: { color: textColor }
4622
4504
  },
4623
- grid: {
4624
- left: yLabel ? "12%" : "3%",
4625
- right: "4%",
4626
- bottom: "15%",
4627
- top: parsed.title ? "15%" : "5%",
4628
- containLabel: true
4629
- },
4505
+ grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title, hasLegend: true }),
4630
4506
  xAxis: isHorizontal ? valueAxis : categoryAxis,
4631
4507
  yAxis: isHorizontal ? categoryAxis : valueAxis,
4632
4508
  series
@@ -4642,7 +4518,7 @@ async function renderEChartsForExport(content, theme, palette, options) {
4642
4518
  if (chartType && STANDARD_CHART_TYPES.has(chartType)) {
4643
4519
  const parsed = parseChart(content, effectivePalette);
4644
4520
  if (parsed.error) return "";
4645
- option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark);
4521
+ option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark, ECHART_EXPORT_WIDTH);
4646
4522
  } else {
4647
4523
  const parsed = parseEChart(content, effectivePalette);
4648
4524
  if (parsed.error) return "";
@@ -4673,30 +4549,21 @@ async function renderEChartsForExport(content, theme, palette, options) {
4673
4549
  chart.dispose();
4674
4550
  }
4675
4551
  }
4676
- var ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
4552
+ var EMPHASIS_SELF, CHART_BASE, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT;
4677
4553
  var init_echarts = __esm({
4678
4554
  "src/echarts.ts"() {
4679
4555
  "use strict";
4680
4556
  init_fonts();
4681
4557
  init_branding();
4682
- init_colors();
4683
4558
  init_palettes();
4684
4559
  init_chart();
4685
4560
  init_diagnostics();
4686
4561
  init_parsing();
4562
+ init_dgmo_router();
4563
+ EMPHASIS_SELF = { focus: "self", blurScope: "global" };
4564
+ CHART_BASE = { backgroundColor: "transparent", animation: false };
4687
4565
  ECHART_EXPORT_WIDTH = 1200;
4688
4566
  ECHART_EXPORT_HEIGHT = 800;
4689
- STANDARD_CHART_TYPES = /* @__PURE__ */ new Set([
4690
- "bar",
4691
- "line",
4692
- "multi-line",
4693
- "area",
4694
- "pie",
4695
- "doughnut",
4696
- "radar",
4697
- "polar-area",
4698
- "bar-stacked"
4699
- ]);
4700
4567
  }
4701
4568
  });
4702
4569
 
@@ -6026,6 +5893,7 @@ var init_parser7 = __esm({
6026
5893
  var dgmo_router_exports = {};
6027
5894
  __export(dgmo_router_exports, {
6028
5895
  DGMO_CHART_TYPE_MAP: () => DGMO_CHART_TYPE_MAP,
5896
+ STANDARD_CHART_TYPES: () => STANDARD_CHART_TYPES,
6029
5897
  getDgmoFramework: () => getDgmoFramework,
6030
5898
  parseDgmo: () => parseDgmo,
6031
5899
  parseDgmoChartType: () => parseDgmoChartType
@@ -6053,53 +5921,19 @@ function parseDgmoChartType(content) {
6053
5921
  function parseDgmo(content) {
6054
5922
  const chartType = parseDgmoChartType(content);
6055
5923
  if (!chartType) {
6056
- const parsed2 = parseD3(content);
6057
- return { diagnostics: parsed2.diagnostics };
6058
- }
6059
- if (chartType === "sequence") {
6060
- const parsed2 = parseSequenceDgmo(content);
6061
- return { diagnostics: parsed2.diagnostics };
6062
- }
6063
- if (chartType === "flowchart") {
6064
- const parsed2 = parseFlowchart(content);
6065
- return { diagnostics: parsed2.diagnostics };
6066
- }
6067
- if (chartType === "class") {
6068
- const parsed2 = parseClassDiagram(content);
6069
- return { diagnostics: parsed2.diagnostics };
5924
+ return { diagnostics: parseD3(content).diagnostics };
6070
5925
  }
6071
- if (chartType === "er") {
6072
- const parsed2 = parseERDiagram(content);
6073
- return { diagnostics: parsed2.diagnostics };
6074
- }
6075
- if (chartType === "org") {
6076
- const parsed2 = parseOrg(content);
6077
- return { diagnostics: parsed2.diagnostics };
6078
- }
6079
- if (chartType === "kanban") {
6080
- const parsed2 = parseKanban(content);
6081
- return { diagnostics: parsed2.diagnostics };
6082
- }
6083
- if (chartType === "c4") {
6084
- const parsed2 = parseC4(content);
6085
- return { diagnostics: parsed2.diagnostics };
6086
- }
6087
- if (chartType === "initiative-status") {
6088
- const parsed2 = parseInitiativeStatus(content);
6089
- return { diagnostics: parsed2.diagnostics };
6090
- }
6091
- if (STANDARD_CHART_TYPES2.has(chartType)) {
6092
- const parsed2 = parseChart(content);
6093
- return { diagnostics: parsed2.diagnostics };
5926
+ const directParser = PARSE_DISPATCH.get(chartType);
5927
+ if (directParser) return { diagnostics: directParser(content).diagnostics };
5928
+ if (STANDARD_CHART_TYPES.has(chartType)) {
5929
+ return { diagnostics: parseChart(content).diagnostics };
6094
5930
  }
6095
5931
  if (ECHART_TYPES.has(chartType)) {
6096
- const parsed2 = parseEChart(content);
6097
- return { diagnostics: parsed2.diagnostics };
5932
+ return { diagnostics: parseEChart(content).diagnostics };
6098
5933
  }
6099
- const parsed = parseD3(content);
6100
- return { diagnostics: parsed.diagnostics };
5934
+ return { diagnostics: parseD3(content).diagnostics };
6101
5935
  }
6102
- var DGMO_CHART_TYPE_MAP, STANDARD_CHART_TYPES2, ECHART_TYPES;
5936
+ var DGMO_CHART_TYPE_MAP, STANDARD_CHART_TYPES, ECHART_TYPES, PARSE_DISPATCH;
6103
5937
  var init_dgmo_router = __esm({
6104
5938
  "src/dgmo-router.ts"() {
6105
5939
  "use strict";
@@ -6148,7 +5982,7 @@ var init_dgmo_router = __esm({
6148
5982
  c4: "d3",
6149
5983
  "initiative-status": "d3"
6150
5984
  };
6151
- STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
5985
+ STANDARD_CHART_TYPES = /* @__PURE__ */ new Set([
6152
5986
  "bar",
6153
5987
  "line",
6154
5988
  "multi-line",
@@ -6167,6 +6001,16 @@ var init_dgmo_router = __esm({
6167
6001
  "heatmap",
6168
6002
  "funnel"
6169
6003
  ]);
6004
+ PARSE_DISPATCH = /* @__PURE__ */ new Map([
6005
+ ["sequence", (c) => parseSequenceDgmo(c)],
6006
+ ["flowchart", (c) => parseFlowchart(c)],
6007
+ ["class", (c) => parseClassDiagram(c)],
6008
+ ["er", (c) => parseERDiagram(c)],
6009
+ ["org", (c) => parseOrg(c)],
6010
+ ["kanban", (c) => parseKanban(c)],
6011
+ ["c4", (c) => parseC4(c)],
6012
+ ["initiative-status", (c) => parseInitiativeStatus(c)]
6013
+ ]);
6170
6014
  }
6171
6015
  });
6172
6016
 
@@ -12166,7 +12010,7 @@ function buildRenderSequence(messages) {
12166
12010
  type: "return",
12167
12011
  from: top.to,
12168
12012
  to: top.from,
12169
- label: top.returnLabel || "",
12013
+ label: "",
12170
12014
  messageIndex: top.messageIndex
12171
12015
  });
12172
12016
  }
@@ -12192,12 +12036,8 @@ function buildRenderSequence(messages) {
12192
12036
  to: msg.to,
12193
12037
  label: msg.label,
12194
12038
  messageIndex: mi,
12195
- ...msg.async ? { async: true } : {},
12196
- ...msg.bidirectional ? { bidirectional: true } : {}
12039
+ ...msg.async ? { async: true } : {}
12197
12040
  });
12198
- if (msg.bidirectional) {
12199
- continue;
12200
- }
12201
12041
  if (msg.async) {
12202
12042
  continue;
12203
12043
  }
@@ -12206,14 +12046,13 @@ function buildRenderSequence(messages) {
12206
12046
  type: "return",
12207
12047
  from: msg.to,
12208
12048
  to: msg.from,
12209
- label: msg.returnLabel || "",
12049
+ label: "",
12210
12050
  messageIndex: mi
12211
12051
  });
12212
12052
  } else {
12213
12053
  stack.push({
12214
12054
  from: msg.from,
12215
12055
  to: msg.to,
12216
- returnLabel: msg.returnLabel,
12217
12056
  messageIndex: mi
12218
12057
  });
12219
12058
  }
@@ -12224,7 +12063,7 @@ function buildRenderSequence(messages) {
12224
12063
  type: "return",
12225
12064
  from: top.to,
12226
12065
  to: top.from,
12227
- label: top.returnLabel || "",
12066
+ label: "",
12228
12067
  messageIndex: top.messageIndex
12229
12068
  });
12230
12069
  }
@@ -12689,14 +12528,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
12689
12528
  "points",
12690
12529
  `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
12691
12530
  ).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
12692
- defs.append("marker").attr("id", "seq-arrowhead-reverse").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", 0).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polygon").attr(
12693
- "points",
12694
- `${ARROWHEAD_SIZE},0 0,${ARROWHEAD_SIZE / 2} ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE}`
12695
- ).attr("fill", palette.text);
12696
- defs.append("marker").attr("id", "seq-arrowhead-async-reverse").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", 0).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polyline").attr(
12697
- "points",
12698
- `${ARROWHEAD_SIZE},0 0,${ARROWHEAD_SIZE / 2} ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE}`
12699
- ).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
12700
12531
  if (title) {
12701
12532
  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);
12702
12533
  if (parsed.titleLineNumber) {
@@ -12977,17 +12808,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
12977
12808
  const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
12978
12809
  const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
12979
12810
  const markerRef = step.async ? "url(#seq-arrowhead-async)" : "url(#seq-arrowhead)";
12980
- const markerStartRef = step.bidirectional ? step.async ? "url(#seq-arrowhead-async-reverse)" : "url(#seq-arrowhead-reverse)" : null;
12981
- const line7 = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", palette.text).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr(
12811
+ svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", palette.text).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr(
12982
12812
  "data-line-number",
12983
12813
  String(messages[step.messageIndex].lineNumber)
12984
12814
  ).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
12985
- if (markerStartRef) {
12986
- line7.attr("marker-start", markerStartRef);
12987
- }
12988
- if (step.bidirectional && step.async) {
12989
- line7.attr("stroke-dasharray", "6 4");
12990
- }
12991
12815
  if (step.label) {
12992
12816
  const midX = (x1 + x2) / 2;
12993
12817
  const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 12).attr("class", "message-label").attr(
@@ -13218,6 +13042,32 @@ import * as d3Selection9 from "d3-selection";
13218
13042
  import * as d3Shape6 from "d3-shape";
13219
13043
  import * as d3Array from "d3-array";
13220
13044
  import cloud from "d3-cloud";
13045
+ function renderChartTitle(svg, title, titleLineNumber, width, textColor, onClickItem) {
13046
+ if (!title) return;
13047
+ 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 && titleLineNumber ? "pointer" : "default").text(title);
13048
+ if (titleLineNumber) {
13049
+ titleEl.attr("data-line-number", titleLineNumber);
13050
+ if (onClickItem) {
13051
+ titleEl.on("click", () => onClickItem(titleLineNumber)).on("mouseenter", function() {
13052
+ d3Selection9.select(this).attr("opacity", 0.7);
13053
+ }).on("mouseleave", function() {
13054
+ d3Selection9.select(this).attr("opacity", 1);
13055
+ });
13056
+ }
13057
+ }
13058
+ }
13059
+ function initD3Chart(container, palette, exportDims) {
13060
+ d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
13061
+ const width = exportDims?.width ?? container.clientWidth;
13062
+ const height = exportDims?.height ?? container.clientHeight;
13063
+ if (width <= 0 || height <= 0) return null;
13064
+ const textColor = palette.text;
13065
+ const mutedColor = palette.border;
13066
+ const bgColor = palette.bg;
13067
+ const colors = getSeriesColors(palette);
13068
+ const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
13069
+ return { svg, width, height, textColor, mutedColor, bgColor, colors };
13070
+ }
13221
13071
  function parseTimelineDate(s) {
13222
13072
  const parts = s.split("-").map((p) => parseInt(p, 10));
13223
13073
  const year = parts[0];
@@ -13780,13 +13630,28 @@ function tokenizeFreeformText(text) {
13780
13630
  }
13781
13631
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
13782
13632
  }
13633
+ function resolveVerticalCollisions(items, minGap, maxY) {
13634
+ if (items.length === 0) return [];
13635
+ const sorted = items.map((it, i) => ({ ...it, idx: i })).sort((a, b) => a.naturalY - b.naturalY);
13636
+ const adjustedY = new Array(items.length);
13637
+ let prevBottom = -Infinity;
13638
+ for (const item of sorted) {
13639
+ const halfH = item.height / 2;
13640
+ let top = Math.max(item.naturalY - halfH, prevBottom + minGap);
13641
+ if (maxY !== void 0) {
13642
+ top = Math.min(top, maxY - item.height);
13643
+ }
13644
+ adjustedY[item.idx] = top + halfH;
13645
+ prevBottom = top + item.height;
13646
+ }
13647
+ return adjustedY;
13648
+ }
13783
13649
  function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
13784
- d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
13785
13650
  const { periods, data, title } = parsed;
13786
13651
  if (data.length === 0 || periods.length < 2) return;
13787
- const width = exportDims?.width ?? container.clientWidth;
13788
- const height = exportDims?.height ?? container.clientHeight;
13789
- if (width <= 0 || height <= 0) return;
13652
+ const init2 = initD3Chart(container, palette, exportDims);
13653
+ if (!init2) return;
13654
+ const { svg, width, height, textColor, mutedColor, bgColor, colors } = init2;
13790
13655
  const maxLabelText = data.reduce((longest, item) => {
13791
13656
  const text = `${item.values[item.values.length - 1]} \u2014 ${item.label}`;
13792
13657
  return text.length > longest.length ? text : longest;
@@ -13799,56 +13664,94 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
13799
13664
  );
13800
13665
  const innerWidth = width - SLOPE_MARGIN.left - rightMargin;
13801
13666
  const innerHeight = height - SLOPE_MARGIN.top - SLOPE_MARGIN.bottom;
13802
- const textColor = palette.text;
13803
- const mutedColor = palette.border;
13804
- const bgColor = palette.bg;
13805
- const colors = getSeriesColors(palette);
13806
13667
  const allValues = data.flatMap((d) => d.values);
13807
13668
  const [minVal, maxVal] = d3Array.extent(allValues);
13808
13669
  const valuePadding = (maxVal - minVal) * 0.1 || 1;
13809
13670
  const yScale = d3Scale.scaleLinear().domain([minVal - valuePadding, maxVal + valuePadding]).range([innerHeight, 0]);
13810
13671
  const xScale = d3Scale.scalePoint().domain(periods).range([0, innerWidth]).padding(0);
13811
- const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
13812
13672
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
13813
13673
  const tooltip = createTooltip(container, palette, isDark);
13814
- if (title) {
13815
- 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);
13816
- if (parsed.titleLineNumber) {
13817
- titleEl.attr("data-line-number", parsed.titleLineNumber);
13818
- if (onClickItem) {
13819
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
13820
- d3Selection9.select(this).attr("opacity", 0.7);
13821
- }).on("mouseleave", function() {
13822
- d3Selection9.select(this).attr("opacity", 1);
13823
- });
13824
- }
13825
- }
13826
- }
13674
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
13827
13675
  for (const period of periods) {
13828
13676
  const x = xScale(period);
13829
13677
  g.append("text").attr("x", x).attr("y", -15).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "600").text(period);
13830
13678
  g.append("line").attr("x1", x).attr("y1", 0).attr("x2", x).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
13831
13679
  }
13832
13680
  const lineGen = d3Shape6.line().x((_d, i) => xScale(periods[i])).y((d) => yScale(d));
13833
- data.forEach((item, idx) => {
13681
+ const seriesInfo = data.map((item, idx) => {
13834
13682
  const color = item.color ?? colors[idx % colors.length];
13835
- const seriesG = g.append("g").attr("class", "slope-series").attr("data-line-number", String(item.lineNumber));
13836
13683
  const firstVal = item.values[0];
13837
13684
  const lastVal = item.values[item.values.length - 1];
13838
13685
  const absChange = lastVal - firstVal;
13839
13686
  const pctChange = firstVal !== 0 ? absChange / firstVal * 100 : null;
13840
13687
  const sign = absChange > 0 ? "+" : "";
13841
- const pctPart = pctChange !== null ? ` (${sign}${pctChange.toFixed(1)}%)` : "";
13842
- const tipLines = [`${sign}${absChange}`];
13688
+ const tipLines = [`${sign}${parseFloat(absChange.toFixed(2))}`];
13843
13689
  if (pctChange !== null) tipLines.push(`${sign}${pctChange.toFixed(1)}%`);
13844
13690
  const tipHtml = tipLines.join("<br>");
13691
+ const lastX = xScale(periods[periods.length - 1]);
13692
+ const labelText = `${lastVal} \u2014 ${item.label}`;
13693
+ const availableWidth = rightMargin - 15;
13694
+ const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);
13695
+ let labelLineCount = 1;
13696
+ let wrappedLines = null;
13697
+ if (labelText.length > maxChars) {
13698
+ const words = labelText.split(/\s+/);
13699
+ const lines = [];
13700
+ let current = "";
13701
+ for (const word of words) {
13702
+ const test = current ? `${current} ${word}` : word;
13703
+ if (test.length > maxChars && current) {
13704
+ lines.push(current);
13705
+ current = word;
13706
+ } else {
13707
+ current = test;
13708
+ }
13709
+ }
13710
+ if (current) lines.push(current);
13711
+ labelLineCount = lines.length;
13712
+ wrappedLines = lines;
13713
+ }
13714
+ const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;
13715
+ const labelHeight = labelLineCount === 1 ? SLOPE_LABEL_FONT_SIZE : labelLineCount * lineHeight;
13716
+ return {
13717
+ item,
13718
+ idx,
13719
+ color,
13720
+ firstVal,
13721
+ lastVal,
13722
+ tipHtml,
13723
+ lastX,
13724
+ labelText,
13725
+ maxChars,
13726
+ wrappedLines,
13727
+ labelHeight
13728
+ };
13729
+ });
13730
+ const leftLabelHeight = 20;
13731
+ const leftLabelCollisions = /* @__PURE__ */ new Map();
13732
+ for (let pi = 0; pi < periods.length - 1; pi++) {
13733
+ const entries = data.map((item) => ({
13734
+ naturalY: yScale(item.values[pi]),
13735
+ height: leftLabelHeight
13736
+ }));
13737
+ leftLabelCollisions.set(pi, resolveVerticalCollisions(entries, 4, innerHeight));
13738
+ }
13739
+ const rightEntries = seriesInfo.map((si) => ({
13740
+ naturalY: yScale(si.lastVal),
13741
+ height: Math.max(si.labelHeight, SLOPE_LABEL_FONT_SIZE * 1.4)
13742
+ }));
13743
+ const rightAdjustedY = resolveVerticalCollisions(rightEntries, 4, innerHeight);
13744
+ data.forEach((item, idx) => {
13745
+ const si = seriesInfo[idx];
13746
+ const color = si.color;
13747
+ const seriesG = g.append("g").attr("class", "slope-series").attr("data-line-number", String(item.lineNumber));
13845
13748
  seriesG.append("path").datum(item.values).attr("fill", "none").attr("stroke", color).attr("stroke-width", 2.5).attr("d", lineGen);
13846
13749
  seriesG.append("path").datum(item.values).attr("fill", "none").attr("stroke", "transparent").attr("stroke-width", 14).attr("d", lineGen).style("cursor", onClickItem ? "pointer" : "default").on(
13847
13750
  "mouseenter",
13848
- (event) => showTooltip(tooltip, tipHtml, event)
13751
+ (event) => showTooltip(tooltip, si.tipHtml, event)
13849
13752
  ).on(
13850
13753
  "mousemove",
13851
- (event) => showTooltip(tooltip, tipHtml, event)
13754
+ (event) => showTooltip(tooltip, si.tipHtml, event)
13852
13755
  ).on("mouseleave", () => hideTooltip(tooltip)).on("click", () => {
13853
13756
  if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);
13854
13757
  });
@@ -13857,46 +13760,30 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
13857
13760
  const y = yScale(val);
13858
13761
  seriesG.append("circle").attr("cx", x).attr("cy", y).attr("r", 4).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5).style("cursor", onClickItem ? "pointer" : "default").on(
13859
13762
  "mouseenter",
13860
- (event) => showTooltip(tooltip, tipHtml, event)
13763
+ (event) => showTooltip(tooltip, si.tipHtml, event)
13861
13764
  ).on(
13862
13765
  "mousemove",
13863
- (event) => showTooltip(tooltip, tipHtml, event)
13766
+ (event) => showTooltip(tooltip, si.tipHtml, event)
13864
13767
  ).on("mouseleave", () => hideTooltip(tooltip)).on("click", () => {
13865
13768
  if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);
13866
13769
  });
13867
13770
  const isFirst = i === 0;
13868
13771
  const isLast = i === periods.length - 1;
13869
13772
  if (!isLast) {
13870
- seriesG.append("text").attr("x", isFirst ? x - 10 : x).attr("y", y).attr("dy", "0.35em").attr("text-anchor", isFirst ? "end" : "middle").attr("fill", textColor).attr("font-size", "16px").text(val.toString());
13773
+ const adjustedY = leftLabelCollisions.get(i)[idx];
13774
+ seriesG.append("text").attr("x", isFirst ? x - 10 : x).attr("y", adjustedY).attr("dy", "0.35em").attr("text-anchor", isFirst ? "end" : "middle").attr("fill", color).attr("font-size", "16px").text(val.toString());
13871
13775
  }
13872
13776
  });
13873
- const lastX = xScale(periods[periods.length - 1]);
13874
- const lastY = yScale(lastVal);
13875
- const labelText = `${lastVal} \u2014 ${item.label}`;
13876
- const availableWidth = rightMargin - 15;
13877
- const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);
13878
- const labelEl = seriesG.append("text").attr("x", lastX + 10).attr("y", lastY).attr("text-anchor", "start").attr("fill", color).attr("font-size", `${SLOPE_LABEL_FONT_SIZE}px`).attr("font-weight", "500");
13879
- if (labelText.length <= maxChars) {
13880
- labelEl.attr("dy", "0.35em").text(labelText);
13777
+ const adjustedLastY = rightAdjustedY[idx];
13778
+ const labelEl = seriesG.append("text").attr("x", si.lastX + 10).attr("y", adjustedLastY).attr("text-anchor", "start").attr("fill", color).attr("font-size", `${SLOPE_LABEL_FONT_SIZE}px`).attr("font-weight", "500");
13779
+ if (!si.wrappedLines) {
13780
+ labelEl.attr("dy", "0.35em").text(si.labelText);
13881
13781
  } else {
13882
- const words = labelText.split(/\s+/);
13883
- const lines = [];
13884
- let current = "";
13885
- for (const word of words) {
13886
- const test = current ? `${current} ${word}` : word;
13887
- if (test.length > maxChars && current) {
13888
- lines.push(current);
13889
- current = word;
13890
- } else {
13891
- current = test;
13892
- }
13893
- }
13894
- if (current) lines.push(current);
13895
13782
  const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;
13896
- const totalHeight = (lines.length - 1) * lineHeight;
13783
+ const totalHeight = (si.wrappedLines.length - 1) * lineHeight;
13897
13784
  const startDy = -totalHeight / 2;
13898
- lines.forEach((line7, li) => {
13899
- labelEl.append("tspan").attr("x", lastX + 10).attr(
13785
+ si.wrappedLines.forEach((line7, li) => {
13786
+ labelEl.append("tspan").attr("x", si.lastX + 10).attr(
13900
13787
  "dy",
13901
13788
  li === 0 ? `${startDy + SLOPE_LABEL_FONT_SIZE * 0.35}px` : `${lineHeight}px`
13902
13789
  ).text(line7);
@@ -13993,12 +13880,11 @@ function orderArcNodes(links, order, groups) {
13993
13880
  return allNodes;
13994
13881
  }
13995
13882
  function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
13996
- d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
13997
13883
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
13998
13884
  if (links.length === 0) return;
13999
- const width = exportDims?.width ?? container.clientWidth;
14000
- const height = exportDims?.height ?? container.clientHeight;
14001
- if (width <= 0 || height <= 0) return;
13885
+ const init2 = initD3Chart(container, palette, exportDims);
13886
+ if (!init2) return;
13887
+ const { svg, width, height, textColor, mutedColor, bgColor, colors } = init2;
14002
13888
  const isVertical = orientation === "vertical";
14003
13889
  const margin = isVertical ? {
14004
13890
  top: ARC_MARGIN.top,
@@ -14008,10 +13894,6 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
14008
13894
  } : ARC_MARGIN;
14009
13895
  const innerWidth = width - margin.left - margin.right;
14010
13896
  const innerHeight = height - margin.top - margin.bottom;
14011
- const textColor = palette.text;
14012
- const mutedColor = palette.border;
14013
- const bgColor = palette.bg;
14014
- const colors = getSeriesColors(palette);
14015
13897
  const nodes = orderArcNodes(links, arcOrder, arcNodeGroups);
14016
13898
  const nodeColorMap = /* @__PURE__ */ new Map();
14017
13899
  for (const group of arcNodeGroups) {
@@ -14030,21 +13912,8 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
14030
13912
  const values = links.map((l) => l.value);
14031
13913
  const [minVal, maxVal] = d3Array.extent(values);
14032
13914
  const strokeScale = d3Scale.scaleLinear().domain([minVal, maxVal]).range([1.5, 6]);
14033
- const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
14034
13915
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
14035
- if (title) {
14036
- 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);
14037
- if (parsed.titleLineNumber) {
14038
- titleEl.attr("data-line-number", parsed.titleLineNumber);
14039
- if (onClickItem) {
14040
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
14041
- d3Selection9.select(this).attr("opacity", 0.7);
14042
- }).on("mouseleave", function() {
14043
- d3Selection9.select(this).attr("opacity", 1);
14044
- });
14045
- }
14046
- }
14047
- }
13916
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
14048
13917
  const neighbors = /* @__PURE__ */ new Map();
14049
13918
  for (const node of nodes) neighbors.set(node, /* @__PURE__ */ new Set());
14050
13919
  for (const link of links) {
@@ -14580,19 +14449,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
14580
14449
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
14581
14450
  const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
14582
14451
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
14583
- if (title) {
14584
- 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);
14585
- if (parsed.titleLineNumber) {
14586
- titleEl.attr("data-line-number", parsed.titleLineNumber);
14587
- if (onClickItem) {
14588
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
14589
- d3Selection9.select(this).attr("opacity", 0.7);
14590
- }).on("mouseleave", function() {
14591
- d3Selection9.select(this).attr("opacity", 1);
14592
- });
14593
- }
14594
- }
14595
- }
14452
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
14596
14453
  renderEras(
14597
14454
  g,
14598
14455
  timelineEras,
@@ -14695,19 +14552,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
14695
14552
  const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
14696
14553
  const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
14697
14554
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
14698
- if (title) {
14699
- 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);
14700
- if (parsed.titleLineNumber) {
14701
- titleEl.attr("data-line-number", parsed.titleLineNumber);
14702
- if (onClickItem) {
14703
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
14704
- d3Selection9.select(this).attr("opacity", 0.7);
14705
- }).on("mouseleave", function() {
14706
- d3Selection9.select(this).attr("opacity", 1);
14707
- });
14708
- }
14709
- }
14710
- }
14555
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
14711
14556
  renderEras(
14712
14557
  g,
14713
14558
  timelineEras,
@@ -14839,19 +14684,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
14839
14684
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
14840
14685
  const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
14841
14686
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
14842
- if (title) {
14843
- 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);
14844
- if (parsed.titleLineNumber) {
14845
- titleEl.attr("data-line-number", parsed.titleLineNumber);
14846
- if (onClickItem) {
14847
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
14848
- d3Selection9.select(this).attr("opacity", 0.7);
14849
- }).on("mouseleave", function() {
14850
- d3Selection9.select(this).attr("opacity", 1);
14851
- });
14852
- }
14853
- }
14854
- }
14687
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
14855
14688
  renderEras(
14856
14689
  g,
14857
14690
  timelineEras,
@@ -14994,19 +14827,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
14994
14827
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
14995
14828
  const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
14996
14829
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
14997
- if (title) {
14998
- 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);
14999
- if (parsed.titleLineNumber) {
15000
- titleEl.attr("data-line-number", parsed.titleLineNumber);
15001
- if (onClickItem) {
15002
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
15003
- d3Selection9.select(this).attr("opacity", 0.7);
15004
- }).on("mouseleave", function() {
15005
- d3Selection9.select(this).attr("opacity", 1);
15006
- });
15007
- }
15008
- }
15009
- }
14830
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
15010
14831
  renderEras(
15011
14832
  g,
15012
14833
  timelineEras,
@@ -15133,17 +14954,13 @@ function getRotateFn(mode) {
15133
14954
  return () => 0;
15134
14955
  }
15135
14956
  function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
15136
- d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
15137
14957
  const { words, title, cloudOptions } = parsed;
15138
14958
  if (words.length === 0) return;
15139
- const width = exportDims?.width ?? container.clientWidth;
15140
- const height = exportDims?.height ?? container.clientHeight;
15141
- if (width <= 0 || height <= 0) return;
14959
+ const init2 = initD3Chart(container, palette, exportDims);
14960
+ if (!init2) return;
14961
+ const { svg, width, height, textColor, colors } = init2;
15142
14962
  const titleHeight = title ? 40 : 0;
15143
14963
  const cloudHeight = height - titleHeight;
15144
- const textColor = palette.text;
15145
- const bgColor = palette.bg;
15146
- const colors = getSeriesColors(palette);
15147
14964
  const { minSize, maxSize } = cloudOptions;
15148
14965
  const weights = words.map((w) => w.weight);
15149
14966
  const minWeight = Math.min(...weights);
@@ -15154,20 +14971,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
15154
14971
  return minSize + t * (maxSize - minSize);
15155
14972
  };
15156
14973
  const rotateFn = getRotateFn(cloudOptions.rotate);
15157
- const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
15158
- if (title) {
15159
- 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);
15160
- if (parsed.titleLineNumber) {
15161
- titleEl.attr("data-line-number", parsed.titleLineNumber);
15162
- if (onClickItem) {
15163
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
15164
- d3Selection9.select(this).attr("opacity", 0.7);
15165
- }).on("mouseleave", function() {
15166
- d3Selection9.select(this).attr("opacity", 1);
15167
- });
15168
- }
15169
- }
15170
- }
14974
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
15171
14975
  const g = svg.append("g").attr(
15172
14976
  "transform",
15173
14977
  `translate(${width / 2},${titleHeight + cloudHeight / 2})`
@@ -15218,12 +15022,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
15218
15022
  };
15219
15023
  const rotateFn = getRotateFn(cloudOptions.rotate);
15220
15024
  const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
15221
- if (title) {
15222
- 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);
15223
- if (parsed.titleLineNumber) {
15224
- titleEl.attr("data-line-number", parsed.titleLineNumber);
15225
- }
15226
- }
15025
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor);
15227
15026
  const g = svg.append("g").attr(
15228
15027
  "transform",
15229
15028
  `translate(${width / 2},${titleHeight + cloudHeight / 2})`
@@ -15354,15 +15153,11 @@ function regionCentroid(circles, inside) {
15354
15153
  return { x: sx / count, y: sy / count };
15355
15154
  }
15356
15155
  function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
15357
- d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
15358
15156
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
15359
15157
  if (vennSets.length < 2) return;
15360
- const width = exportDims?.width ?? container.clientWidth;
15361
- const height = exportDims?.height ?? container.clientHeight;
15362
- if (width <= 0 || height <= 0) return;
15363
- const textColor = palette.text;
15364
- const bgColor = palette.bg;
15365
- const colors = getSeriesColors(palette);
15158
+ const init2 = initD3Chart(container, palette, exportDims);
15159
+ if (!init2) return;
15160
+ const { svg, width, height, textColor, colors } = init2;
15366
15161
  const titleHeight = title ? 40 : 0;
15367
15162
  const radii = vennSets.map((s) => radiusFromArea(s.size));
15368
15163
  const overlapMap = /* @__PURE__ */ new Map();
@@ -15441,21 +15236,8 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
15441
15236
  marginTop,
15442
15237
  marginBottom
15443
15238
  ).map((c) => ({ ...c, y: c.y + titleHeight }));
15444
- const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
15445
15239
  const tooltip = createTooltip(container, palette, isDark);
15446
- if (title) {
15447
- 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);
15448
- if (parsed.titleLineNumber) {
15449
- titleEl.attr("data-line-number", parsed.titleLineNumber);
15450
- if (onClickItem) {
15451
- titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
15452
- d3Selection9.select(this).attr("opacity", 0.7);
15453
- }).on("mouseleave", function() {
15454
- d3Selection9.select(this).attr("opacity", 1);
15455
- });
15456
- }
15457
- }
15458
- }
15240
+ renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor, onClickItem);
15459
15241
  const circleEls = [];
15460
15242
  const circleGroup = svg.append("g");
15461
15243
  circles.forEach((c, i) => {
@@ -15599,7 +15381,6 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
15599
15381
  });
15600
15382
  }
15601
15383
  function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
15602
- d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
15603
15384
  const {
15604
15385
  title,
15605
15386
  quadrantLabels,
@@ -15611,12 +15392,10 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
15611
15392
  quadrantYAxisLineNumber
15612
15393
  } = parsed;
15613
15394
  if (quadrantPoints.length === 0) return;
15614
- const width = exportDims?.width ?? container.clientWidth;
15615
- const height = exportDims?.height ?? container.clientHeight;
15616
- if (width <= 0 || height <= 0) return;
15617
- const textColor = palette.text;
15395
+ const init2 = initD3Chart(container, palette, exportDims);
15396
+ if (!init2) return;
15397
+ const { svg, width, height, textColor } = init2;
15618
15398
  const mutedColor = palette.textMuted;
15619
- const bgColor = palette.bg;
15620
15399
  const borderColor = palette.border;
15621
15400
  const defaultColors = [
15622
15401
  palette.colors.blue,
@@ -15631,24 +15410,8 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
15631
15410
  const chartHeight = height - margin.top - margin.bottom;
15632
15411
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
15633
15412
  const yScale = d3Scale.scaleLinear().domain([0, 1]).range([chartHeight, 0]);
15634
- const svg = d3Selection9.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
15635
15413
  const tooltip = createTooltip(container, palette, isDark);
15636
- if (title) {
15637
- 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(
15638
- "cursor",
15639
- onClickItem && quadrantTitleLineNumber ? "pointer" : "default"
15640
- ).text(title);
15641
- if (quadrantTitleLineNumber) {
15642
- titleText.attr("data-line-number", quadrantTitleLineNumber);
15643
- }
15644
- if (onClickItem && quadrantTitleLineNumber) {
15645
- titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
15646
- d3Selection9.select(this).attr("opacity", 0.7);
15647
- }).on("mouseleave", function() {
15648
- d3Selection9.select(this).attr("opacity", 1);
15649
- });
15650
- }
15651
- }
15414
+ renderChartTitle(svg, title, quadrantTitleLineNumber, width, textColor, onClickItem);
15652
15415
  const chartG = svg.append("g").attr("transform", `translate(${margin.left}, ${margin.top})`);
15653
15416
  const mixHex = (a, b, pct) => {
15654
15417
  const parse = (h) => {
@@ -15897,6 +15660,38 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
15897
15660
  }
15898
15661
  });
15899
15662
  }
15663
+ async function resolveExportPalette(theme, palette) {
15664
+ if (palette) return palette;
15665
+ const { getPalette: getPalette2 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
15666
+ return theme === "dark" ? getPalette2("nord").dark : getPalette2("nord").light;
15667
+ }
15668
+ function createExportContainer(width, height) {
15669
+ const container = document.createElement("div");
15670
+ container.style.width = `${width}px`;
15671
+ container.style.height = `${height}px`;
15672
+ container.style.position = "absolute";
15673
+ container.style.left = "-9999px";
15674
+ document.body.appendChild(container);
15675
+ return container;
15676
+ }
15677
+ function finalizeSvgExport(container, theme, palette, options) {
15678
+ const svgEl = container.querySelector("svg");
15679
+ if (!svgEl) return "";
15680
+ if (theme === "transparent") {
15681
+ svgEl.style.background = "none";
15682
+ } else if (!svgEl.style.background) {
15683
+ svgEl.style.background = palette.bg;
15684
+ }
15685
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
15686
+ svgEl.style.fontFamily = FONT_FAMILY;
15687
+ const svgHtml = svgEl.outerHTML;
15688
+ document.body.removeChild(container);
15689
+ if (options?.branding !== false) {
15690
+ const brandColor = theme === "transparent" ? "#888" : palette.textMuted;
15691
+ return injectBranding(svgHtml, brandColor);
15692
+ }
15693
+ return svgHtml;
15694
+ }
15900
15695
  async function renderD3ForExport(content, theme, palette, orgExportState, options) {
15901
15696
  const { parseDgmoChartType: parseDgmoChartType2 } = await Promise.resolve().then(() => (init_dgmo_router(), dgmo_router_exports));
15902
15697
  const detectedType = parseDgmoChartType2(content);
@@ -15906,8 +15701,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
15906
15701
  const { collapseOrgTree: collapseOrgTree2 } = await Promise.resolve().then(() => (init_collapse(), collapse_exports));
15907
15702
  const { renderOrg: renderOrg2 } = await Promise.resolve().then(() => (init_renderer(), renderer_exports));
15908
15703
  const isDark2 = theme === "dark";
15909
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
15910
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15704
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
15911
15705
  const orgParsed = parseOrg2(content, effectivePalette2);
15912
15706
  if (orgParsed.error) return "";
15913
15707
  const collapsedNodes = orgExportState?.collapsedNodes;
@@ -15924,83 +15718,28 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
15924
15718
  const titleOffset = effectiveParsed.title ? 30 : 0;
15925
15719
  const exportWidth = orgLayout.width + PADDING * 2;
15926
15720
  const exportHeight = orgLayout.height + PADDING * 2 + titleOffset;
15927
- const container2 = document.createElement("div");
15928
- container2.style.width = `${exportWidth}px`;
15929
- container2.style.height = `${exportHeight}px`;
15930
- container2.style.position = "absolute";
15931
- container2.style.left = "-9999px";
15932
- document.body.appendChild(container2);
15933
- try {
15934
- renderOrg2(
15935
- container2,
15936
- effectiveParsed,
15937
- orgLayout,
15938
- effectivePalette2,
15939
- isDark2,
15940
- void 0,
15941
- { width: exportWidth, height: exportHeight },
15942
- activeTagGroup,
15943
- hiddenAttributes
15944
- );
15945
- const svgEl = container2.querySelector("svg");
15946
- if (!svgEl) return "";
15947
- if (theme === "transparent") {
15948
- svgEl.style.background = "none";
15949
- } else if (!svgEl.style.background) {
15950
- svgEl.style.background = effectivePalette2.bg;
15951
- }
15952
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
15953
- svgEl.style.fontFamily = FONT_FAMILY;
15954
- const svgHtml = svgEl.outerHTML;
15955
- if (options?.branding !== false) {
15956
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
15957
- return injectBranding(svgHtml, brandColor);
15958
- }
15959
- return svgHtml;
15960
- } finally {
15961
- document.body.removeChild(container2);
15962
- }
15721
+ const container2 = createExportContainer(exportWidth, exportHeight);
15722
+ renderOrg2(container2, effectiveParsed, orgLayout, effectivePalette2, isDark2, void 0, { width: exportWidth, height: exportHeight }, activeTagGroup, hiddenAttributes);
15723
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
15963
15724
  }
15964
15725
  if (detectedType === "kanban") {
15965
15726
  const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
15966
15727
  const { renderKanban: renderKanban2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
15967
- const isDark2 = theme === "dark";
15968
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
15969
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15728
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
15970
15729
  const kanbanParsed = parseKanban2(content, effectivePalette2);
15971
15730
  if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
15972
15731
  const container2 = document.createElement("div");
15973
15732
  container2.style.position = "absolute";
15974
15733
  container2.style.left = "-9999px";
15975
15734
  document.body.appendChild(container2);
15976
- try {
15977
- renderKanban2(container2, kanbanParsed, effectivePalette2, isDark2);
15978
- const svgEl = container2.querySelector("svg");
15979
- if (!svgEl) return "";
15980
- if (theme === "transparent") {
15981
- svgEl.style.background = "none";
15982
- } else if (!svgEl.style.background) {
15983
- svgEl.style.background = effectivePalette2.bg;
15984
- }
15985
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
15986
- svgEl.style.fontFamily = FONT_FAMILY;
15987
- const svgHtml = svgEl.outerHTML;
15988
- if (options?.branding !== false) {
15989
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
15990
- return injectBranding(svgHtml, brandColor);
15991
- }
15992
- return svgHtml;
15993
- } finally {
15994
- document.body.removeChild(container2);
15995
- }
15735
+ renderKanban2(container2, kanbanParsed, effectivePalette2, theme === "dark");
15736
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
15996
15737
  }
15997
15738
  if (detectedType === "class") {
15998
15739
  const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
15999
15740
  const { layoutClassDiagram: layoutClassDiagram2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
16000
15741
  const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
16001
- const isDark2 = theme === "dark";
16002
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16003
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15742
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
16004
15743
  const classParsed = parseClassDiagram2(content, effectivePalette2);
16005
15744
  if (classParsed.error || classParsed.classes.length === 0) return "";
16006
15745
  const classLayout = layoutClassDiagram2(classParsed);
@@ -16008,48 +15747,15 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
16008
15747
  const titleOffset = classParsed.title ? 40 : 0;
16009
15748
  const exportWidth = classLayout.width + PADDING * 2;
16010
15749
  const exportHeight = classLayout.height + PADDING * 2 + titleOffset;
16011
- const container2 = document.createElement("div");
16012
- container2.style.width = `${exportWidth}px`;
16013
- container2.style.height = `${exportHeight}px`;
16014
- container2.style.position = "absolute";
16015
- container2.style.left = "-9999px";
16016
- document.body.appendChild(container2);
16017
- try {
16018
- renderClassDiagram2(
16019
- container2,
16020
- classParsed,
16021
- classLayout,
16022
- effectivePalette2,
16023
- isDark2,
16024
- void 0,
16025
- { width: exportWidth, height: exportHeight }
16026
- );
16027
- const svgEl = container2.querySelector("svg");
16028
- if (!svgEl) return "";
16029
- if (theme === "transparent") {
16030
- svgEl.style.background = "none";
16031
- } else if (!svgEl.style.background) {
16032
- svgEl.style.background = effectivePalette2.bg;
16033
- }
16034
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16035
- svgEl.style.fontFamily = FONT_FAMILY;
16036
- const svgHtml = svgEl.outerHTML;
16037
- if (options?.branding !== false) {
16038
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
16039
- return injectBranding(svgHtml, brandColor);
16040
- }
16041
- return svgHtml;
16042
- } finally {
16043
- document.body.removeChild(container2);
16044
- }
15750
+ const container2 = createExportContainer(exportWidth, exportHeight);
15751
+ renderClassDiagram2(container2, classParsed, classLayout, effectivePalette2, theme === "dark", void 0, { width: exportWidth, height: exportHeight });
15752
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
16045
15753
  }
16046
15754
  if (detectedType === "er") {
16047
15755
  const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
16048
15756
  const { layoutERDiagram: layoutERDiagram2 } = await Promise.resolve().then(() => (init_layout3(), layout_exports3));
16049
15757
  const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
16050
- const isDark2 = theme === "dark";
16051
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16052
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15758
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
16053
15759
  const erParsed = parseERDiagram2(content, effectivePalette2);
16054
15760
  if (erParsed.error || erParsed.tables.length === 0) return "";
16055
15761
  const erLayout = layoutERDiagram2(erParsed);
@@ -16057,48 +15763,15 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
16057
15763
  const titleOffset = erParsed.title ? 40 : 0;
16058
15764
  const exportWidth = erLayout.width + PADDING * 2;
16059
15765
  const exportHeight = erLayout.height + PADDING * 2 + titleOffset;
16060
- const container2 = document.createElement("div");
16061
- container2.style.width = `${exportWidth}px`;
16062
- container2.style.height = `${exportHeight}px`;
16063
- container2.style.position = "absolute";
16064
- container2.style.left = "-9999px";
16065
- document.body.appendChild(container2);
16066
- try {
16067
- renderERDiagram2(
16068
- container2,
16069
- erParsed,
16070
- erLayout,
16071
- effectivePalette2,
16072
- isDark2,
16073
- void 0,
16074
- { width: exportWidth, height: exportHeight }
16075
- );
16076
- const svgEl = container2.querySelector("svg");
16077
- if (!svgEl) return "";
16078
- if (theme === "transparent") {
16079
- svgEl.style.background = "none";
16080
- } else if (!svgEl.style.background) {
16081
- svgEl.style.background = effectivePalette2.bg;
16082
- }
16083
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16084
- svgEl.style.fontFamily = FONT_FAMILY;
16085
- const svgHtml = svgEl.outerHTML;
16086
- if (options?.branding !== false) {
16087
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
16088
- return injectBranding(svgHtml, brandColor);
16089
- }
16090
- return svgHtml;
16091
- } finally {
16092
- document.body.removeChild(container2);
16093
- }
15766
+ const container2 = createExportContainer(exportWidth, exportHeight);
15767
+ renderERDiagram2(container2, erParsed, erLayout, effectivePalette2, theme === "dark", void 0, { width: exportWidth, height: exportHeight });
15768
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
16094
15769
  }
16095
15770
  if (detectedType === "initiative-status") {
16096
15771
  const { parseInitiativeStatus: parseInitiativeStatus2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports7));
16097
15772
  const { layoutInitiativeStatus: layoutInitiativeStatus2 } = await Promise.resolve().then(() => (init_layout4(), layout_exports4));
16098
15773
  const { renderInitiativeStatus: renderInitiativeStatus2 } = await Promise.resolve().then(() => (init_renderer5(), renderer_exports5));
16099
- const isDark2 = theme === "dark";
16100
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16101
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15774
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
16102
15775
  const isParsed = parseInitiativeStatus2(content);
16103
15776
  if (isParsed.error || isParsed.nodes.length === 0) return "";
16104
15777
  const isLayout = layoutInitiativeStatus2(isParsed);
@@ -16106,48 +15779,15 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
16106
15779
  const titleOffset = isParsed.title ? 40 : 0;
16107
15780
  const exportWidth = isLayout.width + PADDING * 2;
16108
15781
  const exportHeight = isLayout.height + PADDING * 2 + titleOffset;
16109
- const container2 = document.createElement("div");
16110
- container2.style.width = `${exportWidth}px`;
16111
- container2.style.height = `${exportHeight}px`;
16112
- container2.style.position = "absolute";
16113
- container2.style.left = "-9999px";
16114
- document.body.appendChild(container2);
16115
- try {
16116
- renderInitiativeStatus2(
16117
- container2,
16118
- isParsed,
16119
- isLayout,
16120
- effectivePalette2,
16121
- isDark2,
16122
- void 0,
16123
- { width: exportWidth, height: exportHeight }
16124
- );
16125
- const svgEl = container2.querySelector("svg");
16126
- if (!svgEl) return "";
16127
- if (theme === "transparent") {
16128
- svgEl.style.background = "none";
16129
- } else if (!svgEl.style.background) {
16130
- svgEl.style.background = effectivePalette2.bg;
16131
- }
16132
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16133
- svgEl.style.fontFamily = FONT_FAMILY;
16134
- const svgHtml = svgEl.outerHTML;
16135
- if (options?.branding !== false) {
16136
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
16137
- return injectBranding(svgHtml, brandColor);
16138
- }
16139
- return svgHtml;
16140
- } finally {
16141
- document.body.removeChild(container2);
16142
- }
15782
+ const container2 = createExportContainer(exportWidth, exportHeight);
15783
+ renderInitiativeStatus2(container2, isParsed, isLayout, effectivePalette2, theme === "dark", void 0, { width: exportWidth, height: exportHeight });
15784
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
16143
15785
  }
16144
15786
  if (detectedType === "c4") {
16145
15787
  const { parseC4: parseC42 } = await Promise.resolve().then(() => (init_parser6(), parser_exports6));
16146
15788
  const { layoutC4Context: layoutC4Context2, layoutC4Containers: layoutC4Containers2, layoutC4Components: layoutC4Components2, layoutC4Deployment: layoutC4Deployment2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
16147
15789
  const { renderC4Context: renderC4Context2, renderC4Containers: renderC4Containers2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
16148
- const isDark2 = theme === "dark";
16149
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16150
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15790
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
16151
15791
  const c4Parsed = parseC42(content, effectivePalette2);
16152
15792
  if (c4Parsed.error || c4Parsed.elements.length === 0) return "";
16153
15793
  const c4Level = options?.c4Level ?? "context";
@@ -16159,81 +15799,22 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
16159
15799
  const titleOffset = c4Parsed.title ? 40 : 0;
16160
15800
  const exportWidth = c4Layout.width + PADDING * 2;
16161
15801
  const exportHeight = c4Layout.height + PADDING * 2 + titleOffset;
16162
- const container2 = document.createElement("div");
16163
- container2.style.width = `${exportWidth}px`;
16164
- container2.style.height = `${exportHeight}px`;
16165
- container2.style.position = "absolute";
16166
- container2.style.left = "-9999px";
16167
- document.body.appendChild(container2);
16168
- try {
16169
- const renderFn = c4Level === "deployment" || c4Level === "components" && c4System && c4Container || c4Level === "containers" && c4System ? renderC4Containers2 : renderC4Context2;
16170
- renderFn(
16171
- container2,
16172
- c4Parsed,
16173
- c4Layout,
16174
- effectivePalette2,
16175
- isDark2,
16176
- void 0,
16177
- { width: exportWidth, height: exportHeight }
16178
- );
16179
- const svgEl = container2.querySelector("svg");
16180
- if (!svgEl) return "";
16181
- if (theme === "transparent") {
16182
- svgEl.style.background = "none";
16183
- } else if (!svgEl.style.background) {
16184
- svgEl.style.background = effectivePalette2.bg;
16185
- }
16186
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16187
- svgEl.style.fontFamily = FONT_FAMILY;
16188
- const svgHtml = svgEl.outerHTML;
16189
- if (options?.branding !== false) {
16190
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
16191
- return injectBranding(svgHtml, brandColor);
16192
- }
16193
- return svgHtml;
16194
- } finally {
16195
- document.body.removeChild(container2);
16196
- }
15802
+ const container2 = createExportContainer(exportWidth, exportHeight);
15803
+ const renderFn = c4Level === "deployment" || c4Level === "components" && c4System && c4Container || c4Level === "containers" && c4System ? renderC4Containers2 : renderC4Context2;
15804
+ renderFn(container2, c4Parsed, c4Layout, effectivePalette2, theme === "dark", void 0, { width: exportWidth, height: exportHeight });
15805
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
16197
15806
  }
16198
15807
  if (detectedType === "flowchart") {
16199
15808
  const { parseFlowchart: parseFlowchart2 } = await Promise.resolve().then(() => (init_flowchart_parser(), flowchart_parser_exports));
16200
15809
  const { layoutGraph: layoutGraph2 } = await Promise.resolve().then(() => (init_layout6(), layout_exports6));
16201
15810
  const { renderFlowchart: renderFlowchart2 } = await Promise.resolve().then(() => (init_flowchart_renderer(), flowchart_renderer_exports));
16202
- const isDark2 = theme === "dark";
16203
- const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16204
- const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
15811
+ const effectivePalette2 = await resolveExportPalette(theme, palette);
16205
15812
  const fcParsed = parseFlowchart2(content, effectivePalette2);
16206
15813
  if (fcParsed.error || fcParsed.nodes.length === 0) return "";
16207
15814
  const layout = layoutGraph2(fcParsed);
16208
- const container2 = document.createElement("div");
16209
- container2.style.width = `${EXPORT_WIDTH}px`;
16210
- container2.style.height = `${EXPORT_HEIGHT}px`;
16211
- container2.style.position = "absolute";
16212
- container2.style.left = "-9999px";
16213
- document.body.appendChild(container2);
16214
- try {
16215
- renderFlowchart2(container2, fcParsed, layout, effectivePalette2, isDark2, void 0, {
16216
- width: EXPORT_WIDTH,
16217
- height: EXPORT_HEIGHT
16218
- });
16219
- const svgEl = container2.querySelector("svg");
16220
- if (!svgEl) return "";
16221
- if (theme === "transparent") {
16222
- svgEl.style.background = "none";
16223
- } else if (!svgEl.style.background) {
16224
- svgEl.style.background = effectivePalette2.bg;
16225
- }
16226
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16227
- svgEl.style.fontFamily = FONT_FAMILY;
16228
- const svgHtml = svgEl.outerHTML;
16229
- if (options?.branding !== false) {
16230
- const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
16231
- return injectBranding(svgHtml, brandColor);
16232
- }
16233
- return svgHtml;
16234
- } finally {
16235
- document.body.removeChild(container2);
16236
- }
15815
+ const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
15816
+ renderFlowchart2(container2, fcParsed, layout, effectivePalette2, theme === "dark", void 0, { width: EXPORT_WIDTH, height: EXPORT_HEIGHT });
15817
+ return finalizeSvgExport(container2, theme, effectivePalette2, options);
16237
15818
  }
16238
15819
  const parsed = parseD3(content, palette);
16239
15820
  if (parsed.error && parsed.type !== "sequence") {
@@ -16249,56 +15830,32 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
16249
15830
  if (parsed.type === "venn" && parsed.vennSets.length < 2) return "";
16250
15831
  if (parsed.type === "quadrant" && parsed.quadrantPoints.length === 0)
16251
15832
  return "";
15833
+ const effectivePalette = await resolveExportPalette(theme, palette);
16252
15834
  const isDark = theme === "dark";
16253
- const { getPalette: getPalette2 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
16254
- const effectivePalette = palette ?? (isDark ? getPalette2("nord").dark : getPalette2("nord").light);
16255
- const container = document.createElement("div");
16256
- container.style.width = `${EXPORT_WIDTH}px`;
16257
- container.style.height = `${EXPORT_HEIGHT}px`;
16258
- container.style.position = "absolute";
16259
- container.style.left = "-9999px";
16260
- document.body.appendChild(container);
15835
+ const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
16261
15836
  const dims = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };
16262
- try {
16263
- if (parsed.type === "sequence") {
16264
- const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
16265
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer7(), renderer_exports7));
16266
- const seqParsed = parseSequenceDgmo2(content);
16267
- if (seqParsed.error || seqParsed.participants.length === 0) return "";
16268
- renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
16269
- exportWidth: EXPORT_WIDTH
16270
- });
16271
- } else if (parsed.type === "wordcloud") {
16272
- await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);
16273
- } else if (parsed.type === "arc") {
16274
- renderArcDiagram(container, parsed, effectivePalette, isDark, void 0, dims);
16275
- } else if (parsed.type === "timeline") {
16276
- renderTimeline(container, parsed, effectivePalette, isDark, void 0, dims);
16277
- } else if (parsed.type === "venn") {
16278
- renderVenn(container, parsed, effectivePalette, isDark, void 0, dims);
16279
- } else if (parsed.type === "quadrant") {
16280
- renderQuadrant(container, parsed, effectivePalette, isDark, void 0, dims);
16281
- } else {
16282
- renderSlopeChart(container, parsed, effectivePalette, isDark, void 0, dims);
16283
- }
16284
- const svgEl = container.querySelector("svg");
16285
- if (!svgEl) return "";
16286
- if (theme === "transparent") {
16287
- svgEl.style.background = "none";
16288
- } else if (!svgEl.style.background) {
16289
- svgEl.style.background = effectivePalette.bg;
16290
- }
16291
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
16292
- svgEl.style.fontFamily = FONT_FAMILY;
16293
- const svgHtml = svgEl.outerHTML;
16294
- if (options?.branding !== false) {
16295
- const brandColor = theme === "transparent" ? "#888" : effectivePalette.textMuted;
16296
- return injectBranding(svgHtml, brandColor);
16297
- }
16298
- return svgHtml;
16299
- } finally {
16300
- document.body.removeChild(container);
15837
+ if (parsed.type === "sequence") {
15838
+ const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
15839
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer7(), renderer_exports7));
15840
+ const seqParsed = parseSequenceDgmo2(content);
15841
+ if (seqParsed.error || seqParsed.participants.length === 0) return "";
15842
+ renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
15843
+ exportWidth: EXPORT_WIDTH
15844
+ });
15845
+ } else if (parsed.type === "wordcloud") {
15846
+ await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);
15847
+ } else if (parsed.type === "arc") {
15848
+ renderArcDiagram(container, parsed, effectivePalette, isDark, void 0, dims);
15849
+ } else if (parsed.type === "timeline") {
15850
+ renderTimeline(container, parsed, effectivePalette, isDark, void 0, dims);
15851
+ } else if (parsed.type === "venn") {
15852
+ renderVenn(container, parsed, effectivePalette, isDark, void 0, dims);
15853
+ } else if (parsed.type === "quadrant") {
15854
+ renderQuadrant(container, parsed, effectivePalette, isDark, void 0, dims);
15855
+ } else {
15856
+ renderSlopeChart(container, parsed, effectivePalette, isDark, void 0, dims);
16301
15857
  }
15858
+ return finalizeSvgExport(container, theme, effectivePalette, options);
16302
15859
  }
16303
15860
  var DEFAULT_CLOUD_OPTIONS, STOP_WORDS, SLOPE_MARGIN, SLOPE_LABEL_FONT_SIZE, SLOPE_CHAR_WIDTH, ARC_MARGIN, MONTH_ABBR, EXPORT_WIDTH, EXPORT_HEIGHT;
16304
15861
  var init_d3 = __esm({
@@ -17019,6 +16576,7 @@ init_branding();
17019
16576
  export {
17020
16577
  DGMO_CHART_TYPE_MAP,
17021
16578
  RULE_COUNT,
16579
+ STANDARD_CHART_TYPES,
17022
16580
  addDurationToDate,
17023
16581
  applyGroupOrdering,
17024
16582
  applyPositionOverrides,