pptx-kit-preview 0.3.1 → 0.3.2
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 +124 -124
- package/dist/index.js.map +1 -1
- package/dist/node.js +124 -124
- package/dist/node.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -603,27 +603,23 @@ var patternDef = (pat) => {
|
|
|
603
603
|
return `<path d="M0 0L${W} ${H}" stroke="${fg}" stroke-width="${width}"/>`;
|
|
604
604
|
return `<path d="M${W} 0L0 ${H}" stroke="${fg}" stroke-width="${width}"/>`;
|
|
605
605
|
};
|
|
606
|
-
const
|
|
607
|
-
|
|
606
|
+
const BAYER4 = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];
|
|
607
|
+
const screen = (density) => {
|
|
608
|
+
const threshold = density * 16;
|
|
608
609
|
const out = [];
|
|
609
|
-
|
|
610
|
-
[
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
[2, 6],
|
|
616
|
-
[6, 6]
|
|
617
|
-
];
|
|
618
|
-
for (const [x, y] of grid.slice(0, count)) {
|
|
619
|
-
out.push(`<circle cx="${x}" cy="${y}" r="0.7" fill="${fg}"/>`);
|
|
610
|
+
for (let i = 0; i < 16; i++) {
|
|
611
|
+
if (BAYER4[i] < threshold) {
|
|
612
|
+
const cx = i % 4 * 2;
|
|
613
|
+
const cy = Math.floor(i / 4) * 2;
|
|
614
|
+
out.push(`<rect x="${cx}" y="${cy}" width="2" height="2" fill="${fg}"/>`);
|
|
615
|
+
}
|
|
620
616
|
}
|
|
621
617
|
return out.join("");
|
|
622
618
|
};
|
|
623
619
|
const pctMatch = /^pct(\d+)$/.exec(preset);
|
|
624
620
|
if (pctMatch) {
|
|
625
|
-
const pct = Math.min(100, Math.max(
|
|
626
|
-
body =
|
|
621
|
+
const pct = Math.min(100, Math.max(0, Number.parseInt(pctMatch[1], 10)));
|
|
622
|
+
body = screen(pct / 100);
|
|
627
623
|
} else if (preset === "horzBrick" || preset === "ltHorizontal" || preset === "narHorz") {
|
|
628
624
|
body = stripe("h", 0.8);
|
|
629
625
|
} else if (preset === "dkHorizontal") {
|
|
@@ -657,7 +653,7 @@ var patternDef = (pat) => {
|
|
|
657
653
|
} else if (preset === "solidDmnd" || preset === "openDmnd") {
|
|
658
654
|
body = `<path d="M4 1L7 4 4 7 1 4Z" fill="${preset === "solidDmnd" ? fg : "none"}" stroke="${fg}" stroke-width="0.6"/>`;
|
|
659
655
|
} else {
|
|
660
|
-
body =
|
|
656
|
+
body = screen(0.5);
|
|
661
657
|
}
|
|
662
658
|
const defs = `<defs><pattern id="${id}" patternUnits="userSpaceOnUse" width="${W}" height="${H}"><rect width="${W}" height="${H}" fill="${bg}"/>${body}</pattern></defs>`;
|
|
663
659
|
return { defs, fillAttr: `url(#${id})` };
|
|
@@ -2516,6 +2512,9 @@ var DISPLAY_UNIT_LABEL = {
|
|
|
2516
2512
|
billions: "Billions",
|
|
2517
2513
|
trillions: "Trillions"
|
|
2518
2514
|
};
|
|
2515
|
+
var DEFAULT_AXIS_COLOR = "#000000";
|
|
2516
|
+
var DEFAULT_GRID_COLOR = "#D9D9D9";
|
|
2517
|
+
var AXIS_TICK_LEN = 5;
|
|
2519
2518
|
var axisTickAttrs = (style) => {
|
|
2520
2519
|
const sz = style?.sizePt ?? 10;
|
|
2521
2520
|
const fill = style?.color ?? "#6B7280";
|
|
@@ -2532,10 +2531,15 @@ var renderValueAxis = (f, axis) => {
|
|
|
2532
2531
|
})() : niceTicks(axis.min, axis.max);
|
|
2533
2532
|
const out = [];
|
|
2534
2533
|
const range = axis.max - axis.min || 1;
|
|
2535
|
-
const
|
|
2536
|
-
|
|
2534
|
+
const fmtTick = (t) => axis.percent ? `${Math.round(t * 100)}%` : formatAxisLabel(
|
|
2535
|
+
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2536
|
+
axis.numberFormat
|
|
2537
|
+
);
|
|
2538
|
+
const showGrid = axis.majorGridlines ?? false;
|
|
2539
|
+
const gridStroke = axis.majorGridlineColor ?? DEFAULT_GRID_COLOR;
|
|
2540
|
+
const axisColor = axis.lineColor ?? DEFAULT_AXIS_COLOR;
|
|
2537
2541
|
const tickMark = axis.majorTickMark ?? "out";
|
|
2538
|
-
const tickLen =
|
|
2542
|
+
const tickLen = AXIS_TICK_LEN;
|
|
2539
2543
|
for (const t of ticks) {
|
|
2540
2544
|
if (axis.orientation === "vertical") {
|
|
2541
2545
|
const yp = f.plotY + f.plotH - (t - axis.min) / range * f.plotH;
|
|
@@ -2548,19 +2552,14 @@ var renderValueAxis = (f, axis) => {
|
|
|
2548
2552
|
const tx1 = tickMark === "in" ? f.plotX : f.plotX - tickLen;
|
|
2549
2553
|
const tx2 = tickMark === "out" ? f.plotX : tickMark === "cross" ? f.plotX + tickLen : f.plotX + tickLen;
|
|
2550
2554
|
out.push(
|
|
2551
|
-
`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="
|
|
2555
|
+
`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2552
2556
|
);
|
|
2553
2557
|
}
|
|
2554
2558
|
const labelX = f.plotX - 4;
|
|
2555
2559
|
const rot = axis.labelRotationDeg ?? 0;
|
|
2556
2560
|
const transform = rot ? ` transform="rotate(${rot} ${px(labelX)} ${px(yp)})"` : "";
|
|
2557
2561
|
out.push(
|
|
2558
|
-
`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml2(
|
|
2559
|
-
formatAxisLabel(
|
|
2560
|
-
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2561
|
-
axis.numberFormat
|
|
2562
|
-
)
|
|
2563
|
-
)}</text>`
|
|
2562
|
+
`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml2(fmtTick(t))}</text>`
|
|
2564
2563
|
);
|
|
2565
2564
|
} else {
|
|
2566
2565
|
const xp = f.plotX + (t - axis.min) / range * f.plotW;
|
|
@@ -2574,19 +2573,14 @@ var renderValueAxis = (f, axis) => {
|
|
|
2574
2573
|
const ty1 = tickMark === "in" ? baseY : baseY + tickLen;
|
|
2575
2574
|
const ty2 = tickMark === "out" ? baseY : tickMark === "cross" ? baseY - tickLen : baseY - tickLen;
|
|
2576
2575
|
out.push(
|
|
2577
|
-
`<line x1="${px(xp)}" y1="${px(ty1)}" x2="${px(xp)}" y2="${px(ty2)}" stroke="
|
|
2576
|
+
`<line x1="${px(xp)}" y1="${px(ty1)}" x2="${px(xp)}" y2="${px(ty2)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2578
2577
|
);
|
|
2579
2578
|
}
|
|
2580
2579
|
const horizLabelY = f.plotY + f.plotH + 12;
|
|
2581
2580
|
const rotH = axis.labelRotationDeg ?? 0;
|
|
2582
2581
|
const transformH = rotH ? ` transform="rotate(${rotH} ${px(xp)} ${px(horizLabelY)})"` : "";
|
|
2583
2582
|
out.push(
|
|
2584
|
-
`<text x="${px(xp)}" y="${px(horizLabelY)}" text-anchor="middle" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transformH}>${escapeXml2(
|
|
2585
|
-
formatAxisLabel(
|
|
2586
|
-
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2587
|
-
axis.numberFormat
|
|
2588
|
-
)
|
|
2589
|
-
)}</text>`
|
|
2583
|
+
`<text x="${px(xp)}" y="${px(horizLabelY)}" text-anchor="middle" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transformH}>${escapeXml2(fmtTick(t))}</text>`
|
|
2590
2584
|
);
|
|
2591
2585
|
}
|
|
2592
2586
|
}
|
|
@@ -2604,16 +2598,16 @@ var renderValueAxis = (f, axis) => {
|
|
|
2604
2598
|
);
|
|
2605
2599
|
}
|
|
2606
2600
|
}
|
|
2607
|
-
if (axis.
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
)
|
|
2616
|
-
|
|
2601
|
+
if (axis.orientation === "vertical") {
|
|
2602
|
+
out.push(
|
|
2603
|
+
`<line x1="${px(f.plotX)}" y1="${px(f.plotY)}" x2="${px(f.plotX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2604
|
+
);
|
|
2605
|
+
} else {
|
|
2606
|
+
const zeroY = f.plotY + f.plotH - (0 - axis.min) / range * f.plotH;
|
|
2607
|
+
const spineY = axis.min <= 0 && axis.max >= 0 ? zeroY : f.plotY + f.plotH;
|
|
2608
|
+
out.push(
|
|
2609
|
+
`<line x1="${px(f.plotX)}" y1="${px(spineY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(spineY)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2610
|
+
);
|
|
2617
2611
|
}
|
|
2618
2612
|
return out.join("");
|
|
2619
2613
|
};
|
|
@@ -2642,7 +2636,7 @@ var renderCategoryAxis = (f, orientation, cats, pointCount2, skip = 1, labelStyl
|
|
|
2642
2636
|
const truncLen = labelRotationDeg && Math.abs(labelRotationDeg) >= 30 ? 28 : 14;
|
|
2643
2637
|
for (let i = 0; i < pointCount2; i++) {
|
|
2644
2638
|
if (skip > 1 && i % skip !== 0) continue;
|
|
2645
|
-
const cy = f.plotY + (i + 0.5) * step;
|
|
2639
|
+
const cy = f.plotY + (pointCount2 - 1 - i + 0.5) * step;
|
|
2646
2640
|
const lx = f.plotX - 4;
|
|
2647
2641
|
const truncated = labels[i] !== void 0 && labels[i].length > truncLen ? `${labels[i].slice(0, truncLen - 2)}\u2026` : labels[i] ?? "";
|
|
2648
2642
|
const transform = labelRotationDeg && labelRotationDeg !== 0 ? ` transform="rotate(${labelRotationDeg} ${px(lx)} ${px(cy)})"` : "";
|
|
@@ -2651,27 +2645,63 @@ var renderCategoryAxis = (f, orientation, cats, pointCount2, skip = 1, labelStyl
|
|
|
2651
2645
|
);
|
|
2652
2646
|
}
|
|
2653
2647
|
}
|
|
2654
|
-
|
|
2655
|
-
|
|
2648
|
+
const axisColor = lineColor ?? DEFAULT_AXIS_COLOR;
|
|
2649
|
+
if (orientation === "horizontal") {
|
|
2650
|
+
const baseY = f.plotY + f.plotH;
|
|
2651
|
+
out.push(
|
|
2652
|
+
`<line x1="${px(f.plotX)}" y1="${px(baseY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(baseY)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2653
|
+
);
|
|
2654
|
+
const stepB = pointCount2 > 0 ? f.plotW / pointCount2 : 0;
|
|
2655
|
+
for (let i = 0; i <= pointCount2; i++) {
|
|
2656
|
+
const bx = f.plotX + i * stepB;
|
|
2656
2657
|
out.push(
|
|
2657
|
-
`<line x1="${px(
|
|
2658
|
+
`<line x1="${px(bx)}" y1="${px(baseY)}" x2="${px(bx)}" y2="${px(baseY + AXIS_TICK_LEN)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2658
2659
|
);
|
|
2659
|
-
}
|
|
2660
|
+
}
|
|
2661
|
+
} else {
|
|
2662
|
+
out.push(
|
|
2663
|
+
`<line x1="${px(f.plotX)}" y1="${px(f.plotY)}" x2="${px(f.plotX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2664
|
+
);
|
|
2665
|
+
const stepB = pointCount2 > 0 ? f.plotH / pointCount2 : 0;
|
|
2666
|
+
for (let i = 0; i <= pointCount2; i++) {
|
|
2667
|
+
const by = f.plotY + i * stepB;
|
|
2660
2668
|
out.push(
|
|
2661
|
-
`<line x1="${px(f.plotX)}" y1="${px(
|
|
2669
|
+
`<line x1="${px(f.plotX - AXIS_TICK_LEN)}" y1="${px(by)}" x2="${px(f.plotX)}" y2="${px(by)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2662
2670
|
);
|
|
2663
2671
|
}
|
|
2664
2672
|
}
|
|
2665
2673
|
return out.join("");
|
|
2666
2674
|
};
|
|
2667
2675
|
var seriesMinMax = (spec) => {
|
|
2676
|
+
const isStacked = spec.grouping === "stacked" || spec.grouping === "percentStacked";
|
|
2677
|
+
const isPercent = spec.grouping === "percentStacked";
|
|
2668
2678
|
let min = Infinity;
|
|
2669
2679
|
let max = -Infinity;
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2680
|
+
if (isPercent) {
|
|
2681
|
+
min = 0;
|
|
2682
|
+
max = 1;
|
|
2683
|
+
} else if (isStacked) {
|
|
2684
|
+
const N = spec.series.reduce((n, s) => Math.max(n, s.values.length), 0);
|
|
2685
|
+
for (let c = 0; c < N; c++) {
|
|
2686
|
+
let pos = 0;
|
|
2687
|
+
let neg = 0;
|
|
2688
|
+
for (const s of spec.series) {
|
|
2689
|
+
const v = s.values[c];
|
|
2690
|
+
if (v !== null && v !== void 0 && Number.isFinite(v)) {
|
|
2691
|
+
if (v >= 0) pos += v;
|
|
2692
|
+
else neg += v;
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
if (pos > max) max = pos;
|
|
2696
|
+
if (neg < min) min = neg;
|
|
2697
|
+
}
|
|
2698
|
+
} else {
|
|
2699
|
+
for (const s of spec.series) {
|
|
2700
|
+
for (const v of s.values) {
|
|
2701
|
+
if (v !== null && Number.isFinite(v)) {
|
|
2702
|
+
if (v < min) min = v;
|
|
2703
|
+
if (v > max) max = v;
|
|
2704
|
+
}
|
|
2675
2705
|
}
|
|
2676
2706
|
}
|
|
2677
2707
|
}
|
|
@@ -2679,6 +2709,9 @@ var seriesMinMax = (spec) => {
|
|
|
2679
2709
|
if (!Number.isFinite(max)) max = 1;
|
|
2680
2710
|
if (max === min) max = min + 1;
|
|
2681
2711
|
if (min > 0) min = 0;
|
|
2712
|
+
if (isPercent) {
|
|
2713
|
+
return { min: 0, max: 1, step: 0.2 };
|
|
2714
|
+
}
|
|
2682
2715
|
const step = niceStep(max - min);
|
|
2683
2716
|
max = (Math.floor(max / step) + 1) * step;
|
|
2684
2717
|
if (spec.valueAxis?.min !== void 0) min = spec.valueAxis.min;
|
|
@@ -2704,9 +2737,9 @@ var renderChartLegend = (f, names, colors, position = "b", textStyle, markerSymb
|
|
|
2704
2737
|
const swatch = (i, swatchX, swatchY) => {
|
|
2705
2738
|
const color = colors[i % colors.length];
|
|
2706
2739
|
const sym = markerSymbols?.[i];
|
|
2707
|
-
if (
|
|
2740
|
+
if (markerSymbols !== void 0 && sym !== "none") {
|
|
2708
2741
|
const r = 4.5;
|
|
2709
|
-
return seriesMarker(sym, swatchX + r, swatchY + r, r, color);
|
|
2742
|
+
return seriesMarker(autoMarkerSymbol(sym, i), swatchX + r, swatchY + r, r, color);
|
|
2710
2743
|
}
|
|
2711
2744
|
return `<rect x="${px(swatchX)}" y="${px(swatchY)}" width="9" height="9" fill="${color}"/>`;
|
|
2712
2745
|
};
|
|
@@ -2769,24 +2802,7 @@ var renderColumnChart = (f, spec, colors) => {
|
|
|
2769
2802
|
const grouping = spec.grouping ?? "clustered";
|
|
2770
2803
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
2771
2804
|
const isPercent = grouping === "percentStacked";
|
|
2772
|
-
|
|
2773
|
-
if (isStacked) {
|
|
2774
|
-
let sumMin = Infinity;
|
|
2775
|
-
let sumMax = -Infinity;
|
|
2776
|
-
for (let c = 0; c < N; c++) {
|
|
2777
|
-
let pos = 0;
|
|
2778
|
-
let neg = 0;
|
|
2779
|
-
for (const s of spec.series) {
|
|
2780
|
-
const v = s.values[c] ?? 0;
|
|
2781
|
-
if (v >= 0) pos += v;
|
|
2782
|
-
else neg += v;
|
|
2783
|
-
}
|
|
2784
|
-
if (neg < sumMin) sumMin = neg;
|
|
2785
|
-
if (pos > sumMax) sumMax = pos;
|
|
2786
|
-
}
|
|
2787
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
2788
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
2789
|
-
}
|
|
2805
|
+
const { min, max } = seriesMinMax(spec);
|
|
2790
2806
|
const range = max - min || 1;
|
|
2791
2807
|
const groupW = f.plotW / N;
|
|
2792
2808
|
const gapPctC = (spec.gapWidthPct ?? 150) / 100;
|
|
@@ -2819,7 +2835,7 @@ var renderColumnChart = (f, spec, colors) => {
|
|
|
2819
2835
|
const y1 = f.plotY + f.plotH - (Math.min(stackedTop, stackedBase) - min) / range * f.plotH;
|
|
2820
2836
|
const h = Math.abs(y1 - y0);
|
|
2821
2837
|
out.push(
|
|
2822
|
-
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(barW)}" height="${px(h)}" fill="${colors[s % colors.length]}"/>`
|
|
2838
|
+
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(barW)}" height="${px(h)}" fill="${spec.series[s]?.color ?? colors[s % colors.length]}"/>`
|
|
2823
2839
|
);
|
|
2824
2840
|
if (showLabelFor(s) && Math.abs(v) > 0) {
|
|
2825
2841
|
const labelY = (y0 + y1) / 2 + 3;
|
|
@@ -2993,6 +3009,17 @@ var smoothPath = (pts) => {
|
|
|
2993
3009
|
}
|
|
2994
3010
|
return parts.join(" ");
|
|
2995
3011
|
};
|
|
3012
|
+
var AUTO_MARKER_SYMBOLS = [
|
|
3013
|
+
"diamond",
|
|
3014
|
+
"square",
|
|
3015
|
+
"triangle",
|
|
3016
|
+
"x",
|
|
3017
|
+
"star",
|
|
3018
|
+
"dot",
|
|
3019
|
+
"plus",
|
|
3020
|
+
"dash"
|
|
3021
|
+
];
|
|
3022
|
+
var autoMarkerSymbol = (symbol, seriesIdx) => symbol !== void 0 && symbol !== "auto" ? symbol : AUTO_MARKER_SYMBOLS[seriesIdx % AUTO_MARKER_SYMBOLS.length];
|
|
2996
3023
|
var seriesMarker = (symbol, cx, cy, r, color) => {
|
|
2997
3024
|
switch (symbol) {
|
|
2998
3025
|
case "square":
|
|
@@ -3054,24 +3081,7 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3054
3081
|
const grouping = spec.grouping ?? "clustered";
|
|
3055
3082
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
3056
3083
|
const isPercent = grouping === "percentStacked";
|
|
3057
|
-
|
|
3058
|
-
if (isStacked) {
|
|
3059
|
-
let sumMin = Infinity;
|
|
3060
|
-
let sumMax = -Infinity;
|
|
3061
|
-
for (let c = 0; c < N; c++) {
|
|
3062
|
-
let pos = 0;
|
|
3063
|
-
let neg = 0;
|
|
3064
|
-
for (const s of spec.series) {
|
|
3065
|
-
const v = s.values[c] ?? 0;
|
|
3066
|
-
if (v >= 0) pos += v;
|
|
3067
|
-
else neg += v;
|
|
3068
|
-
}
|
|
3069
|
-
if (neg < sumMin) sumMin = neg;
|
|
3070
|
-
if (pos > sumMax) sumMax = pos;
|
|
3071
|
-
}
|
|
3072
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
3073
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
3074
|
-
}
|
|
3084
|
+
const { min, max } = seriesMinMax(spec);
|
|
3075
3085
|
const range = max - min || 1;
|
|
3076
3086
|
const groupH = f.plotH / N;
|
|
3077
3087
|
const gapPctB = (spec.gapWidthPct ?? 150) / 100;
|
|
@@ -3096,12 +3106,12 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3096
3106
|
}
|
|
3097
3107
|
const base = v >= 0 ? posAcc : negAcc;
|
|
3098
3108
|
const stackedTop = base + v;
|
|
3099
|
-
const y0 = f.plotY + c * groupH + (groupH - barH) / 2;
|
|
3109
|
+
const y0 = f.plotY + (N - 1 - c) * groupH + (groupH - barH) / 2;
|
|
3100
3110
|
const x0 = f.plotX + (Math.min(base, stackedTop) - min) / range * f.plotW;
|
|
3101
3111
|
const x1 = f.plotX + (Math.max(base, stackedTop) - min) / range * f.plotW;
|
|
3102
3112
|
const w = Math.abs(x1 - x0);
|
|
3103
3113
|
out.push(
|
|
3104
|
-
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(w)}" height="${px(barH)}" fill="${colors[s % colors.length]}"/>`
|
|
3114
|
+
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(w)}" height="${px(barH)}" fill="${spec.series[s]?.color ?? colors[s % colors.length]}"/>`
|
|
3105
3115
|
);
|
|
3106
3116
|
if (showLabelForBar(s) && Math.abs(v) > 0) {
|
|
3107
3117
|
const labelX = (x0 + x1) / 2;
|
|
@@ -3115,11 +3125,11 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3115
3125
|
}
|
|
3116
3126
|
} else {
|
|
3117
3127
|
const clusterH = barH * clusterUnitsB;
|
|
3118
|
-
const clusterStartY = f.plotY + c * groupH + (groupH - clusterH) / 2;
|
|
3128
|
+
const clusterStartY = f.plotY + (N - 1 - c) * groupH + (groupH - clusterH) / 2;
|
|
3119
3129
|
const strideB = barH * (1 - overlapPctB);
|
|
3120
3130
|
for (let s = 0; s < spec.series.length; s++) {
|
|
3121
3131
|
const v = spec.series[s]?.values[c] ?? 0;
|
|
3122
|
-
const y0 = clusterStartY + s * strideB;
|
|
3132
|
+
const y0 = clusterStartY + (Sb - 1 - s) * strideB;
|
|
3123
3133
|
const tip = f.plotX + (v - min) / range * f.plotW;
|
|
3124
3134
|
const x0 = Math.min(tip, baseX);
|
|
3125
3135
|
const w = Math.abs(tip - baseX);
|
|
@@ -3167,24 +3177,7 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3167
3177
|
const grouping = spec.grouping ?? "clustered";
|
|
3168
3178
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
3169
3179
|
const isPercent = grouping === "percentStacked";
|
|
3170
|
-
|
|
3171
|
-
if (isStacked) {
|
|
3172
|
-
let sumMin = Infinity;
|
|
3173
|
-
let sumMax = -Infinity;
|
|
3174
|
-
for (let c = 0; c < N; c++) {
|
|
3175
|
-
let pos = 0;
|
|
3176
|
-
let neg = 0;
|
|
3177
|
-
for (const s of spec.series) {
|
|
3178
|
-
const v = s.values[c] ?? 0;
|
|
3179
|
-
if (v >= 0) pos += v;
|
|
3180
|
-
else neg += v;
|
|
3181
|
-
}
|
|
3182
|
-
if (neg < sumMin) sumMin = neg;
|
|
3183
|
-
if (pos > sumMax) sumMax = pos;
|
|
3184
|
-
}
|
|
3185
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
3186
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
3187
|
-
}
|
|
3180
|
+
const { min, max } = seriesMinMax(spec);
|
|
3188
3181
|
const range = max - min || 1;
|
|
3189
3182
|
const step = N > 1 ? f.plotW / (N - 1) : 0;
|
|
3190
3183
|
const baseY = f.plotY + f.plotH - (0 - min) / range * f.plotH;
|
|
@@ -3245,7 +3238,7 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3245
3238
|
})();
|
|
3246
3239
|
if (fill) {
|
|
3247
3240
|
const back = basePts.slice().reverse().map(([xp, yp]) => `L${px(xp)},${px(yp)}`).join(" ");
|
|
3248
|
-
out.push(`<path d="${dPath} ${back} Z" fill="${color}"
|
|
3241
|
+
out.push(`<path d="${dPath} ${back} Z" fill="${color}" stroke="none"/>`);
|
|
3249
3242
|
}
|
|
3250
3243
|
const lineWPx = series.lineWidthEmu ? Math.max(0.3, series.lineWidthEmu / EMU_PER_PX) : 1.5;
|
|
3251
3244
|
const dashAttr = series.lineDash ? (() => {
|
|
@@ -3259,8 +3252,9 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3259
3252
|
`<path d="${dPath}" fill="none" stroke="${color}" stroke-width="${lineWPx.toFixed(2)}" stroke-linejoin="round" stroke-linecap="round"${dashAttr}/>`
|
|
3260
3253
|
);
|
|
3261
3254
|
if (!isStacked) {
|
|
3262
|
-
const
|
|
3263
|
-
if (
|
|
3255
|
+
const explicitSymbol = series.markerSymbol !== void 0 && series.markerSymbol !== "auto" && series.markerSymbol !== "none";
|
|
3256
|
+
if (series.markerSymbol !== "none" && !fill && (spec.lineMarkers === true || explicitSymbol)) {
|
|
3257
|
+
const symbol = autoMarkerSymbol(series.markerSymbol, s);
|
|
3264
3258
|
const size = series.markerSizePt ?? 5;
|
|
3265
3259
|
const r = Math.max(1, size * 0.5);
|
|
3266
3260
|
for (const [xp, yp] of pts) {
|
|
@@ -3502,7 +3496,7 @@ var renderScatterChart = (f, spec, colors) => {
|
|
|
3502
3496
|
const drawMarker = sym === "none" ? false : showMarker || sym !== void 0 && sym !== "auto";
|
|
3503
3497
|
if (drawMarker) {
|
|
3504
3498
|
const r = Math.max(1.5, (series.markerSizePt ?? 5) * 0.5);
|
|
3505
|
-
const glyph = sym
|
|
3499
|
+
const glyph = autoMarkerSymbol(sym, s);
|
|
3506
3500
|
for (const [xp, yp] of proj) out.push(seriesMarker(glyph, xp, yp, r, color));
|
|
3507
3501
|
}
|
|
3508
3502
|
}
|
|
@@ -3625,7 +3619,7 @@ var renderRadarChart = (f, spec, colors) => {
|
|
|
3625
3619
|
);
|
|
3626
3620
|
if (showMarker) {
|
|
3627
3621
|
const r = Math.max(1.5, (series.markerSizePt ?? 5) * 0.5);
|
|
3628
|
-
const glyph = series.markerSymbol
|
|
3622
|
+
const glyph = autoMarkerSymbol(series.markerSymbol, s);
|
|
3629
3623
|
for (const [xp, yp] of proj) out.push(seriesMarker(glyph, xp, yp, r, color));
|
|
3630
3624
|
}
|
|
3631
3625
|
}
|
|
@@ -3661,7 +3655,9 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3661
3655
|
const hiddenSet = new Set(spec.legend?.hiddenIndices ?? []);
|
|
3662
3656
|
const seriesNamesForLegend = allNamesForLegend.filter((_, i) => !hiddenSet.has(i));
|
|
3663
3657
|
const seriesColorsForLegend = allColorsForLegend.filter((_, i) => !hiddenSet.has(i));
|
|
3664
|
-
const
|
|
3658
|
+
const explicitMarker = (sym) => sym !== void 0 && sym !== "auto" && sym !== "none";
|
|
3659
|
+
const showsMarkers = spec.kind === "line" && (spec.lineMarkers === true || spec.series.some((s) => explicitMarker(s.markerSymbol)));
|
|
3660
|
+
const markerSymbolsForLegend = showsMarkers ? spec.series.map((s) => s.markerSymbol).filter((_, i) => !hiddenSet.has(i)) : void 0;
|
|
3665
3661
|
let finiteCount = 0;
|
|
3666
3662
|
for (const s of spec.series) {
|
|
3667
3663
|
for (const v of s.values) if (v !== null && Number.isFinite(v)) finiteCount++;
|
|
@@ -3684,7 +3680,8 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3684
3680
|
...spec.valueAxisLabelRotationDeg !== void 0 ? { labelRotationDeg: spec.valueAxisLabelRotationDeg } : {},
|
|
3685
3681
|
...spec.valueAxis?.displayUnits !== void 0 ? { displayUnits: spec.valueAxis.displayUnits } : {}
|
|
3686
3682
|
};
|
|
3687
|
-
const
|
|
3683
|
+
const isPercentStacked = spec.grouping === "percentStacked";
|
|
3684
|
+
const valueAxis = spec.kind === "bar" ? { orientation: "horizontal", min, max, percent: isPercentStacked, ...axisExtras } : { orientation: "vertical", min, max, percent: isPercentStacked, ...axisExtras };
|
|
3688
3685
|
if (!spec.valueAxisHidden) axes = renderValueAxis(f, valueAxis);
|
|
3689
3686
|
const labelsHidden = spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none";
|
|
3690
3687
|
if (N > 0 && !labelsHidden) {
|
|
@@ -3749,8 +3746,11 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3749
3746
|
`<g${transform}>`,
|
|
3750
3747
|
// Chart-area backdrop honors <c:chartSpace><c:spPr><a:solidFill> /
|
|
3751
3748
|
// <a:ln>. plot-area gets its own tinted rect + border when
|
|
3752
|
-
// <c:plotArea><c:spPr> authors them.
|
|
3753
|
-
|
|
3749
|
+
// <c:plotArea><c:spPr> authors them. PowerPoint draws no chart-area
|
|
3750
|
+
// border unless the chartSpace authors an <a:ln>, so the default is
|
|
3751
|
+
// `none` — an invented light-gray frame is the most visible single
|
|
3752
|
+
// divergence from PowerPoint's actual rendering.
|
|
3753
|
+
`<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"' : ""}/>`,
|
|
3754
3754
|
spec.plotAreaFill || spec.plotAreaStrokeColor ? `<rect x="${px(f.plotX)}" y="${px(f.plotY)}" width="${px(f.plotW)}" height="${px(f.plotH)}" fill="${spec.plotAreaFill ?? "none"}" stroke="${spec.plotAreaStrokeColor ?? "none"}" stroke-width="0.6"/>` : "",
|
|
3755
3755
|
renderChartTitle(f, spec.title ?? "", spec.titleStyle),
|
|
3756
3756
|
axes,
|