@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.cjs CHANGED
@@ -189,6 +189,14 @@ function parseReturnLabel(rawLabel) {
189
189
  if (umlReturn) {
190
190
  return { label: umlReturn[1].trim(), returnLabel: umlReturn[2].trim() };
191
191
  }
192
+ const lastSep = rawLabel.lastIndexOf(" : ");
193
+ if (lastSep > 0) {
194
+ const reqPart = rawLabel.substring(0, lastSep).trim();
195
+ const resPart = rawLabel.substring(lastSep + 3).trim();
196
+ if (reqPart && resPart) {
197
+ return { label: reqPart, returnLabel: resPart };
198
+ }
199
+ }
192
200
  return { label: rawLabel };
193
201
  }
194
202
  function measureIndent(line2) {
@@ -1393,7 +1401,7 @@ var init_bold = __esm({
1393
1401
  dark: {
1394
1402
  bg: "#000000",
1395
1403
  surface: "#111111",
1396
- overlay: "#000000",
1404
+ overlay: "#1a1a1a",
1397
1405
  border: "#333333",
1398
1406
  text: "#ffffff",
1399
1407
  textMuted: "#aaaaaa",
@@ -2036,7 +2044,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2036
2044
  {
2037
2045
  let fi = 0;
2038
2046
  for (let oi = 0; oi < allRenderSteps.length; oi++) {
2039
- if (!hiddenMsgIndices.has(allRenderSteps[oi].messageIndex)) {
2047
+ const step = allRenderSteps[oi];
2048
+ if (!hiddenMsgIndices.has(step.messageIndex) && (step.type === "call" || step.label)) {
2040
2049
  originalToFiltered.set(oi, fi);
2041
2050
  fi++;
2042
2051
  }
@@ -2125,7 +2134,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2125
2134
  PARTICIPANT_BOX_WIDTH + 40
2126
2135
  );
2127
2136
  const totalHeight = participantStartY + PARTICIPANT_BOX_HEIGHT + Math.max(lifelineLength, 40) + 40;
2128
- const { width: containerWidth } = container.getBoundingClientRect();
2137
+ const containerWidth = options?.exportWidth ?? container.getBoundingClientRect().width;
2129
2138
  const svgWidth = Math.max(totalWidth, containerWidth);
2130
2139
  const diagramWidth = participants.length * PARTICIPANT_GAP;
2131
2140
  const offsetX = Math.max(0, (svgWidth - diagramWidth) / 2) + PARTICIPANT_GAP / 2;
@@ -2148,7 +2157,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
2148
2157
  `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`
2149
2158
  ).attr("fill", "none").attr("stroke", palette.text).attr("stroke-width", 1.2);
2150
2159
  if (title) {
2151
- 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);
2160
+ 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);
2152
2161
  }
2153
2162
  for (const group of groups) {
2154
2163
  if (group.participantIds.length === 0) continue;
@@ -2943,9 +2952,10 @@ function parseEChart(content, palette) {
2943
2952
  }
2944
2953
  return result;
2945
2954
  }
2946
- function buildEChartsOption(parsed, palette, _isDark) {
2955
+ function buildEChartsOption(parsed, palette, isDark) {
2947
2956
  const textColor = palette.text;
2948
2957
  const axisLineColor = palette.border;
2958
+ const gridOpacity = isDark ? 0.7 : 0.4;
2949
2959
  const colors = getSeriesColors(palette);
2950
2960
  if (parsed.error) {
2951
2961
  return {};
@@ -2953,9 +2963,10 @@ function buildEChartsOption(parsed, palette, _isDark) {
2953
2963
  const titleConfig = parsed.title ? {
2954
2964
  text: parsed.title,
2955
2965
  left: "center",
2966
+ top: 8,
2956
2967
  textStyle: {
2957
2968
  color: textColor,
2958
- fontSize: 18,
2969
+ fontSize: 20,
2959
2970
  fontWeight: "bold",
2960
2971
  fontFamily: FONT_FAMILY
2961
2972
  }
@@ -2989,6 +3000,7 @@ function buildEChartsOption(parsed, palette, _isDark) {
2989
3000
  palette,
2990
3001
  textColor,
2991
3002
  axisLineColor,
3003
+ gridOpacity,
2992
3004
  colors,
2993
3005
  titleConfig,
2994
3006
  tooltipTheme
@@ -3000,6 +3012,7 @@ function buildEChartsOption(parsed, palette, _isDark) {
3000
3012
  palette,
3001
3013
  textColor,
3002
3014
  axisLineColor,
3015
+ gridOpacity,
3003
3016
  colors,
3004
3017
  titleConfig,
3005
3018
  tooltipTheme
@@ -3171,7 +3184,7 @@ function evaluateExpression(expr, x) {
3171
3184
  return NaN;
3172
3185
  }
3173
3186
  }
3174
- function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors, titleConfig, tooltipTheme) {
3187
+ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3175
3188
  const xRange = parsed.xRange ?? { min: -10, max: 10 };
3176
3189
  const samples = 200;
3177
3190
  const step = (xRange.max - xRange.min) / samples;
@@ -3219,7 +3232,7 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3219
3232
  }
3220
3233
  },
3221
3234
  grid: {
3222
- left: "3%",
3235
+ left: "4%",
3223
3236
  right: "4%",
3224
3237
  bottom: "15%",
3225
3238
  top: parsed.title ? "15%" : "5%",
@@ -3233,11 +3246,13 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3233
3246
  lineStyle: { color: axisLineColor }
3234
3247
  },
3235
3248
  axisLabel: {
3236
- color: textColor
3249
+ color: textColor,
3250
+ fontSize: 16
3237
3251
  },
3238
3252
  splitLine: {
3239
3253
  lineStyle: {
3240
- color: palette.overlay
3254
+ color: palette.border,
3255
+ opacity: gridOpacity
3241
3256
  }
3242
3257
  }
3243
3258
  },
@@ -3247,18 +3262,20 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, colors,
3247
3262
  lineStyle: { color: axisLineColor }
3248
3263
  },
3249
3264
  axisLabel: {
3250
- color: textColor
3265
+ color: textColor,
3266
+ fontSize: 16
3251
3267
  },
3252
3268
  splitLine: {
3253
3269
  lineStyle: {
3254
- color: palette.overlay
3270
+ color: palette.border,
3271
+ opacity: gridOpacity
3255
3272
  }
3256
3273
  }
3257
3274
  },
3258
3275
  series
3259
3276
  };
3260
3277
  }
3261
- function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, titleConfig, tooltipTheme) {
3278
+ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3262
3279
  const points = parsed.scatterPoints ?? [];
3263
3280
  const defaultSize = 15;
3264
3281
  const hasCategories = points.some((p) => p.category !== void 0);
@@ -3334,6 +3351,14 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3334
3351
  return html;
3335
3352
  }
3336
3353
  };
3354
+ const xValues = points.map((p) => p.x);
3355
+ const yValues = points.map((p) => p.y);
3356
+ const xMin = Math.min(...xValues);
3357
+ const xMax = Math.max(...xValues);
3358
+ const yMin = Math.min(...yValues);
3359
+ const yMax = Math.max(...yValues);
3360
+ const xPad = (xMax - xMin) * 0.1 || 1;
3361
+ const yPad = (yMax - yMin) * 0.1 || 1;
3337
3362
  return {
3338
3363
  backgroundColor: "transparent",
3339
3364
  animation: false,
@@ -3347,9 +3372,9 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3347
3372
  }
3348
3373
  },
3349
3374
  grid: {
3350
- left: "3%",
3375
+ left: parsed.ylabel ? "5%" : "3%",
3351
3376
  right: "4%",
3352
- bottom: hasCategories ? "15%" : "3%",
3377
+ bottom: hasCategories ? "15%" : parsed.xlabel ? "10%" : "3%",
3353
3378
  top: parsed.title ? "15%" : "5%",
3354
3379
  containLabel: true
3355
3380
  },
@@ -3357,20 +3382,24 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3357
3382
  type: "value",
3358
3383
  name: parsed.xlabel,
3359
3384
  nameLocation: "middle",
3360
- nameGap: 30,
3385
+ nameGap: 40,
3361
3386
  nameTextStyle: {
3362
3387
  color: textColor,
3363
- fontSize: 12
3388
+ fontSize: 18
3364
3389
  },
3390
+ min: Math.floor(xMin - xPad),
3391
+ max: Math.ceil(xMax + xPad),
3365
3392
  axisLine: {
3366
3393
  lineStyle: { color: axisLineColor }
3367
3394
  },
3368
3395
  axisLabel: {
3369
- color: textColor
3396
+ color: textColor,
3397
+ fontSize: 16
3370
3398
  },
3371
3399
  splitLine: {
3372
3400
  lineStyle: {
3373
- color: palette.overlay
3401
+ color: palette.border,
3402
+ opacity: gridOpacity
3374
3403
  }
3375
3404
  }
3376
3405
  },
@@ -3378,20 +3407,24 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, colors, t
3378
3407
  type: "value",
3379
3408
  name: parsed.ylabel,
3380
3409
  nameLocation: "middle",
3381
- nameGap: 40,
3410
+ nameGap: 50,
3382
3411
  nameTextStyle: {
3383
3412
  color: textColor,
3384
- fontSize: 12
3413
+ fontSize: 18
3385
3414
  },
3415
+ min: Math.floor(yMin - yPad),
3416
+ max: Math.ceil(yMax + yPad),
3386
3417
  axisLine: {
3387
3418
  lineStyle: { color: axisLineColor }
3388
3419
  },
3389
3420
  axisLabel: {
3390
- color: textColor
3421
+ color: textColor,
3422
+ fontSize: 16
3391
3423
  },
3392
3424
  splitLine: {
3393
3425
  lineStyle: {
3394
- color: palette.overlay
3426
+ color: palette.border,
3427
+ opacity: gridOpacity
3395
3428
  }
3396
3429
  }
3397
3430
  },
@@ -3443,7 +3476,8 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3443
3476
  lineStyle: { color: axisLineColor }
3444
3477
  },
3445
3478
  axisLabel: {
3446
- color: textColor
3479
+ color: textColor,
3480
+ fontSize: 16
3447
3481
  }
3448
3482
  },
3449
3483
  yAxis: {
@@ -3456,7 +3490,8 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3456
3490
  lineStyle: { color: axisLineColor }
3457
3491
  },
3458
3492
  axisLabel: {
3459
- color: textColor
3493
+ color: textColor,
3494
+ fontSize: 16
3460
3495
  }
3461
3496
  },
3462
3497
  visualMap: {
@@ -3468,7 +3503,6 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3468
3503
  top: "center",
3469
3504
  inRange: {
3470
3505
  color: [
3471
- palette.bg,
3472
3506
  palette.primary,
3473
3507
  palette.colors.cyan,
3474
3508
  palette.colors.yellow,
@@ -3485,7 +3519,9 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
3485
3519
  data,
3486
3520
  label: {
3487
3521
  show: true,
3488
- color: textColor
3522
+ color: "#ffffff",
3523
+ fontSize: 14,
3524
+ fontWeight: "bold"
3489
3525
  },
3490
3526
  emphasis: {
3491
3527
  itemStyle: {
@@ -3605,33 +3641,35 @@ function resolveAxisLabels(parsed) {
3605
3641
  yLabel: parsed.ylabel ?? (isHorizontal ? void 0 : parsed.label)
3606
3642
  };
3607
3643
  }
3608
- function makeGridAxis(type, textColor, axisLineColor, splitLineColor, label, data) {
3644
+ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacity, label, data) {
3609
3645
  return {
3610
3646
  type,
3611
3647
  ...data && { data },
3612
3648
  axisLine: { lineStyle: { color: axisLineColor } },
3613
- axisLabel: { color: textColor, fontFamily: FONT_FAMILY },
3614
- splitLine: { lineStyle: { color: splitLineColor } },
3649
+ axisLabel: { color: textColor, fontSize: 16, fontFamily: FONT_FAMILY },
3650
+ splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },
3615
3651
  ...label && {
3616
3652
  name: label,
3617
3653
  nameLocation: "middle",
3618
- nameGap: 30,
3619
- nameTextStyle: { color: textColor, fontSize: 12, fontFamily: FONT_FAMILY }
3654
+ nameGap: 40,
3655
+ nameTextStyle: { color: textColor, fontSize: 18, fontFamily: FONT_FAMILY }
3620
3656
  }
3621
3657
  };
3622
3658
  }
3623
- function buildEChartsOptionFromChart(parsed, palette, _isDark) {
3659
+ function buildEChartsOptionFromChart(parsed, palette, isDark) {
3624
3660
  if (parsed.error) return {};
3625
3661
  const textColor = palette.text;
3626
3662
  const axisLineColor = palette.border;
3627
- const splitLineColor = palette.overlay;
3663
+ const splitLineColor = palette.border;
3664
+ const gridOpacity = isDark ? 0.7 : 0.4;
3628
3665
  const colors = getSeriesColors(palette);
3629
3666
  const titleConfig = parsed.title ? {
3630
3667
  text: parsed.title,
3631
3668
  left: "center",
3669
+ top: 8,
3632
3670
  textStyle: {
3633
3671
  color: textColor,
3634
- fontSize: 18,
3672
+ fontSize: 20,
3635
3673
  fontWeight: "bold",
3636
3674
  fontFamily: FONT_FAMILY
3637
3675
  }
@@ -3643,24 +3681,24 @@ function buildEChartsOptionFromChart(parsed, palette, _isDark) {
3643
3681
  };
3644
3682
  switch (parsed.type) {
3645
3683
  case "bar":
3646
- return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme);
3684
+ return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
3647
3685
  case "bar-stacked":
3648
- return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme);
3686
+ return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);
3649
3687
  case "line":
3650
- return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme);
3688
+ return parsed.seriesNames ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
3651
3689
  case "area":
3652
- return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme);
3690
+ return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);
3653
3691
  case "pie":
3654
3692
  return buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, false);
3655
3693
  case "doughnut":
3656
3694
  return buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, true);
3657
3695
  case "radar":
3658
- return buildRadarOption(parsed, palette, textColor, colors, titleConfig, tooltipTheme);
3696
+ return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);
3659
3697
  case "polar-area":
3660
3698
  return buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipTheme);
3661
3699
  }
3662
3700
  }
3663
- function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3701
+ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3664
3702
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3665
3703
  const isHorizontal = parsed.orientation === "horizontal";
3666
3704
  const labels = parsed.data.map((d) => d.label);
@@ -3668,8 +3706,8 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3668
3706
  value: d.value,
3669
3707
  itemStyle: { color: d.color ?? colors[i % colors.length] }
3670
3708
  }));
3671
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, isHorizontal ? yLabel : xLabel, labels);
3672
- const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, isHorizontal ? xLabel : yLabel);
3709
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);
3710
+ const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
3673
3711
  return {
3674
3712
  backgroundColor: "transparent",
3675
3713
  animation: false,
@@ -3680,9 +3718,9 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3680
3718
  axisPointer: { type: "shadow" }
3681
3719
  },
3682
3720
  grid: {
3683
- left: "3%",
3721
+ left: yLabel ? "5%" : "3%",
3684
3722
  right: "4%",
3685
- bottom: "3%",
3723
+ bottom: xLabel ? "10%" : "3%",
3686
3724
  top: parsed.title ? "15%" : "5%",
3687
3725
  containLabel: true
3688
3726
  },
@@ -3696,7 +3734,7 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, colors
3696
3734
  ]
3697
3735
  };
3698
3736
  }
3699
- function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme) {
3737
+ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
3700
3738
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3701
3739
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3702
3740
  const labels = parsed.data.map((d) => d.label);
@@ -3711,14 +3749,14 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
3711
3749
  axisPointer: { type: "line" }
3712
3750
  },
3713
3751
  grid: {
3714
- left: "3%",
3752
+ left: yLabel ? "5%" : "3%",
3715
3753
  right: "4%",
3716
- bottom: "3%",
3754
+ bottom: xLabel ? "10%" : "3%",
3717
3755
  top: parsed.title ? "15%" : "5%",
3718
3756
  containLabel: true
3719
3757
  },
3720
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3721
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3758
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3759
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3722
3760
  series: [
3723
3761
  {
3724
3762
  type: "line",
@@ -3731,7 +3769,7 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
3731
3769
  ]
3732
3770
  };
3733
3771
  }
3734
- function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3772
+ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3735
3773
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3736
3774
  const seriesNames = parsed.seriesNames ?? [];
3737
3775
  const labels = parsed.data.map((d) => d.label);
@@ -3765,18 +3803,18 @@ function buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor,
3765
3803
  textStyle: { color: textColor }
3766
3804
  },
3767
3805
  grid: {
3768
- left: "3%",
3806
+ left: yLabel ? "5%" : "3%",
3769
3807
  right: "4%",
3770
3808
  bottom: "15%",
3771
3809
  top: parsed.title ? "15%" : "5%",
3772
3810
  containLabel: true
3773
3811
  },
3774
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3775
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3812
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3813
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3776
3814
  series
3777
3815
  };
3778
3816
  }
3779
- function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, titleConfig, tooltipTheme) {
3817
+ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme) {
3780
3818
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3781
3819
  const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3782
3820
  const labels = parsed.data.map((d) => d.label);
@@ -3791,14 +3829,14 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
3791
3829
  axisPointer: { type: "line" }
3792
3830
  },
3793
3831
  grid: {
3794
- left: "3%",
3832
+ left: yLabel ? "5%" : "3%",
3795
3833
  right: "4%",
3796
- bottom: "3%",
3834
+ bottom: xLabel ? "10%" : "3%",
3797
3835
  top: parsed.title ? "15%" : "5%",
3798
3836
  containLabel: true
3799
3837
  },
3800
- xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, xLabel, labels),
3801
- yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, yLabel),
3838
+ xAxis: makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),
3839
+ yAxis: makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),
3802
3840
  series: [
3803
3841
  {
3804
3842
  type: "line",
@@ -3833,7 +3871,7 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
3833
3871
  data,
3834
3872
  label: {
3835
3873
  position: "outside",
3836
- formatter: "{b}",
3874
+ formatter: "{b} \u2014 {c} ({d}%)",
3837
3875
  color: textColor,
3838
3876
  fontFamily: FONT_FAMILY
3839
3877
  },
@@ -3842,11 +3880,10 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
3842
3880
  ]
3843
3881
  };
3844
3882
  }
3845
- function buildRadarOption(parsed, palette, textColor, colors, titleConfig, tooltipTheme) {
3883
+ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3846
3884
  const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
3847
3885
  const values = parsed.data.map((d) => d.value);
3848
3886
  const maxValue = Math.max(...values) * 1.15;
3849
- const gridOpacity = 0.6;
3850
3887
  const indicator = parsed.data.map((d) => ({
3851
3888
  name: d.label,
3852
3889
  max: maxValue
@@ -3863,7 +3900,8 @@ function buildRadarOption(parsed, palette, textColor, colors, titleConfig, toolt
3863
3900
  indicator,
3864
3901
  axisName: {
3865
3902
  color: textColor,
3866
- fontFamily: FONT_FAMILY
3903
+ fontFamily: FONT_FAMILY,
3904
+ fontSize: 16
3867
3905
  },
3868
3906
  splitLine: {
3869
3907
  lineStyle: { color: palette.border, opacity: gridOpacity }
@@ -3920,7 +3958,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
3920
3958
  data,
3921
3959
  label: {
3922
3960
  position: "outside",
3923
- formatter: "{b}",
3961
+ formatter: "{b} \u2014 {c} ({d}%)",
3924
3962
  color: textColor,
3925
3963
  fontFamily: FONT_FAMILY
3926
3964
  },
@@ -3929,7 +3967,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
3929
3967
  ]
3930
3968
  };
3931
3969
  }
3932
- function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, colors, titleConfig, tooltipTheme) {
3970
+ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
3933
3971
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
3934
3972
  const isHorizontal = parsed.orientation === "horizontal";
3935
3973
  const seriesNames = parsed.seriesNames ?? [];
@@ -3944,11 +3982,20 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
3944
3982
  type: "bar",
3945
3983
  stack: "total",
3946
3984
  data,
3947
- itemStyle: { color }
3985
+ itemStyle: { color },
3986
+ label: {
3987
+ show: true,
3988
+ position: "inside",
3989
+ formatter: "{c}",
3990
+ color: "#ffffff",
3991
+ fontSize: 14,
3992
+ fontWeight: "bold",
3993
+ fontFamily: FONT_FAMILY
3994
+ }
3948
3995
  };
3949
3996
  });
3950
- const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, isHorizontal ? yLabel : xLabel, labels);
3951
- const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, isHorizontal ? xLabel : yLabel);
3997
+ const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);
3998
+ const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
3952
3999
  return {
3953
4000
  backgroundColor: "transparent",
3954
4001
  animation: false,
@@ -3964,7 +4011,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
3964
4011
  textStyle: { color: textColor }
3965
4012
  },
3966
4013
  grid: {
3967
- left: "3%",
4014
+ left: yLabel ? "5%" : "3%",
3968
4015
  right: "4%",
3969
4016
  bottom: "15%",
3970
4017
  top: parsed.title ? "15%" : "5%",
@@ -4015,9 +4062,10 @@ async function renderEChartsForExport(content, theme, palette) {
4015
4062
  chart.setOption(option);
4016
4063
  const svgString = chart.renderToSVGString();
4017
4064
  if (!svgString) return "";
4065
+ const bgStyle = theme !== "transparent" ? `background: ${effectivePalette.bg}; ` : "";
4018
4066
  return svgString.replace(
4019
4067
  /^<svg /,
4020
- `<svg style="font-family: ${FONT_FAMILY}" `
4068
+ `<svg style="${bgStyle}font-family: ${FONT_FAMILY}" `
4021
4069
  );
4022
4070
  } finally {
4023
4071
  chart.dispose();
@@ -4682,14 +4730,14 @@ function tokenizeFreeformText(text) {
4682
4730
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
4683
4731
  }
4684
4732
  var SLOPE_MARGIN = { top: 80, bottom: 40, left: 80 };
4685
- var SLOPE_LABEL_FONT_SIZE = 12;
4686
- var SLOPE_CHAR_WIDTH = 7;
4687
- function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4733
+ var SLOPE_LABEL_FONT_SIZE = 14;
4734
+ var SLOPE_CHAR_WIDTH = 8;
4735
+ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
4688
4736
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
4689
4737
  const { periods, data, title } = parsed;
4690
4738
  if (data.length === 0 || periods.length < 2) return;
4691
- const width = container.clientWidth;
4692
- const height = container.clientHeight;
4739
+ const width = exportDims?.width ?? container.clientWidth;
4740
+ const height = exportDims?.height ?? container.clientHeight;
4693
4741
  if (width <= 0 || height <= 0) return;
4694
4742
  const maxLabelText = data.reduce((longest, item) => {
4695
4743
  const text = `${item.values[item.values.length - 1]} \u2014 ${item.label}`;
@@ -4698,14 +4746,14 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4698
4746
  const estimatedLabelWidth = maxLabelText.length * SLOPE_CHAR_WIDTH;
4699
4747
  const maxRightMargin = Math.floor(width * 0.35);
4700
4748
  const rightMargin = Math.min(
4701
- Math.max(estimatedLabelWidth + 20, 100),
4749
+ Math.max(estimatedLabelWidth + 30, 120),
4702
4750
  maxRightMargin
4703
4751
  );
4704
4752
  const innerWidth = width - SLOPE_MARGIN.left - rightMargin;
4705
4753
  const innerHeight = height - SLOPE_MARGIN.top - SLOPE_MARGIN.bottom;
4706
4754
  const textColor = palette.text;
4707
4755
  const mutedColor = palette.border;
4708
- const bgColor = palette.overlay;
4756
+ const bgColor = palette.bg;
4709
4757
  const colors = getSeriesColors(palette);
4710
4758
  const allValues = data.flatMap((d) => d.values);
4711
4759
  const [minVal, maxVal] = d3Array.extent(allValues);
@@ -4716,11 +4764,11 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4716
4764
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
4717
4765
  const tooltip = createTooltip(container, palette, isDark);
4718
4766
  if (title) {
4719
- 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);
4767
+ 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);
4720
4768
  }
4721
4769
  for (const period of periods) {
4722
4770
  const x = xScale(period);
4723
- 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);
4771
+ 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);
4724
4772
  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");
4725
4773
  }
4726
4774
  const lineGen = d3Shape.line().x((_d, i) => xScale(periods[i])).y((d) => yScale(d));
@@ -4758,7 +4806,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem) {
4758
4806
  const isFirst = i === 0;
4759
4807
  const isLast = i === periods.length - 1;
4760
4808
  if (!isLast) {
4761
- 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());
4809
+ 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());
4762
4810
  }
4763
4811
  });
4764
4812
  const lastX = xScale(periods[periods.length - 1]);
@@ -4884,12 +4932,12 @@ function orderArcNodes(links, order, groups) {
4884
4932
  return allNodes;
4885
4933
  }
4886
4934
  var ARC_MARGIN = { top: 60, right: 40, bottom: 60, left: 40 };
4887
- function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4935
+ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
4888
4936
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
4889
4937
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
4890
4938
  if (links.length === 0) return;
4891
- const width = container.clientWidth;
4892
- const height = container.clientHeight;
4939
+ const width = exportDims?.width ?? container.clientWidth;
4940
+ const height = exportDims?.height ?? container.clientHeight;
4893
4941
  if (width <= 0 || height <= 0) return;
4894
4942
  const isVertical = orientation === "vertical";
4895
4943
  const margin = isVertical ? {
@@ -4902,7 +4950,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4902
4950
  const innerHeight = height - margin.top - margin.bottom;
4903
4951
  const textColor = palette.text;
4904
4952
  const mutedColor = palette.border;
4905
- const bgColor = palette.overlay;
4953
+ const bgColor = palette.bg;
4906
4954
  const colors = getSeriesColors(palette);
4907
4955
  const nodes = orderArcNodes(links, arcOrder, arcNodeGroups);
4908
4956
  const nodeColorMap = /* @__PURE__ */ new Map();
@@ -4925,7 +4973,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4925
4973
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
4926
4974
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
4927
4975
  if (title) {
4928
- 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);
4976
+ 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);
4929
4977
  }
4930
4978
  const neighbors = /* @__PURE__ */ new Map();
4931
4979
  for (const node of nodes) neighbors.set(node, /* @__PURE__ */ new Set());
@@ -4958,11 +5006,11 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
4958
5006
  g.selectAll(".arc-node").attr("opacity", 1);
4959
5007
  g.selectAll(".arc-group-band").attr(
4960
5008
  "fill-opacity",
4961
- 0.08
5009
+ 0.06
4962
5010
  );
4963
5011
  g.selectAll(".arc-group-label").attr(
4964
5012
  "fill-opacity",
4965
- 0.7
5013
+ 0.5
4966
5014
  );
4967
5015
  }
4968
5016
  function handleGroupEnter(groupName) {
@@ -5002,10 +5050,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
5002
5050
  const minY = Math.min(...positions) - bandPad;
5003
5051
  const maxY = Math.max(...positions) + bandPad;
5004
5052
  const bandColor = group.color ?? mutedColor;
5005
- 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", () => {
5053
+ 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", () => {
5006
5054
  if (onClickItem) onClickItem(group.lineNumber);
5007
5055
  });
5008
- 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", () => {
5056
+ 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", () => {
5009
5057
  if (onClickItem) onClickItem(group.lineNumber);
5010
5058
  });
5011
5059
  }
@@ -5046,10 +5094,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem) {
5046
5094
  const minX = Math.min(...positions) - bandPad;
5047
5095
  const maxX = Math.max(...positions) + bandPad;
5048
5096
  const bandColor = group.color ?? mutedColor;
5049
- 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", () => {
5097
+ 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", () => {
5050
5098
  if (onClickItem) onClickItem(group.lineNumber);
5051
5099
  });
5052
- 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", () => {
5100
+ 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", () => {
5053
5101
  if (onClickItem) onClickItem(group.lineNumber);
5054
5102
  });
5055
5103
  }
@@ -5345,7 +5393,7 @@ function buildEventTooltipHtml(ev) {
5345
5393
  function buildEraTooltipHtml(era) {
5346
5394
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
5347
5395
  }
5348
- function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5396
+ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
5349
5397
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
5350
5398
  const {
5351
5399
  timelineEvents,
@@ -5360,13 +5408,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5360
5408
  } = parsed;
5361
5409
  if (timelineEvents.length === 0) return;
5362
5410
  const tooltip = createTooltip(container, palette, isDark);
5363
- const width = container.clientWidth;
5364
- const height = container.clientHeight;
5411
+ const width = exportDims?.width ?? container.clientWidth;
5412
+ const height = exportDims?.height ?? container.clientHeight;
5365
5413
  if (width <= 0 || height <= 0) return;
5366
5414
  const isVertical = orientation === "vertical";
5367
5415
  const textColor = palette.text;
5368
5416
  const mutedColor = palette.border;
5369
- const bgColor = palette.overlay;
5417
+ const bgColor = palette.bg;
5370
5418
  const colors = getSeriesColors(palette);
5371
5419
  const groupColorMap = /* @__PURE__ */ new Map();
5372
5420
  timelineGroups.forEach((grp, i) => {
@@ -5470,7 +5518,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5470
5518
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5471
5519
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5472
5520
  if (title) {
5473
- 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);
5521
+ 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);
5474
5522
  }
5475
5523
  renderEras(
5476
5524
  g,
@@ -5564,7 +5612,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5564
5612
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5565
5613
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5566
5614
  if (title) {
5567
- 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);
5615
+ 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);
5568
5616
  }
5569
5617
  renderEras(
5570
5618
  g,
@@ -5687,7 +5735,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5687
5735
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5688
5736
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5689
5737
  if (title) {
5690
- 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);
5738
+ 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);
5691
5739
  }
5692
5740
  renderEras(
5693
5741
  g,
@@ -5797,7 +5845,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5797
5845
  }
5798
5846
  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);
5799
5847
  if (labelFitsInside) {
5800
- 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);
5848
+ 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);
5801
5849
  } else {
5802
5850
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
5803
5851
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -5832,7 +5880,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5832
5880
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5833
5881
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
5834
5882
  if (title) {
5835
- 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);
5883
+ 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);
5836
5884
  }
5837
5885
  renderEras(
5838
5886
  g,
@@ -5936,7 +5984,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem) {
5936
5984
  }
5937
5985
  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);
5938
5986
  if (labelFitsInside) {
5939
- 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);
5987
+ 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);
5940
5988
  } else {
5941
5989
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
5942
5990
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -5959,17 +6007,17 @@ function getRotateFn(mode) {
5959
6007
  if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
5960
6008
  return () => 0;
5961
6009
  }
5962
- function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
6010
+ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
5963
6011
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
5964
6012
  const { words, title, cloudOptions } = parsed;
5965
6013
  if (words.length === 0) return;
5966
- const width = container.clientWidth;
5967
- const height = container.clientHeight;
6014
+ const width = exportDims?.width ?? container.clientWidth;
6015
+ const height = exportDims?.height ?? container.clientHeight;
5968
6016
  if (width <= 0 || height <= 0) return;
5969
6017
  const titleHeight = title ? 40 : 0;
5970
6018
  const cloudHeight = height - titleHeight;
5971
6019
  const textColor = palette.text;
5972
- const bgColor = palette.overlay;
6020
+ const bgColor = palette.bg;
5973
6021
  const colors = getSeriesColors(palette);
5974
6022
  const { minSize, maxSize } = cloudOptions;
5975
6023
  const weights = words.map((w) => w.weight);
@@ -5983,7 +6031,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
5983
6031
  const rotateFn = getRotateFn(cloudOptions.rotate);
5984
6032
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
5985
6033
  if (title) {
5986
- 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);
6034
+ 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);
5987
6035
  }
5988
6036
  const g = svg.append("g").attr(
5989
6037
  "transform",
@@ -6002,7 +6050,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem) {
6002
6050
  });
6003
6051
  }).start();
6004
6052
  }
6005
- function renderWordCloudAsync(container, parsed, palette, _isDark) {
6053
+ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
6006
6054
  return new Promise((resolve) => {
6007
6055
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6008
6056
  const { words, title, cloudOptions } = parsed;
@@ -6010,8 +6058,8 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
6010
6058
  resolve();
6011
6059
  return;
6012
6060
  }
6013
- const width = container.clientWidth;
6014
- const height = container.clientHeight;
6061
+ const width = exportDims?.width ?? container.clientWidth;
6062
+ const height = exportDims?.height ?? container.clientHeight;
6015
6063
  if (width <= 0 || height <= 0) {
6016
6064
  resolve();
6017
6065
  return;
@@ -6019,7 +6067,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
6019
6067
  const titleHeight = title ? 40 : 0;
6020
6068
  const cloudHeight = height - titleHeight;
6021
6069
  const textColor = palette.text;
6022
- const bgColor = palette.overlay;
6070
+ const bgColor = palette.bg;
6023
6071
  const colors = getSeriesColors(palette);
6024
6072
  const { minSize, maxSize } = cloudOptions;
6025
6073
  const weights = words.map((w) => w.weight);
@@ -6033,7 +6081,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark) {
6033
6081
  const rotateFn = getRotateFn(cloudOptions.rotate);
6034
6082
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
6035
6083
  if (title) {
6036
- 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);
6084
+ 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);
6037
6085
  }
6038
6086
  const g = svg.append("g").attr(
6039
6087
  "transform",
@@ -6174,15 +6222,15 @@ function blendColors(hexColors) {
6174
6222
  function circlePathD(cx, cy, r) {
6175
6223
  return `M${cx - r},${cy} A${r},${r} 0 1,0 ${cx + r},${cy} A${r},${r} 0 1,0 ${cx - r},${cy} Z`;
6176
6224
  }
6177
- function renderVenn(container, parsed, palette, isDark, onClickItem) {
6225
+ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
6178
6226
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6179
6227
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
6180
6228
  if (vennSets.length < 2) return;
6181
- const width = container.clientWidth;
6182
- const height = container.clientHeight;
6229
+ const width = exportDims?.width ?? container.clientWidth;
6230
+ const height = exportDims?.height ?? container.clientHeight;
6183
6231
  if (width <= 0 || height <= 0) return;
6184
6232
  const textColor = palette.text;
6185
- const bgColor = palette.overlay;
6233
+ const bgColor = palette.bg;
6186
6234
  const colors = getSeriesColors(palette);
6187
6235
  const titleHeight = title ? 40 : 0;
6188
6236
  const radii = vennSets.map((s) => radiusFromArea(s.size));
@@ -6243,7 +6291,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem) {
6243
6291
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
6244
6292
  const tooltip = createTooltip(container, palette, isDark);
6245
6293
  if (title) {
6246
- 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);
6294
+ 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);
6247
6295
  }
6248
6296
  const defs = svg.append("defs");
6249
6297
  const pad = 20;
@@ -6385,7 +6433,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem) {
6385
6433
  });
6386
6434
  });
6387
6435
  }
6388
- function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6436
+ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
6389
6437
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6390
6438
  const {
6391
6439
  title,
@@ -6398,12 +6446,12 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6398
6446
  quadrantYAxisLineNumber
6399
6447
  } = parsed;
6400
6448
  if (quadrantPoints.length === 0) return;
6401
- const width = container.clientWidth;
6402
- const height = container.clientHeight;
6449
+ const width = exportDims?.width ?? container.clientWidth;
6450
+ const height = exportDims?.height ?? container.clientHeight;
6403
6451
  if (width <= 0 || height <= 0) return;
6404
6452
  const textColor = palette.text;
6405
6453
  const mutedColor = palette.textMuted;
6406
- const bgColor = palette.overlay;
6454
+ const bgColor = palette.bg;
6407
6455
  const borderColor = palette.border;
6408
6456
  const defaultColors = [
6409
6457
  palette.colors.blue,
@@ -6411,7 +6459,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6411
6459
  palette.colors.yellow,
6412
6460
  palette.colors.purple
6413
6461
  ];
6414
- const margin = { top: title ? 60 : 30, right: 30, bottom: 50, left: 60 };
6462
+ const hasXAxis = !!quadrantXAxis;
6463
+ const hasYAxis = !!quadrantYAxis;
6464
+ const margin = { top: title ? 60 : 30, right: 30, bottom: hasXAxis ? 70 : 40, left: hasYAxis ? 80 : 40 };
6415
6465
  const chartWidth = width - margin.left - margin.right;
6416
6466
  const chartHeight = height - margin.top - margin.bottom;
6417
6467
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
@@ -6419,7 +6469,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6419
6469
  const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
6420
6470
  const tooltip = createTooltip(container, palette, isDark);
6421
6471
  if (title) {
6422
- 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(
6472
+ 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(
6423
6473
  "cursor",
6424
6474
  onClickItem && quadrantTitleLineNumber ? "pointer" : "default"
6425
6475
  ).text(title);
@@ -6432,6 +6482,16 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6432
6482
  }
6433
6483
  }
6434
6484
  const chartG = svg.append("g").attr("transform", `translate(${margin.left}, ${margin.top})`);
6485
+ const mixHex = (a, b, pct) => {
6486
+ const parse = (h) => {
6487
+ const r = h.replace("#", "");
6488
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6489
+ return [parseInt(f.substring(0, 2), 16), parseInt(f.substring(2, 4), 16), parseInt(f.substring(4, 6), 16)];
6490
+ };
6491
+ const [ar, ag, ab] = parse(a), [br, bg, bb] = parse(b), t = pct / 100;
6492
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6493
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6494
+ };
6435
6495
  const getQuadrantFill = (label, defaultIdx) => {
6436
6496
  return label?.color ?? defaultColors[defaultIdx % defaultColors.length];
6437
6497
  };
@@ -6486,9 +6546,13 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6486
6546
  }
6487
6547
  ];
6488
6548
  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);
6489
- const contrastColor = isDark ? "#ffffff" : "#333333";
6490
- const shadowColor = isDark ? "rgba(0,0,0,0.3)" : "rgba(255,255,255,0.5)";
6491
- 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(
6549
+ const contrastColor = "#ffffff";
6550
+ const shadowColor = "rgba(0,0,0,0.4)";
6551
+ const getQuadrantLabelColor = (d) => {
6552
+ const fill2 = getQuadrantFill(d.label, d.colorIdx);
6553
+ return mixHex("#000000", fill2, 40);
6554
+ };
6555
+ 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(
6492
6556
  "cursor",
6493
6557
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
6494
6558
  ).text((d) => d.label.text);
@@ -6502,15 +6566,14 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6502
6566
  });
6503
6567
  }
6504
6568
  if (quadrantXAxis) {
6505
- 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(
6569
+ 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(
6506
6570
  "cursor",
6507
6571
  onClickItem && quadrantXAxisLineNumber ? "pointer" : "default"
6508
6572
  ).text(quadrantXAxis[0]);
6509
- 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(
6573
+ 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(
6510
6574
  "cursor",
6511
6575
  onClickItem && quadrantXAxisLineNumber ? "pointer" : "default"
6512
6576
  ).text(quadrantXAxis[1]);
6513
- svg.append("text").attr("x", width / 2).attr("y", height - 15).attr("text-anchor", "middle").attr("fill", mutedColor).attr("font-size", "12px").text("\u2192");
6514
6577
  if (onClickItem && quadrantXAxisLineNumber) {
6515
6578
  [xLowLabel, xHighLabel].forEach((label) => {
6516
6579
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
@@ -6522,15 +6585,16 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6522
6585
  }
6523
6586
  }
6524
6587
  if (quadrantYAxis) {
6525
- 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(
6588
+ const yMidBottom = margin.top + chartHeight * 3 / 4;
6589
+ const yMidTop = margin.top + chartHeight / 4;
6590
+ 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(
6526
6591
  "cursor",
6527
6592
  onClickItem && quadrantYAxisLineNumber ? "pointer" : "default"
6528
6593
  ).text(quadrantYAxis[0]);
6529
- 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(
6594
+ 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(
6530
6595
  "cursor",
6531
6596
  onClickItem && quadrantYAxisLineNumber ? "pointer" : "default"
6532
6597
  ).text(quadrantYAxis[1]);
6533
- 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");
6534
6598
  if (onClickItem && quadrantYAxisLineNumber) {
6535
6599
  [yLowLabel, yHighLabel].forEach((label) => {
6536
6600
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
@@ -6557,8 +6621,8 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem) {
6557
6621
  const quadDef = quadrantDefs.find((d) => d.position === quadrant);
6558
6622
  const pointColor = quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];
6559
6623
  const pointG = pointsG.append("g").attr("class", "point-group");
6560
- pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", contrastColor).attr("stroke", pointColor).attr("stroke-width", 2);
6561
- 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);
6624
+ pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", "#ffffff").attr("stroke", pointColor).attr("stroke-width", 2);
6625
+ 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);
6562
6626
  const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;
6563
6627
  pointG.style("cursor", onClickItem ? "pointer" : "default").on("mouseenter", (event) => {
6564
6628
  showTooltip(tooltip, tipHtml, event);
@@ -6600,7 +6664,11 @@ var EXPORT_WIDTH = 1200;
6600
6664
  var EXPORT_HEIGHT = 800;
6601
6665
  async function renderD3ForExport(content, theme, palette) {
6602
6666
  const parsed = parseD3(content, palette);
6603
- if (parsed.error) return "";
6667
+ if (parsed.error && parsed.type !== "sequence") {
6668
+ const looksLikeSequence2 = /->|~>|<-/.test(content);
6669
+ if (!looksLikeSequence2) return "";
6670
+ parsed.type = "sequence";
6671
+ }
6604
6672
  if (parsed.type === "wordcloud" && parsed.words.length === 0) return "";
6605
6673
  if (parsed.type === "slope" && parsed.data.length === 0) return "";
6606
6674
  if (parsed.type === "arc" && parsed.links.length === 0) return "";
@@ -6618,30 +6686,35 @@ async function renderD3ForExport(content, theme, palette) {
6618
6686
  container.style.position = "absolute";
6619
6687
  container.style.left = "-9999px";
6620
6688
  document.body.appendChild(container);
6689
+ const dims = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };
6621
6690
  try {
6622
6691
  if (parsed.type === "sequence") {
6623
6692
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
6624
6693
  const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer(), renderer_exports));
6625
6694
  const seqParsed = parseSequenceDgmo2(content);
6626
6695
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
6627
- renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark);
6696
+ renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
6697
+ exportWidth: EXPORT_WIDTH
6698
+ });
6628
6699
  } else if (parsed.type === "wordcloud") {
6629
- await renderWordCloudAsync(container, parsed, effectivePalette, isDark);
6700
+ await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);
6630
6701
  } else if (parsed.type === "arc") {
6631
- renderArcDiagram(container, parsed, effectivePalette, isDark);
6702
+ renderArcDiagram(container, parsed, effectivePalette, isDark, void 0, dims);
6632
6703
  } else if (parsed.type === "timeline") {
6633
- renderTimeline(container, parsed, effectivePalette, isDark);
6704
+ renderTimeline(container, parsed, effectivePalette, isDark, void 0, dims);
6634
6705
  } else if (parsed.type === "venn") {
6635
- renderVenn(container, parsed, effectivePalette, isDark);
6706
+ renderVenn(container, parsed, effectivePalette, isDark, void 0, dims);
6636
6707
  } else if (parsed.type === "quadrant") {
6637
- renderQuadrant(container, parsed, effectivePalette, isDark);
6708
+ renderQuadrant(container, parsed, effectivePalette, isDark, void 0, dims);
6638
6709
  } else {
6639
- renderSlopeChart(container, parsed, effectivePalette, isDark);
6710
+ renderSlopeChart(container, parsed, effectivePalette, isDark, void 0, dims);
6640
6711
  }
6641
6712
  const svgEl = container.querySelector("svg");
6642
6713
  if (!svgEl) return "";
6643
6714
  if (theme === "transparent") {
6644
6715
  svgEl.style.background = "none";
6716
+ } else if (!svgEl.style.background) {
6717
+ svgEl.style.background = effectivePalette.bg;
6645
6718
  }
6646
6719
  svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
6647
6720
  svgEl.style.fontFamily = FONT_FAMILY;