@rowsncolumns/charts 28.1.11 → 28.1.12

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.
@@ -23,12 +23,12 @@ import { applyEmptyCellsPolicy, connectsAcrossEmptyCells, isolatedPointIndexes,
23
23
  import { getEchartsGlState, loadEchartsGl, } from "../utils/echarts-gl-loader";
24
24
  import { echartsGroupedCategoryAxes, resolveCategoryLevels, } from "../utils/category-levels";
25
25
  import { gradientToEcharts } from "../utils/gradient";
26
- import { buildHierarchyTree, extractHierarchyRows, getHierarchyHeaderTitle, } from "../utils/hierarchy";
27
- import { binHistogram, computePareto, isParetoSpec, } from "../utils/histogram";
26
+ import { buildHierarchyTree, contrastTextColor, extractHierarchyRows, getHierarchyHeaderTitle, } from "../utils/hierarchy";
27
+ import { aggregateByCategory, binHistogram, computePareto, isParetoSpec, } from "../utils/histogram";
28
28
  import { categoryAxisNameGap, legendLabelsFrom, reserveEchartsLegendBand, } from "../utils/legend-layout";
29
29
  import { clampSecondPieSize, isOfPieChartSpec, otherSliceHalfAngle, resolveOfPieType, splitOfPie, } from "../utils/of-pie";
30
30
  import { clampDoughnutHole, doughnutRings } from "../utils/doughnut";
31
- import { applyAxisOverrides, applyLegendOverrides, buildSeriesLabelOption, resolveSeriesDataLabels, } from "../utils/overrides";
31
+ import { applyAxisOverrides, dataLabelFormatter, applyLegendOverrides, buildSeriesLabelOption, resolveSeriesDataLabels, } from "../utils/overrides";
32
32
  import { buildRadarIndicators, buildRadarSeriesData } from "../utils/radar";
33
33
  import { buildRegionMapData, buildSequentialColorRamp, isRegionMapSpec, resolveGeoScope, warnOnceForUnmatchedRegions, } from "../utils/region-map";
34
34
  import { loadRegionMapGeo } from "../utils/region-map-loader";
@@ -116,7 +116,14 @@ const HIERARCHY_LEVEL_STYLES = [
116
116
  },
117
117
  {
118
118
  itemStyle: {
119
- gapWidth: 1,
119
+ gapWidth: 2,
120
+ borderColor: "#ffffff",
121
+ borderWidth: 1,
122
+ },
123
+ },
124
+ {
125
+ itemStyle: {
126
+ gapWidth: 0,
120
127
  borderColor: "#ffffff",
121
128
  borderWidth: 1,
122
129
  },
@@ -139,14 +146,22 @@ const treemapBannerShown = (layout) => layout !== "none";
139
146
  * Colour a hierarchy like Excel: each top-level node takes the next
140
147
  * palette colour and every descendant inherits it (#1072).
141
148
  */
142
- const colorHierarchyNodes = (nodes, palette) => nodes.map((node, index) => {
149
+ const colorHierarchyNodes = (nodes, palette, options = {}) => nodes.map((node, index) => {
143
150
  const color = chartPaletteColorAt(palette, index);
144
- const paint = (n) => ({
151
+ const paint = (n, depth) => ({
145
152
  ...n,
146
- itemStyle: { color },
147
- ...(n.children ? { children: n.children.map(paint) } : {}),
153
+ // A top-level node's "border" is what echarts paints behind its
154
+ // banner strip: fill it with the category colour and write the name
155
+ // in a contrasting colour, like Excel's banner (#1086).
156
+ itemStyle: depth === 0 && options.banner
157
+ ? { color, borderColor: color }
158
+ : { color },
159
+ ...(depth === 0 && options.banner
160
+ ? { upperLabel: { color: contrastTextColor(color) } }
161
+ : {}),
162
+ ...(n.children ? { children: n.children.map((c) => paint(c, depth + 1)) } : {}),
148
163
  });
149
- return paint(node);
164
+ return paint(node, 0);
150
165
  });
151
166
  /** Sunburst rings: Excel leaves the centre empty, so even the first level is a ring (#1073). */
152
167
  const SUNBURST_RADIUS = ["15%", "80%"];
@@ -834,13 +849,13 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
834
849
  theme.themeColors.accent5,
835
850
  theme.themeColors.accent6,
836
851
  ]);
837
- const hierarchyData = colorHierarchyNodes(buildHierarchyTree(hierarchyRows), hierarchyPalette);
852
+ const isTreemap = spec.chartType === "treemap";
853
+ const banner = isTreemap && treemapBannerShown(spec.parentLabelLayout);
854
+ const hierarchyData = colorHierarchyNodes(buildHierarchyTree(hierarchyRows), hierarchyPalette, { banner });
838
855
  const rootName = hierarchyData.length === 1 ? hierarchyData[0]?.name ?? "" : "";
839
856
  const drillDown = Boolean(spec.drillDown);
840
857
  const seriesDisplayName = explicitChartTitle ?? headerTitle ?? rootName ?? "";
841
858
  const hierarchyDepth = getHierarchyDepth(hierarchyData);
842
- const isTreemap = spec.chartType === "treemap";
843
- const banner = isTreemap && treemapBannerShown(spec.parentLabelLayout);
844
859
  const levels = buildHierarchyLevels(hierarchyDepth, {
845
860
  treemap: isTreemap,
846
861
  banner,
@@ -873,12 +888,45 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
873
888
  : params.value ?? "";
874
889
  return `${params.name}: ${formatAxisValue(sizeNumberFormat, value, locale)}`;
875
890
  };
876
- // Spec-level overrides — treemap/sunburst default to no legend,
877
- // but an authored legend (visibility/position) still wins.
891
+ // Data labels: a treemap block's label always sits in its bottom-left
892
+ // corner (the bar placements mean nothing on a block) with each part
893
+ // — name, value — on its own line; `{ show: false }` turns the labels
894
+ // off entirely (#1086). Without `dataLabels` the block shows its name.
878
895
  const hierarchyDataLabels = spec.dataLabels;
879
- const hierarchySeriesLabel = buildSeriesLabelOption(hierarchyDataLabels && !hierarchyDataLabels.numberFormatPattern
896
+ const hierarchyLabelOpts = hierarchyDataLabels && !hierarchyDataLabels.numberFormatPattern
880
897
  ? { ...hierarchyDataLabels, numberFormatPattern: sizeNumberFormat }
881
- : hierarchyDataLabels, undefined, locale);
898
+ : hierarchyDataLabels;
899
+ const hierarchyLabel = hierarchyLabelOpts?.show === false
900
+ ? { show: false }
901
+ : hierarchyLabelOpts?.show
902
+ ? {
903
+ show: true,
904
+ formatter: dataLabelFormatter(hierarchyLabelOpts, locale, isTreemap ? "\n" : ": "),
905
+ ...(isTreemap ? { position: "insideBottomLeft" } : {}),
906
+ }
907
+ : {
908
+ show: true,
909
+ formatter: "{b}",
910
+ ...(isTreemap ? { position: "insideBottomLeft" } : {}),
911
+ };
912
+ // Reserve a band for the legend (and the title) so neither paints
913
+ // over the blocks (#1086), as the cartesian layout does.
914
+ const hierarchyBand = reserveEchartsLegendBand({
915
+ position: spec.legend?.position,
916
+ visible: legendShown && hierarchyData.length > 0,
917
+ labels: hierarchyData.map((node) => node.name),
918
+ legendFontSize: hierarchyLegend.textStyle?.fontSize ??
919
+ spec.legend?.textFormat?.fontSize ??
920
+ 12,
921
+ legendItemWidth: defaultLegendConfig.itemWidth,
922
+ width: width ?? 0,
923
+ height: height ?? 0,
924
+ hasTitle: Boolean(explicitChartTitle ?? headerTitle),
925
+ titleFontSize: spec.titleTextFormat?.fontSize ?? 16,
926
+ hasBottomAxisTitle: false,
927
+ bottomAxisNameGap: 0,
928
+ hasLeftAxisTitle: false,
929
+ });
882
930
  chartRef.current?.setOption({
883
931
  xAxis: [
884
932
  {
@@ -894,6 +942,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
894
942
  ],
895
943
  legend: {
896
944
  ...hierarchyLegend,
945
+ ...hierarchyBand.legend,
897
946
  data: hierarchyData.map((node) => node.name),
898
947
  selectedMode: false,
899
948
  },
@@ -913,16 +962,22 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
913
962
  name: seriesDisplayName,
914
963
  rootName: rootName || seriesDisplayName || "",
915
964
  data: hierarchyData,
916
- label: {
917
- show: true,
918
- formatter: "{b}",
919
- ...(isTreemap ? { position: "insideBottomLeft" } : {}),
920
- ...(hierarchySeriesLabel ?? {}),
921
- },
965
+ label: hierarchyLabel,
922
966
  // Only `levels[1]` (the categories) may carry a banner; see
923
967
  // buildHierarchyLevels.
924
968
  upperLabel: isTreemap ? { show: false } : undefined,
925
969
  levels,
970
+ ...(isTreemap
971
+ ? {
972
+ // Excel has no wheel zoom / drag pan on a treemap; the
973
+ // sheet keeps scrolling under the pointer (#1086).
974
+ roam: drillDown,
975
+ left: hierarchyBand.grid.left,
976
+ right: hierarchyBand.grid.right,
977
+ top: hierarchyBand.grid.top,
978
+ bottom: hierarchyBand.grid.bottom,
979
+ }
980
+ : {}),
926
981
  // Excel has no drill-down on either chart: zooming into a
927
982
  // branch on click (and the treemap breadcrumb) is opt-in.
928
983
  nodeClick: drillDown
@@ -2418,7 +2473,21 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
2418
2473
  }
2419
2474
  else if (spec.chartType === "histogram") {
2420
2475
  const rawValues = flattenChartDataValues(spec.series, getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map((v) => (typeof v === "number" ? v : Number(v)));
2421
- let { labels, counts } = binHistogram(rawValues, spec.binCount);
2476
+ // A domain names a category column: Excel's "By Category" histogram
2477
+ // / Pareto over categories aggregates the values per category (sum
2478
+ // unless the series says otherwise) instead of binning them (#1087).
2479
+ const histogramDomainSource = spec.domains?.[0]?.sources?.[0];
2480
+ const histogramCategories = histogramDomainSource
2481
+ ? (getDomainValuesFromRange(histogramDomainSource, spec.hiddenDimensionStrategy) ?? [])
2482
+ : [];
2483
+ let { labels, counts } = histogramCategories.length
2484
+ ? aggregateByCategory(histogramCategories, rawValues, spec.series?.[0]?.aggregateType ?? "SUM")
2485
+ : binHistogram(rawValues, spec.binCount, {
2486
+ binSize: spec.binSize,
2487
+ intervalClosed: spec.intervalClosed,
2488
+ overflow: spec.overflow,
2489
+ underflow: spec.underflow,
2490
+ });
2422
2491
  // Pareto — a histogram whose bins are sorted descending with a
2423
2492
  // cumulative-% line overlaid on a secondary 0-100% axis. The
2424
2493
  // authored type arrives as `sourceChartType: "PARETO"` on an
@@ -2448,7 +2517,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
2448
2517
  type: "bar",
2449
2518
  name: spec.series?.[0]?.dataLabel ?? "",
2450
2519
  data: counts,
2451
- barCategoryGap: "1%",
2520
+ // Excel's histogram columns touch unless `gapWidth` says otherwise
2521
+ // (#1087); the gap maps like a column chart's.
2522
+ barCategoryGap: gapWidthToBarCategoryGap(spec.gapWidth ?? 0, { seriesCount: 1 }) ??
2523
+ "0%",
2452
2524
  };
2453
2525
  const histogramColor = spec.series?.[0]?.color;
2454
2526
  if (histogramColor) {
@@ -2458,14 +2530,21 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
2458
2530
  if (isPareto) {
2459
2531
  // Cumulative-% overlay on the secondary axis (yAxisIndex 1);
2460
2532
  // the matching 0-100% axis element is appended with the other
2461
- // value axes below.
2533
+ // value axes below. Excel draws the Pareto line without markers.
2534
+ const paretoLineColor = spec.paretoLineColor;
2462
2535
  chartSeries.push({
2463
2536
  type: "line",
2464
2537
  name: "Cumulative %",
2465
2538
  data: cumulativePercents,
2466
2539
  yAxisIndex: 1,
2467
- symbol: "circle",
2468
- symbolSize: 6,
2540
+ showSymbol: false,
2541
+ symbol: "none",
2542
+ ...(paretoLineColor
2543
+ ? {
2544
+ itemStyle: { color: paretoLineColor },
2545
+ lineStyle: { color: paretoLineColor },
2546
+ }
2547
+ : {}),
2469
2548
  });
2470
2549
  }
2471
2550
  legend.data = [];
@@ -1 +1 @@
1
- {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA6ZxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBAilFjB,CAAC"}
1
+ {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA+ZxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBA4nFjB,CAAC"}
@@ -25,7 +25,7 @@ import { resolvePlotlyClickSelection, wasDragged, } from "../../utils/plotly-cli
25
25
  import { buildPlotlySurfaceTrace } from "../../utils/plotly-surface";
26
26
  import { normalize3DSourceType, } from "../../utils/three-d";
27
27
  import { extractHierarchyRows, getHierarchyHeaderTitle, hierarchyNodeColors, toPlotlyHierarchy, } from "../../utils/hierarchy";
28
- import { binHistogram, computePareto, isParetoSpec, } from "../../utils/histogram";
28
+ import { aggregateByCategory, binHistogram, computePareto, hasExcelBinning, isParetoSpec, } from "../../utils/histogram";
29
29
  import { clampSecondPieSize, isOfPieChartSpec, otherSliceHalfAngle, resolveOfPieType, splitOfPie, } from "../../utils/of-pie";
30
30
  import { buildRadarIndicators } from "../../utils/radar";
31
31
  import { buildSequentialColorRamp, isRegionMapSpec, resolveGeoScope, WORLD_GEO_SCOPE, } from "../../utils/region-map";
@@ -851,9 +851,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
851
851
  ...(isSunburst ? { line: { width: 1 } } : {}),
852
852
  },
853
853
  name: seriesName,
854
- textinfo: "label+value",
854
+ // `dataLabels: { show: false }` turns the labels off (#1086).
855
+ textinfo: spec.dataLabels?.show === false ? "none" : "label+value",
855
856
  branchvalues: "total",
856
- ...(isSunburst
857
+ ...(isSunburst || spec.dataLabels?.show === false
857
858
  ? {}
858
859
  : {
859
860
  textposition: "bottom left",
@@ -1619,12 +1620,29 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
1619
1620
  if (effectiveChartType === "histogram") {
1620
1621
  const rawValues = seriesValuesOf(seriesData);
1621
1622
  const binCount = spec.binCount;
1623
+ const binningOptions = {
1624
+ binSize: spec.binSize,
1625
+ intervalClosed: spec.intervalClosed,
1626
+ overflow: spec.overflow,
1627
+ underflow: spec.underflow,
1628
+ };
1629
+ // A domain names a category column: aggregate per category (Excel's
1630
+ // "By Category" / Pareto over categories) instead of binning
1631
+ // (#1087). Excel binning options also pre-bin with the shared util,
1632
+ // since plotly's native histogram cannot close intervals on the
1633
+ // right or add overflow bins.
1634
+ const categories = domainData;
1635
+ const prebinned = categories.length
1636
+ ? aggregateByCategory(categories, rawValues, series.aggregateType ?? "SUM")
1637
+ : hasExcelBinning(binningOptions)
1638
+ ? binHistogram(rawValues, binCount, binningOptions)
1639
+ : null;
1622
1640
  if (isPareto) {
1623
1641
  // Plotly's native histogram trace bins in axis order and
1624
1642
  // can't reorder bins, so Pareto pre-bins with the shared
1625
1643
  // util, sorts descending, and renders a bar trace plus the
1626
1644
  // cumulative-% line pointed at the y2 overlay axis.
1627
- const { labels, counts, cumulativePercents } = computePareto(binHistogram(rawValues, binCount));
1645
+ const { labels, counts, cumulativePercents } = computePareto(prebinned ?? binHistogram(rawValues, binCount));
1628
1646
  const barTrace = {
1629
1647
  type: "bar",
1630
1648
  x: labels,
@@ -1638,16 +1656,34 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
1638
1656
  effectiveChartType,
1639
1657
  });
1640
1658
  traces.push(barTrace);
1659
+ const paretoLineColor = spec.paretoLineColor;
1660
+ // Excel draws the Pareto line without markers.
1641
1661
  traces.push({
1642
1662
  type: "scatter",
1643
- mode: "lines+markers",
1663
+ mode: "lines",
1644
1664
  x: labels,
1645
1665
  y: cumulativePercents,
1646
1666
  name: "Cumulative %",
1647
1667
  yaxis: "y2",
1668
+ ...(paretoLineColor ? { line: { color: paretoLineColor } } : {}),
1648
1669
  });
1649
1670
  hasSecondaryAxis = true;
1650
1671
  }
1672
+ else if (prebinned) {
1673
+ const barTrace = {
1674
+ type: "bar",
1675
+ x: prebinned.labels,
1676
+ y: prebinned.counts,
1677
+ name: dataLabel,
1678
+ };
1679
+ applyTraceColor(barTrace, series.color ?? undefined, {
1680
+ noFill: series.noFill,
1681
+ dataPointColors: series.dataPointColors,
1682
+ seriesIndex: currentSeriesIndex,
1683
+ effectiveChartType,
1684
+ });
1685
+ traces.push(barTrace);
1686
+ }
1651
1687
  else {
1652
1688
  const trace = {
1653
1689
  type: "histogram",
@@ -2131,7 +2167,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
2131
2167
  // gapWidth=150 (default) → ~0.4 bargap.
2132
2168
  ...(typeof spec.gapWidth === "number"
2133
2169
  ? { bargap: Math.max(0, Math.min(0.95, spec.gapWidth / 400)) }
2134
- : {}),
2170
+ : spec.chartType === "histogram"
2171
+ ? // Excel's histogram columns touch by default (#1087).
2172
+ { bargap: 0 }
2173
+ : {}),
2135
2174
  font: {
2136
2175
  family: "Untitled Sans, apple-system, sans-serif",
2137
2176
  size: 12,
@@ -46,5 +46,11 @@ export declare const toPlotlyHierarchy: (rows: HierarchyRow[]) => PlotlyHierarch
46
46
  * Returns the colour per node of `toPlotlyHierarchy`'s flat arrays.
47
47
  */
48
48
  export declare const hierarchyNodeColors: (hierarchy: Pick<PlotlyHierarchy, "ids" | "parents">, palette: string[]) => string[];
49
+ /**
50
+ * Black or white, whichever reads on `background` (a `#rgb` / `#rrggbb`
51
+ * colour; anything else gets white) — for a treemap banner filled with
52
+ * its category's colour (rowsncolumns/spreadsheet#1086).
53
+ */
54
+ export declare const contrastTextColor: (background: string | undefined) => string;
49
55
  export {};
50
56
  //# sourceMappingURL=hierarchy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hierarchy.d.ts","sourceRoot":"","sources":["../../../utils/hierarchy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,UAAU,EACV,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,KAAK,SAAS,GAAG,CACf,KAAK,EAAE,UAAU,EACjB,cAAc,CAAC,EAAE,SAAS,CAAC,yBAAyB,CAAC,KAClD,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,wBAAwB,EAAE,SAAS,CAAC;IACpC,wBAAwB,EAAE,SAAS,CAAC;IACpC,uBAAuB,CAAC,EAAE,SAAS,CAAC,yBAAyB,CAAC,CAAC;CAChE,CAAC;AA0CF,eAAO,MAAM,uBAAuB,GAClC,MAAM,YAAY,EAClB,SAAS,cAAc,KACtB,MAAM,GAAG,SAgBX,CAAC;AAyCF,eAAO,MAAM,oBAAoB,GAC/B,MAAM,YAAY,EAClB,SAAS,cAAc,KACtB,YAAY,EAiFd,CAAC;AAiDF,eAAO,MAAM,kBAAkB,GAAI,MAAM,YAAY,EAAE,KAAG,aAAa,EAmDtE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,YAAY,EAAE,KAAG,eAwBxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,SAAS,CAAC,EACnD,SAAS,MAAM,EAAE,KAChB,MAAM,EAYR,CAAC"}
1
+ {"version":3,"file":"hierarchy.d.ts","sourceRoot":"","sources":["../../../utils/hierarchy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,UAAU,EACV,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,KAAK,SAAS,GAAG,CACf,KAAK,EAAE,UAAU,EACjB,cAAc,CAAC,EAAE,SAAS,CAAC,yBAAyB,CAAC,KAClD,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,wBAAwB,EAAE,SAAS,CAAC;IACpC,wBAAwB,EAAE,SAAS,CAAC;IACpC,uBAAuB,CAAC,EAAE,SAAS,CAAC,yBAAyB,CAAC,CAAC;CAChE,CAAC;AA0CF,eAAO,MAAM,uBAAuB,GAClC,MAAM,YAAY,EAClB,SAAS,cAAc,KACtB,MAAM,GAAG,SAgBX,CAAC;AAyCF,eAAO,MAAM,oBAAoB,GAC/B,MAAM,YAAY,EAClB,SAAS,cAAc,KACtB,YAAY,EAiFd,CAAC;AAiDF,eAAO,MAAM,kBAAkB,GAAI,MAAM,YAAY,EAAE,KAAG,aAAa,EAmDtE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,YAAY,EAAE,KAAG,eAwBxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,SAAS,CAAC,EACnD,SAAS,MAAM,EAAE,KAChB,MAAM,EAYR,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,GAAG,SAAS,KAAG,MAelE,CAAC"}
@@ -266,3 +266,24 @@ export const hierarchyNodeColors = (hierarchy, palette) => {
266
266
  return color;
267
267
  });
268
268
  };
269
+ /**
270
+ * Black or white, whichever reads on `background` (a `#rgb` / `#rrggbb`
271
+ * colour; anything else gets white) — for a treemap banner filled with
272
+ * its category's colour (rowsncolumns/spreadsheet#1086).
273
+ */
274
+ export const contrastTextColor = (background) => {
275
+ const hex = (background ?? "").trim().replace(/^#/, "");
276
+ const full = hex.length === 3
277
+ ? hex
278
+ .split("")
279
+ .map((c) => c + c)
280
+ .join("")
281
+ : hex;
282
+ if (!/^[0-9a-f]{6}$/i.test(full))
283
+ return "#ffffff";
284
+ const r = parseInt(full.slice(0, 2), 16);
285
+ const g = parseInt(full.slice(2, 4), 16);
286
+ const b = parseInt(full.slice(4, 6), 16);
287
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
288
+ return luminance > 0.6 ? "#000000" : "#ffffff";
289
+ };
@@ -39,8 +39,47 @@ export declare const isParetoSpec: (spec: {
39
39
  */
40
40
  export declare const computePareto: (bins: HistogramBins) => ParetoData;
41
41
  /**
42
- * Bin a set of numeric values into `binCount` equal-width bins.
43
- * When `binCount` is omitted, uses Sturges' rule: ceil(log2(n) + 1).
42
+ * Excel's `<cx:binning>` options (rowsncolumns/spreadsheet#1087). Any of
43
+ * them present switches the histogram to Excel's conventions: intervals
44
+ * closed on the right by default and automatic bins by Excel's rule.
44
45
  */
45
- export declare const binHistogram: (values: (number | null | undefined)[], binCount?: number | null) => HistogramBins;
46
+ export type HistogramBinningOptions = {
47
+ /** Fixed bin width (`<cx:binSize>`); wins over `binCount`. */
48
+ binSize?: number | null;
49
+ /** Which side of an interval is closed (`intervalClosed`); Excel's default is `r`. */
50
+ intervalClosed?: "l" | "r" | null;
51
+ /** Values above this collect in a final `> overflow` bin. */
52
+ overflow?: number | null;
53
+ /** Values below this collect in a first `< underflow` bin. */
54
+ underflow?: number | null;
55
+ };
56
+ /** True when the spec authored any Excel binning option. */
57
+ export declare const hasExcelBinning: (options: HistogramBinningOptions | null | undefined) => boolean;
58
+ /**
59
+ * Excel's automatic bin width: Scott's normal reference rule,
60
+ * 3.5 · σ / ∛n with the sample standard deviation, rounded up to two
61
+ * significant digits. For the 20 values 12 … 95 of #1087 (σ ≈ 23.86) that
62
+ * is 30.77 → 31, i.e. Excel's three bins [12, 43], (43, 74], (74, 105].
63
+ */
64
+ export declare const excelAutoBinWidth: (numeric: number[]) => number;
65
+ /**
66
+ * Bin a set of numeric values into equal-width bins.
67
+ *
68
+ * Default (no Excel options): `binCount` bins over [min, max], closed on
69
+ * the left — or Sturges' rule, ceil(log2(n) + 1), when `binCount` is
70
+ * omitted. With Excel binning options (#1087): bins start at the minimum
71
+ * (or the underflow bound), are `binSize` wide — else (max − min) /
72
+ * `binCount`, else Excel's automatic width — closed on the right unless
73
+ * `intervalClosed` is `l`, and values beyond `overflow` / `underflow`
74
+ * collect in their own end bins.
75
+ */
76
+ export declare const binHistogram: (values: (number | null | undefined)[], binCount?: number | null, options?: HistogramBinningOptions | null) => HistogramBins;
77
+ export type HistogramAggregateType = "SUM" | "AVERAGE" | "COUNT" | "MAX" | "MIN" | "MEDIAN";
78
+ /**
79
+ * Excel's histogram "By Category" / Pareto over categories
80
+ * (`<cx:aggregation/>`, #1087): one column per distinct category in order
81
+ * of first appearance, its value the aggregate (sum by default) of the
82
+ * series values of that category — instead of binning the values.
83
+ */
84
+ export declare const aggregateByCategory: (categories: (string | number | null | undefined)[], values: (number | null | undefined)[], aggregateType?: HistogramAggregateType | null | undefined) => HistogramBins;
46
85
  //# sourceMappingURL=histogram.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"histogram.d.ts","sourceRoot":"","sources":["../../../utils/histogram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,gDAAgD;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,KAAG,OAGgD,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,aAAa,KAAG,UAmBnD,CAAC;AASF;;;GAGG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,WAAW,MAAM,GAAG,IAAI,KACvB,aA0CF,CAAC"}
1
+ {"version":3,"file":"histogram.d.ts","sourceRoot":"","sources":["../../../utils/histogram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,gDAAgD;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,KAAG,OAGgD,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,aAAa,KAAG,UAmBnD,CAAC;AAUF;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sFAAsF;IACtF,cAAc,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAKF,4DAA4D;AAC5D,eAAO,MAAM,eAAe,GAC1B,SAAS,uBAAuB,GAAG,IAAI,GAAG,SAAS,KAClD,OAQA,CAAC;AASJ;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,EAAE,KAAG,MASrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,WAAW,MAAM,GAAG,IAAI,EACxB,UAAU,uBAAuB,GAAG,IAAI,KACvC,aA4CF,CAAC;AAiFF,MAAM,MAAM,sBAAsB,GAC9B,KAAK,GACL,SAAS,GACT,OAAO,GACP,KAAK,GACL,KAAK,GACL,QAAQ,CAAC;AAEb;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC9B,YAAY,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAClD,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,gBAAe,sBAAsB,GAAG,IAAI,GAAG,SAAiB,KAC/D,aA0CF,CAAC"}
@@ -45,17 +45,58 @@ export const computePareto = (bins) => {
45
45
  const formatBinBound = (value) => {
46
46
  if (!Number.isFinite(value))
47
47
  return String(value);
48
+ if (value === 0)
49
+ return "0";
48
50
  const abs = Math.abs(value);
49
51
  if (abs >= 1000 || abs < 0.01)
50
52
  return value.toExponential(2);
51
53
  return Number.parseFloat(value.toFixed(2)).toString();
52
54
  };
55
+ const isFinite_ = (v) => typeof v === "number" && Number.isFinite(v);
56
+ /** True when the spec authored any Excel binning option. */
57
+ export const hasExcelBinning = (options) => Boolean(options &&
58
+ (isFinite_(options.binSize) ||
59
+ options.intervalClosed === "l" ||
60
+ options.intervalClosed === "r" ||
61
+ isFinite_(options.overflow) ||
62
+ isFinite_(options.underflow)));
63
+ /** Round up to two significant digits (31 for 30.77, 0.038 for 0.0377). */
64
+ const ceilToTwoSignificant = (value) => {
65
+ if (!(value > 0))
66
+ return value;
67
+ const magnitude = 10 ** (Math.floor(Math.log10(value)) - 1);
68
+ return Math.ceil(value / magnitude - 1e-9) * magnitude;
69
+ };
70
+ /**
71
+ * Excel's automatic bin width: Scott's normal reference rule,
72
+ * 3.5 · σ / ∛n with the sample standard deviation, rounded up to two
73
+ * significant digits. For the 20 values 12 … 95 of #1087 (σ ≈ 23.86) that
74
+ * is 30.77 → 31, i.e. Excel's three bins [12, 43], (43, 74], (74, 105].
75
+ */
76
+ export const excelAutoBinWidth = (numeric) => {
77
+ const n = numeric.length;
78
+ if (n < 2)
79
+ return 1;
80
+ const mean = numeric.reduce((sum, v) => sum + v, 0) / n;
81
+ const variance = numeric.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (n - 1);
82
+ const sigma = Math.sqrt(variance);
83
+ if (!(sigma > 0))
84
+ return 1;
85
+ return ceilToTwoSignificant((3.5 * sigma) / Math.cbrt(n));
86
+ };
53
87
  /**
54
- * Bin a set of numeric values into `binCount` equal-width bins.
55
- * When `binCount` is omitted, uses Sturges' rule: ceil(log2(n) + 1).
88
+ * Bin a set of numeric values into equal-width bins.
89
+ *
90
+ * Default (no Excel options): `binCount` bins over [min, max], closed on
91
+ * the left — or Sturges' rule, ceil(log2(n) + 1), when `binCount` is
92
+ * omitted. With Excel binning options (#1087): bins start at the minimum
93
+ * (or the underflow bound), are `binSize` wide — else (max − min) /
94
+ * `binCount`, else Excel's automatic width — closed on the right unless
95
+ * `intervalClosed` is `l`, and values beyond `overflow` / `underflow`
96
+ * collect in their own end bins.
56
97
  */
57
- export const binHistogram = (values, binCount) => {
58
- const numeric = values.filter((v) => typeof v === "number" && Number.isFinite(v));
98
+ export const binHistogram = (values, binCount, options) => {
99
+ const numeric = values.filter(isFinite_);
59
100
  if (numeric.length === 0) {
60
101
  return { labels: [], counts: [] };
61
102
  }
@@ -67,6 +108,9 @@ export const binHistogram = (values, binCount) => {
67
108
  if (v > max)
68
109
  max = v;
69
110
  }
111
+ if (hasExcelBinning(options)) {
112
+ return binExcel(numeric, min, max, binCount, options);
113
+ }
70
114
  const sturges = Math.max(1, Math.ceil(Math.log2(numeric.length) + 1));
71
115
  const bins = typeof binCount === "number" && binCount > 0
72
116
  ? Math.floor(binCount)
@@ -93,3 +137,126 @@ export const binHistogram = (values, binCount) => {
93
137
  }
94
138
  return { labels, counts };
95
139
  };
140
+ const binExcel = (numeric, min, max, binCount, options) => {
141
+ const rightClosed = options.intervalClosed !== "l";
142
+ const underflow = isFinite_(options.underflow) ? options.underflow : null;
143
+ const overflow = isFinite_(options.overflow) ? options.overflow : null;
144
+ // The regular bins span the values between the end bins.
145
+ const inRange = numeric.filter((v) => (underflow === null || v >= underflow) &&
146
+ (overflow === null || v <= overflow));
147
+ const start = underflow ?? (inRange.length ? Math.min(...inRange) : min);
148
+ const end = overflow ?? (inRange.length ? Math.max(...inRange) : max);
149
+ const span = end - start;
150
+ let width;
151
+ if (isFinite_(options.binSize) && options.binSize > 0) {
152
+ width = options.binSize;
153
+ }
154
+ else if (typeof binCount === "number" && binCount > 0) {
155
+ width = span > 0 ? span / Math.floor(binCount) : 1;
156
+ }
157
+ else {
158
+ width = excelAutoBinWidth(inRange.length ? inRange : numeric);
159
+ }
160
+ // Enough bins to reach the last value; a right-closed layout needs one
161
+ // more when the span is an exact multiple (the boundary value belongs to
162
+ // the bin below, so the top bin stays).
163
+ let bins = span > 0 ? Math.ceil(span / width - 1e-9) : 1;
164
+ bins = Math.max(1, bins);
165
+ const counts = new Array(bins).fill(0);
166
+ const edges = Array.from({ length: bins + 1 }, (_, i) => start + width * i);
167
+ let under = 0;
168
+ let over = 0;
169
+ for (const v of numeric) {
170
+ if (underflow !== null && v < underflow) {
171
+ under++;
172
+ continue;
173
+ }
174
+ if (overflow !== null && v > overflow) {
175
+ over++;
176
+ continue;
177
+ }
178
+ let idx;
179
+ if (rightClosed) {
180
+ // (lo, hi]: a value on a boundary belongs to the bin below it; the
181
+ // first bin also takes its own lower bound.
182
+ idx = Math.ceil((v - start) / width - 1e-9) - 1;
183
+ if (idx < 0)
184
+ idx = 0;
185
+ }
186
+ else {
187
+ idx = Math.floor((v - start) / width + 1e-9);
188
+ }
189
+ if (idx >= bins)
190
+ idx = bins - 1;
191
+ counts[idx]++;
192
+ }
193
+ const labels = edges.slice(0, -1).map((lo, i) => {
194
+ const hi = edges[i + 1];
195
+ if (rightClosed) {
196
+ const opening = i === 0 ? "[" : "(";
197
+ return `${opening}${formatBinBound(lo)}, ${formatBinBound(hi)}]`;
198
+ }
199
+ const closing = i === bins - 1 ? "]" : ")";
200
+ return `[${formatBinBound(lo)}, ${formatBinBound(hi)}${closing}`;
201
+ });
202
+ if (underflow !== null) {
203
+ labels.unshift(`< ${formatBinBound(underflow)}`);
204
+ counts.unshift(under);
205
+ }
206
+ if (overflow !== null) {
207
+ labels.push(`> ${formatBinBound(overflow)}`);
208
+ counts.push(over);
209
+ }
210
+ return { labels, counts };
211
+ };
212
+ /**
213
+ * Excel's histogram "By Category" / Pareto over categories
214
+ * (`<cx:aggregation/>`, #1087): one column per distinct category in order
215
+ * of first appearance, its value the aggregate (sum by default) of the
216
+ * series values of that category — instead of binning the values.
217
+ */
218
+ export const aggregateByCategory = (categories, values, aggregateType = "SUM") => {
219
+ const groups = new Map();
220
+ const order = [];
221
+ const count = Math.max(categories.length, values.length);
222
+ for (let i = 0; i < count; i++) {
223
+ const raw = categories[i];
224
+ const label = raw === null || raw === undefined ? "" : `${raw}`.trim();
225
+ if (label === "")
226
+ continue;
227
+ if (!groups.has(label)) {
228
+ groups.set(label, []);
229
+ order.push(label);
230
+ }
231
+ const v = values[i];
232
+ if (isFinite_(v))
233
+ groups.get(label).push(v);
234
+ }
235
+ const reduce = (nums) => {
236
+ if (nums.length === 0)
237
+ return 0;
238
+ switch (aggregateType ?? "SUM") {
239
+ case "COUNT":
240
+ return nums.length;
241
+ case "AVERAGE":
242
+ return nums.reduce((a, b) => a + b, 0) / nums.length;
243
+ case "MAX":
244
+ return Math.max(...nums);
245
+ case "MIN":
246
+ return Math.min(...nums);
247
+ case "MEDIAN": {
248
+ const sorted = [...nums].sort((a, b) => a - b);
249
+ const mid = Math.floor(sorted.length / 2);
250
+ return sorted.length % 2
251
+ ? sorted[mid]
252
+ : (sorted[mid - 1] + sorted[mid]) / 2;
253
+ }
254
+ default:
255
+ return nums.reduce((a, b) => a + b, 0);
256
+ }
257
+ };
258
+ return {
259
+ labels: order,
260
+ counts: order.map((label) => reduce(groups.get(label) ?? [])),
261
+ };
262
+ };
@@ -8,7 +8,7 @@ export declare const applyLegendOverrides: (legend: LegendComponentOption, opts:
8
8
  * becomes the tick-label formatter.
9
9
  */
10
10
  export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string, locale?: string) => any;
11
- export declare const dataLabelFormatter: (opts: any, locale?: string) => (params: any) => string;
11
+ export declare const dataLabelFormatter: (opts: any, locale?: string, joiner?: string) => (params: any) => string;
12
12
  /**
13
13
  * The data-label options one series renders with: its own
14
14
  * `ChartData.dataLabels` when it has them (OOXML's `<c:ser><c:dLbls>`
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAAI,MAAM,GAAG,EAAE,SAAS,MAAM,MAAM,QAAQ,GAAG,WAoD7E,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlG0D,GAAG;aA+G7E,CAAC"}
1
+ {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,SAAS,MAAM,EAEf,eAAa,MACT,QAAQ,GAAG,WAoDhB,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlGH,GAAG;aA+GhB,CAAC"}