@office-kit/pptx-preview 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { S as shapeTextRect, _ as paragraphNumberLabels, a as renderSlideSvg, b as verticalTextStyle, d as SERIF, f as TIMES, g as decimalSeparatorOf, h as substituteFamily, i as renderSlideLayoutSvg, l as MONO, n as shapeTextAnchorOffset, o as renderTextEffectsSvg, p as defaultMeasurer, r as auditTextLayout, s as ARIAL, t as shapeAutoFitScale, u as SANS, v as textUnderlineStyle, x as resolveTextBodyRect, y as textColumnsStyle } from "./src-ayE1F9lH.js";
1
+ import { S as shapeTextRect, _ as paragraphNumberLabels, a as renderSlideSvg, b as verticalTextStyle, d as SERIF, f as TIMES, g as decimalSeparatorOf, h as substituteFamily, i as renderSlideLayoutSvg, l as MONO, n as shapeTextAnchorOffset, o as renderTextEffectsSvg, p as defaultMeasurer, r as auditTextLayout, s as ARIAL, t as shapeAutoFitScale, u as SANS, v as textUnderlineStyle, x as resolveTextBodyRect, y as textColumnsStyle } from "./src-BGzSNWjt.js";
2
2
  export { ARIAL, MONO, SANS, SERIF, TIMES, auditTextLayout, decimalSeparatorOf, defaultMeasurer, paragraphNumberLabels, renderSlideLayoutSvg as renderSlideLayoutToSvg, renderSlideSvg as renderSlideToSvg, renderTextEffectsSvg, resolveTextBodyRect, shapeAutoFitScale, shapeTextAnchorOffset, shapeTextRect, substituteFamily, textColumnsStyle, textUnderlineStyle, verticalTextStyle };
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { S as shapeTextRect, _ as paragraphNumberLabels, a as renderSlideSvg, b as verticalTextStyle, c as AVG_GLYPH_W_RATIO, d as SERIF, f as TIMES, g as decimalSeparatorOf, h as substituteFamily, i as renderSlideLayoutSvg, l as MONO, m as isCjk, n as shapeTextAnchorOffset, o as renderTextEffectsSvg, p as defaultMeasurer, r as auditTextLayout, s as ARIAL, t as shapeAutoFitScale, u as SANS, v as textUnderlineStyle, x as resolveTextBodyRect, y as textColumnsStyle } from "./src-ayE1F9lH.js";
1
+ import { S as shapeTextRect, _ as paragraphNumberLabels, a as renderSlideSvg, b as verticalTextStyle, c as AVG_GLYPH_W_RATIO, d as SERIF, f as TIMES, g as decimalSeparatorOf, h as substituteFamily, i as renderSlideLayoutSvg, l as MONO, m as isCjk, n as shapeTextAnchorOffset, o as renderTextEffectsSvg, p as defaultMeasurer, r as auditTextLayout, s as ARIAL, t as shapeAutoFitScale, u as SANS, v as textUnderlineStyle, x as resolveTextBodyRect, y as textColumnsStyle } from "./src-BGzSNWjt.js";
2
2
  import { getSlideSize } from "@office-kit/pptx";
3
3
  import { Resvg } from "@resvg/resvg-js";
4
4
  import * as fontkit from "fontkit";
@@ -2526,6 +2526,7 @@ const renderRun = (text, format, theme, effectivePt, defaultColor, _wasDefault =
2526
2526
  return `<span style="${styles.join(";")}">${content}</span>`;
2527
2527
  };
2528
2528
  const LINE_HEIGHT = 1.05;
2529
+ const NO_AUTOSPACE = "text-autospace:no-autospace;";
2529
2530
  const AUTOFIT_FLOOR = .25;
2530
2531
  const AUTOFIT_STEP = .05;
2531
2532
  const decimalSeparatorField = (lang) => {
@@ -3272,7 +3273,7 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
3272
3273
  const vertStyles = (writingMode ? `;${writingMode}${extraTransform}` : "") + colStyles;
3273
3274
  const wrapStyle = effectiveBody.wrap === "none" ? "white-space:nowrap" : "word-break:break-word";
3274
3275
  const content = paragraphs.join("");
3275
- const body = `<div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:visible;font-family:${effectiveDefaultFont};color:${defaultColor};${`translate:${model.anchorOffset.x}px ${model.anchorOffset.y}px;`}${wrapStyle}${vertStyles}">${content}</div>`;
3276
+ const body = `<div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:visible;font-family:${effectiveDefaultFont};color:${defaultColor};${NO_AUTOSPACE}${`translate:${model.anchorOffset.x}px ${model.anchorOffset.y}px;`}${wrapStyle}${vertStyles}">${content}</div>`;
3276
3277
  const foreign = `<foreignObject x="${E(innerX)}" y="${E(innerY)}" width="${E(innerW)}" height="${E(innerH)}" overflow="visible">${body}</foreignObject>`;
3277
3278
  const hasCharacterEffect = bevel !== null || paraData.some((para) => para.runs.some((run) => run.fmt?.reflection !== void 0 && run.fmt.reflection !== null || run.fmt?.innerShadow !== void 0 && run.fmt.innerShadow !== null || hasPaintedTextFill(run)));
3278
3279
  let reflectionOverlay = "";
@@ -3444,7 +3445,7 @@ const chartText = (f, x, y, attrs, content) => {
3444
3445
  }
3445
3446
  return `<text x="${px(x)}" y="${px(y)}" ${attrs}>${content}</text>`;
3446
3447
  };
3447
- const layoutChart = (xEmu, yEmu, wEmu, hEmu, hasTitle, hasAxes, titleOverlay = false, legendOverlay = false, hasLegend = true, titlePx = DEFAULT_CHART_TITLE_PT * PX_PER_PT, plotAreaLayout) => {
3448
+ const layoutChart = (xEmu, yEmu, wEmu, hEmu, hasTitle, hasAxes, titleOverlay = false, legendOverlay = false, hasLegend = true, titlePx = DEFAULT_CHART_TITLE_PT * PX_PER_PT, plotAreaLayout, yAxisGutter = hasAxes ? DEFAULT_Y_AXIS_GUTTER : 0, xAxisGutter = hasAxes ? BAR_VALUE_LABEL_ROW : 0) => {
3448
3449
  const x = xEmu / EMU_PER_PX;
3449
3450
  const y = yEmu / EMU_PER_PX;
3450
3451
  const w = wEmu / EMU_PER_PX;
@@ -3452,8 +3453,6 @@ const layoutChart = (xEmu, yEmu, wEmu, hEmu, hasTitle, hasAxes, titleOverlay = f
3452
3453
  const titleStrip = hasTitle && !titleOverlay ? Math.round(titlePx * 2.4) : 0;
3453
3454
  const legendStrip = hasLegend && !legendOverlay ? 18 : 0;
3454
3455
  const padding = 8;
3455
- const yAxisGutter = hasAxes ? 32 : 0;
3456
- const xAxisGutter = hasAxes ? 18 : 0;
3457
3456
  const inner = plotAreaLayout?.target === "inner" ? plotAreaLayout : void 0;
3458
3457
  const plotX = inner ? x + Math.max(0, Math.min(1, inner.x)) * w : x + padding + yAxisGutter;
3459
3458
  const plotY = inner ? y + Math.max(0, Math.min(1, inner.y)) * h : y + titleStrip + padding;
@@ -3566,9 +3565,10 @@ const DEFAULT_AXIS_COLOR = "#000000";
3566
3565
  const DEFAULT_GRID_COLOR = "#D9D9D9";
3567
3566
  const AXIS_TICK_LEN = 5;
3568
3567
  const AXIS_MINOR_TICK_LEN = 3;
3568
+ const AXIS_LABEL_GAP = 3;
3569
3569
  const chartFontPx = (sizePt) => (sizePt * PX_PER_PT).toFixed(1);
3570
3570
  const axisTickAttrs = (style) => {
3571
- const sz = style?.sizePt ?? 10;
3571
+ const sz = style?.sizePt ?? DEFAULT_AXIS_LABEL_PT;
3572
3572
  const fill = style?.color ?? "#6B7280";
3573
3573
  const weight = style?.bold ? " font-weight=\"600\"" : "";
3574
3574
  const italic = style?.italic ? " font-style=\"italic\"" : "";
@@ -3617,7 +3617,8 @@ const renderValueAxis = (f, axis) => {
3617
3617
  const tx2 = tickMark === "out" ? edgeX : edgeX + inward;
3618
3618
  out.push(`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="${axisColor}" stroke-width="1"/>`);
3619
3619
  }
3620
- const labelX = onRight ? edgeX + 4 : edgeX - 4;
3620
+ const labelOffset = (tickMark === "out" || tickMark === "cross" ? tickLen : 0) + AXIS_LABEL_GAP;
3621
+ const labelX = onRight ? edgeX + labelOffset : edgeX - labelOffset;
3621
3622
  const rot = axis.labelRotationDeg ?? 0;
3622
3623
  const transform = rot ? ` transform="rotate(${rot} ${px(labelX)} ${px(yp)})"` : "";
3623
3624
  out.push(chartText(f, labelX, yp, `text-anchor="${onRight ? "start" : "end"}" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}`, `${escapeXml(fmtTick(t))}`));
@@ -3638,20 +3639,81 @@ const renderValueAxis = (f, axis) => {
3638
3639
  if (axis.displayUnits) {
3639
3640
  const lbl = DISPLAY_UNIT_LABEL[axis.displayUnits];
3640
3641
  if (axis.orientation === "vertical") {
3641
- const lblX = f.plotX - 26;
3642
+ const lblX = axis.side === "right" ? f.plotX + f.plotW + 26 : f.plotX - 26;
3642
3643
  const lblY = f.plotY + f.plotH / 2;
3643
3644
  out.push(chartText(f, lblX, lblY, `text-anchor="middle" font-family="sans-serif" font-size="9" fill="#6B7280" font-style="italic" transform="rotate(-90 ${px(lblX)} ${px(lblY)})"`, `${escapeXml(lbl)}`));
3644
3645
  } else out.push(chartText(f, f.plotX + f.plotW, f.plotY + f.plotH + 22, `text-anchor="end" font-family="sans-serif" font-size="9" fill="#6B7280" font-style="italic"`, `${escapeXml(lbl)}`));
3645
3646
  }
3646
- if (!axis.lineHidden) if (axis.orientation === "vertical") out.push(`<line x1="${px(f.plotX)}" y1="${px(f.plotY)}" x2="${px(f.plotX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`);
3647
- else {
3647
+ if (!axis.lineHidden) if (axis.orientation === "vertical") {
3648
+ const spineX = axis.side === "right" ? f.plotX + f.plotW : f.plotX;
3649
+ out.push(`<line x1="${px(spineX)}" y1="${px(f.plotY)}" x2="${px(spineX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`);
3650
+ } else {
3648
3651
  const zeroY = f.plotY + f.plotH - (0 - axis.min) / range * f.plotH;
3649
3652
  const spineY = axis.min <= 0 && axis.max >= 0 ? zeroY : f.plotY + f.plotH;
3650
3653
  out.push(`<line x1="${px(f.plotX)}" y1="${px(spineY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(spineY)}" stroke="${axisColor}" stroke-width="1"/>`);
3651
3654
  }
3652
3655
  return out.join("");
3653
3656
  };
3654
- const renderCategoryAxis = (f, orientation, cats, pointCount, skip = 1, labelStyle, labelRotationDeg, labelAlign, lineColor, lineHidden = false, majorTickMark = "out", minorTickMark = "none") => {
3657
+ const CATEGORY_LABEL_GAP = 6;
3658
+ const CATEGORY_LABEL_LINE_HEIGHT = 1.2;
3659
+ const MAX_BAR_CATEGORY_LABEL_SHARE = .5;
3660
+ const DEFAULT_Y_AXIS_GUTTER = 32;
3661
+ const BAR_VALUE_LABEL_ROW = 18;
3662
+ const DEFAULT_AXIS_TITLE_PT = 11;
3663
+ const DEFAULT_AXIS_LABEL_PT = 10;
3664
+ const categoryLabelFontPx = (style) => (style?.sizePt ?? DEFAULT_AXIS_LABEL_PT) * PX_PER_PT;
3665
+ const axisTitleRowPx = (style) => (style?.sizePt ?? DEFAULT_AXIS_TITLE_PT) * PX_PER_PT * CATEGORY_LABEL_LINE_HEIGHT;
3666
+ const NO_LINE_START = /* @__PURE__ */ new Set("、。,.,.))]]」』】〉》%%!!??::;;ー〜…・");
3667
+ const chartLabelSegments = (text) => {
3668
+ const segments = [];
3669
+ let word = "";
3670
+ for (const ch of text) if (NO_LINE_START.has(ch) && word === "" && segments.length > 0) segments[segments.length - 1] += ch;
3671
+ else if (FULLWIDTH_CHAR_PATTERN.test(ch) && !NO_LINE_START.has(ch)) {
3672
+ if (word !== "") segments.push(word);
3673
+ segments.push(ch);
3674
+ word = "";
3675
+ } else {
3676
+ word += ch;
3677
+ if (/\s/u.test(ch)) {
3678
+ segments.push(word);
3679
+ word = "";
3680
+ }
3681
+ }
3682
+ if (word !== "") segments.push(word);
3683
+ return segments;
3684
+ };
3685
+ const wrapChartLabel = (text, maxPx, widthOf) => {
3686
+ const lines = [];
3687
+ let line = "";
3688
+ for (const segment of chartLabelSegments(text)) {
3689
+ if (line !== "" && widthOf((line + segment).trimEnd()) > maxPx) {
3690
+ lines.push(line.trimEnd());
3691
+ line = "";
3692
+ }
3693
+ line += segment;
3694
+ }
3695
+ if (line.trim() !== "") lines.push(line.trimEnd());
3696
+ return lines;
3697
+ };
3698
+ const layoutBarCategoryLabels = (spec, chartWidthPx, measure) => {
3699
+ const style = spec.categoryAxisLabelStyle;
3700
+ const font = {
3701
+ family: SANS,
3702
+ sizePx: categoryLabelFontPx(style),
3703
+ bold: style?.bold === true,
3704
+ italic: style?.italic === true,
3705
+ letterSpacingPx: 0
3706
+ };
3707
+ const widthOf = (text) => measure(text, font).widthPx;
3708
+ const labels = Array.from({ length: pointCount(spec) }, (_, i) => spec.categories[i] ?? (i + 1).toString());
3709
+ const maxPx = chartWidthPx * MAX_BAR_CATEGORY_LABEL_SHARE;
3710
+ const lines = labels.map((label) => wrapChartLabel(label, maxPx, widthOf));
3711
+ return {
3712
+ widthPx: Math.max(0, ...lines.flatMap((ls) => ls.map(widthOf))),
3713
+ lines
3714
+ };
3715
+ };
3716
+ const renderCategoryAxis = (f, orientation, cats, pointCount, skip = 1, labelStyle, labelRotationDeg, labelAlign, lineColor, lineHidden = false, majorTickMark = "out", minorTickMark = "none", wrappedLabels) => {
3655
3717
  const labels = [];
3656
3718
  for (let i = 0; i < pointCount; i++) labels.push(cats[i] ?? (i + 1).toString());
3657
3719
  const out = [];
@@ -3673,6 +3735,14 @@ const renderCategoryAxis = (f, orientation, cats, pointCount, skip = 1, labelSty
3673
3735
  for (let i = 0; i < pointCount; i++) {
3674
3736
  if (skip > 1 && i % skip !== 0) continue;
3675
3737
  const cy = f.plotY + (pointCount - 1 - i + .5) * step;
3738
+ const lines = wrappedLabels?.[i];
3739
+ if (lines) {
3740
+ const lx = f.plotX - CATEGORY_LABEL_GAP;
3741
+ const lineH = categoryLabelFontPx(labelStyle) * CATEGORY_LABEL_LINE_HEIGHT;
3742
+ const content = lines.length === 1 ? escapeXml(lines[0]) : lines.map((line, k) => `<tspan x="${px(lx)}" dy="${px(k === 0 ? -(lines.length - 1) * lineH / 2 : lineH)}">${escapeXml(line)}</tspan>`).join("");
3743
+ out.push(chartText(f, lx, cy, `text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(labelStyle)}`, content));
3744
+ continue;
3745
+ }
3676
3746
  const lx = f.plotX - 4;
3677
3747
  const truncated = labels[i] !== void 0 && labels[i].length > truncLen ? `${labels[i].slice(0, truncLen - 2)}…` : labels[i] ?? "";
3678
3748
  const transform = labelRotationDeg && labelRotationDeg !== 0 ? ` transform="rotate(${labelRotationDeg} ${px(lx)} ${px(cy)})"` : "";
@@ -3727,16 +3797,21 @@ const seriesMinMax = (spec) => {
3727
3797
  if (!Number.isFinite(min)) min = 0;
3728
3798
  if (!Number.isFinite(max)) max = 1;
3729
3799
  if (max === min) max = min + 1;
3730
- if (min > 0) min = 0;
3731
3800
  if (isPercent) return {
3732
3801
  min: 0,
3733
3802
  max: 1,
3734
3803
  step: .2
3735
3804
  };
3736
- const step = niceStep(max - min);
3737
- max = (Math.floor(max / step) + 1) * step;
3738
- if (spec.valueAxis?.min !== void 0) min = spec.valueAxis.min;
3739
- if (spec.valueAxis?.max !== void 0) max = spec.valueAxis.max;
3805
+ const authoredMin = spec.valueAxis?.min;
3806
+ const authoredMax = spec.valueAxis?.max;
3807
+ const lo = authoredMin ?? min;
3808
+ const hi = authoredMax ?? max;
3809
+ const pad = (hi - lo) / AUTO_AXIS_PAD_DIVISOR;
3810
+ const autoMin = lo < 0 ? lo - pad : lo >= hi * AUTO_AXIS_ZERO_THRESHOLD ? lo - pad : 0;
3811
+ const autoMax = hi > 0 ? hi + pad : hi <= lo * AUTO_AXIS_ZERO_THRESHOLD ? hi + pad : 0;
3812
+ const step = niceStep((authoredMax ?? autoMax) - (authoredMin ?? autoMin));
3813
+ min = authoredMin ?? snapToStep(autoMin, step, Math.floor);
3814
+ max = authoredMax ?? snapToStep(autoMax, step, Math.ceil);
3740
3815
  if (max === min) max = min + 1;
3741
3816
  return {
3742
3817
  min,
@@ -3744,6 +3819,10 @@ const seriesMinMax = (spec) => {
3744
3819
  step
3745
3820
  };
3746
3821
  };
3822
+ const AUTO_AXIS_PAD_DIVISOR = 20;
3823
+ const AUTO_AXIS_ZERO_THRESHOLD = 5 / 6;
3824
+ const AXIS_BOUND_PRECISION = 12;
3825
+ const snapToStep = (value, step, round) => Number((round(value / step) * step).toPrecision(AXIS_BOUND_PRECISION));
3747
3826
  const renderChartTitle = (f, title, style) => {
3748
3827
  if (!title) return "";
3749
3828
  const sz = style?.sizePt ?? DEFAULT_CHART_TITLE_PT;
@@ -4592,7 +4671,7 @@ const renderRadarChart = (f, spec, colors) => {
4592
4671
  }
4593
4672
  return out.join("");
4594
4673
  };
4595
- const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4674
+ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected, measure) => {
4596
4675
  let spec = null;
4597
4676
  try {
4598
4677
  spec = getShapeChartSpec(shape);
@@ -4612,10 +4691,13 @@ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4612
4691
  const isCartesian = spec.kind === "column" || spec.kind === "bar" || spec.kind === "line" || spec.kind === "area";
4613
4692
  const hasAxes = isCartesian || spec.kind === "scatter" || spec.kind === "bubble";
4614
4693
  const hasLegend = spec.legend !== void 0 && spec.legend.position !== null;
4694
+ const barLabels = spec.kind === "bar" && !spec.categoryAxisHidden && spec.categoryAxisTickLabelPos !== "none" && !spec.categoryAxisLabelRotationDeg ? layoutBarCategoryLabels(spec, w / EMU_PER_PX, measure) : void 0;
4695
+ const barValueTitleRow = spec.kind === "bar" && spec.valueAxisTitle ? axisTitleRowPx(spec.valueAxisTitleStyle) : 0;
4696
+ const barCategoryTitleRow = spec.kind === "bar" && spec.categoryAxisTitle ? axisTitleRowPx(spec.categoryAxisTitleStyle) : 0;
4615
4697
  const flip = getShapeFlip(shape);
4616
4698
  const f = {
4617
4699
  reflected: groupReflected !== Boolean(flip && flip.horizontal !== flip.vertical),
4618
- ...layoutChart(x, y, w, h, !!spec.title, hasAxes, spec.titleOverlay ?? false, spec.legend?.overlay ?? false, hasLegend, (spec.titleStyle?.sizePt ?? DEFAULT_CHART_TITLE_PT) * PX_PER_PT, spec.plotAreaLayout)
4700
+ ...layoutChart(x, y, w, h, !!spec.title, hasAxes, spec.titleOverlay ?? false, spec.legend?.overlay ?? false, hasLegend, (spec.titleStyle?.sizePt ?? DEFAULT_CHART_TITLE_PT) * PX_PER_PT, spec.plotAreaLayout, barLabels ? Math.max(DEFAULT_Y_AXIS_GUTTER, barLabels.widthPx + CATEGORY_LABEL_GAP) + barCategoryTitleRow : void 0, barValueTitleRow > 0 ? BAR_VALUE_LABEL_ROW + barValueTitleRow : void 0)
4619
4701
  };
4620
4702
  const allNamesForLegend = spec.kind === "pie" || spec.kind === "doughnut" ? Array.from(spec.categories) : spec.series.map((s) => s.name);
4621
4703
  const allColorsForLegend = spec.kind === "pie" || spec.kind === "doughnut" ? spec.categories.map((_, i) => spec.series[0]?.pointColors?.[i] ?? spec.series[0]?.color ?? colors[i % colors.length] ?? "#888") : spec.series.map((s, i) => s.color ?? colors[i % colors.length] ?? "#888");
@@ -4640,10 +4722,11 @@ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4640
4722
  ...spec,
4641
4723
  series: primarySeries
4642
4724
  });
4643
- const { valueAxis: _primaryOnlyAxis, ...specWithoutAxis } = spec;
4725
+ const secondaryAxis = spec.secondaryValueAxis;
4644
4726
  const secondaryScale = secondarySeries.length > 0 ? seriesMinMax({
4645
- ...specWithoutAxis,
4646
- series: secondarySeries
4727
+ ...spec,
4728
+ series: secondarySeries,
4729
+ valueAxis: secondaryAxis ?? {}
4647
4730
  }) : null;
4648
4731
  const N = pointCount(spec);
4649
4732
  if (!spec.valueAxisHidden) axes = renderValueAxis(f, {
@@ -4662,14 +4745,20 @@ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4662
4745
  ...spec.valueAxisMajorGridlines !== void 0 ? { majorGridlines: spec.valueAxisMajorGridlines } : {},
4663
4746
  ...spec.valueAxisLabelStyle !== void 0 ? { labelStyle: spec.valueAxisLabelStyle } : {}
4664
4747
  });
4665
- if (secondaryScale) axes += renderValueAxis(f, {
4748
+ const secondaryLabelStyle = secondaryAxis?.labelStyle ?? spec.valueAxisLabelStyle;
4749
+ if (secondaryScale && secondaryAxis?.tickLabelPos !== "none") axes += renderValueAxis(f, {
4666
4750
  orientation: "vertical",
4667
4751
  side: "right",
4668
4752
  min: secondaryScale.min,
4669
4753
  max: secondaryScale.max,
4670
- majorUnit: secondaryScale.step,
4671
- majorGridlines: false,
4672
- ...spec.valueAxisLabelStyle !== void 0 ? { labelStyle: spec.valueAxisLabelStyle } : {}
4754
+ majorUnit: secondaryAxis?.majorUnit ?? secondaryScale.step,
4755
+ majorGridlines: secondaryAxis?.majorGridlines ?? false,
4756
+ ...secondaryAxis?.numberFormat !== void 0 ? { numberFormat: secondaryAxis.numberFormat } : {},
4757
+ ...secondaryAxis?.displayUnits !== void 0 ? { displayUnits: secondaryAxis.displayUnits } : {},
4758
+ ...secondaryAxis?.majorGridlineColor !== void 0 ? { majorGridlineColor: secondaryAxis.majorGridlineColor } : {},
4759
+ ...secondaryAxis?.majorTickMark !== void 0 ? { majorTickMark: secondaryAxis.majorTickMark } : {},
4760
+ ...secondaryAxis?.lineColor !== void 0 ? { lineColor: secondaryAxis.lineColor } : {},
4761
+ ...secondaryLabelStyle !== void 0 ? { labelStyle: secondaryLabelStyle } : {}
4673
4762
  });
4674
4763
  if (N > 0 && !(spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none")) axes += renderCategoryAxis(f, "horizontal", spec.categories, N, spec.categoryAxisTickLabelSkip ?? 1, spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg, spec.categoryAxisLabelAlign, spec.categoryAxisLineColor, spec.categoryAxisLineHidden, spec.categoryAxisMajorTickMark, spec.categoryAxisMinorTickMark);
4675
4764
  const groups = /* @__PURE__ */ new Map();
@@ -4737,7 +4826,7 @@ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4737
4826
  };
4738
4827
  if (!spec.valueAxisHidden) axes = renderValueAxis(f, valueAxis);
4739
4828
  const labelsHidden = spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none";
4740
- if (N > 0 && !labelsHidden) axes += renderCategoryAxis(f, spec.kind === "bar" ? "vertical" : "horizontal", spec.categories, N, spec.categoryAxisTickLabelSkip ?? 1, spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg, spec.categoryAxisLabelAlign, spec.categoryAxisLineColor, spec.categoryAxisLineHidden, spec.categoryAxisMajorTickMark, spec.categoryAxisMinorTickMark);
4829
+ if (N > 0 && !labelsHidden) axes += renderCategoryAxis(f, spec.kind === "bar" ? "vertical" : "horizontal", spec.categories, N, spec.categoryAxisTickLabelSkip ?? 1, spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg, spec.categoryAxisLabelAlign, spec.categoryAxisLineColor, spec.categoryAxisLineHidden, spec.categoryAxisMajorTickMark, spec.categoryAxisMinorTickMark, barLabels?.lines);
4741
4830
  }
4742
4831
  if (!isCombo) switch (spec.kind) {
4743
4832
  case "column":
@@ -4769,19 +4858,30 @@ const renderChart = (shape, x, y, w, h, transform, theme, groupReflected) => {
4769
4858
  }
4770
4859
  const emptyHint = finiteCount === 0 ? chartText(f, f.plotX + f.plotW / 2, f.plotY + f.plotH / 2, `text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="12" fill="#9CA3AF"`, `${escapeXml(`chart (${spec.kind}) — no data`)}`) : "";
4771
4860
  const axisTitleAttrs = (style) => {
4772
- const sz = style?.sizePt ?? 11;
4861
+ const sz = style?.sizePt ?? DEFAULT_AXIS_TITLE_PT;
4773
4862
  const fill = style?.color ?? "#374151";
4774
4863
  const weight = style?.bold === false ? "400" : "600";
4775
4864
  const italicAttr = style?.italic ? " font-style=\"italic\"" : "";
4776
4865
  return `font-family="sans-serif" font-size="${chartFontPx(sz)}" fill="${fill}" font-weight="${weight}"${italicAttr}`;
4777
4866
  };
4778
- const valueAxisTitleRot = spec.valueAxisTitleRotationDeg ?? -90;
4779
- const valueAxisTitleSvg = spec.valueAxisTitle ? chartText(f, f.plotX - 26, f.plotY + f.plotH / 2, `text-anchor="middle" ${axisTitleAttrs(spec.valueAxisTitleStyle)} transform="rotate(${valueAxisTitleRot} ${px(f.plotX - 26)} ${px(f.plotY + f.plotH / 2)})"`, `${escapeXml(spec.valueAxisTitle)}`) : "";
4780
- const catTitleRot = spec.categoryAxisTitleRotationDeg ?? 0;
4781
- const catTitleCx = f.plotX + f.plotW / 2;
4782
- const catTitleCy = f.plotY + f.plotH + 28;
4783
- const catTitleTransform = catTitleRot !== 0 ? ` transform="rotate(${catTitleRot} ${px(catTitleCx)} ${px(catTitleCy)})"` : "";
4784
- const categoryAxisTitleSvg = spec.categoryAxisTitle ? chartText(f, catTitleCx, catTitleCy, `text-anchor="middle" ${axisTitleAttrs(spec.categoryAxisTitleStyle)}${catTitleTransform}`, `${escapeXml(spec.categoryAxisTitle)}`) : "";
4867
+ const bottomTitle = {
4868
+ x: f.plotX + f.plotW / 2,
4869
+ y: f.plotY + f.plotH + 28
4870
+ };
4871
+ const sideTitle = {
4872
+ x: barLabels ? f.plotX - CATEGORY_LABEL_GAP - barLabels.widthPx - barCategoryTitleRow / 2 : f.plotX - 26,
4873
+ y: f.plotY + f.plotH / 2
4874
+ };
4875
+ const isBar = spec.kind === "bar";
4876
+ const axisTitleSvg = (title, style, rotationDeg, side) => {
4877
+ if (!title) return "";
4878
+ const at = side ? sideTitle : bottomTitle;
4879
+ const rot = rotationDeg ?? (side ? -90 : 0);
4880
+ const transform = rot !== 0 ? ` transform="rotate(${rot} ${px(at.x)} ${px(at.y)})"` : "";
4881
+ return chartText(f, at.x, at.y, `text-anchor="middle" ${axisTitleAttrs(style)}${transform}`, escapeXml(title));
4882
+ };
4883
+ const valueAxisTitleSvg = axisTitleSvg(spec.valueAxisTitle, spec.valueAxisTitleStyle, spec.valueAxisTitleRotationDeg, !isBar);
4884
+ const categoryAxisTitleSvg = axisTitleSvg(spec.categoryAxisTitle, spec.categoryAxisTitleStyle, spec.categoryAxisTitleRotationDeg, isBar);
4785
4885
  return [
4786
4886
  `<g${transform}>`,
4787
4887
  `<rect x="${px(f.x)}" y="${px(f.y)}" width="${px(f.w)}" height="${px(f.h)}" fill="${spec.chartAreaFill ?? "#FFFFFF"}" stroke="${spec.chartAreaStrokeColor ?? "none"}" stroke-width="0.6"${spec.roundedCorners ? " rx=\"6\" ry=\"6\"" : ""}/>`,
@@ -4929,7 +5029,7 @@ const renderTableCellText = (cell, paragraphs, cx, cy, cw, ch, color, pres, shap
4929
5029
  const justify = vAnchor === "top" ? "flex-start" : vAnchor === "bottom" ? "flex-end" : "center";
4930
5030
  const familyFont = escapeXml(browserFontFamily(themeFace));
4931
5031
  const body = renderHtmlParagraphs(paraData, numberLabels, theme, 1, DEFAULT_BODY_PT, color).join("");
4932
- return `<foreignObject x="${px(innerX)}" y="${px(innerY)}" width="${px(innerW)}" height="${px(innerH)}"><div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:hidden;line-height:${LINE_HEIGHT};font-family:${familyFont};color:${color};word-break:break-word;${directionStyle}">${body}</div></foreignObject>${fillOverlay()}${bevelOverlay()}`;
5032
+ return `<foreignObject x="${px(innerX)}" y="${px(innerY)}" width="${px(innerW)}" height="${px(innerH)}"><div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:hidden;line-height:${LINE_HEIGHT};font-family:${familyFont};color:${color};${NO_AUTOSPACE}word-break:break-word;${directionStyle}">${body}</div></foreignObject>${fillOverlay()}${bevelOverlay()}`;
4933
5033
  };
4934
5034
  const TWO_STOP_TABLE_GRADIENT_EXPONENT = 1.85;
4935
5035
  const TWO_STOP_TABLE_GRADIENT_SAMPLES = 16;
@@ -5516,7 +5616,7 @@ const renderShapeContent = (shape, pres, theme, ctx) => {
5516
5616
  }
5517
5617
  if (kind === "graphicFrame") {
5518
5618
  if (isChartShape(shape)) {
5519
- const chartSvg = renderChart(shape, x, y, w, h, transform, theme, ctx.groupReflected);
5619
+ const chartSvg = renderChart(shape, x, y, w, h, transform, theme, ctx.groupReflected, ctx.measure);
5520
5620
  if (chartSvg) return chartSvg;
5521
5621
  }
5522
5622
  if (isTableShape(shape)) {
@@ -6216,4 +6316,4 @@ function shapeTextAnchorOffset(pres, shape, options = {}) {
6216
6316
  //#endregion
6217
6317
  export { shapeTextRect as S, paragraphNumberLabels as _, renderSlideSvg as a, verticalTextStyle as b, AVG_GLYPH_W_RATIO as c, SERIF as d, TIMES as f, decimalSeparatorOf as g, substituteFamily as h, renderSlideLayoutSvg as i, MONO as l, isCjk as m, shapeTextAnchorOffset as n, renderTextEffectsSvg as o, defaultMeasurer as p, auditTextLayout as r, ARIAL as s, shapeAutoFitScale as t, SANS as u, textUnderlineStyle as v, resolveTextBodyRect as x, textColumnsStyle as y };
6218
6318
 
6219
- //# sourceMappingURL=src-ayE1F9lH.js.map
6319
+ //# sourceMappingURL=src-BGzSNWjt.js.map