@rowsncolumns/charts 28.1.14 → 28.1.15
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/cjs/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/basic-chart/basic-chart.js +308 -270
- package/dist/cjs/components/editors/chart-editor-capabilities.d.ts +48 -0
- package/dist/cjs/components/editors/chart-editor-capabilities.d.ts.map +1 -0
- package/dist/cjs/components/editors/chart-editor-capabilities.js +62 -0
- package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/chart-editor.js +200 -534
- package/dist/cjs/components/editors/fields/axis-options-fields.d.ts +16 -0
- package/dist/cjs/components/editors/fields/axis-options-fields.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/axis-options-fields.js +31 -0
- package/dist/cjs/components/editors/fields/chart-type-options.d.ts +25 -0
- package/dist/cjs/components/editors/fields/chart-type-options.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/chart-type-options.js +170 -0
- package/dist/cjs/components/editors/fields/data-labels-fields.d.ts +15 -0
- package/dist/cjs/components/editors/fields/data-labels-fields.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/data-labels-fields.js +57 -0
- package/dist/cjs/components/editors/fields/primitives.d.ts +54 -0
- package/dist/cjs/components/editors/fields/primitives.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/primitives.js +52 -0
- package/dist/cjs/components/editors/fields/series-format-fields.d.ts +17 -0
- package/dist/cjs/components/editors/fields/series-format-fields.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/series-format-fields.js +165 -0
- package/dist/cjs/components/editors/fields/series-name-field.d.ts +16 -0
- package/dist/cjs/components/editors/fields/series-name-field.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/series-name-field.js +36 -0
- package/dist/cjs/components/editors/fields/text-format-fields.d.ts +20 -0
- package/dist/cjs/components/editors/fields/text-format-fields.d.ts.map +1 -0
- package/dist/cjs/components/editors/fields/text-format-fields.js +46 -0
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +3 -0
- package/dist/cjs/interface/create-chart.d.ts +3 -2
- package/dist/cjs/interface/create-chart.d.ts.map +1 -1
- package/dist/cjs/interface/create-chart.js +7 -0
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +255 -218
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/chart-orientation.d.ts.map +1 -1
- package/dist/cjs/utils/chart-orientation.js +24 -12
- package/dist/cjs/utils/chart-spec-utils.d.ts.map +1 -1
- package/dist/cjs/utils/chart-spec-utils.js +120 -21
- package/dist/cjs/utils/echarts-overlays.d.ts +2 -0
- package/dist/cjs/utils/echarts-overlays.d.ts.map +1 -1
- package/dist/cjs/utils/echarts-overlays.js +25 -12
- package/dist/cjs/utils/series-name.d.ts +12 -0
- package/dist/cjs/utils/series-name.d.ts.map +1 -0
- package/dist/cjs/utils/series-name.js +26 -0
- package/dist/cjs/utils/trendline.d.ts +9 -0
- package/dist/cjs/utils/trendline.d.ts.map +1 -1
- package/dist/cjs/utils/trendline.js +16 -1
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +73 -37
- package/dist/esm/components/editors/chart-editor-capabilities.d.ts +48 -0
- package/dist/esm/components/editors/chart-editor-capabilities.d.ts.map +1 -0
- package/dist/esm/components/editors/chart-editor-capabilities.js +58 -0
- package/dist/esm/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/chart-editor.js +166 -448
- package/dist/esm/components/editors/fields/axis-options-fields.d.ts +16 -0
- package/dist/esm/components/editors/fields/axis-options-fields.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/axis-options-fields.js +22 -0
- package/dist/esm/components/editors/fields/chart-type-options.d.ts +25 -0
- package/dist/esm/components/editors/fields/chart-type-options.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/chart-type-options.js +151 -0
- package/dist/esm/components/editors/fields/data-labels-fields.d.ts +15 -0
- package/dist/esm/components/editors/fields/data-labels-fields.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/data-labels-fields.js +47 -0
- package/dist/esm/components/editors/fields/primitives.d.ts +54 -0
- package/dist/esm/components/editors/fields/primitives.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/primitives.js +26 -0
- package/dist/esm/components/editors/fields/series-format-fields.d.ts +17 -0
- package/dist/esm/components/editors/fields/series-format-fields.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/series-format-fields.js +143 -0
- package/dist/esm/components/editors/fields/series-name-field.d.ts +16 -0
- package/dist/esm/components/editors/fields/series-name-field.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/series-name-field.js +31 -0
- package/dist/esm/components/editors/fields/text-format-fields.d.ts +20 -0
- package/dist/esm/components/editors/fields/text-format-fields.d.ts.map +1 -0
- package/dist/esm/components/editors/fields/text-format-fields.js +34 -0
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +3 -0
- package/dist/esm/interface/create-chart.d.ts +3 -2
- package/dist/esm/interface/create-chart.d.ts.map +1 -1
- package/dist/esm/interface/create-chart.js +8 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +52 -30
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/chart-orientation.d.ts.map +1 -1
- package/dist/esm/utils/chart-orientation.js +20 -0
- package/dist/esm/utils/chart-spec-utils.d.ts.map +1 -1
- package/dist/esm/utils/chart-spec-utils.js +95 -8
- package/dist/esm/utils/echarts-overlays.d.ts +2 -0
- package/dist/esm/utils/echarts-overlays.d.ts.map +1 -1
- package/dist/esm/utils/echarts-overlays.js +15 -1
- package/dist/esm/utils/series-name.d.ts +12 -0
- package/dist/esm/utils/series-name.d.ts.map +1 -0
- package/dist/esm/utils/series-name.js +24 -0
- package/dist/esm/utils/trendline.d.ts +9 -0
- package/dist/esm/utils/trendline.d.ts.map +1 -1
- package/dist/esm/utils/trendline.js +14 -0
- package/package.json +3 -3
|
@@ -14,27 +14,28 @@ import { circularTooltipFormatter, formatAxisValue, resolveSeriesNumberFormats,
|
|
|
14
14
|
import { gapWidthToBarCategoryGap, overlapToBarGap, } from "../utils/bar-layout";
|
|
15
15
|
import { computeBoxplotSummary } from "../utils/boxplot";
|
|
16
16
|
import { createBubbleSizeScale, prepareBubbleSeriesData, } from "../utils/bubble";
|
|
17
|
-
import {
|
|
18
|
-
import { canSwitchRowColumn, cellLabelGetterFromRangeReader, switchRowColumn, } from "../utils/chart-orientation";
|
|
17
|
+
import { echartsGroupedCategoryAxes, resolveCategoryLevels, } from "../utils/category-levels";
|
|
19
18
|
import { dataUrlToBlob } from "../utils/chart-image";
|
|
19
|
+
import { canSwitchRowColumn, cellLabelGetterFromRangeReader, switchRowColumn, } from "../utils/chart-orientation";
|
|
20
|
+
import { coerceCalculatedLabel, getChartDataRanges, } from "../utils/chart-spec-utils";
|
|
20
21
|
import { getChartPalette } from "../utils/chart-styles";
|
|
21
|
-
import {
|
|
22
|
-
import { applyEmptyCellsPolicy, connectsAcrossEmptyCells, isolatedPointIndexes, isLineLikeChartType, } from "../utils/empty-cells";
|
|
22
|
+
import { clampDoughnutHole, doughnutRings } from "../utils/doughnut";
|
|
23
23
|
import { getEchartsGlState, loadEchartsGl, } from "../utils/echarts-gl-loader";
|
|
24
|
-
import {
|
|
24
|
+
import { buildEchartsOverlaySeries } from "../utils/echarts-overlays";
|
|
25
|
+
import { applyEmptyCellsPolicy, connectsAcrossEmptyCells, isLineLikeChartType, isolatedPointIndexes, } from "../utils/empty-cells";
|
|
25
26
|
import { gradientToEcharts } from "../utils/gradient";
|
|
26
27
|
import { buildHierarchyTree, contrastTextColor, extractHierarchyRows, getHierarchyHeaderTitle, } from "../utils/hierarchy";
|
|
27
28
|
import { aggregateByCategory, binHistogram, computePareto, isParetoSpec, } from "../utils/histogram";
|
|
28
29
|
import { categoryAxisNameGap, legendLabelsFrom, reserveEchartsLegendBand, } from "../utils/legend-layout";
|
|
29
30
|
import { clampSecondPieSize, isOfPieChartSpec, otherSliceHalfAngle, resolveOfPieType, splitOfPie, } from "../utils/of-pie";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
31
|
+
import { applyAxisOverrides, applyLegendOverrides, buildSeriesLabelOption, dataLabelFormatter, resolveSeriesDataLabels, } from "../utils/overrides";
|
|
32
|
+
import { explosionOffsetPx, pieRadiusPx, resolveExplosion, } from "../utils/pie-explosion";
|
|
32
33
|
import { buildRadarIndicators, buildRadarSeriesData } from "../utils/radar";
|
|
33
34
|
import { buildRegionMapData, buildSequentialColorRamp, isRegionMapSpec, resolveGeoScope, warnOnceForUnmatchedRegions, } from "../utils/region-map";
|
|
34
35
|
import { loadRegionMapGeo } from "../utils/region-map-loader";
|
|
35
|
-
import { STOCK_ROLES, toCandlestick, toLineSeries, toVolumeSeries, } from "../utils/stock";
|
|
36
|
-
import { explosionOffsetPx, pieRadiusPx, resolveExplosion, } from "../utils/pie-explosion";
|
|
37
36
|
import { chartSeriesId, chartSeriesSpecIndex, resolveClickedDataIndex, resolveClickedSeriesIndex, } from "../utils/series-click";
|
|
37
|
+
import { linkedSeriesName } from "../utils/series-name";
|
|
38
|
+
import { STOCK_ROLES, toCandlestick, toLineSeries, toVolumeSeries, } from "../utils/stock";
|
|
38
39
|
import { buildBar3DData, buildContourData, buildLine3DSeries, buildSurfaceData, getCategoryCount, getValueExtent, isContourSpec, resolve3DRenderKind, SURFACE_COLOR_RAMP, } from "../utils/three-d";
|
|
39
40
|
import { computeWaterfall } from "../utils/waterfall";
|
|
40
41
|
import { isWebGLAvailable } from "../utils/webgl";
|
|
@@ -518,9 +519,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
518
519
|
: "rgba(0,0,0,0.06)";
|
|
519
520
|
const borderColor = isDarkMode ? "rgba(255,255,255,0.3)" : "#FFFFFF";
|
|
520
521
|
const regionSeriesLabel = buildSeriesLabelOption(spec.dataLabels, undefined, locale);
|
|
521
|
-
const seriesName = seriesEntry
|
|
522
|
-
|
|
523
|
-
|
|
522
|
+
const seriesName = linkedSeriesName(seriesEntry, getDomainValuesFromRange) ??
|
|
523
|
+
(seriesEntry?.dataLabel && !isAFormula(seriesEntry.dataLabel)
|
|
524
|
+
? seriesEntry.dataLabel
|
|
525
|
+
: "");
|
|
524
526
|
chartRef.current?.setOption({
|
|
525
527
|
// The visualMap color scale is the value legend; the series
|
|
526
528
|
// legend stays hidden unless an authored override turns it on.
|
|
@@ -576,6 +578,8 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
576
578
|
previousSeriesCount.current = 1;
|
|
577
579
|
return;
|
|
578
580
|
}
|
|
581
|
+
// Box & whisker: hidden value x-axis the point overlays are plotted on.
|
|
582
|
+
let boxplotOverlayAxis;
|
|
579
583
|
const chartDomains = [];
|
|
580
584
|
const chartSeries = [];
|
|
581
585
|
const legend = { ...defaultLegendConfig, data: [] };
|
|
@@ -597,8 +601,9 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
597
601
|
const seriesInputs = [];
|
|
598
602
|
for (let i = 0; i < spec.series.length; i++) {
|
|
599
603
|
const seriesEntry = spec.series[i];
|
|
600
|
-
|
|
601
|
-
|
|
604
|
+
const linkedLabel = linkedSeriesName(seriesEntry, getDomainValuesFromRange);
|
|
605
|
+
let resolvedLabel = linkedLabel ?? seriesEntry.dataLabel ?? "";
|
|
606
|
+
if (linkedLabel === undefined && resolvedLabel && isAFormula(resolvedLabel)) {
|
|
602
607
|
resolvedLabel = coerceCalculatedLabel(await onRequestCalculate(resolvedLabel, position.sheetId ?? sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex));
|
|
603
608
|
}
|
|
604
609
|
const xValues = perSeriesX[i] ?? perSeriesX[0];
|
|
@@ -1044,9 +1049,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1044
1049
|
const categories = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, false).map((v) => String(v ?? ""));
|
|
1045
1050
|
const contourSeriesInputs = [];
|
|
1046
1051
|
for (const seriesEntry of spec.series ?? []) {
|
|
1047
|
-
const dataLabel =
|
|
1048
|
-
|
|
1049
|
-
|
|
1052
|
+
const dataLabel = linkedSeriesName(seriesEntry, getDomainValuesFromRange) ??
|
|
1053
|
+
(!isNil(seriesEntry.dataLabel) && isAFormula(seriesEntry.dataLabel)
|
|
1054
|
+
? coerceCalculatedLabel(await onRequestCalculate(seriesEntry.dataLabel, position.sheetId ?? sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex))
|
|
1055
|
+
: seriesEntry.dataLabel ?? "");
|
|
1050
1056
|
const values = flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map(sanitizeChartValue);
|
|
1051
1057
|
contourSeriesInputs.push({ name: dataLabel, values });
|
|
1052
1058
|
}
|
|
@@ -1163,9 +1169,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1163
1169
|
const categories = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, false).map((v) => String(v ?? ""));
|
|
1164
1170
|
const threeDSeriesInputs = [];
|
|
1165
1171
|
for (const seriesEntry of spec.series ?? []) {
|
|
1166
|
-
const dataLabel =
|
|
1167
|
-
|
|
1168
|
-
|
|
1172
|
+
const dataLabel = linkedSeriesName(seriesEntry, getDomainValuesFromRange) ??
|
|
1173
|
+
(!isNil(seriesEntry.dataLabel) && isAFormula(seriesEntry.dataLabel)
|
|
1174
|
+
? coerceCalculatedLabel(await onRequestCalculate(seriesEntry.dataLabel, position.sheetId ?? sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex))
|
|
1175
|
+
: seriesEntry.dataLabel ?? "");
|
|
1169
1176
|
const values = flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map(sanitizeChartValue);
|
|
1170
1177
|
threeDSeriesInputs.push({ name: dataLabel, values });
|
|
1171
1178
|
}
|
|
@@ -1368,9 +1375,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1368
1375
|
const categories = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, skipHeaders);
|
|
1369
1376
|
const radarSeriesInputs = [];
|
|
1370
1377
|
for (const seriesEntry of spec.series ?? []) {
|
|
1371
|
-
const label = seriesEntry
|
|
1372
|
-
|
|
1373
|
-
|
|
1378
|
+
const label = linkedSeriesName(seriesEntry, getDomainValuesFromRange) ??
|
|
1379
|
+
(seriesEntry.dataLabel && !isAFormula(seriesEntry.dataLabel)
|
|
1380
|
+
? seriesEntry.dataLabel
|
|
1381
|
+
: "");
|
|
1374
1382
|
const values = flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map((v) => (typeof v === "number" ? v : Number(v)));
|
|
1375
1383
|
radarSeriesInputs.push({ name: label, values });
|
|
1376
1384
|
}
|
|
@@ -1856,9 +1864,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1856
1864
|
]);
|
|
1857
1865
|
const paletteColorAt = (index) => chartPaletteColorAt(seriesPalette, index);
|
|
1858
1866
|
for (const [specSeriesIndex, series] of (spec.series ?? []).entries()) {
|
|
1859
|
-
const dataLabel =
|
|
1860
|
-
|
|
1861
|
-
|
|
1867
|
+
const dataLabel = linkedSeriesName(series, getDomainValuesFromRange) ??
|
|
1868
|
+
(!isNil(series.dataLabel) && isAFormula(series.dataLabel)
|
|
1869
|
+
? coerceCalculatedLabel(await onRequestCalculate(series.dataLabel, position.sheetId ?? sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex))
|
|
1870
|
+
: series.dataLabel ?? "");
|
|
1862
1871
|
// Label
|
|
1863
1872
|
if (dataLabel) {
|
|
1864
1873
|
legend.data?.push(dataLabel);
|
|
@@ -2464,7 +2473,9 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2464
2473
|
}
|
|
2465
2474
|
}
|
|
2466
2475
|
const boxSeriesSpecs = spec.series ?? [];
|
|
2467
|
-
|
|
2476
|
+
// Without a category domain every series is one box and all of them
|
|
2477
|
+
// share a single category group, as Excel draws it (axis label "1").
|
|
2478
|
+
const slots = grouped ? groups : ["1"];
|
|
2468
2479
|
// Excel sizes the boxes like columns: gapWidth is a percentage of the
|
|
2469
2480
|
// box width (default 150). echarts' boxplot only clamps its width
|
|
2470
2481
|
// (`boxWidth`), so the clamp is the box width that gap allows in the
|
|
@@ -2474,9 +2485,20 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2474
2485
|
const boxBand = slots.length ? boxPlotWidth / slots.length : boxPlotWidth;
|
|
2475
2486
|
const boxWidthMax = Math.max(2, Math.round(boxBand / (Math.max(1, boxSeriesSpecs.length) + boxGap / 100)));
|
|
2476
2487
|
const boxCount = Math.max(1, boxSeriesSpecs.length);
|
|
2477
|
-
//
|
|
2478
|
-
//
|
|
2479
|
-
|
|
2488
|
+
// echarts lays a category's boxes out side by side (boxplotLayout:
|
|
2489
|
+
// 80% of the band minus 2px, a 30% gap between boxes, the clamp only
|
|
2490
|
+
// narrows a box around its centre). The outliers, inner points and
|
|
2491
|
+
// means of a series must sit on that series' box, so they are plotted
|
|
2492
|
+
// on a hidden value axis spanning the same bands (a category axis
|
|
2493
|
+
// rounds a fractional position to the band centre, #1099).
|
|
2494
|
+
const boxCentre = (slotIndex, seriesIndex) => {
|
|
2495
|
+
const band = Math.max(1, boxBand);
|
|
2496
|
+
const available = band * 0.8 - 2;
|
|
2497
|
+
const gap = (available / boxCount) * 0.3;
|
|
2498
|
+
const boxWidth = (available - gap * (boxCount - 1)) / boxCount;
|
|
2499
|
+
const offset = boxWidth / 2 - available / 2 + seriesIndex * (gap + boxWidth);
|
|
2500
|
+
return slotIndex + offset / band;
|
|
2501
|
+
};
|
|
2480
2502
|
chartDomains.length = 0;
|
|
2481
2503
|
chartDomains.push({
|
|
2482
2504
|
type: "category",
|
|
@@ -2489,12 +2511,23 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2489
2511
|
nameLocation: "middle",
|
|
2490
2512
|
nameGap: 30,
|
|
2491
2513
|
});
|
|
2514
|
+
boxplotOverlayAxis = {
|
|
2515
|
+
type: "value",
|
|
2516
|
+
min: -0.5,
|
|
2517
|
+
max: slots.length - 0.5,
|
|
2518
|
+
show: false,
|
|
2519
|
+
axisLine: { show: false },
|
|
2520
|
+
axisTick: { show: false },
|
|
2521
|
+
axisLabel: { show: false },
|
|
2522
|
+
splitLine: { show: false },
|
|
2523
|
+
};
|
|
2492
2524
|
chartSeries.length = 0;
|
|
2493
2525
|
const boxLegend = [];
|
|
2494
2526
|
boxSeriesSpecs.forEach((seriesEntry, seriesIndex) => {
|
|
2495
|
-
const label = seriesEntry
|
|
2496
|
-
|
|
2497
|
-
|
|
2527
|
+
const label = linkedSeriesName(seriesEntry, getDomainValuesFromRange) ??
|
|
2528
|
+
(seriesEntry.dataLabel && !isAFormula(seriesEntry.dataLabel)
|
|
2529
|
+
? seriesEntry.dataLabel
|
|
2530
|
+
: "");
|
|
2498
2531
|
const rawValues = flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map((v) => (typeof v === "number" ? v : Number(v)));
|
|
2499
2532
|
const color = seriesEntry.color ?? paletteColorAt(seriesIndex);
|
|
2500
2533
|
const boxData = [];
|
|
@@ -2504,7 +2537,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2504
2537
|
const meanLine = [];
|
|
2505
2538
|
const slotValues = grouped
|
|
2506
2539
|
? groups.map((g) => rawValues.filter((_, i) => boxCategories[i] === g))
|
|
2507
|
-
:
|
|
2540
|
+
: [rawValues];
|
|
2508
2541
|
slotValues.forEach((values, slotIndex) => {
|
|
2509
2542
|
const summary = computeBoxplotSummary(values, { quartileMethod });
|
|
2510
2543
|
if (!summary) {
|
|
@@ -2522,7 +2555,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2522
2555
|
summary.upperWhisker,
|
|
2523
2556
|
]);
|
|
2524
2557
|
meanLine.push(summary.mean);
|
|
2525
|
-
const x =
|
|
2558
|
+
const x = boxCentre(slotIndex, seriesIndex);
|
|
2526
2559
|
if (showOutliers) {
|
|
2527
2560
|
for (const outlier of summary.outliers)
|
|
2528
2561
|
outlierPoints.push([x, outlier]);
|
|
@@ -2551,6 +2584,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2551
2584
|
type: "scatter",
|
|
2552
2585
|
name,
|
|
2553
2586
|
data: points,
|
|
2587
|
+
xAxisIndex: 1,
|
|
2554
2588
|
itemStyle: { color },
|
|
2555
2589
|
tooltip: { show: false },
|
|
2556
2590
|
...extra,
|
|
@@ -2568,7 +2602,8 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2568
2602
|
chartSeries.push({
|
|
2569
2603
|
type: "line",
|
|
2570
2604
|
name: "",
|
|
2571
|
-
|
|
2605
|
+
xAxisIndex: 1,
|
|
2606
|
+
data: meanLine.map((m, slotIndex) => m === null ? null : [boxCentre(slotIndex, seriesIndex), m]),
|
|
2572
2607
|
showSymbol: false,
|
|
2573
2608
|
lineStyle: { color, type: "dashed", width: 1 },
|
|
2574
2609
|
itemStyle: { color },
|
|
@@ -2983,7 +3018,8 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2983
3018
|
nameGap: CATEGORY_AXIS_NAME_GAP,
|
|
2984
3019
|
},
|
|
2985
3020
|
];
|
|
2986
|
-
|
|
3021
|
+
const axes = base.map((axis) => applyAxisOverrides(axis, spec.categoryAxisOptions));
|
|
3022
|
+
return boxplotOverlayAxis ? [...axes, boxplotOverlayAxis] : axes;
|
|
2987
3023
|
})(),
|
|
2988
3024
|
yAxis: (() => {
|
|
2989
3025
|
if (isOfPie) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { EmbeddedChart } from "@rowsncolumns/spreadsheet";
|
|
2
|
+
type ChartSpec = EmbeddedChart["spec"];
|
|
3
|
+
/**
|
|
4
|
+
* Which editor controls a chart type gets — Excel's rule set, so an option
|
|
5
|
+
* is only offered where the chart (and the renderers) honour it
|
|
6
|
+
* (rowsncolumns/spreadsheet#1102): a funnel has no axes, a box & whisker
|
|
7
|
+
* no trendlines, a pie no gap width.
|
|
8
|
+
*/
|
|
9
|
+
export type ChartEditorCapabilities = {
|
|
10
|
+
category: "basic" | "bubble" | "hierarchy";
|
|
11
|
+
/** Value axis scale / gridlines / number format / visibility / font. */
|
|
12
|
+
hasValueAxis: boolean;
|
|
13
|
+
/** Category axis gridlines / direction / visibility / font. */
|
|
14
|
+
hasCategoryAxis: boolean;
|
|
15
|
+
/** The second value axis a series can opt into. */
|
|
16
|
+
hasSecondaryAxis: boolean;
|
|
17
|
+
/** Vertical / horizontal axis titles. */
|
|
18
|
+
hasAxisTitles: boolean;
|
|
19
|
+
hasTrendlines: boolean;
|
|
20
|
+
hasErrorBars: boolean;
|
|
21
|
+
/** Gap between category clusters (bars, columns, bins, boxes, waterfall steps). */
|
|
22
|
+
hasGapWidth: boolean;
|
|
23
|
+
/** Overlap of the bars of one category. */
|
|
24
|
+
hasOverlap: boolean;
|
|
25
|
+
/** "Invert if negative" + the negative fill. */
|
|
26
|
+
hasInvertIfNegative: boolean;
|
|
27
|
+
/** Per-series marker shape and size. */
|
|
28
|
+
hasMarkers: boolean;
|
|
29
|
+
hasLegend: boolean;
|
|
30
|
+
hasDataLabels: boolean;
|
|
31
|
+
/** Pie / doughnut "percentage" label. */
|
|
32
|
+
hasPercentLabels: boolean;
|
|
33
|
+
/** Bubble "bubble size" label. */
|
|
34
|
+
hasBubbleSizeLabels: boolean;
|
|
35
|
+
/** Per-series fill options: colour, gradient, no fill, point colours. */
|
|
36
|
+
hasSeriesFill: boolean;
|
|
37
|
+
/** Per-point colours (Format Data Point → Fill). */
|
|
38
|
+
hasPointColors: boolean;
|
|
39
|
+
/** Per-series chart type (combo). */
|
|
40
|
+
hasSeriesChartType: boolean;
|
|
41
|
+
/** Multi-level category axis (several label columns). */
|
|
42
|
+
hasCategoryLevels: boolean;
|
|
43
|
+
/** Empty-cell / #N/A handling (cell-driven series). */
|
|
44
|
+
hasEmptyCellOptions: boolean;
|
|
45
|
+
};
|
|
46
|
+
export declare const getChartEditorCapabilities: (spec: Pick<ChartSpec, "chartType">) => ChartEditorCapabilities;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=chart-editor-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-editor-capabilities.d.ts","sourceRoot":"","sources":["../../../../components/editors/chart-editor-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI/D,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC3C,wEAAwE;IACxE,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,eAAe,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,yCAAyC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,UAAU,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,mBAAmB,EAAE,OAAO,CAAC;IAC7B,wCAAwC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,yEAAyE;IACzE,aAAa,EAAE,OAAO,CAAC;IACvB,oDAAoD;IACpD,cAAc,EAAE,OAAO,CAAC;IACxB,qCAAqC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AA6BF,eAAO,MAAM,0BAA0B,GACrC,MAAM,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,KACjC,uBAmCF,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getChartCategory } from "../../utils/chart-spec-utils";
|
|
2
|
+
const CARTESIAN = new Set([
|
|
3
|
+
"bar",
|
|
4
|
+
"column",
|
|
5
|
+
"line",
|
|
6
|
+
"area",
|
|
7
|
+
"combo",
|
|
8
|
+
"stock",
|
|
9
|
+
"histogram",
|
|
10
|
+
"boxplot",
|
|
11
|
+
"waterfall",
|
|
12
|
+
"scatter",
|
|
13
|
+
"bubble",
|
|
14
|
+
]);
|
|
15
|
+
/** Excel offers trendlines and error bars on the unstacked XY-ish families only. */
|
|
16
|
+
const FITTABLE = new Set([
|
|
17
|
+
"bar",
|
|
18
|
+
"column",
|
|
19
|
+
"line",
|
|
20
|
+
"area",
|
|
21
|
+
"combo",
|
|
22
|
+
"scatter",
|
|
23
|
+
"bubble",
|
|
24
|
+
]);
|
|
25
|
+
const BARS = new Set(["bar", "column", "combo"]);
|
|
26
|
+
export const getChartEditorCapabilities = (spec) => {
|
|
27
|
+
const type = spec.chartType;
|
|
28
|
+
const category = getChartCategory(type);
|
|
29
|
+
const cartesian = CARTESIAN.has(type);
|
|
30
|
+
const fittable = FITTABLE.has(type);
|
|
31
|
+
const circular = type === "pie" || type === "doughnut";
|
|
32
|
+
const hierarchy = category === "hierarchy";
|
|
33
|
+
return {
|
|
34
|
+
category,
|
|
35
|
+
hasValueAxis: cartesian || type === "radar",
|
|
36
|
+
hasCategoryAxis: cartesian,
|
|
37
|
+
hasSecondaryAxis: fittable,
|
|
38
|
+
hasAxisTitles: cartesian,
|
|
39
|
+
hasTrendlines: fittable,
|
|
40
|
+
hasErrorBars: fittable,
|
|
41
|
+
hasGapWidth: BARS.has(type) ||
|
|
42
|
+
type === "histogram" ||
|
|
43
|
+
type === "boxplot" ||
|
|
44
|
+
type === "waterfall",
|
|
45
|
+
hasOverlap: BARS.has(type),
|
|
46
|
+
hasInvertIfNegative: BARS.has(type),
|
|
47
|
+
hasMarkers: type === "line" || type === "scatter" || type === "radar",
|
|
48
|
+
hasLegend: true,
|
|
49
|
+
hasDataLabels: type !== "regionMap",
|
|
50
|
+
hasPercentLabels: circular,
|
|
51
|
+
hasBubbleSizeLabels: type === "bubble",
|
|
52
|
+
hasSeriesFill: type !== "regionMap" && type !== "stock",
|
|
53
|
+
hasPointColors: !hierarchy && type !== "regionMap" && type !== "stock" && type !== "radar",
|
|
54
|
+
hasSeriesChartType: type === "combo",
|
|
55
|
+
hasCategoryLevels: BARS.has(type) || type === "line" || type === "area" || type === "stock",
|
|
56
|
+
hasEmptyCellOptions: category === "basic",
|
|
57
|
+
};
|
|
58
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/chart-editor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,aAAa,EAGd,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"chart-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/chart-editor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,aAAa,EAGd,MAAM,2BAA2B,CAAC;AAwBnC,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,+BAA+B,CAAC;AAuDvC,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAChD;;;OAGG;IACH,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;CAC1C,CAAC;AAuBF,eAAO,MAAM,WAAW,GAAI,sEAMzB,gBAAgB,sBAkhClB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|