@diagrammo/dgmo 0.2.2 → 0.2.3

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
@@ -167,6 +167,14 @@ function parseReturnLabel(rawLabel) {
167
167
  if (umlReturn) {
168
168
  return { label: umlReturn[1].trim(), returnLabel: umlReturn[2].trim() };
169
169
  }
170
+ const lastSep = rawLabel.lastIndexOf(" : ");
171
+ if (lastSep > 0) {
172
+ const reqPart = rawLabel.substring(0, lastSep).trim();
173
+ const resPart = rawLabel.substring(lastSep + 3).trim();
174
+ if (reqPart && resPart) {
175
+ return { label: reqPart, returnLabel: resPart };
176
+ }
177
+ }
170
178
  return { label: rawLabel };
171
179
  }
172
180
  function measureIndent(line2) {
@@ -1371,7 +1379,7 @@ var init_bold = __esm({
1371
1379
  dark: {
1372
1380
  bg: "#000000",
1373
1381
  surface: "#111111",
1374
- overlay: "#000000",
1382
+ overlay: "#1a1a1a",
1375
1383
  border: "#333333",
1376
1384
  text: "#ffffff",
1377
1385
  textMuted: "#aaaaaa",
@@ -2015,7 +2023,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2015
2023
  {
2016
2024
  let fi = 0;
2017
2025
  for (let oi = 0; oi < allRenderSteps.length; oi++) {
2018
- if (!hiddenMsgIndices.has(allRenderSteps[oi].messageIndex)) {
2026
+ const step = allRenderSteps[oi];
2027
+ if (!hiddenMsgIndices.has(step.messageIndex) && (step.type === "call" || step.label)) {
2019
2028
  originalToFiltered.set(oi, fi);
2020
2029
  fi++;
2021
2030
  }
@@ -2104,7 +2113,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2104
2113
  PARTICIPANT_BOX_WIDTH + 40
2105
2114
  );
2106
2115
  const totalHeight = participantStartY + PARTICIPANT_BOX_HEIGHT + Math.max(lifelineLength, 40) + 40;
2107
- const { width: containerWidth } = container.getBoundingClientRect();
2116
+ const containerWidth = options?.exportWidth ?? container.getBoundingClientRect().width;
2108
2117
  const svgWidth = Math.max(totalWidth, containerWidth);
2109
2118
  const diagramWidth = participants.length * PARTICIPANT_GAP;
2110
2119
  const offsetX = Math.max(0, (svgWidth - diagramWidth) / 2) + PARTICIPANT_GAP / 2;
@@ -2127,7 +2136,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2127
2136
  `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
2128
2137
  ).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
2129
2138
  if (title) {
2130
- svg.append("text").attr("x", svgWidth / 2).attr("y", TOP_MARGIN + TITLE_HEIGHT * 0.7).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 16).attr("font-weight", "bold").text(title);
2139
+ svg.append("text").attr("x", svgWidth / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 20).attr("font-weight", "bold").text(title);
2131
2140
  }
2132
2141
  for (const group of groups) {
2133
2142
  if (group.participantIds.length === 0) continue;
@@ -2855,9 +2864,10 @@ function parseEChart(content, palette) {
2855
2864
  }
2856
2865
  return result;
2857
2866
  }
2858
- function buildEChartsOption(parsed, palette, _isDark) {
2867
+ function buildEChartsOption(parsed, palette, isDark) {
2859
2868
  const textColor = palette.text;
2860
2869
  const axisLineColor = palette.border;
2870
+ const gridOpacity = isDark ? 0.7 : 0.4;
2861
2871
  const colors = getSeriesColors(palette);
2862
2872
  if (parsed.error) {
2863
2873
  return {};
@@ -2865,9 +2875,10 @@ function buildEChartsOption(parsed, palette, _isDark) {
2865
2875
  const titleConfig = parsed.title ? {
2866
2876
  text: parsed.title,
2867
2877
  left: "center",
2878
+ top: 8,
2868
2879
  textStyle: {
2869
2880
  color: textColor,
2870
- fontSize: 18,
2881
+ fontSize: 20,
2871
2882
  fontWeight: "bold",
2872
2883
  fontFamily: FONT_FAMILY
2873
2884
  }
@@ -2901,6 +2912,7 @@ function buildEChartsOption(parsed, palette, _isDark) {
2901
2912
  palette,
2902
2913
  textColor,
2903
2914
  axisLineColor,
2915
+ gridOpacity,
2904
2916
  colors,
2905
2917
  titleConfig,
2906
2918
  tooltipTheme
@@ -2912,6 +2924,7 @@ function buildEChartsOption(parsed, palette, _isDark) {
2912
2924
  palette,
2913
2925
  textColor,
2914
2926
  axisLineColor,
2927
+ gridOpacity,
2915
2928
  colors,
2916
2929
  titleConfig,
2917
2930
  tooltipTheme
@@ -3083,7 +3096,7 @@ function evaluateExpression(expr, x) {
3083
3096
  return NaN;
3084
3097
  }
3085
3098
  }
3086
- function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors, titleConfig, tooltipTheme) {
3099
+ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3087
3100
  const xRange = parsed.xRange ?? { min: -10, max: 10 };
3088
3101
  const samples = 200;
3089
3102
  const step = (xRange.max - xRange.min) / samples;
@@ -3131,7 +3144,7 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3131
3144
  }
3132
3145
  },
3133
3146
  grid: {
3134
- left: "3%",
3147
+ left: "4%",
3135
3148
  right: "4%",
3136
3149
  bottom: "15%",
3137
3150
  top: parsed.title ? "15%" : "5%",
@@ -3145,11 +3158,13 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3145
3158
  lineStyle: { color: axisLineColor }
3146
3159
  },
3147
3160
  axisLabel: {
3148
- color: textColor
3161
+ color: textColor,
3162
+ fontSize: 16
3149
3163
  },
3150
3164
  splitLine: {
3151
3165
  lineStyle: {
3152
- color: palette.overlay
3166
+ color: palette.border,
3167
+ opacity: gridOpacity
3153
3168
  }
3154
3169
  }
3155
3170
  },
@@ -3159,18 +3174,20 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3159
3174
  lineStyle: { color: axisLineColor }
3160
3175
  },
3161
3176
  axisLabel: {
3162
- color: textColor
3177
+ color: textColor,
3178
+ fontSize: 16
3163
3179
  },
3164
3180
  splitLine: {
3165
3181
  lineStyle: {
3166
- color: palette.overlay
3182
+ color: palette.border,
3183
+ opacity: gridOpacity
3167
3184
  }
3168
3185
  }
3169
3186
  },
3170
3187
  series
3171
3188
  };
3172
3189
  }
3173
- function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, titleConfig, tooltipTheme) {
3190
+ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3174
3191
  const points = parsed.scatterPoints ?? [];
3175
3192
  const defaultSize = 15;
3176
3193
  const hasCategories = points.some((p) => p.category !== void 0);
@@ -3246,6 +3263,14 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3246
3263
  return html;
3247
3264
  }
3248
3265
  };
3266
+ const xValues = points.map((p) => p.x);
3267
+ const yValues = points.map((p) => p.y);
3268
+ const xMin = Math.min(...xValues);
3269
+ const xMax = Math.max(...xValues);
3270
+ const yMin = Math.min(...yValues);
3271
+ const yMax = Math.max(...yValues);
3272
+ const xPad = (xMax - xMin) * 0.1 || 1;
3273
+ const yPad = (yMax - yMin) * 0.1 || 1;
3249
3274
  return {
3250
3275
  backgroundColor: "transparent",
3251
3276
  animation: false,
@@ -3259,9 +3284,9 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3259
3284
  }
3260
3285
  },
3261
3286
  grid: {
3262
- left: "3%",
3287
+ left: parsed.ylabel ? "5%" : "3%",
3263
3288
  right: "4%",
3264
- bottom: hasCategories ? "15%" : "3%",
3289
+ bottom: hasCategories ? "15%" : parsed.xlabel ? "10%" : "3%",
3265
3290
  top: parsed.title ? "15%" : "5%",
3266
3291
  containLabel: true
3267
3292
  },
@@ -3269,20 +3294,24 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3269
3294
  type: "value",
3270
3295
  name: parsed.xlabel,
3271
3296
  nameLocation: "middle",
3272
- nameGap: 30,
3297
+ nameGap: 40,
3273
3298
  nameTextStyle: {
3274
3299
  color: textColor,
3275
- fontSize: 12
3300
+ fontSize: 18
3276
3301
  },
3302
+ min: Math.floor(xMin - xPad),
3303
+ max: Math.ceil(xMax + xPad),
3277
3304
  axisLine: {
3278
3305
  lineStyle: { color: axisLineColor }
3279
3306
  },
3280
3307
  axisLabel: {
3281
- color: textColor
3308
+ color: textColor,
3309
+ fontSize: 16
3282
3310
  },
3283
3311
  splitLine: {
3284
3312
  lineStyle: {
3285
- color: palette.overlay
3313
+ color: palette.border,
3314
+ opacity: gridOpacity
3286
3315
  }
3287
3316
  }
3288
3317
  },
@@ -3290,20 +3319,24 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3290
3319
  type: "value",
3291
3320
  name: parsed.ylabel,
3292
3321
  nameLocation: "middle",
3293
- nameGap: 40,
3322
+ nameGap: 50,
3294
3323
  nameTextStyle: {
3295
3324
  color: textColor,
3296
- fontSize: 12
3325
+ fontSize: 18
3297
3326
  },
3327
+ min: Math.floor(yMin - yPad),
3328
+ max: Math.ceil(yMax + yPad),
3298
3329
  axisLine: {
3299
3330
  lineStyle: { color: axisLineColor }
3300
3331
  },
3301
3332
  axisLabel: {
3302
- color: textColor
3333
+ color: textColor,
3334
+ fontSize: 16
3303
3335
  },
3304
3336
  splitLine: {
3305
3337
  lineStyle: {
3306
- color: palette.overlay
3338
+ color: palette.border,
3339
+ opacity: gridOpacity
3307
3340
  }
3308
3341
  }
3309
3342
  },
@@ -3355,7 +3388,8 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3355
3388
  lineStyle: { color: axisLineColor }
3356
3389
  },
3357
3390
  axisLabel: {
3358
- color: textColor
3391
+ color: textColor,
3392
+ fontSize: 16
3359
3393
  }
3360
3394
  },
3361
3395
  yAxis: {
@@ -3368,7 +3402,8 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3368
3402
  lineStyle: { color: axisLineColor }
3369
3403
  },
3370
3404
  axisLabel: {
3371
- color: textColor
3405
+ color: textColor,
3406
+ fontSize: 16
3372
3407
  }
3373
3408
  },
3374
3409
  visualMap: {
@@ -3380,7 +3415,6 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3380
3415
  top: "center",
3381
3416
  inRange: {
3382
3417
  color: [
3383
- palette.bg,
3384
3418
  palette.primary,
3385
3419
  palette.colors.cyan,
3386
3420
  palette.colors.yellow,
@@ -3397,7 +3431,9 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3397
3431
  data,
3398
3432
  label: {
3399
3433
  show: true,
3400
- color: textColor
3434
+ color: "#ffffff",
3435
+ fontSize: 14,
3436
+ fontWeight: "bold"
3401
3437
  },
3402
3438
  emphasis: {
3403
3439
  itemStyle: {
@@ -3517,33 +3553,35 @@ function resolveAxisLabels(parsed) {
3517
3553
  yLabel: parsed.ylabel ?? (isHorizontal ? void 0 : parsed.label)
3518
3554
  };
3519
3555
  }
3520
- function makeGridAxis(type, textColor, axisLineColor, splitLineColor, label, data) {
3556
+ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data) {
3521
3557
  return {
3522
3558
  type,
3523
3559
  ...data && { data },
3524
3560
  axisLine: { lineStyle: { color: axisLineColor } },
3525
- axisLabel: { color: textColor, fontFamily: FONT_FAMILY },
3526
- splitLine: { lineStyle: { color: splitLineColor } },
3561
+ axisLabel: { color: textColor, fontSize: 16, fontFamily: FONT_FAMILY },
3562
+ splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },
3527
3563
  ...label && {
3528
3564
  name: label,
3529
3565
  nameLocation: "middle",
3530
- nameGap: 30,
3531
- nameTextStyle: { color: textColor, fontSize: 12, fontFamily: FONT_FAMILY }
3566
+ nameGap: 40,
3567
+ nameTextStyle: { color: textColor, fontSize: 18, fontFamily: FONT_FAMILY }
3532
3568
  }
3533
3569
  };
3534
3570
  }
3535
- function buildEChartsOptionFromChart(parsed, palette, _isDark) {
3571
+ function buildEChartsOptionFromChart(parsed, palette, isDark) {
3536
3572
  if (parsed.error) return {};
3537
3573
  const textColor = palette.text;
3538
3574
  const axisLineColor = palette.border;
3539
- const splitLineColor = palette.overlay;
3575
+ const splitLineColor = palette.border;
3576
+ const gridOpacity = isDark ? 0.7 : 0.4;
3540
3577
  const colors = getSeriesColors(palette);
3541
3578
  const titleConfig = parsed.title ? {
3542
3579
  text: parsed.title,
3543
3580
  left: "center",
3581
+ top: 8,
3544
3582
  textStyle: {
3545
3583
  color: textColor,
3546
- fontSize: 18,
3584
+ fontSize: 20,
3547
3585
  fontWeight: "bold",
3548
3586
  fontFamily: FONT_FAMILY
3549
3587
  }
@@ -3555,24 +3593,24 @@ function buildEChartsOptionFromChart(parsed, palette, _isDark) {
3555
3593
  };
3556
3594
  switch (parsed.type) {
3557
3595
  case "bar":
3558
- return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme);
3596
+ return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
3559
3597
  case "bar-stacked":
3560
- return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme);
3598
+ return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
3561
3599
  case "line":
3562
- return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme);
3600
+ return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
3563
3601
  case "area":
3564
- return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme);
3602
+ return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
3565
3603
  case "pie":
3566
3604
  return buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, false);
3567
3605
  case "doughnut":
3568
3606
  return buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, true);
3569
3607
  case "radar":
3570
- return buildRadarOption(parsed, palette, textColor, colors, titleConfig, tooltipTheme);
3608
+ return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);
3571
3609
  case "polar-area":
3572
3610
  return buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipTheme);
3573
3611
  }
3574
3612
  }
3575
- function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3613
+ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3576
3614
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3577
3615
  const isHorizontal = parsed.orientation === "horizontal";
3578
3616
  const labels = parsed.data.map((d) => d.label);
@@ -3580,8 +3618,8 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3580
3618
  value: d.value,
3581
3619
  itemStyle: { color: d.color ?? colors[i % colors.length] }
3582
3620
  }));
3583
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, isHorizontal ? yLabel : xLabel, labels);
3584
- const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, isHorizontal ? xLabel : yLabel);
3621
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);
3622
+ const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
3585
3623
  return {
3586
3624
  backgroundColor: "transparent",
3587
3625
  animation: false,
@@ -3592,9 +3630,9 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3592
3630
  axisPointer: { type: "shadow" }
3593
3631
  },
3594
3632
  grid: {
3595
- left: "3%",
3633
+ left: yLabel ? "5%" : "3%",
3596
3634
  right: "4%",
3597
- bottom: "3%",
3635
+ bottom: xLabel ? "10%" : "3%",
3598
3636
  top: parsed.title ? "15%" : "5%",
3599
3637
  containLabel: true
3600
3638
  },
@@ -3608,7 +3646,7 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3608
3646
  ]
3609
3647
  };
3610
3648
  }
3611
- function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme) {
3649
+ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
3612
3650
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3613
3651
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3614
3652
  const labels = parsed.data.map((d) => d.label);
@@ -3623,14 +3661,14 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
3623
3661
  axisPointer: { type: "line" }
3624
3662
  },
3625
3663
  grid: {
3626
- left: "3%",
3664
+ left: yLabel ? "5%" : "3%",
3627
3665
  right: "4%",
3628
- bottom: "3%",
3666
+ bottom: xLabel ? "10%" : "3%",
3629
3667
  top: parsed.title ? "15%" : "5%",
3630
3668
  containLabel: true
3631
3669
  },
3632
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3633
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3670
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3671
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3634
3672
  series: [
3635
3673
  {
3636
3674
  type: "line",
@@ -3643,7 +3681,7 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
3643
3681
  ]
3644
3682
  };
3645
3683
  }
3646
- function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3684
+ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3647
3685
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3648
3686
  const seriesNames = parsed.seriesNames ?? [];
3649
3687
  const labels = parsed.data.map((d) => d.label);
@@ -3677,18 +3715,18 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
3677
3715
  textStyle: { color: textColor }
3678
3716
  },
3679
3717
  grid: {
3680
- left: "3%",
3718
+ left: yLabel ? "5%" : "3%",
3681
3719
  right: "4%",
3682
3720
  bottom: "15%",
3683
3721
  top: parsed.title ? "15%" : "5%",
3684
3722
  containLabel: true
3685
3723
  },
3686
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3687
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3724
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3725
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3688
3726
  series
3689
3727
  };
3690
3728
  }
3691
- function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme) {
3729
+ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
3692
3730
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3693
3731
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3694
3732
  const labels = parsed.data.map((d) => d.label);
@@ -3703,14 +3741,14 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
3703
3741
  axisPointer: { type: "line" }
3704
3742
  },
3705
3743
  grid: {
3706
- left: "3%",
3744
+ left: yLabel ? "5%" : "3%",
3707
3745
  right: "4%",
3708
- bottom: "3%",
3746
+ bottom: xLabel ? "10%" : "3%",
3709
3747
  top: parsed.title ? "15%" : "5%",
3710
3748
  containLabel: true
3711
3749
  },
3712
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3713
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3750
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3751
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3714
3752
  series: [
3715
3753
  {
3716
3754
  type: "line",
@@ -3745,7 +3783,7 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
3745
3783
  data,
3746
3784
  label: {
3747
3785
  position: "outside",
3748
- formatter: "{b}",
3786
+ formatter: "{b} \u2014 {c} ({d}%)",
3749
3787
  color: textColor,
3750
3788
  fontFamily: FONT_FAMILY
3751
3789
  },
@@ -3754,11 +3792,10 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
3754
3792
  ]
3755
3793
  };
3756
3794
  }
3757
- function buildRadarOption(parsed, palette, textColor, colors, titleConfig, tooltipTheme) {
3795
+ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3758
3796
  const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3759
3797
  const values = parsed.data.map((d) => d.value);
3760
3798
  const maxValue = Math.max(...values) * 1.15;
3761
- const gridOpacity = 0.6;
3762
3799
  const indicator = parsed.data.map((d) => ({
3763
3800
  name: d.label,
3764
3801
  max: maxValue
@@ -3775,7 +3812,8 @@ function buildRadarOption(parsed, palette, textColor, colors, titleConfig, toolt
3775
3812
  indicator,
3776
3813
  axisName: {
3777
3814
  color: textColor,
3778
- fontFamily: FONT_FAMILY
3815
+ fontFamily: FONT_FAMILY,
3816
+ fontSize: 16
3779
3817
  },
3780
3818
  splitLine: {
3781
3819
  lineStyle: { color: palette.border, opacity: gridOpacity }
@@ -3832,7 +3870,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
3832
3870
  data,
3833
3871
  label: {
3834
3872
  position: "outside",
3835
- formatter: "{b}",
3873
+ formatter: "{b} \u2014 {c} ({d}%)",
3836
3874
  color: textColor,
3837
3875
  fontFamily: FONT_FAMILY
3838
3876
  },
@@ -3841,7 +3879,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
3841
3879
  ]
3842
3880
  };
3843
3881
  }
3844
- function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3882
+ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3845
3883
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3846
3884
  const isHorizontal = parsed.orientation === "horizontal";
3847
3885
  const seriesNames = parsed.seriesNames ?? [];
@@ -3856,11 +3894,20 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
3856
3894
  type: "bar",
3857
3895
  stack: "total",
3858
3896
  data,
3859
- itemStyle: { color }
3897
+ itemStyle: { color },
3898
+ label: {
3899
+ show: true,
3900
+ position: "inside",
3901
+ formatter: "{c}",
3902
+ color: "#ffffff",
3903
+ fontSize: 14,
3904
+ fontWeight: "bold",
3905
+ fontFamily: FONT_FAMILY
3906
+ }
3860
3907
  };
3861
3908
  });
3862
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, isHorizontal ? yLabel : xLabel, labels);
3863
- const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, isHorizontal ? xLabel : yLabel);
3909
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);
3910
+ const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
3864
3911
  return {
3865
3912
  backgroundColor: "transparent",
3866
3913
  animation: false,
@@ -3876,7 +3923,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
3876
3923
  textStyle: { color: textColor }
3877
3924
  },
3878
3925
  grid: {
3879
- left: "3%",
3926
+ left: yLabel ? "5%" : "3%",
3880
3927
  right: "4%",
3881
3928
  bottom: "15%",
3882
3929
  top: parsed.title ? "15%" : "5%",
@@ -3927,9 +3974,10 @@ async function renderEChartsForExport(content, theme, palette) {
3927
3974
  chart.setOption(option);
3928
3975
  const svgString = chart.renderToSVGString();
3929
3976
  if (!svgString) return "";
3977
+ const bgStyle = theme !== "transparent" ? `background: ${effectivePalette.bg}; ` : "";
3930
3978
  return svgString.replace(
3931
3979
  /^<svg /,
3932
- `<svg style="font-family: ${FONT_FAMILY}" `
3980
+ `<svg style="${bgStyle}font-family: ${FONT_FAMILY}" `
3933
3981
  );
3934
3982
  } finally {
3935
3983
  chart.dispose();
@@ -4594,14 +4642,14 @@ function tokenizeFreeformText(text) {
4594
4642
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
4595
4643
  }
4596
4644
  var SLOPE_MARGIN = { top: 80, bottom: 40, left: 80 };
4597
- var SLOPE_LABEL_FONT_SIZE = 12;
4598
- var SLOPE_CHAR_WIDTH = 7;
4599
- function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4645
+ var SLOPE_LABEL_FONT_SIZE = 14;
4646
+ var SLOPE_CHAR_WIDTH = 8;
4647
+ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
4600
4648
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
4601
4649
  const { periods, data, title } = parsed;
4602
4650
  if (data.length === 0 || periods.length < 2) return;
4603
- const width = container.clientWidth;
4604
- const height = container.clientHeight;
4651
+ const width = exportDims?.width ?? container.clientWidth;
4652
+ const height = exportDims?.height ?? container.clientHeight;
4605
4653
  if (width <= 0 || height <= 0) return;
4606
4654
  const maxLabelText = data.reduce((longest, item) => {
4607
4655
  const text = `${item.values[item.values.length - 1]} \u2014 ${item.label}`;
@@ -4610,14 +4658,14 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4610
4658
  const estimatedLabelWidth = maxLabelText.length * SLOPE_CHAR_WIDTH;
4611
4659
  const maxRightMargin = Math.floor(width * 0.35);
4612
4660
  const rightMargin = Math.min(
4613
- Math.max(estimatedLabelWidth + 20, 100),
4661
+ Math.max(estimatedLabelWidth + 30, 120),
4614
4662
  maxRightMargin
4615
4663
  );
4616
4664
  const innerWidth = width - SLOPE_MARGIN.left - rightMargin;
4617
4665
  const innerHeight = height - SLOPE_MARGIN.top - SLOPE_MARGIN.bottom;
4618
4666
  const textColor = palette.text;
4619
4667
  const mutedColor = palette.border;
4620
- const bgColor = palette.overlay;
4668
+ const bgColor = palette.bg;
4621
4669
  const colors = getSeriesColors(palette);
4622
4670
  const allValues = data.flatMap((d) => d.values);
4623
4671
  const [minVal, maxVal] = d3Array.extent(allValues);
@@ -4628,11 +4676,11 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4628
4676
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
4629
4677
  const tooltip = createTooltip(container, palette, isDark);
4630
4678
  if (title) {
4631
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
4679
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
4632
4680
  }
4633
4681
  for (const period of periods) {
4634
4682
  const x = xScale(period);
4635
- g.append("text").attr("x", x).attr("y", -15).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "13px").attr("font-weight", "600").text(period);
4683
+ 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);
4636
4684
  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");
4637
4685
  }
4638
4686
  const lineGen = d3Shape.line().x((_d, i) => xScale(periods[i])).y((d) => yScale(d));
@@ -4670,7 +4718,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4670
4718
  const isFirst = i === 0;
4671
4719
  const isLast = i === periods.length - 1;
4672
4720
  if (!isLast) {
4673
- g.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", "12px").text(val.toString());
4721
+ g.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());
4674
4722
  }
4675
4723
  });
4676
4724
  const lastX = xScale(periods[periods.length - 1]);
@@ -4796,12 +4844,12 @@ function orderArcNodes(links, order, groups) {
4796
4844
  return allNodes;
4797
4845
  }
4798
4846
  var ARC_MARGIN = { top: 60, right: 40, bottom: 60, left: 40 };
4799
- function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4847
+ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
4800
4848
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
4801
4849
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
4802
4850
  if (links.length === 0) return;
4803
- const width = container.clientWidth;
4804
- const height = container.clientHeight;
4851
+ const width = exportDims?.width ?? container.clientWidth;
4852
+ const height = exportDims?.height ?? container.clientHeight;
4805
4853
  if (width <= 0 || height <= 0) return;
4806
4854
  const isVertical = orientation === "vertical";
4807
4855
  const margin = isVertical ? {
@@ -4814,7 +4862,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4814
4862
  const innerHeight = height - margin.top - margin.bottom;
4815
4863
  const textColor = palette.text;
4816
4864
  const mutedColor = palette.border;
4817
- const bgColor = palette.overlay;
4865
+ const bgColor = palette.bg;
4818
4866
  const colors = getSeriesColors(palette);
4819
4867
  const nodes = orderArcNodes(links, arcOrder, arcNodeGroups);
4820
4868
  const nodeColorMap = /* @__PURE__ */ new Map();
@@ -4837,7 +4885,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4837
4885
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
4838
4886
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
4839
4887
  if (title) {
4840
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
4888
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
4841
4889
  }
4842
4890
  const neighbors = /* @__PURE__ */ new Map();
4843
4891
  for (const node of nodes) neighbors.set(node, /* @__PURE__ */ new Set());
@@ -4870,11 +4918,11 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4870
4918
  g.selectAll(".arc-node").attr("opacity", 1);
4871
4919
  g.selectAll(".arc-group-band").attr(
4872
4920
  "fill-opacity",
4873
- 0.08
4921
+ 0.06
4874
4922
  );
4875
4923
  g.selectAll(".arc-group-label").attr(
4876
4924
  "fill-opacity",
4877
- 0.7
4925
+ 0.5
4878
4926
  );
4879
4927
  }
4880
4928
  function handleGroupEnter(groupName) {
@@ -4914,10 +4962,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4914
4962
  const minY = Math.min(...positions) - bandPad;
4915
4963
  const maxY = Math.max(...positions) + bandPad;
4916
4964
  const bandColor = group.color ?? mutedColor;
4917
- g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("x", baseX - bandHalfW).attr("y", minY).attr("width", bandHalfW * 2).attr("height", maxY - minY).attr("rx", 4).attr("fill", bandColor).attr("fill-opacity", 0.08).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4965
+ g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("x", baseX - bandHalfW).attr("y", minY).attr("width", bandHalfW * 2).attr("height", maxY - minY).attr("rx", 4).attr("fill", textColor).attr("fill-opacity", 0.06).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4918
4966
  if (onClickItem) onClickItem(group.lineNumber);
4919
4967
  });
4920
- g.append("text").attr("class", "arc-group-label").attr("data-group", group.name).attr("x", baseX - bandHalfW + 6).attr("y", minY + 12).attr("fill", bandColor).attr("font-size", "10px").attr("font-weight", "600").attr("fill-opacity", 0.7).style("cursor", onClickItem ? "pointer" : "default").text(group.name).on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4968
+ g.append("text").attr("class", "arc-group-label").attr("data-group", group.name).attr("x", baseX - bandHalfW + 6).attr("y", minY + 14).attr("fill", textColor).attr("font-size", "12px").attr("font-weight", "600").attr("fill-opacity", 0.5).style("cursor", onClickItem ? "pointer" : "default").text(group.name).on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4921
4969
  if (onClickItem) onClickItem(group.lineNumber);
4922
4970
  });
4923
4971
  }
@@ -4958,10 +5006,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4958
5006
  const minX = Math.min(...positions) - bandPad;
4959
5007
  const maxX = Math.max(...positions) + bandPad;
4960
5008
  const bandColor = group.color ?? mutedColor;
4961
- g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("x", minX).attr("y", baseY - bandHalfH).attr("width", maxX - minX).attr("height", bandHalfH * 2).attr("rx", 4).attr("fill", bandColor).attr("fill-opacity", 0.08).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
5009
+ g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("x", minX).attr("y", baseY - bandHalfH).attr("width", maxX - minX).attr("height", bandHalfH * 2).attr("rx", 4).attr("fill", textColor).attr("fill-opacity", 0.06).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4962
5010
  if (onClickItem) onClickItem(group.lineNumber);
4963
5011
  });
4964
- g.append("text").attr("class", "arc-group-label").attr("data-group", group.name).attr("x", (minX + maxX) / 2).attr("y", baseY + bandHalfH - 4).attr("text-anchor", "middle").attr("fill", bandColor).attr("font-size", "10px").attr("font-weight", "600").attr("fill-opacity", 0.7).style("cursor", onClickItem ? "pointer" : "default").text(group.name).on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
5012
+ g.append("text").attr("class", "arc-group-label").attr("data-group", group.name).attr("x", (minX + maxX) / 2).attr("y", baseY + bandHalfH - 4).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "12px").attr("font-weight", "600").attr("fill-opacity", 0.5).style("cursor", onClickItem ? "pointer" : "default").text(group.name).on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
4965
5013
  if (onClickItem) onClickItem(group.lineNumber);
4966
5014
  });
4967
5015
  }
@@ -5257,7 +5305,7 @@ function buildEventTooltipHtml(ev) {
5257
5305
  function buildEraTooltipHtml(era) {
5258
5306
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
5259
5307
  }
5260
- function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5308
+ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
5261
5309
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
5262
5310
  const {
5263
5311
  timelineEvents,
@@ -5272,13 +5320,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5272
5320
  } = parsed;
5273
5321
  if (timelineEvents.length === 0) return;
5274
5322
  const tooltip = createTooltip(container, palette, isDark);
5275
- const width = container.clientWidth;
5276
- const height = container.clientHeight;
5323
+ const width = exportDims?.width ?? container.clientWidth;
5324
+ const height = exportDims?.height ?? container.clientHeight;
5277
5325
  if (width <= 0 || height <= 0) return;
5278
5326
  const isVertical = orientation === "vertical";
5279
5327
  const textColor = palette.text;
5280
5328
  const mutedColor = palette.border;
5281
- const bgColor = palette.overlay;
5329
+ const bgColor = palette.bg;
5282
5330
  const colors = getSeriesColors(palette);
5283
5331
  const groupColorMap = /* @__PURE__ */ new Map();
5284
5332
  timelineGroups.forEach((grp, i) => {
@@ -5382,7 +5430,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5382
5430
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5383
5431
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5384
5432
  if (title) {
5385
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5433
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5386
5434
  }
5387
5435
  renderEras(
5388
5436
  g,
@@ -5476,7 +5524,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5476
5524
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5477
5525
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5478
5526
  if (title) {
5479
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5527
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5480
5528
  }
5481
5529
  renderEras(
5482
5530
  g,
@@ -5599,7 +5647,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5599
5647
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5600
5648
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5601
5649
  if (title) {
5602
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5650
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5603
5651
  }
5604
5652
  renderEras(
5605
5653
  g,
@@ -5709,7 +5757,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5709
5757
  }
5710
5758
  evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2);
5711
5759
  if (labelFitsInside) {
5712
- evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "13px").attr("font-weight", "500").text(ev.label);
5760
+ evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
5713
5761
  } else {
5714
5762
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
5715
5763
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -5744,7 +5792,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5744
5792
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5745
5793
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5746
5794
  if (title) {
5747
- svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5795
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5748
5796
  }
5749
5797
  renderEras(
5750
5798
  g,
@@ -5848,7 +5896,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5848
5896
  }
5849
5897
  evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2);
5850
5898
  if (labelFitsInside) {
5851
- evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "13px").attr("font-weight", "500").text(ev.label);
5899
+ evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
5852
5900
  } else {
5853
5901
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
5854
5902
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -5871,17 +5919,17 @@ function getRotateFn(mode) {
5871
5919
  if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
5872
5920
  return () => 0;
5873
5921
  }
5874
- function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
5922
+ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
5875
5923
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
5876
5924
  const { words, title, cloudOptions } = parsed;
5877
5925
  if (words.length === 0) return;
5878
- const width = container.clientWidth;
5879
- const height = container.clientHeight;
5926
+ const width = exportDims?.width ?? container.clientWidth;
5927
+ const height = exportDims?.height ?? container.clientHeight;
5880
5928
  if (width <= 0 || height <= 0) return;
5881
5929
  const titleHeight = title ? 40 : 0;
5882
5930
  const cloudHeight = height - titleHeight;
5883
5931
  const textColor = palette.text;
5884
- const bgColor = palette.overlay;
5932
+ const bgColor = palette.bg;
5885
5933
  const colors = getSeriesColors(palette);
5886
5934
  const { minSize, maxSize } = cloudOptions;
5887
5935
  const weights = words.map((w) => w.weight);
@@ -5895,7 +5943,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
5895
5943
  const rotateFn = getRotateFn(cloudOptions.rotate);
5896
5944
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5897
5945
  if (title) {
5898
- svg.append("text").attr("x", width / 2).attr("y", 28).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5946
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5899
5947
  }
5900
5948
  const g = svg.append("g").attr(
5901
5949
  "transform",
@@ -5914,7 +5962,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
5914
5962
  });
5915
5963
  }).start();
5916
5964
  }
5917
- function renderWordCloudAsync(container, parsed, palette, _isDark) {
5965
+ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
5918
5966
  return new Promise((resolve) => {
5919
5967
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
5920
5968
  const { words, title, cloudOptions } = parsed;
@@ -5922,8 +5970,8 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
5922
5970
  resolve();
5923
5971
  return;
5924
5972
  }
5925
- const width = container.clientWidth;
5926
- const height = container.clientHeight;
5973
+ const width = exportDims?.width ?? container.clientWidth;
5974
+ const height = exportDims?.height ?? container.clientHeight;
5927
5975
  if (width <= 0 || height <= 0) {
5928
5976
  resolve();
5929
5977
  return;
@@ -5931,7 +5979,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
5931
5979
  const titleHeight = title ? 40 : 0;
5932
5980
  const cloudHeight = height - titleHeight;
5933
5981
  const textColor = palette.text;
5934
- const bgColor = palette.overlay;
5982
+ const bgColor = palette.bg;
5935
5983
  const colors = getSeriesColors(palette);
5936
5984
  const { minSize, maxSize } = cloudOptions;
5937
5985
  const weights = words.map((w) => w.weight);
@@ -5945,7 +5993,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
5945
5993
  const rotateFn = getRotateFn(cloudOptions.rotate);
5946
5994
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5947
5995
  if (title) {
5948
- svg.append("text").attr("x", width / 2).attr("y", 28).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
5996
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
5949
5997
  }
5950
5998
  const g = svg.append("g").attr(
5951
5999
  "transform",
@@ -6086,15 +6134,15 @@ function blendColors(hexColors) {
6086
6134
  function circlePathD(cx, cy, r) {
6087
6135
  return `M${cx - r},${cy} A${r},${r} 0 1,0 ${cx + r},${cy} A${r},${r} 0 1,0 ${cx - r},${cy} Z`;
6088
6136
  }
6089
- function renderVenn(container, parsed, palette, isDark, onClickItem) {
6137
+ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
6090
6138
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6091
6139
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
6092
6140
  if (vennSets.length < 2) return;
6093
- const width = container.clientWidth;
6094
- const height = container.clientHeight;
6141
+ const width = exportDims?.width ?? container.clientWidth;
6142
+ const height = exportDims?.height ?? container.clientHeight;
6095
6143
  if (width <= 0 || height <= 0) return;
6096
6144
  const textColor = palette.text;
6097
- const bgColor = palette.overlay;
6145
+ const bgColor = palette.bg;
6098
6146
  const colors = getSeriesColors(palette);
6099
6147
  const titleHeight = title ? 40 : 0;
6100
6148
  const radii = vennSets.map((s) => radiusFromArea(s.size));
@@ -6155,7 +6203,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem) {
6155
6203
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
6156
6204
  const tooltip = createTooltip(container, palette, isDark);
6157
6205
  if (title) {
6158
- svg.append("text").attr("x", width / 2).attr("y", 28).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").text(title);
6206
+ svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
6159
6207
  }
6160
6208
  const defs = svg.append("defs");
6161
6209
  const pad = 20;
@@ -6297,7 +6345,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem) {
6297
6345
  });
6298
6346
  });
6299
6347
  }
6300
- function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6348
+ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
6301
6349
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6302
6350
  const {
6303
6351
  title,
@@ -6310,12 +6358,12 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6310
6358
  quadrantYAxisLineNumber
6311
6359
  } = parsed;
6312
6360
  if (quadrantPoints.length === 0) return;
6313
- const width = container.clientWidth;
6314
- const height = container.clientHeight;
6361
+ const width = exportDims?.width ?? container.clientWidth;
6362
+ const height = exportDims?.height ?? container.clientHeight;
6315
6363
  if (width <= 0 || height <= 0) return;
6316
6364
  const textColor = palette.text;
6317
6365
  const mutedColor = palette.textMuted;
6318
- const bgColor = palette.overlay;
6366
+ const bgColor = palette.bg;
6319
6367
  const borderColor = palette.border;
6320
6368
  const defaultColors = [
6321
6369
  palette.colors.blue,
@@ -6323,7 +6371,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6323
6371
  palette.colors.yellow,
6324
6372
  palette.colors.purple
6325
6373
  ];
6326
- const margin = { top: title ? 60 : 30, right: 30, bottom: 50, left: 60 };
6374
+ const hasXAxis = !!quadrantXAxis;
6375
+ const hasYAxis = !!quadrantYAxis;
6376
+ const margin = { top: title ? 60 : 30, right: 30, bottom: hasXAxis ? 70 : 40, left: hasYAxis ? 80 : 40 };
6327
6377
  const chartWidth = width - margin.left - margin.right;
6328
6378
  const chartHeight = height - margin.top - margin.bottom;
6329
6379
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
@@ -6331,7 +6381,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6331
6381
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
6332
6382
  const tooltip = createTooltip(container, palette, isDark);
6333
6383
  if (title) {
6334
- const titleText = svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("font-weight", "700").style(
6384
+ const titleText = svg.append("text").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style(
6335
6385
  "cursor",
6336
6386
  onClickItem && quadrantTitleLineNumber ? "pointer" : "default"
6337
6387
  ).text(title);
@@ -6344,6 +6394,16 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6344
6394
  }
6345
6395
  }
6346
6396
  const chartG = svg.append("g").attr("transform", `translate(${margin.left}, ${margin.top})`);
6397
+ const mixHex = (a, b, pct) => {
6398
+ const parse = (h) => {
6399
+ const r = h.replace("#", "");
6400
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6401
+ return [parseInt(f.substring(0, 2), 16), parseInt(f.substring(2, 4), 16), parseInt(f.substring(4, 6), 16)];
6402
+ };
6403
+ const [ar, ag, ab] = parse(a), [br, bg, bb] = parse(b), t = pct / 100;
6404
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6405
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6406
+ };
6347
6407
  const getQuadrantFill = (label, defaultIdx) => {
6348
6408
  return label?.color ?? defaultColors[defaultIdx % defaultColors.length];
6349
6409
  };
@@ -6398,9 +6458,13 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6398
6458
  }
6399
6459
  ];
6400
6460
  const quadrantRects = chartG.selectAll("rect.quadrant").data(quadrantDefs).enter().append("rect").attr("class", "quadrant").attr("x", (d) => d.x).attr("y", (d) => d.y).attr("width", (d) => d.w).attr("height", (d) => d.h).attr("fill", (d) => getQuadrantFill(d.label, d.colorIdx)).attr("stroke", borderColor).attr("stroke-width", 0.5);
6401
- const contrastColor = isDark ? "#ffffff" : "#333333";
6402
- const shadowColor = isDark ? "rgba(0,0,0,0.3)" : "rgba(255,255,255,0.5)";
6403
- const quadrantLabelTexts = chartG.selectAll("text.quadrant-label").data(quadrantDefs.filter((d) => d.label !== null)).enter().append("text").attr("class", "quadrant-label").attr("x", (d) => d.labelX).attr("y", (d) => d.labelY).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", contrastColor).attr("font-size", "16px").attr("font-weight", "600").style("text-shadow", `0 1px 2px ${shadowColor}`).style(
6461
+ const contrastColor = "#ffffff";
6462
+ const shadowColor = "rgba(0,0,0,0.4)";
6463
+ const getQuadrantLabelColor = (d) => {
6464
+ const fill2 = getQuadrantFill(d.label, d.colorIdx);
6465
+ return mixHex("#000000", fill2, 40);
6466
+ };
6467
+ const quadrantLabelTexts = chartG.selectAll("text.quadrant-label").data(quadrantDefs.filter((d) => d.label !== null)).enter().append("text").attr("class", "quadrant-label").attr("x", (d) => d.labelX).attr("y", (d) => d.labelY).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", (d) => getQuadrantLabelColor(d)).attr("font-size", "48px").attr("font-weight", "700").style(
6404
6468
  "cursor",
6405
6469
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
6406
6470
  ).text((d) => d.label.text);
@@ -6414,15 +6478,14 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6414
6478
  });
6415
6479
  }
6416
6480
  if (quadrantXAxis) {
6417
- const xLowLabel = svg.append("text").attr("x", margin.left).attr("y", height - 15).attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "12px").style(
6481
+ const xLowLabel = svg.append("text").attr("x", margin.left + chartWidth / 4).attr("y", height - 20).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").style(
6418
6482
  "cursor",
6419
6483
  onClickItem && quadrantXAxisLineNumber ? "pointer" : "default"
6420
6484
  ).text(quadrantXAxis[0]);
6421
- const xHighLabel = svg.append("text").attr("x", width - margin.right).attr("y", height - 15).attr("text-anchor", "end").attr("fill", textColor).attr("font-size", "12px").style(
6485
+ const xHighLabel = svg.append("text").attr("x", margin.left + chartWidth * 3 / 4).attr("y", height - 20).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").style(
6422
6486
  "cursor",
6423
6487
  onClickItem && quadrantXAxisLineNumber ? "pointer" : "default"
6424
6488
  ).text(quadrantXAxis[1]);
6425
- svg.append("text").attr("x", width / 2).attr("y", height - 15).attr("text-anchor", "middle").attr("fill", mutedColor).attr("font-size", "12px").text("\u2192");
6426
6489
  if (onClickItem && quadrantXAxisLineNumber) {
6427
6490
  [xLowLabel, xHighLabel].forEach((label) => {
6428
6491
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
@@ -6434,15 +6497,16 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6434
6497
  }
6435
6498
  }
6436
6499
  if (quadrantYAxis) {
6437
- const yLowLabel = svg.append("text").attr("x", 15).attr("y", height - margin.bottom).attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "12px").attr("transform", `rotate(-90, 15, ${height - margin.bottom})`).style(
6500
+ const yMidBottom = margin.top + chartHeight * 3 / 4;
6501
+ const yMidTop = margin.top + chartHeight / 4;
6502
+ const yLowLabel = svg.append("text").attr("x", 22).attr("y", yMidBottom).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("transform", `rotate(-90, 22, ${yMidBottom})`).style(
6438
6503
  "cursor",
6439
6504
  onClickItem && quadrantYAxisLineNumber ? "pointer" : "default"
6440
6505
  ).text(quadrantYAxis[0]);
6441
- const yHighLabel = svg.append("text").attr("x", 15).attr("y", margin.top).attr("text-anchor", "end").attr("fill", textColor).attr("font-size", "12px").attr("transform", `rotate(-90, 15, ${margin.top})`).style(
6506
+ const yHighLabel = svg.append("text").attr("x", 22).attr("y", yMidTop).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "18px").attr("transform", `rotate(-90, 22, ${yMidTop})`).style(
6442
6507
  "cursor",
6443
6508
  onClickItem && quadrantYAxisLineNumber ? "pointer" : "default"
6444
6509
  ).text(quadrantYAxis[1]);
6445
- svg.append("text").attr("x", 15).attr("y", height / 2).attr("text-anchor", "middle").attr("fill", mutedColor).attr("font-size", "12px").attr("transform", `rotate(-90, 15, ${height / 2})`).text("\u2192");
6446
6510
  if (onClickItem && quadrantYAxisLineNumber) {
6447
6511
  [yLowLabel, yHighLabel].forEach((label) => {
6448
6512
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
@@ -6469,8 +6533,8 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6469
6533
  const quadDef = quadrantDefs.find((d) => d.position === quadrant);
6470
6534
  const pointColor = quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];
6471
6535
  const pointG = pointsG.append("g").attr("class", "point-group");
6472
- pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", contrastColor).attr("stroke", pointColor).attr("stroke-width", 2);
6473
- pointG.append("text").attr("x", cx).attr("y", cy - 10).attr("text-anchor", "middle").attr("fill", contrastColor).attr("font-size", "11px").style("text-shadow", `0 1px 2px ${shadowColor}`).text(point.label);
6536
+ pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", "#ffffff").attr("stroke", pointColor).attr("stroke-width", 2);
6537
+ pointG.append("text").attr("x", cx).attr("y", cy - 10).attr("text-anchor", "middle").attr("fill", contrastColor).attr("font-size", "12px").attr("font-weight", "700").style("text-shadow", `0 1px 2px ${shadowColor}`).text(point.label);
6474
6538
  const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;
6475
6539
  pointG.style("cursor", onClickItem ? "pointer" : "default").on("mouseenter", (event) => {
6476
6540
  showTooltip(tooltip, tipHtml, event);
@@ -6512,7 +6576,11 @@ var EXPORT_WIDTH = 1200;
6512
6576
  var EXPORT_HEIGHT = 800;
6513
6577
  async function renderD3ForExport(content, theme, palette) {
6514
6578
  const parsed = parseD3(content, palette);
6515
- if (parsed.error) return "";
6579
+ if (parsed.error && parsed.type !== "sequence") {
6580
+ const looksLikeSequence2 = /->|~>|<-/.test(content);
6581
+ if (!looksLikeSequence2) return "";
6582
+ parsed.type = "sequence";
6583
+ }
6516
6584
  if (parsed.type === "wordcloud" && parsed.words.length === 0) return "";
6517
6585
  if (parsed.type === "slope" && parsed.data.length === 0) return "";
6518
6586
  if (parsed.type === "arc" && parsed.links.length === 0) return "";
@@ -6530,30 +6598,35 @@ async function renderD3ForExport(content, theme, palette) {
6530
6598
  container.style.position = "absolute";
6531
6599
  container.style.left = "-9999px";
6532
6600
  document.body.appendChild(container);
6601
+ const dims = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };
6533
6602
  try {
6534
6603
  if (parsed.type === "sequence") {
6535
6604
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
6536
6605
  const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer(), renderer_exports));
6537
6606
  const seqParsed = parseSequenceDgmo2(content);
6538
6607
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
6539
- renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark);
6608
+ renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
6609
+ exportWidth: EXPORT_WIDTH
6610
+ });
6540
6611
  } else if (parsed.type === "wordcloud") {
6541
- await renderWordCloudAsync(container, parsed, effectivePalette, isDark);
6612
+ await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);
6542
6613
  } else if (parsed.type === "arc") {
6543
- renderArcDiagram(container, parsed, effectivePalette, isDark);
6614
+ renderArcDiagram(container, parsed, effectivePalette, isDark, void 0, dims);
6544
6615
  } else if (parsed.type === "timeline") {
6545
- renderTimeline(container, parsed, effectivePalette, isDark);
6616
+ renderTimeline(container, parsed, effectivePalette, isDark, void 0, dims);
6546
6617
  } else if (parsed.type === "venn") {
6547
- renderVenn(container, parsed, effectivePalette, isDark);
6618
+ renderVenn(container, parsed, effectivePalette, isDark, void 0, dims);
6548
6619
  } else if (parsed.type === "quadrant") {
6549
- renderQuadrant(container, parsed, effectivePalette, isDark);
6620
+ renderQuadrant(container, parsed, effectivePalette, isDark, void 0, dims);
6550
6621
  } else {
6551
- renderSlopeChart(container, parsed, effectivePalette, isDark);
6622
+ renderSlopeChart(container, parsed, effectivePalette, isDark, void 0, dims);
6552
6623
  }
6553
6624
  const svgEl = container.querySelector("svg");
6554
6625
  if (!svgEl) return "";
6555
6626
  if (theme === "transparent") {
6556
6627
  svgEl.style.background = "none";
6628
+ } else if (!svgEl.style.background) {
6629
+ svgEl.style.background = effectivePalette.bg;
6557
6630
  }
6558
6631
  svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
6559
6632
  svgEl.style.fontFamily = FONT_FAMILY;