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/node.js
CHANGED
|
@@ -607,27 +607,23 @@ var patternDef = (pat) => {
|
|
|
607
607
|
return `<path d="M0 0L${W} ${H}" stroke="${fg}" stroke-width="${width}"/>`;
|
|
608
608
|
return `<path d="M${W} 0L0 ${H}" stroke="${fg}" stroke-width="${width}"/>`;
|
|
609
609
|
};
|
|
610
|
-
const
|
|
611
|
-
|
|
610
|
+
const BAYER4 = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];
|
|
611
|
+
const screen = (density) => {
|
|
612
|
+
const threshold = density * 16;
|
|
612
613
|
const out = [];
|
|
613
|
-
|
|
614
|
-
[
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
[2, 6],
|
|
620
|
-
[6, 6]
|
|
621
|
-
];
|
|
622
|
-
for (const [x, y] of grid.slice(0, count)) {
|
|
623
|
-
out.push(`<circle cx="${x}" cy="${y}" r="0.7" fill="${fg}"/>`);
|
|
614
|
+
for (let i = 0; i < 16; i++) {
|
|
615
|
+
if (BAYER4[i] < threshold) {
|
|
616
|
+
const cx = i % 4 * 2;
|
|
617
|
+
const cy = Math.floor(i / 4) * 2;
|
|
618
|
+
out.push(`<rect x="${cx}" y="${cy}" width="2" height="2" fill="${fg}"/>`);
|
|
619
|
+
}
|
|
624
620
|
}
|
|
625
621
|
return out.join("");
|
|
626
622
|
};
|
|
627
623
|
const pctMatch = /^pct(\d+)$/.exec(preset);
|
|
628
624
|
if (pctMatch) {
|
|
629
|
-
const pct = Math.min(100, Math.max(
|
|
630
|
-
body =
|
|
625
|
+
const pct = Math.min(100, Math.max(0, Number.parseInt(pctMatch[1], 10)));
|
|
626
|
+
body = screen(pct / 100);
|
|
631
627
|
} else if (preset === "horzBrick" || preset === "ltHorizontal" || preset === "narHorz") {
|
|
632
628
|
body = stripe("h", 0.8);
|
|
633
629
|
} else if (preset === "dkHorizontal") {
|
|
@@ -661,7 +657,7 @@ var patternDef = (pat) => {
|
|
|
661
657
|
} else if (preset === "solidDmnd" || preset === "openDmnd") {
|
|
662
658
|
body = `<path d="M4 1L7 4 4 7 1 4Z" fill="${preset === "solidDmnd" ? fg : "none"}" stroke="${fg}" stroke-width="0.6"/>`;
|
|
663
659
|
} else {
|
|
664
|
-
body =
|
|
660
|
+
body = screen(0.5);
|
|
665
661
|
}
|
|
666
662
|
const defs = `<defs><pattern id="${id}" patternUnits="userSpaceOnUse" width="${W}" height="${H}"><rect width="${W}" height="${H}" fill="${bg}"/>${body}</pattern></defs>`;
|
|
667
663
|
return { defs, fillAttr: `url(#${id})` };
|
|
@@ -2520,6 +2516,9 @@ var DISPLAY_UNIT_LABEL = {
|
|
|
2520
2516
|
billions: "Billions",
|
|
2521
2517
|
trillions: "Trillions"
|
|
2522
2518
|
};
|
|
2519
|
+
var DEFAULT_AXIS_COLOR = "#000000";
|
|
2520
|
+
var DEFAULT_GRID_COLOR = "#D9D9D9";
|
|
2521
|
+
var AXIS_TICK_LEN = 5;
|
|
2523
2522
|
var axisTickAttrs = (style) => {
|
|
2524
2523
|
const sz = style?.sizePt ?? 10;
|
|
2525
2524
|
const fill = style?.color ?? "#6B7280";
|
|
@@ -2536,10 +2535,15 @@ var renderValueAxis = (f, axis) => {
|
|
|
2536
2535
|
})() : niceTicks(axis.min, axis.max);
|
|
2537
2536
|
const out = [];
|
|
2538
2537
|
const range = axis.max - axis.min || 1;
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2538
|
+
const fmtTick = (t) => axis.percent ? `${Math.round(t * 100)}%` : formatAxisLabel(
|
|
2539
|
+
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2540
|
+
axis.numberFormat
|
|
2541
|
+
);
|
|
2542
|
+
const showGrid = axis.majorGridlines ?? false;
|
|
2543
|
+
const gridStroke = axis.majorGridlineColor ?? DEFAULT_GRID_COLOR;
|
|
2544
|
+
const axisColor = axis.lineColor ?? DEFAULT_AXIS_COLOR;
|
|
2541
2545
|
const tickMark = axis.majorTickMark ?? "out";
|
|
2542
|
-
const tickLen =
|
|
2546
|
+
const tickLen = AXIS_TICK_LEN;
|
|
2543
2547
|
for (const t of ticks) {
|
|
2544
2548
|
if (axis.orientation === "vertical") {
|
|
2545
2549
|
const yp = f.plotY + f.plotH - (t - axis.min) / range * f.plotH;
|
|
@@ -2552,19 +2556,14 @@ var renderValueAxis = (f, axis) => {
|
|
|
2552
2556
|
const tx1 = tickMark === "in" ? f.plotX : f.plotX - tickLen;
|
|
2553
2557
|
const tx2 = tickMark === "out" ? f.plotX : tickMark === "cross" ? f.plotX + tickLen : f.plotX + tickLen;
|
|
2554
2558
|
out.push(
|
|
2555
|
-
`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="
|
|
2559
|
+
`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2556
2560
|
);
|
|
2557
2561
|
}
|
|
2558
2562
|
const labelX = f.plotX - 4;
|
|
2559
2563
|
const rot = axis.labelRotationDeg ?? 0;
|
|
2560
2564
|
const transform = rot ? ` transform="rotate(${rot} ${px(labelX)} ${px(yp)})"` : "";
|
|
2561
2565
|
out.push(
|
|
2562
|
-
`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml2(
|
|
2563
|
-
formatAxisLabel(
|
|
2564
|
-
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2565
|
-
axis.numberFormat
|
|
2566
|
-
)
|
|
2567
|
-
)}</text>`
|
|
2566
|
+
`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml2(fmtTick(t))}</text>`
|
|
2568
2567
|
);
|
|
2569
2568
|
} else {
|
|
2570
2569
|
const xp = f.plotX + (t - axis.min) / range * f.plotW;
|
|
@@ -2578,19 +2577,14 @@ var renderValueAxis = (f, axis) => {
|
|
|
2578
2577
|
const ty1 = tickMark === "in" ? baseY : baseY + tickLen;
|
|
2579
2578
|
const ty2 = tickMark === "out" ? baseY : tickMark === "cross" ? baseY - tickLen : baseY - tickLen;
|
|
2580
2579
|
out.push(
|
|
2581
|
-
`<line x1="${px(xp)}" y1="${px(ty1)}" x2="${px(xp)}" y2="${px(ty2)}" stroke="
|
|
2580
|
+
`<line x1="${px(xp)}" y1="${px(ty1)}" x2="${px(xp)}" y2="${px(ty2)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2582
2581
|
);
|
|
2583
2582
|
}
|
|
2584
2583
|
const horizLabelY = f.plotY + f.plotH + 12;
|
|
2585
2584
|
const rotH = axis.labelRotationDeg ?? 0;
|
|
2586
2585
|
const transformH = rotH ? ` transform="rotate(${rotH} ${px(xp)} ${px(horizLabelY)})"` : "";
|
|
2587
2586
|
out.push(
|
|
2588
|
-
`<text x="${px(xp)}" y="${px(horizLabelY)}" text-anchor="middle" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transformH}>${escapeXml2(
|
|
2589
|
-
formatAxisLabel(
|
|
2590
|
-
axis.displayUnits ? t / DISPLAY_UNIT_DIVISOR[axis.displayUnits] : t,
|
|
2591
|
-
axis.numberFormat
|
|
2592
|
-
)
|
|
2593
|
-
)}</text>`
|
|
2587
|
+
`<text x="${px(xp)}" y="${px(horizLabelY)}" text-anchor="middle" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transformH}>${escapeXml2(fmtTick(t))}</text>`
|
|
2594
2588
|
);
|
|
2595
2589
|
}
|
|
2596
2590
|
}
|
|
@@ -2608,16 +2602,16 @@ var renderValueAxis = (f, axis) => {
|
|
|
2608
2602
|
);
|
|
2609
2603
|
}
|
|
2610
2604
|
}
|
|
2611
|
-
if (axis.
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
)
|
|
2620
|
-
|
|
2605
|
+
if (axis.orientation === "vertical") {
|
|
2606
|
+
out.push(
|
|
2607
|
+
`<line x1="${px(f.plotX)}" y1="${px(f.plotY)}" x2="${px(f.plotX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2608
|
+
);
|
|
2609
|
+
} else {
|
|
2610
|
+
const zeroY = f.plotY + f.plotH - (0 - axis.min) / range * f.plotH;
|
|
2611
|
+
const spineY = axis.min <= 0 && axis.max >= 0 ? zeroY : f.plotY + f.plotH;
|
|
2612
|
+
out.push(
|
|
2613
|
+
`<line x1="${px(f.plotX)}" y1="${px(spineY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(spineY)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2614
|
+
);
|
|
2621
2615
|
}
|
|
2622
2616
|
return out.join("");
|
|
2623
2617
|
};
|
|
@@ -2646,7 +2640,7 @@ var renderCategoryAxis = (f, orientation, cats, pointCount2, skip = 1, labelStyl
|
|
|
2646
2640
|
const truncLen = labelRotationDeg && Math.abs(labelRotationDeg) >= 30 ? 28 : 14;
|
|
2647
2641
|
for (let i = 0; i < pointCount2; i++) {
|
|
2648
2642
|
if (skip > 1 && i % skip !== 0) continue;
|
|
2649
|
-
const cy = f.plotY + (i + 0.5) * step;
|
|
2643
|
+
const cy = f.plotY + (pointCount2 - 1 - i + 0.5) * step;
|
|
2650
2644
|
const lx = f.plotX - 4;
|
|
2651
2645
|
const truncated = labels[i] !== void 0 && labels[i].length > truncLen ? `${labels[i].slice(0, truncLen - 2)}\u2026` : labels[i] ?? "";
|
|
2652
2646
|
const transform = labelRotationDeg && labelRotationDeg !== 0 ? ` transform="rotate(${labelRotationDeg} ${px(lx)} ${px(cy)})"` : "";
|
|
@@ -2655,27 +2649,63 @@ var renderCategoryAxis = (f, orientation, cats, pointCount2, skip = 1, labelStyl
|
|
|
2655
2649
|
);
|
|
2656
2650
|
}
|
|
2657
2651
|
}
|
|
2658
|
-
|
|
2659
|
-
|
|
2652
|
+
const axisColor = lineColor ?? DEFAULT_AXIS_COLOR;
|
|
2653
|
+
if (orientation === "horizontal") {
|
|
2654
|
+
const baseY = f.plotY + f.plotH;
|
|
2655
|
+
out.push(
|
|
2656
|
+
`<line x1="${px(f.plotX)}" y1="${px(baseY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(baseY)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2657
|
+
);
|
|
2658
|
+
const stepB = pointCount2 > 0 ? f.plotW / pointCount2 : 0;
|
|
2659
|
+
for (let i = 0; i <= pointCount2; i++) {
|
|
2660
|
+
const bx = f.plotX + i * stepB;
|
|
2660
2661
|
out.push(
|
|
2661
|
-
`<line x1="${px(
|
|
2662
|
+
`<line x1="${px(bx)}" y1="${px(baseY)}" x2="${px(bx)}" y2="${px(baseY + AXIS_TICK_LEN)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2662
2663
|
);
|
|
2663
|
-
}
|
|
2664
|
+
}
|
|
2665
|
+
} else {
|
|
2666
|
+
out.push(
|
|
2667
|
+
`<line x1="${px(f.plotX)}" y1="${px(f.plotY)}" x2="${px(f.plotX)}" y2="${px(f.plotY + f.plotH)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2668
|
+
);
|
|
2669
|
+
const stepB = pointCount2 > 0 ? f.plotH / pointCount2 : 0;
|
|
2670
|
+
for (let i = 0; i <= pointCount2; i++) {
|
|
2671
|
+
const by = f.plotY + i * stepB;
|
|
2664
2672
|
out.push(
|
|
2665
|
-
`<line x1="${px(f.plotX)}" y1="${px(
|
|
2673
|
+
`<line x1="${px(f.plotX - AXIS_TICK_LEN)}" y1="${px(by)}" x2="${px(f.plotX)}" y2="${px(by)}" stroke="${axisColor}" stroke-width="1"/>`
|
|
2666
2674
|
);
|
|
2667
2675
|
}
|
|
2668
2676
|
}
|
|
2669
2677
|
return out.join("");
|
|
2670
2678
|
};
|
|
2671
2679
|
var seriesMinMax = (spec) => {
|
|
2680
|
+
const isStacked = spec.grouping === "stacked" || spec.grouping === "percentStacked";
|
|
2681
|
+
const isPercent = spec.grouping === "percentStacked";
|
|
2672
2682
|
let min = Infinity;
|
|
2673
2683
|
let max = -Infinity;
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2684
|
+
if (isPercent) {
|
|
2685
|
+
min = 0;
|
|
2686
|
+
max = 1;
|
|
2687
|
+
} else if (isStacked) {
|
|
2688
|
+
const N = spec.series.reduce((n, s) => Math.max(n, s.values.length), 0);
|
|
2689
|
+
for (let c = 0; c < N; c++) {
|
|
2690
|
+
let pos = 0;
|
|
2691
|
+
let neg = 0;
|
|
2692
|
+
for (const s of spec.series) {
|
|
2693
|
+
const v = s.values[c];
|
|
2694
|
+
if (v !== null && v !== void 0 && Number.isFinite(v)) {
|
|
2695
|
+
if (v >= 0) pos += v;
|
|
2696
|
+
else neg += v;
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
if (pos > max) max = pos;
|
|
2700
|
+
if (neg < min) min = neg;
|
|
2701
|
+
}
|
|
2702
|
+
} else {
|
|
2703
|
+
for (const s of spec.series) {
|
|
2704
|
+
for (const v of s.values) {
|
|
2705
|
+
if (v !== null && Number.isFinite(v)) {
|
|
2706
|
+
if (v < min) min = v;
|
|
2707
|
+
if (v > max) max = v;
|
|
2708
|
+
}
|
|
2679
2709
|
}
|
|
2680
2710
|
}
|
|
2681
2711
|
}
|
|
@@ -2683,6 +2713,9 @@ var seriesMinMax = (spec) => {
|
|
|
2683
2713
|
if (!Number.isFinite(max)) max = 1;
|
|
2684
2714
|
if (max === min) max = min + 1;
|
|
2685
2715
|
if (min > 0) min = 0;
|
|
2716
|
+
if (isPercent) {
|
|
2717
|
+
return { min: 0, max: 1, step: 0.2 };
|
|
2718
|
+
}
|
|
2686
2719
|
const step = niceStep(max - min);
|
|
2687
2720
|
max = (Math.floor(max / step) + 1) * step;
|
|
2688
2721
|
if (spec.valueAxis?.min !== void 0) min = spec.valueAxis.min;
|
|
@@ -2708,9 +2741,9 @@ var renderChartLegend = (f, names, colors, position = "b", textStyle, markerSymb
|
|
|
2708
2741
|
const swatch = (i, swatchX, swatchY) => {
|
|
2709
2742
|
const color = colors[i % colors.length];
|
|
2710
2743
|
const sym = markerSymbols?.[i];
|
|
2711
|
-
if (
|
|
2744
|
+
if (markerSymbols !== void 0 && sym !== "none") {
|
|
2712
2745
|
const r = 4.5;
|
|
2713
|
-
return seriesMarker(sym, swatchX + r, swatchY + r, r, color);
|
|
2746
|
+
return seriesMarker(autoMarkerSymbol(sym, i), swatchX + r, swatchY + r, r, color);
|
|
2714
2747
|
}
|
|
2715
2748
|
return `<rect x="${px(swatchX)}" y="${px(swatchY)}" width="9" height="9" fill="${color}"/>`;
|
|
2716
2749
|
};
|
|
@@ -2773,24 +2806,7 @@ var renderColumnChart = (f, spec, colors) => {
|
|
|
2773
2806
|
const grouping = spec.grouping ?? "clustered";
|
|
2774
2807
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
2775
2808
|
const isPercent = grouping === "percentStacked";
|
|
2776
|
-
|
|
2777
|
-
if (isStacked) {
|
|
2778
|
-
let sumMin = Infinity;
|
|
2779
|
-
let sumMax = -Infinity;
|
|
2780
|
-
for (let c = 0; c < N; c++) {
|
|
2781
|
-
let pos = 0;
|
|
2782
|
-
let neg = 0;
|
|
2783
|
-
for (const s of spec.series) {
|
|
2784
|
-
const v = s.values[c] ?? 0;
|
|
2785
|
-
if (v >= 0) pos += v;
|
|
2786
|
-
else neg += v;
|
|
2787
|
-
}
|
|
2788
|
-
if (neg < sumMin) sumMin = neg;
|
|
2789
|
-
if (pos > sumMax) sumMax = pos;
|
|
2790
|
-
}
|
|
2791
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
2792
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
2793
|
-
}
|
|
2809
|
+
const { min, max } = seriesMinMax(spec);
|
|
2794
2810
|
const range = max - min || 1;
|
|
2795
2811
|
const groupW = f.plotW / N;
|
|
2796
2812
|
const gapPctC = (spec.gapWidthPct ?? 150) / 100;
|
|
@@ -2823,7 +2839,7 @@ var renderColumnChart = (f, spec, colors) => {
|
|
|
2823
2839
|
const y1 = f.plotY + f.plotH - (Math.min(stackedTop, stackedBase) - min) / range * f.plotH;
|
|
2824
2840
|
const h = Math.abs(y1 - y0);
|
|
2825
2841
|
out.push(
|
|
2826
|
-
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(barW)}" height="${px(h)}" fill="${colors[s % colors.length]}"/>`
|
|
2842
|
+
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(barW)}" height="${px(h)}" fill="${spec.series[s]?.color ?? colors[s % colors.length]}"/>`
|
|
2827
2843
|
);
|
|
2828
2844
|
if (showLabelFor(s) && Math.abs(v) > 0) {
|
|
2829
2845
|
const labelY = (y0 + y1) / 2 + 3;
|
|
@@ -2997,6 +3013,17 @@ var smoothPath = (pts) => {
|
|
|
2997
3013
|
}
|
|
2998
3014
|
return parts.join(" ");
|
|
2999
3015
|
};
|
|
3016
|
+
var AUTO_MARKER_SYMBOLS = [
|
|
3017
|
+
"diamond",
|
|
3018
|
+
"square",
|
|
3019
|
+
"triangle",
|
|
3020
|
+
"x",
|
|
3021
|
+
"star",
|
|
3022
|
+
"dot",
|
|
3023
|
+
"plus",
|
|
3024
|
+
"dash"
|
|
3025
|
+
];
|
|
3026
|
+
var autoMarkerSymbol = (symbol, seriesIdx) => symbol !== void 0 && symbol !== "auto" ? symbol : AUTO_MARKER_SYMBOLS[seriesIdx % AUTO_MARKER_SYMBOLS.length];
|
|
3000
3027
|
var seriesMarker = (symbol, cx, cy, r, color) => {
|
|
3001
3028
|
switch (symbol) {
|
|
3002
3029
|
case "square":
|
|
@@ -3058,24 +3085,7 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3058
3085
|
const grouping = spec.grouping ?? "clustered";
|
|
3059
3086
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
3060
3087
|
const isPercent = grouping === "percentStacked";
|
|
3061
|
-
|
|
3062
|
-
if (isStacked) {
|
|
3063
|
-
let sumMin = Infinity;
|
|
3064
|
-
let sumMax = -Infinity;
|
|
3065
|
-
for (let c = 0; c < N; c++) {
|
|
3066
|
-
let pos = 0;
|
|
3067
|
-
let neg = 0;
|
|
3068
|
-
for (const s of spec.series) {
|
|
3069
|
-
const v = s.values[c] ?? 0;
|
|
3070
|
-
if (v >= 0) pos += v;
|
|
3071
|
-
else neg += v;
|
|
3072
|
-
}
|
|
3073
|
-
if (neg < sumMin) sumMin = neg;
|
|
3074
|
-
if (pos > sumMax) sumMax = pos;
|
|
3075
|
-
}
|
|
3076
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
3077
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
3078
|
-
}
|
|
3088
|
+
const { min, max } = seriesMinMax(spec);
|
|
3079
3089
|
const range = max - min || 1;
|
|
3080
3090
|
const groupH = f.plotH / N;
|
|
3081
3091
|
const gapPctB = (spec.gapWidthPct ?? 150) / 100;
|
|
@@ -3100,12 +3110,12 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3100
3110
|
}
|
|
3101
3111
|
const base = v >= 0 ? posAcc : negAcc;
|
|
3102
3112
|
const stackedTop = base + v;
|
|
3103
|
-
const y0 = f.plotY + c * groupH + (groupH - barH) / 2;
|
|
3113
|
+
const y0 = f.plotY + (N - 1 - c) * groupH + (groupH - barH) / 2;
|
|
3104
3114
|
const x0 = f.plotX + (Math.min(base, stackedTop) - min) / range * f.plotW;
|
|
3105
3115
|
const x1 = f.plotX + (Math.max(base, stackedTop) - min) / range * f.plotW;
|
|
3106
3116
|
const w = Math.abs(x1 - x0);
|
|
3107
3117
|
out.push(
|
|
3108
|
-
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(w)}" height="${px(barH)}" fill="${colors[s % colors.length]}"/>`
|
|
3118
|
+
`<rect x="${px(x0)}" y="${px(y0)}" width="${px(w)}" height="${px(barH)}" fill="${spec.series[s]?.color ?? colors[s % colors.length]}"/>`
|
|
3109
3119
|
);
|
|
3110
3120
|
if (showLabelForBar(s) && Math.abs(v) > 0) {
|
|
3111
3121
|
const labelX = (x0 + x1) / 2;
|
|
@@ -3119,11 +3129,11 @@ var renderBarChart = (f, spec, colors) => {
|
|
|
3119
3129
|
}
|
|
3120
3130
|
} else {
|
|
3121
3131
|
const clusterH = barH * clusterUnitsB;
|
|
3122
|
-
const clusterStartY = f.plotY + c * groupH + (groupH - clusterH) / 2;
|
|
3132
|
+
const clusterStartY = f.plotY + (N - 1 - c) * groupH + (groupH - clusterH) / 2;
|
|
3123
3133
|
const strideB = barH * (1 - overlapPctB);
|
|
3124
3134
|
for (let s = 0; s < spec.series.length; s++) {
|
|
3125
3135
|
const v = spec.series[s]?.values[c] ?? 0;
|
|
3126
|
-
const y0 = clusterStartY + s * strideB;
|
|
3136
|
+
const y0 = clusterStartY + (Sb - 1 - s) * strideB;
|
|
3127
3137
|
const tip = f.plotX + (v - min) / range * f.plotW;
|
|
3128
3138
|
const x0 = Math.min(tip, baseX);
|
|
3129
3139
|
const w = Math.abs(tip - baseX);
|
|
@@ -3171,24 +3181,7 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3171
3181
|
const grouping = spec.grouping ?? "clustered";
|
|
3172
3182
|
const isStacked = grouping === "stacked" || grouping === "percentStacked";
|
|
3173
3183
|
const isPercent = grouping === "percentStacked";
|
|
3174
|
-
|
|
3175
|
-
if (isStacked) {
|
|
3176
|
-
let sumMin = Infinity;
|
|
3177
|
-
let sumMax = -Infinity;
|
|
3178
|
-
for (let c = 0; c < N; c++) {
|
|
3179
|
-
let pos = 0;
|
|
3180
|
-
let neg = 0;
|
|
3181
|
-
for (const s of spec.series) {
|
|
3182
|
-
const v = s.values[c] ?? 0;
|
|
3183
|
-
if (v >= 0) pos += v;
|
|
3184
|
-
else neg += v;
|
|
3185
|
-
}
|
|
3186
|
-
if (neg < sumMin) sumMin = neg;
|
|
3187
|
-
if (pos > sumMax) sumMax = pos;
|
|
3188
|
-
}
|
|
3189
|
-
min = isPercent ? 0 : Math.min(0, sumMin);
|
|
3190
|
-
max = isPercent ? 1 : Math.max(1, sumMax);
|
|
3191
|
-
}
|
|
3184
|
+
const { min, max } = seriesMinMax(spec);
|
|
3192
3185
|
const range = max - min || 1;
|
|
3193
3186
|
const step = N > 1 ? f.plotW / (N - 1) : 0;
|
|
3194
3187
|
const baseY = f.plotY + f.plotH - (0 - min) / range * f.plotH;
|
|
@@ -3249,7 +3242,7 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3249
3242
|
})();
|
|
3250
3243
|
if (fill) {
|
|
3251
3244
|
const back = basePts.slice().reverse().map(([xp, yp]) => `L${px(xp)},${px(yp)}`).join(" ");
|
|
3252
|
-
out.push(`<path d="${dPath} ${back} Z" fill="${color}"
|
|
3245
|
+
out.push(`<path d="${dPath} ${back} Z" fill="${color}" stroke="none"/>`);
|
|
3253
3246
|
}
|
|
3254
3247
|
const lineWPx = series.lineWidthEmu ? Math.max(0.3, series.lineWidthEmu / EMU_PER_PX) : 1.5;
|
|
3255
3248
|
const dashAttr = series.lineDash ? (() => {
|
|
@@ -3263,8 +3256,9 @@ var renderLineChart = (f, spec, colors, fill) => {
|
|
|
3263
3256
|
`<path d="${dPath}" fill="none" stroke="${color}" stroke-width="${lineWPx.toFixed(2)}" stroke-linejoin="round" stroke-linecap="round"${dashAttr}/>`
|
|
3264
3257
|
);
|
|
3265
3258
|
if (!isStacked) {
|
|
3266
|
-
const
|
|
3267
|
-
if (
|
|
3259
|
+
const explicitSymbol = series.markerSymbol !== void 0 && series.markerSymbol !== "auto" && series.markerSymbol !== "none";
|
|
3260
|
+
if (series.markerSymbol !== "none" && !fill && (spec.lineMarkers === true || explicitSymbol)) {
|
|
3261
|
+
const symbol = autoMarkerSymbol(series.markerSymbol, s);
|
|
3268
3262
|
const size = series.markerSizePt ?? 5;
|
|
3269
3263
|
const r = Math.max(1, size * 0.5);
|
|
3270
3264
|
for (const [xp, yp] of pts) {
|
|
@@ -3506,7 +3500,7 @@ var renderScatterChart = (f, spec, colors) => {
|
|
|
3506
3500
|
const drawMarker = sym === "none" ? false : showMarker || sym !== void 0 && sym !== "auto";
|
|
3507
3501
|
if (drawMarker) {
|
|
3508
3502
|
const r = Math.max(1.5, (series.markerSizePt ?? 5) * 0.5);
|
|
3509
|
-
const glyph = sym
|
|
3503
|
+
const glyph = autoMarkerSymbol(sym, s);
|
|
3510
3504
|
for (const [xp, yp] of proj) out.push(seriesMarker(glyph, xp, yp, r, color));
|
|
3511
3505
|
}
|
|
3512
3506
|
}
|
|
@@ -3629,7 +3623,7 @@ var renderRadarChart = (f, spec, colors) => {
|
|
|
3629
3623
|
);
|
|
3630
3624
|
if (showMarker) {
|
|
3631
3625
|
const r = Math.max(1.5, (series.markerSizePt ?? 5) * 0.5);
|
|
3632
|
-
const glyph = series.markerSymbol
|
|
3626
|
+
const glyph = autoMarkerSymbol(series.markerSymbol, s);
|
|
3633
3627
|
for (const [xp, yp] of proj) out.push(seriesMarker(glyph, xp, yp, r, color));
|
|
3634
3628
|
}
|
|
3635
3629
|
}
|
|
@@ -3665,7 +3659,9 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3665
3659
|
const hiddenSet = new Set(spec.legend?.hiddenIndices ?? []);
|
|
3666
3660
|
const seriesNamesForLegend = allNamesForLegend.filter((_, i) => !hiddenSet.has(i));
|
|
3667
3661
|
const seriesColorsForLegend = allColorsForLegend.filter((_, i) => !hiddenSet.has(i));
|
|
3668
|
-
const
|
|
3662
|
+
const explicitMarker = (sym) => sym !== void 0 && sym !== "auto" && sym !== "none";
|
|
3663
|
+
const showsMarkers = spec.kind === "line" && (spec.lineMarkers === true || spec.series.some((s) => explicitMarker(s.markerSymbol)));
|
|
3664
|
+
const markerSymbolsForLegend = showsMarkers ? spec.series.map((s) => s.markerSymbol).filter((_, i) => !hiddenSet.has(i)) : void 0;
|
|
3669
3665
|
let finiteCount = 0;
|
|
3670
3666
|
for (const s of spec.series) {
|
|
3671
3667
|
for (const v of s.values) if (v !== null && Number.isFinite(v)) finiteCount++;
|
|
@@ -3688,7 +3684,8 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3688
3684
|
...spec.valueAxisLabelRotationDeg !== void 0 ? { labelRotationDeg: spec.valueAxisLabelRotationDeg } : {},
|
|
3689
3685
|
...spec.valueAxis?.displayUnits !== void 0 ? { displayUnits: spec.valueAxis.displayUnits } : {}
|
|
3690
3686
|
};
|
|
3691
|
-
const
|
|
3687
|
+
const isPercentStacked = spec.grouping === "percentStacked";
|
|
3688
|
+
const valueAxis = spec.kind === "bar" ? { orientation: "horizontal", min, max, percent: isPercentStacked, ...axisExtras } : { orientation: "vertical", min, max, percent: isPercentStacked, ...axisExtras };
|
|
3692
3689
|
if (!spec.valueAxisHidden) axes = renderValueAxis(f, valueAxis);
|
|
3693
3690
|
const labelsHidden = spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none";
|
|
3694
3691
|
if (N > 0 && !labelsHidden) {
|
|
@@ -3753,8 +3750,11 @@ var renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3753
3750
|
`<g${transform}>`,
|
|
3754
3751
|
// Chart-area backdrop honors <c:chartSpace><c:spPr><a:solidFill> /
|
|
3755
3752
|
// <a:ln>. plot-area gets its own tinted rect + border when
|
|
3756
|
-
// <c:plotArea><c:spPr> authors them.
|
|
3757
|
-
|
|
3753
|
+
// <c:plotArea><c:spPr> authors them. PowerPoint draws no chart-area
|
|
3754
|
+
// border unless the chartSpace authors an <a:ln>, so the default is
|
|
3755
|
+
// `none` — an invented light-gray frame is the most visible single
|
|
3756
|
+
// divergence from PowerPoint's actual rendering.
|
|
3757
|
+
`<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"' : ""}/>`,
|
|
3758
3758
|
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"/>` : "",
|
|
3759
3759
|
renderChartTitle(f, spec.title ?? "", spec.titleStyle),
|
|
3760
3760
|
axes,
|