@rowsncolumns/charts 28.1.2 → 28.1.4
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 +138 -76
- package/dist/cjs/basic-chart/helpers.d.ts +9 -0
- package/dist/cjs/basic-chart/helpers.d.ts.map +1 -1
- package/dist/cjs/basic-chart/helpers.js +55 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +218 -128
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/axis-number-format.d.ts +14 -0
- package/dist/cjs/utils/axis-number-format.d.ts.map +1 -1
- package/dist/cjs/utils/axis-number-format.js +41 -1
- package/dist/cjs/utils/empty-cells.d.ts +9 -0
- package/dist/cjs/utils/empty-cells.d.ts.map +1 -1
- package/dist/cjs/utils/empty-cells.js +26 -1
- package/dist/cjs/utils/legend-layout.d.ts +168 -0
- package/dist/cjs/utils/legend-layout.d.ts.map +1 -0
- package/dist/cjs/utils/legend-layout.js +338 -0
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +96 -34
- package/dist/esm/basic-chart/helpers.d.ts +9 -0
- package/dist/esm/basic-chart/helpers.d.ts.map +1 -1
- package/dist/esm/basic-chart/helpers.js +30 -0
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +136 -6
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/axis-number-format.d.ts +14 -0
- package/dist/esm/utils/axis-number-format.d.ts.map +1 -1
- package/dist/esm/utils/axis-number-format.js +36 -0
- package/dist/esm/utils/empty-cells.d.ts +9 -0
- package/dist/esm/utils/empty-cells.d.ts.map +1 -1
- package/dist/esm/utils/empty-cells.js +21 -0
- package/dist/esm/utils/legend-layout.d.ts +168 -0
- package/dist/esm/utils/legend-layout.d.ts.map +1 -0
- package/dist/esm/utils/legend-layout.js +299 -0
- package/package.json +7 -7
|
@@ -6,17 +6,18 @@ import { debug, isAFormula, isNil, ssfFormat } from "@rowsncolumns/utils";
|
|
|
6
6
|
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
7
7
|
import Plot from "react-plotly.js";
|
|
8
8
|
import { aggregateSeriesByDomain, getDomainValuesForAxis, sanitizeDomainValues, shouldAggregateSeries, } from "../../utils/aggregation";
|
|
9
|
-
import { formatAxisValue, numberFormatToPlotlyTicks, resolveSeriesNumberFormats, resolveValueAxisNumberFormat, } from "../../utils/axis-number-format";
|
|
9
|
+
import { formatAxisValue, numberFormatToPlotlyTicks, resolveSeriesNumberFormats, resolveValueAxisNumberFormat, valueAxisNameGap, } from "../../utils/axis-number-format";
|
|
10
10
|
import { computeBoxplotSummary } from "../../utils/boxplot";
|
|
11
11
|
import { createBubbleSizeScale, prepareBubbleSeriesData, toLabelString, } from "../../utils/bubble";
|
|
12
12
|
import { canSwitchRowColumn, cellLabelGetterFromRangeReader, switchRowColumn, } from "../../utils/chart-orientation";
|
|
13
13
|
import { dataUrlToBlob } from "../../utils/chart-image";
|
|
14
14
|
import { getChartPalette } from "../../utils/chart-styles";
|
|
15
15
|
import { coerceCalculatedLabel } from "../../utils/chart-spec-utils";
|
|
16
|
-
import { applyEmptyCellsPolicy, connectsAcrossEmptyCells, isLineLikeChartType, } from "../../utils/empty-cells";
|
|
16
|
+
import { applyEmptyCellsPolicy, connectsAcrossEmptyCells, isLineLikeChartType, isolatedPointIndexes, } from "../../utils/empty-cells";
|
|
17
17
|
import { computeErrorBars, resolveCustomErrorBarValues, } from "../../utils/error-bars";
|
|
18
18
|
import { plotlyMulticategoryX, resolveCategoryLevels, } from "../../utils/category-levels";
|
|
19
19
|
import { gradientToPlotly } from "../../utils/gradient";
|
|
20
|
+
import { BAND_GAP, legendLabelsFrom, measureTextWidth, reservePlotlyLegendBand, } from "../../utils/legend-layout";
|
|
20
21
|
import { plotlyTitleText } from "../../utils/plotly-title";
|
|
21
22
|
import { explosionToPlotlyPull, resolveExplosion, } from "../../utils/pie-explosion";
|
|
22
23
|
import { resolvePlotlyClickSelection, wasDragged, } from "../../utils/plotly-click";
|
|
@@ -115,6 +116,16 @@ const applyLegendOverridesPlotly = (legend, opts) => {
|
|
|
115
116
|
next.font = applyTextFormatToFont(next.font, opts.textFormat);
|
|
116
117
|
return { legend: next, showlegend: true };
|
|
117
118
|
};
|
|
119
|
+
/**
|
|
120
|
+
* `title.standoff` for a VALUE axis. Without it plotly places the axis title
|
|
121
|
+
* a fixed ~34px from the axis line and only nudges it off the tick labels
|
|
122
|
+
* after measuring them — a currency axis ("$2,000,000.00") is wider than
|
|
123
|
+
* that, and on the first paint (before `automargin` has grown the margin)
|
|
124
|
+
* the title lands on top of its own tick labels. With a standoff plotly
|
|
125
|
+
* positions the title at `tick-label depth + standoff`, so it always clears
|
|
126
|
+
* the labels, and `automargin` grows the margin to fit (#37265 A8).
|
|
127
|
+
*/
|
|
128
|
+
const VALUE_AXIS_TITLE_STANDOFF = 12;
|
|
118
129
|
/**
|
|
119
130
|
* `numberFormatPattern` is the axis' RESOLVED format (explicit pattern or
|
|
120
131
|
* the linked source-cell format). Plotly formats ticks AND hover values
|
|
@@ -1006,7 +1017,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1006
1017
|
// to 100 (plotly `groupnorm`); Excel's "Line with Markers"
|
|
1007
1018
|
// (spec.showMarkers) or a series' own marker switches the line trace
|
|
1008
1019
|
// to lines+markers, and a series marker of "none" hides them.
|
|
1009
|
-
const lineTraceVariant = (series, effectiveChartType) => {
|
|
1020
|
+
const lineTraceVariant = (series, effectiveChartType, values) => {
|
|
1010
1021
|
if (effectiveChartType !== "line" && effectiveChartType !== "area") {
|
|
1011
1022
|
return {};
|
|
1012
1023
|
}
|
|
@@ -1027,6 +1038,22 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1027
1038
|
size: marker?.size ?? 6,
|
|
1028
1039
|
};
|
|
1029
1040
|
}
|
|
1041
|
+
else {
|
|
1042
|
+
// A marker-less line draws nothing for a point with a gap on both sides (a data
|
|
1043
|
+
// row followed by a blank row — the first row included), so that row vanishes from
|
|
1044
|
+
// the chart. Excel plots an isolated marker there: keep the line and give only those
|
|
1045
|
+
// points a marker (plotly's `marker.size` / `marker.opacity` are per-point arrays;
|
|
1046
|
+
// a 0-size, 0-opacity marker paints nothing on the connected points).
|
|
1047
|
+
const isolated = new Set(isolatedPointIndexes(values, connectsAcrossEmptyCells(spec, true)));
|
|
1048
|
+
if (isolated.size) {
|
|
1049
|
+
extra.mode = "lines+markers";
|
|
1050
|
+
extra.marker = {
|
|
1051
|
+
symbol: "circle",
|
|
1052
|
+
size: values.map((_, i) => (isolated.has(i) ? 6 : 0)),
|
|
1053
|
+
opacity: values.map((_, i) => (isolated.has(i) ? 1 : 0)),
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1030
1057
|
}
|
|
1031
1058
|
return extra;
|
|
1032
1059
|
};
|
|
@@ -1714,7 +1741,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1714
1741
|
name: dataLabel,
|
|
1715
1742
|
stackgroup: isStacked ? "one" : undefined,
|
|
1716
1743
|
...seriesTraceStyle,
|
|
1717
|
-
...lineTraceVariant(series, effectiveChartType),
|
|
1744
|
+
...lineTraceVariant(series, effectiveChartType, seriesData.values),
|
|
1718
1745
|
};
|
|
1719
1746
|
// Ties the trace back to spec.series for click selection
|
|
1720
1747
|
trace.meta = {
|
|
@@ -1744,7 +1771,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1744
1771
|
name: dataLabel,
|
|
1745
1772
|
stackgroup: isStacked ? "one" : undefined,
|
|
1746
1773
|
...seriesTraceStyle,
|
|
1747
|
-
...lineTraceVariant(series, effectiveChartType),
|
|
1774
|
+
...lineTraceVariant(series, effectiveChartType, numericValues),
|
|
1748
1775
|
};
|
|
1749
1776
|
// Ties the trace back to spec.series for click selection
|
|
1750
1777
|
trace.meta = {
|
|
@@ -1786,6 +1813,65 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1786
1813
|
getFormattingFromRange,
|
|
1787
1814
|
hiddenDimensionStrategy: spec.hiddenDimensionStrategy,
|
|
1788
1815
|
});
|
|
1816
|
+
// Legend position / visibility from the spec, then a band reserved
|
|
1817
|
+
// for it outside the axis titles and tick labels so it never paints
|
|
1818
|
+
// over them — Excel shrinks the plot area instead (#986).
|
|
1819
|
+
const { legend: legendOverrides, showlegend } = applyLegendOverridesPlotly({ font: { color: textColor } }, spec.legend);
|
|
1820
|
+
const axisFontSize = 12;
|
|
1821
|
+
const primaryValues = traces.flatMap((trace) => {
|
|
1822
|
+
const values = isHorizontalBarChart ? trace?.x : trace?.y;
|
|
1823
|
+
return trace?.[valueAxisKey] === secondaryValueAxisRef || !Array.isArray(values)
|
|
1824
|
+
? []
|
|
1825
|
+
: values;
|
|
1826
|
+
});
|
|
1827
|
+
// Tick-label depth of the left axis: value labels formatted from the
|
|
1828
|
+
// plotted extremes on a vertical chart, the widest category on a
|
|
1829
|
+
// horizontal bar; plus the rotated axis title band when present.
|
|
1830
|
+
const leftAxisLabelDepth = isHorizontalBarChart
|
|
1831
|
+
? Math.ceil(Math.max(0, ...(domainData ?? []).map((label) => measureTextWidth(String(label ?? ""), axisFontSize)))) + 8
|
|
1832
|
+
: valueAxisNameGap({
|
|
1833
|
+
values: primaryValues,
|
|
1834
|
+
pattern: primaryAxisNumberFormat,
|
|
1835
|
+
fontSize: axisFontSize,
|
|
1836
|
+
minimum: 0,
|
|
1837
|
+
}) -
|
|
1838
|
+
axisFontSize -
|
|
1839
|
+
6;
|
|
1840
|
+
const leftAxisDepth = leftAxisLabelDepth +
|
|
1841
|
+
(spec.verticalAxisTitle
|
|
1842
|
+
? VALUE_AXIS_TITLE_STANDOFF + Math.ceil(axisFontSize * 1.3)
|
|
1843
|
+
: 0);
|
|
1844
|
+
const rightAxisDepth = hasSecondaryAxis && !isHorizontalBarChart
|
|
1845
|
+
? valueAxisNameGap({
|
|
1846
|
+
values: traces.flatMap((trace) => trace?.[valueAxisKey] === secondaryValueAxisRef && Array.isArray(trace?.y)
|
|
1847
|
+
? trace.y
|
|
1848
|
+
: []),
|
|
1849
|
+
pattern: secondaryAxisNumberFormat,
|
|
1850
|
+
fontSize: axisFontSize,
|
|
1851
|
+
minimum: 0,
|
|
1852
|
+
}) -
|
|
1853
|
+
axisFontSize -
|
|
1854
|
+
6
|
|
1855
|
+
: 0;
|
|
1856
|
+
const bottomAxisTitleStandoff = isHorizontalBarChart
|
|
1857
|
+
? VALUE_AXIS_TITLE_STANDOFF
|
|
1858
|
+
: BAND_GAP;
|
|
1859
|
+
const legendBand = reservePlotlyLegendBand({
|
|
1860
|
+
position: spec.legend?.position,
|
|
1861
|
+
visible: showlegend !== false,
|
|
1862
|
+
labels: legendLabelsFrom(undefined, traces.map((trace) => trace?.name)),
|
|
1863
|
+
legendFontSize: spec.legend?.textFormat?.fontSize ?? axisFontSize,
|
|
1864
|
+
width: Math.max(0, (width ?? 0) - 2),
|
|
1865
|
+
height: Math.max(0, (height ?? 0) - 2),
|
|
1866
|
+
hasTitle: Boolean(title),
|
|
1867
|
+
titleFontSize: authoredTitleFmt?.fontSize ?? 16,
|
|
1868
|
+
hasBottomAxisTitle: Boolean(spec.horizontalAxisTitle),
|
|
1869
|
+
hasLeftAxisTitle: Boolean(spec.verticalAxisTitle),
|
|
1870
|
+
leftAxisDepth,
|
|
1871
|
+
rightAxisDepth,
|
|
1872
|
+
bottomAxisTitleStandoff,
|
|
1873
|
+
axisFontSize,
|
|
1874
|
+
});
|
|
1789
1875
|
const newLayout = {
|
|
1790
1876
|
title: {
|
|
1791
1877
|
text: plotlyTitleText(title, spec.titleTextFormat),
|
|
@@ -1796,7 +1882,32 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1796
1882
|
}, authoredTitleFmt),
|
|
1797
1883
|
x: 0.02, // Small left margin (0.02 = 2% from left edge)
|
|
1798
1884
|
xanchor: "left",
|
|
1885
|
+
...legendBand.title,
|
|
1799
1886
|
},
|
|
1887
|
+
showlegend: showlegend === undefined ? true : showlegend,
|
|
1888
|
+
legend: { ...legendOverrides, ...(legendBand.legend ?? {}) },
|
|
1889
|
+
margin: legendBand.margin,
|
|
1890
|
+
autosize: true,
|
|
1891
|
+
// Bar/column stacking. Plotly's `barmode: "stack"` stacks bars
|
|
1892
|
+
// at the same X (or Y for horizontal). `barnorm: "percent"`
|
|
1893
|
+
// normalises each category's stack to 100% — Excel's
|
|
1894
|
+
// `percentStacked` grouping. Default is grouped (clustered).
|
|
1895
|
+
...((spec.chartType === "bar" || spec.chartType === "column") &&
|
|
1896
|
+
spec.stackedType
|
|
1897
|
+
? {
|
|
1898
|
+
barmode: spec.stackedType === "STACKED" ||
|
|
1899
|
+
spec.stackedType === "PERCENT_STACKED"
|
|
1900
|
+
? "stack"
|
|
1901
|
+
: "group",
|
|
1902
|
+
...(isPercentStackedBars ? { barnorm: "percent" } : {}),
|
|
1903
|
+
}
|
|
1904
|
+
: {}),
|
|
1905
|
+
// gapWidth — Excel stores 0..500 as a percentage of bar width.
|
|
1906
|
+
// Plotly's `bargap` is a fraction of the slot (0..1). Approx:
|
|
1907
|
+
// gapWidth=150 (default) → ~0.4 bargap.
|
|
1908
|
+
...(typeof spec.gapWidth === "number"
|
|
1909
|
+
? { bargap: Math.max(0, Math.min(0.95, spec.gapWidth / 400)) }
|
|
1910
|
+
: {}),
|
|
1800
1911
|
font: {
|
|
1801
1912
|
family: "Untitled Sans, apple-system, sans-serif",
|
|
1802
1913
|
size: 12,
|
|
@@ -1808,6 +1919,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1808
1919
|
title: {
|
|
1809
1920
|
text: spec.horizontalAxisTitle ?? "",
|
|
1810
1921
|
font: { color: textColor },
|
|
1922
|
+
standoff: bottomAxisTitleStandoff,
|
|
1811
1923
|
},
|
|
1812
1924
|
automargin: true,
|
|
1813
1925
|
showgrid: true,
|
|
@@ -1827,6 +1939,9 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1827
1939
|
title: {
|
|
1828
1940
|
text: spec.verticalAxisTitle ?? "",
|
|
1829
1941
|
font: { color: textColor },
|
|
1942
|
+
...(isHorizontalBarChart
|
|
1943
|
+
? {}
|
|
1944
|
+
: { standoff: VALUE_AXIS_TITLE_STANDOFF }),
|
|
1830
1945
|
},
|
|
1831
1946
|
showgrid: !isHorizontalBarChart,
|
|
1832
1947
|
gridcolor: gridColor,
|
|
@@ -1845,7 +1960,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1845
1960
|
...(hasSecondaryAxis
|
|
1846
1961
|
? {
|
|
1847
1962
|
[isHorizontalBarChart ? "xaxis2" : "yaxis2"]: applyAxisOverridesPlotly({
|
|
1848
|
-
title: {
|
|
1963
|
+
title: {
|
|
1964
|
+
font: { color: textColor },
|
|
1965
|
+
standoff: VALUE_AXIS_TITLE_STANDOFF,
|
|
1966
|
+
},
|
|
1849
1967
|
overlaying: isHorizontalBarChart ? "x" : "y",
|
|
1850
1968
|
side: isHorizontalBarChart ? "top" : "right",
|
|
1851
1969
|
showgrid: false,
|
|
@@ -1875,6 +1993,18 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1875
1993
|
},
|
|
1876
1994
|
}
|
|
1877
1995
|
: {}),
|
|
1996
|
+
// Of-pie composite — connector-line shapes plus (bar-of-pie) the
|
|
1997
|
+
// hidden secondary axes and stacked bar mode. Spread last: an
|
|
1998
|
+
// of-pie is a single pie series, so its `xaxis2`/`yaxis2` own the
|
|
1999
|
+
// secondary-axis slots.
|
|
2000
|
+
...(ofPieExtras
|
|
2001
|
+
? {
|
|
2002
|
+
shapes: ofPieExtras.shapes,
|
|
2003
|
+
...(ofPieExtras.barmode ? { barmode: ofPieExtras.barmode } : {}),
|
|
2004
|
+
...(ofPieExtras.xaxis2 ? { xaxis2: ofPieExtras.xaxis2 } : {}),
|
|
2005
|
+
...(ofPieExtras.yaxis2 ? { yaxis2: ofPieExtras.yaxis2 } : {}),
|
|
2006
|
+
}
|
|
2007
|
+
: {}),
|
|
1878
2008
|
};
|
|
1879
2009
|
// Phase 5.1: apply data labels per trace, and set the doughnut hole
|
|
1880
2010
|
// when chartType === "doughnut".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../../config.ts","../../echarts-gl.d.ts","../../geo-modules.d.ts","../../index.ts","../../plotly-dist.d.ts","../../types.ts","../../vitest.config.ts","../../atoms/editing-chart.atom.ts","../../atoms/pivot-chart.atom.ts","../../basic-chart/basic-chart.tsx","../../basic-chart/helpers.ts","../../basic-chart/index.tsx","../../components/dialogs/chart-editor-dialog.tsx","../../components/dialogs/pivot-chart-dialog.tsx","../../components/editors/chart-editor.tsx","../../components/editors/chart-range-input.tsx","../../hooks/use-chart-editor.ts","../../hooks/use-charts.ts","../../hooks/use-on-create-chart.ts","../../hooks/use-on-delete-chart.ts","../../hooks/use-on-move-chart-to-sheet.ts","../../hooks/use-on-move-chart.ts","../../hooks/use-on-resize-chart.ts","../../hooks/use-on-update-chart.ts","../../interface/create-chart.ts","../../interface/delete-chart.ts","../../interface/move-chart-to-sheet.ts","../../interface/move-chart.ts","../../interface/resize-chart.ts","../../interface/shift-chart-ranges.ts","../../interface/update-chart.ts","../../plotly/basic-chart/basic-chart.tsx","../../plotly/basic-chart/helpers.ts","../../plotly/basic-chart/index.tsx","../../utils/aggregation.ts","../../utils/axis-number-format.ts","../../utils/bar-layout.ts","../../utils/boxplot.ts","../../utils/bubble.ts","../../utils/category-levels.ts","../../utils/chart-image.ts","../../utils/chart-orientation.ts","../../utils/chart-spec-utils.ts","../../utils/chart-styles.ts","../../utils/echarts-gl-loader.ts","../../utils/empty-cells.ts","../../utils/error-bars.ts","../../utils/gradient.ts","../../utils/hierarchy.ts","../../utils/histogram.ts","../../utils/of-pie.ts","../../utils/overrides.ts","../../utils/pie-explosion.ts","../../utils/plotly-click.ts","../../utils/plotly-surface.ts","../../utils/plotly-title.ts","../../utils/radar.ts","../../utils/region-map-loader.ts","../../utils/region-map.ts","../../utils/series-click.ts","../../utils/stock.ts","../../utils/three-d.ts","../../utils/trendline.ts","../../utils/waterfall.ts","../../utils/webgl.ts"],"version":"5.8.3"}
|
|
1
|
+
{"root":["../../config.ts","../../echarts-gl.d.ts","../../geo-modules.d.ts","../../index.ts","../../plotly-dist.d.ts","../../types.ts","../../vitest.config.ts","../../atoms/editing-chart.atom.ts","../../atoms/pivot-chart.atom.ts","../../basic-chart/basic-chart.tsx","../../basic-chart/helpers.ts","../../basic-chart/index.tsx","../../components/dialogs/chart-editor-dialog.tsx","../../components/dialogs/pivot-chart-dialog.tsx","../../components/editors/chart-editor.tsx","../../components/editors/chart-range-input.tsx","../../hooks/use-chart-editor.ts","../../hooks/use-charts.ts","../../hooks/use-on-create-chart.ts","../../hooks/use-on-delete-chart.ts","../../hooks/use-on-move-chart-to-sheet.ts","../../hooks/use-on-move-chart.ts","../../hooks/use-on-resize-chart.ts","../../hooks/use-on-update-chart.ts","../../interface/create-chart.ts","../../interface/delete-chart.ts","../../interface/move-chart-to-sheet.ts","../../interface/move-chart.ts","../../interface/resize-chart.ts","../../interface/shift-chart-ranges.ts","../../interface/update-chart.ts","../../plotly/basic-chart/basic-chart.tsx","../../plotly/basic-chart/helpers.ts","../../plotly/basic-chart/index.tsx","../../utils/aggregation.ts","../../utils/axis-number-format.ts","../../utils/bar-layout.ts","../../utils/boxplot.ts","../../utils/bubble.ts","../../utils/category-levels.ts","../../utils/chart-image.ts","../../utils/chart-orientation.ts","../../utils/chart-spec-utils.ts","../../utils/chart-styles.ts","../../utils/echarts-gl-loader.ts","../../utils/empty-cells.ts","../../utils/error-bars.ts","../../utils/gradient.ts","../../utils/hierarchy.ts","../../utils/histogram.ts","../../utils/legend-layout.ts","../../utils/of-pie.ts","../../utils/overrides.ts","../../utils/pie-explosion.ts","../../utils/plotly-click.ts","../../utils/plotly-surface.ts","../../utils/plotly-title.ts","../../utils/radar.ts","../../utils/region-map-loader.ts","../../utils/region-map.ts","../../utils/series-click.ts","../../utils/stock.ts","../../utils/three-d.ts","../../utils/trendline.ts","../../utils/waterfall.ts","../../utils/webgl.ts"],"version":"5.8.3"}
|
|
@@ -65,5 +65,19 @@ export type PlotlyTickFormat = {
|
|
|
65
65
|
* section is used — plotly applies one format to every tick.
|
|
66
66
|
*/
|
|
67
67
|
export declare const numberFormatToPlotlyTicks: (pattern: string | undefined) => PlotlyTickFormat | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* echarts `nameGap` for a value axis whose title sits in the middle, rotated
|
|
70
|
+
* beside the tick labels. The gap is the distance from the axis line to the
|
|
71
|
+
* title's centre, so it must clear the tick labels' full width: the labels
|
|
72
|
+
* ("$2,000.00", "1,500,000") are formatted from the plotted extremes and
|
|
73
|
+
* measured; the fixed default of 50px only fits labels up to ~4 digits and
|
|
74
|
+
* lets a currency axis title paint over its own tick labels.
|
|
75
|
+
*/
|
|
76
|
+
export declare const valueAxisNameGap: ({ values, pattern, fontSize, minimum, }: {
|
|
77
|
+
values: readonly unknown[];
|
|
78
|
+
pattern: string | undefined;
|
|
79
|
+
fontSize?: number;
|
|
80
|
+
minimum?: number;
|
|
81
|
+
}) => number;
|
|
68
82
|
export {};
|
|
69
83
|
//# sourceMappingURL=axis-number-format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,yBAAyB,EACzB,KAAK,EACL,UAAU,EACX,MAAM,2BAA2B,CAAC;AAWnC,KAAK,iBAAiB,GAAG,CACvB,UAAU,EAAE,UAAU,EACtB,uBAAuB,CAAC,EAAE,yBAAyB,KAChD,OAAO,EAAE,CAAC;AAMf;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,YAGjC,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,UAAU,EAAE,GAAG,SAAS,EACjC,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,MAAM,GAAG,SAWX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,2EAK1C;IACD,WAAW,EAAE,KAAK,CAAC;QAAE,mBAAmB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACxE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;IACrC,sBAAsB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtD,uBAAuB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC5D,KAAG,MAAM,GAAG,SAQZ,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,GAAG,SAAS,EAC3B,OAAO,OAAO,KACb,MAIF,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,GAAG,SAAS,cAC/C,OAAO,wBAAgD,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,GAAG,SAAS,cAEnD,OAAO,mCAIN,CAAC;AAEhB;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACrC,QAAQ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,EAChD,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,CAAC,MAAM,GAAG,SAAS,CAAC,EAOpB,CAAC;AAEJ,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,GAClC,SAAS,MAAM,GAAG,SAAS,MAC3B,QAAQ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,WAGvD,CAAC;AAET,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,MAAM,GAAG,SAAS,KAC1B,gBAAgB,GAAG,SA4DrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,yBAAyB,EACzB,KAAK,EACL,UAAU,EACX,MAAM,2BAA2B,CAAC;AAWnC,KAAK,iBAAiB,GAAG,CACvB,UAAU,EAAE,UAAU,EACtB,uBAAuB,CAAC,EAAE,yBAAyB,KAChD,OAAO,EAAE,CAAC;AAMf;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,YAGjC,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,UAAU,EAAE,GAAG,SAAS,EACjC,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,MAAM,GAAG,SAWX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,2EAK1C;IACD,WAAW,EAAE,KAAK,CAAC;QAAE,mBAAmB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACxE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;IACrC,sBAAsB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtD,uBAAuB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC5D,KAAG,MAAM,GAAG,SAQZ,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,GAAG,SAAS,EAC3B,OAAO,OAAO,KACb,MAIF,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,GAAG,SAAS,cAC/C,OAAO,wBAAgD,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,GAAG,SAAS,cAEnD,OAAO,mCAIN,CAAC;AAEhB;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACrC,QAAQ,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,EAChD,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,CAAC,MAAM,GAAG,SAAS,CAAC,EAOpB,CAAC;AAEJ,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,GAClC,SAAS,MAAM,GAAG,SAAS,MAC3B,QAAQ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,WAGvD,CAAC;AAET,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,MAAM,GAAG,SAAS,KAC1B,gBAAgB,GAAG,SA4DrB,CAAC;AA2BF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,yCAK9B;IACD,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,KAAG,MAgBH,CAAC"}
|
|
@@ -168,3 +168,39 @@ const firstSection = (pattern) => {
|
|
|
168
168
|
}
|
|
169
169
|
return pattern;
|
|
170
170
|
};
|
|
171
|
+
/** Approximate rendered width of an axis tick label in px at `fontSize` (canvas when available). */
|
|
172
|
+
const measureLabelWidth = (text, fontSize) => {
|
|
173
|
+
if (typeof document !== "undefined") {
|
|
174
|
+
const ctx = document.createElement("canvas").getContext("2d");
|
|
175
|
+
if (ctx) {
|
|
176
|
+
ctx.font = `${fontSize}px sans-serif`;
|
|
177
|
+
const width = ctx.measureText(text).width;
|
|
178
|
+
if (Number.isFinite(width) && width > 0)
|
|
179
|
+
return width;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Headless fallback: ~0.6em per character (digits / punctuation heavy).
|
|
183
|
+
return text.length * fontSize * 0.6;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* echarts `nameGap` for a value axis whose title sits in the middle, rotated
|
|
187
|
+
* beside the tick labels. The gap is the distance from the axis line to the
|
|
188
|
+
* title's centre, so it must clear the tick labels' full width: the labels
|
|
189
|
+
* ("$2,000.00", "1,500,000") are formatted from the plotted extremes and
|
|
190
|
+
* measured; the fixed default of 50px only fits labels up to ~4 digits and
|
|
191
|
+
* lets a currency axis title paint over its own tick labels.
|
|
192
|
+
*/
|
|
193
|
+
export const valueAxisNameGap = ({ values, pattern, fontSize = 12, minimum = 50, }) => {
|
|
194
|
+
const numbers = values.filter((v) => typeof v === "number" && Number.isFinite(v));
|
|
195
|
+
if (!numbers.length)
|
|
196
|
+
return minimum;
|
|
197
|
+
const min = Math.min(...numbers, 0);
|
|
198
|
+
const max = Math.max(...numbers, 0);
|
|
199
|
+
// echarts' default axis label puts thousands separators on plain numbers.
|
|
200
|
+
const defaultLabel = (v) => v.toLocaleString("en-US");
|
|
201
|
+
const labels = [min, max].map((v) => pattern ? formatAxisValue(pattern, v) : defaultLabel(v));
|
|
202
|
+
const widest = Math.max(...labels.map((l) => measureLabelWidth(l, fontSize)));
|
|
203
|
+
// 8px tick-label margin + the rotated title's own line box + breathing room.
|
|
204
|
+
const AXIS_LABEL_MARGIN = 8;
|
|
205
|
+
return Math.max(minimum, Math.ceil(widest + AXIS_LABEL_MARGIN + fontSize + 6));
|
|
206
|
+
};
|
|
@@ -26,5 +26,14 @@ export declare const connectsAcrossEmptyCells: (spec: EmptyCellsSpec, lineLike:
|
|
|
26
26
|
* pre-2016 #N/A behaviour), and any other series leaves a gap.
|
|
27
27
|
*/
|
|
28
28
|
export declare const applyEmptyCellsPolicy: (values: readonly (number | null | undefined)[], rawValues: readonly unknown[], spec: EmptyCellsSpec, lineLike: boolean) => (number | null)[];
|
|
29
|
+
/**
|
|
30
|
+
* Indexes of the plotted points that have no plottable neighbour to draw a
|
|
31
|
+
* line segment to — a value between two gaps (or at an edge next to a gap).
|
|
32
|
+
* A line-only series (no markers) draws nothing for them, so a row of data
|
|
33
|
+
* followed by a blank row vanishes from the chart; Excel still plots an
|
|
34
|
+
* isolated marker there. When the series connects across gaps every point
|
|
35
|
+
* links to the next plotted one, so only a lone single point is isolated.
|
|
36
|
+
*/
|
|
37
|
+
export declare const isolatedPointIndexes: (values: readonly (number | null | undefined)[], connectAcrossGaps?: boolean) => number[];
|
|
29
38
|
export {};
|
|
30
39
|
//# sourceMappingURL=empty-cells.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empty-cells.d.ts","sourceRoot":"","sources":["../../../utils/empty-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;AAEpE,KAAK,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;AAetE,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,OACuB,CAAC;AAE3E,gCAAgC;AAChC,eAAO,MAAM,mBAAmB,GAAI,MAAM,cAAc,KAAG,gBAChC,CAAC;AAE5B,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,GAC9B,WAAW,SAAS,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KACnD,OAAuD,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,MAAM,cAAc,EACpB,UAAU,OAAO,KAChB,OAA8D,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC9C,WAAW,SAAS,OAAO,EAAE,EAC7B,MAAM,cAAc,EACpB,UAAU,OAAO,KAChB,CAAC,MAAM,GAAG,IAAI,CAAC,EA4BjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"empty-cells.d.ts","sourceRoot":"","sources":["../../../utils/empty-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;AAEpE,KAAK,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;AAetE,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,OACuB,CAAC;AAE3E,gCAAgC;AAChC,eAAO,MAAM,mBAAmB,GAAI,MAAM,cAAc,KAAG,gBAChC,CAAC;AAE5B,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,GAC9B,WAAW,SAAS,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KACnD,OAAuD,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,MAAM,cAAc,EACpB,UAAU,OAAO,KAChB,OAA8D,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC9C,WAAW,SAAS,OAAO,EAAE,EAC7B,MAAM,cAAc,EACpB,UAAU,OAAO,KAChB,CAAC,MAAM,GAAG,IAAI,CAAC,EA4BjB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,SAAS,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC9C,2BAAyB,KACxB,MAAM,EAYR,CAAC"}
|
|
@@ -65,3 +65,24 @@ export const applyEmptyCellsPolicy = (values, rawValues, spec, lineLike) => {
|
|
|
65
65
|
}
|
|
66
66
|
return plotted;
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Indexes of the plotted points that have no plottable neighbour to draw a
|
|
70
|
+
* line segment to — a value between two gaps (or at an edge next to a gap).
|
|
71
|
+
* A line-only series (no markers) draws nothing for them, so a row of data
|
|
72
|
+
* followed by a blank row vanishes from the chart; Excel still plots an
|
|
73
|
+
* isolated marker there. When the series connects across gaps every point
|
|
74
|
+
* links to the next plotted one, so only a lone single point is isolated.
|
|
75
|
+
*/
|
|
76
|
+
export const isolatedPointIndexes = (values, connectAcrossGaps = false) => {
|
|
77
|
+
const plotted = (i) => i >= 0 && i < values.length && typeof values[i] === "number";
|
|
78
|
+
const indexes = [];
|
|
79
|
+
if (connectAcrossGaps) {
|
|
80
|
+
const all = values.flatMap((_, i) => (plotted(i) ? [i] : []));
|
|
81
|
+
return all.length === 1 ? all : [];
|
|
82
|
+
}
|
|
83
|
+
for (let i = 0; i < values.length; i++) {
|
|
84
|
+
if (plotted(i) && !plotted(i - 1) && !plotted(i + 1))
|
|
85
|
+
indexes.push(i);
|
|
86
|
+
}
|
|
87
|
+
return indexes;
|
|
88
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export type LegendBandPosition = "top" | "bottom" | "left" | "right" | "topRight" | "none";
|
|
2
|
+
/** Space kept between neighbouring bands (legend ↔ axis title ↔ labels). */
|
|
3
|
+
export declare const BAND_GAP = 8;
|
|
4
|
+
/** Inset of the outermost band from the chart frame. */
|
|
5
|
+
export declare const EDGE_PAD = 10;
|
|
6
|
+
/** echarts `legend.padding` default used by both adapters' legend boxes. */
|
|
7
|
+
export declare const LEGEND_PADDING = 10;
|
|
8
|
+
/** echarts `legend.itemGap` default. */
|
|
9
|
+
export declare const LEGEND_ITEM_GAP = 10;
|
|
10
|
+
/** Approximate rendered width of `text` at `fontSize` (canvas when available). */
|
|
11
|
+
export declare const measureTextWidth: (text: string, fontSize: number) => number;
|
|
12
|
+
export type LegendBandInput = {
|
|
13
|
+
/** Legend entry labels, one per item. */
|
|
14
|
+
labels: readonly string[];
|
|
15
|
+
/** Legend text size in px. */
|
|
16
|
+
fontSize?: number;
|
|
17
|
+
/** Legend icon width in px. */
|
|
18
|
+
itemWidth?: number;
|
|
19
|
+
/** Gap between items (and between wrapped rows / columns) in px. */
|
|
20
|
+
itemGap?: number;
|
|
21
|
+
/** Legend box padding in px (each side). */
|
|
22
|
+
padding?: number;
|
|
23
|
+
/** Horizontal (top / bottom) or vertical (left / right) item flow. */
|
|
24
|
+
orientation: "horizontal" | "vertical";
|
|
25
|
+
/** Frame width available to a horizontal legend before it wraps. */
|
|
26
|
+
availableWidth: number;
|
|
27
|
+
/** Frame height available to a vertical legend before it wraps. */
|
|
28
|
+
availableHeight: number;
|
|
29
|
+
};
|
|
30
|
+
export type LegendBand = {
|
|
31
|
+
/** Rows of items (horizontal legends wrap long series lists). */
|
|
32
|
+
rows: number;
|
|
33
|
+
/** Columns of items (vertical legends wrap when taller than the frame). */
|
|
34
|
+
columns: number;
|
|
35
|
+
/** Rendered width in px including padding. */
|
|
36
|
+
width: number;
|
|
37
|
+
/** Rendered height in px including padding. */
|
|
38
|
+
height: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Estimate the legend's rendered box from its items. Horizontal legends
|
|
42
|
+
* pack items greedily into rows no wider than the frame; vertical legends
|
|
43
|
+
* stack items and spill into a new column when taller than the frame.
|
|
44
|
+
*/
|
|
45
|
+
export declare const estimateLegendBand: ({ labels, fontSize, itemWidth, itemGap, padding, orientation, availableWidth, availableHeight, }: LegendBandInput) => LegendBand;
|
|
46
|
+
/**
|
|
47
|
+
* Pull the legend entry labels out of an echarts `legend.data` (strings or
|
|
48
|
+
* `{ name }` items); falls back to the series names, which is what echarts
|
|
49
|
+
* itself lists when `data` is empty.
|
|
50
|
+
*/
|
|
51
|
+
export declare const legendLabelsFrom: (legendData: readonly unknown[] | undefined, seriesNames: readonly unknown[]) => string[];
|
|
52
|
+
/**
|
|
53
|
+
* Depth (px) of one row of echarts axis tick labels measured from the axis
|
|
54
|
+
* line: 5px tick + 8px label margin + one 12px line, rounded up. With
|
|
55
|
+
* `grid.containLabel` this is the part the grid already accounts for; the
|
|
56
|
+
* axis title sits beyond it.
|
|
57
|
+
*/
|
|
58
|
+
export declare const echartsAxisLabelDepth: (fontSize?: number) => number;
|
|
59
|
+
/**
|
|
60
|
+
* echarts `nameGap` for a category axis whose title sits in the middle
|
|
61
|
+
* below the tick labels: clear one row of labels plus a small gap, measured
|
|
62
|
+
* to the title's centre line.
|
|
63
|
+
*/
|
|
64
|
+
export declare const categoryAxisNameGap: (fontSize?: number) => number;
|
|
65
|
+
/** Height of the echarts chart-title band (padding 10 each side + one line). */
|
|
66
|
+
export declare const echartsTitleBand: (titleFontSize?: number) => number;
|
|
67
|
+
export type EchartsLegendBandInput = {
|
|
68
|
+
/** Resolved legend position (`undefined` = echarts default: top). */
|
|
69
|
+
position: LegendBandPosition | null | undefined;
|
|
70
|
+
/** Whether the legend renders at all (`show !== false` and has items). */
|
|
71
|
+
visible: boolean;
|
|
72
|
+
labels: readonly string[];
|
|
73
|
+
legendFontSize?: number;
|
|
74
|
+
legendItemWidth?: number;
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
/** A chart title is drawn across the top. */
|
|
78
|
+
hasTitle: boolean;
|
|
79
|
+
titleFontSize?: number;
|
|
80
|
+
/** The bottom axis carries a title (`name`). */
|
|
81
|
+
hasBottomAxisTitle: boolean;
|
|
82
|
+
/** `nameGap` used for the bottom axis title (px from axis line to title centre). */
|
|
83
|
+
bottomAxisNameGap: number;
|
|
84
|
+
/** The left axis carries a title (`name`). */
|
|
85
|
+
hasLeftAxisTitle: boolean;
|
|
86
|
+
axisFontSize?: number;
|
|
87
|
+
};
|
|
88
|
+
export type EchartsLegendBandLayout = {
|
|
89
|
+
band: LegendBand;
|
|
90
|
+
grid: {
|
|
91
|
+
left: number;
|
|
92
|
+
right: number;
|
|
93
|
+
top: number;
|
|
94
|
+
bottom: number;
|
|
95
|
+
containLabel: true;
|
|
96
|
+
};
|
|
97
|
+
/** Legend placement to spread over the positioned legend option. */
|
|
98
|
+
legend: {
|
|
99
|
+
top?: number | string;
|
|
100
|
+
bottom?: number | string;
|
|
101
|
+
left?: number | string;
|
|
102
|
+
right?: number | string;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Echarts cartesian geometry with a band reserved for the legend in its
|
|
107
|
+
* position, outside the axis-title band, outside the tick labels.
|
|
108
|
+
*/
|
|
109
|
+
export declare const reserveEchartsLegendBand: ({ position, visible, labels, legendFontSize, legendItemWidth, width, height, hasTitle, titleFontSize, hasBottomAxisTitle, bottomAxisNameGap, hasLeftAxisTitle, axisFontSize, }: EchartsLegendBandInput) => EchartsLegendBandLayout;
|
|
110
|
+
export type PlotlyLegendBandInput = {
|
|
111
|
+
/** Resolved legend position (`undefined` = plotly default: right). */
|
|
112
|
+
position: LegendBandPosition | null | undefined;
|
|
113
|
+
visible: boolean;
|
|
114
|
+
labels: readonly string[];
|
|
115
|
+
legendFontSize?: number;
|
|
116
|
+
width: number;
|
|
117
|
+
height: number;
|
|
118
|
+
hasTitle: boolean;
|
|
119
|
+
titleFontSize?: number;
|
|
120
|
+
hasBottomAxisTitle: boolean;
|
|
121
|
+
hasLeftAxisTitle: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Px from the left axis line to the outer edge of its tick labels (and
|
|
124
|
+
* title when present) — what the legend must clear on the left.
|
|
125
|
+
*/
|
|
126
|
+
leftAxisDepth: number;
|
|
127
|
+
/** Same for a secondary value axis drawn on the right (0 when absent). */
|
|
128
|
+
rightAxisDepth?: number;
|
|
129
|
+
/** `title.standoff` the caller sets on the bottom axis (px labels → title). */
|
|
130
|
+
bottomAxisTitleStandoff?: number;
|
|
131
|
+
axisFontSize?: number;
|
|
132
|
+
};
|
|
133
|
+
export type PlotlyLegendBandLayout = {
|
|
134
|
+
band: LegendBand;
|
|
135
|
+
margin: {
|
|
136
|
+
l: number;
|
|
137
|
+
r: number;
|
|
138
|
+
t: number;
|
|
139
|
+
b: number;
|
|
140
|
+
};
|
|
141
|
+
/** Legend anchor + orientation to spread over the legend option. */
|
|
142
|
+
legend: {
|
|
143
|
+
orientation: "h" | "v";
|
|
144
|
+
x: number;
|
|
145
|
+
y: number;
|
|
146
|
+
xanchor: "left" | "center" | "right";
|
|
147
|
+
yanchor: "top" | "middle" | "bottom";
|
|
148
|
+
} | null;
|
|
149
|
+
/** Bottom axis title standoff (px between tick labels and title). */
|
|
150
|
+
bottomAxisTitleStandoff: number;
|
|
151
|
+
/** Title pinned to the top of the container so it never drifts into the legend band. */
|
|
152
|
+
title: {
|
|
153
|
+
yref: "container";
|
|
154
|
+
y: number;
|
|
155
|
+
yanchor: "top";
|
|
156
|
+
pad: {
|
|
157
|
+
t: number;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Plotly geometry with a band reserved for the legend in its position.
|
|
163
|
+
* Legend coordinates are paper-relative (fractions of the plot area), so
|
|
164
|
+
* they are derived from the margins this returns; `automargin` on the
|
|
165
|
+
* axes may still grow a margin further for unusually deep tick labels.
|
|
166
|
+
*/
|
|
167
|
+
export declare const reservePlotlyLegendBand: ({ position, visible, labels, legendFontSize, width, height, hasTitle, titleFontSize, hasBottomAxisTitle, hasLeftAxisTitle, leftAxisDepth, rightAxisDepth, bottomAxisTitleStandoff, axisFontSize, }: PlotlyLegendBandInput) => PlotlyLegendBandLayout;
|
|
168
|
+
//# sourceMappingURL=legend-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legend-layout.d.ts","sourceRoot":"","sources":["../../../utils/legend-layout.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,kBAAkB,GAC1B,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,MAAM,CAAC;AAEX,4EAA4E;AAC5E,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,wDAAwD;AACxD,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B,4EAA4E;AAC5E,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,wCAAwC;AACxC,eAAO,MAAM,eAAe,KAAK,CAAC;AAIlC,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAWjE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,yCAAyC;IACzC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC;IACvC,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,kGAShC,eAAe,KAAG,UA4CpB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,YAAY,SAAS,OAAO,EAAE,GAAG,SAAS,EAC1C,aAAa,SAAS,OAAO,EAAE,KAC9B,MAAM,EAcR,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,iBAAa,KAAG,MACnB,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,iBAAa,KAAG,MACsB,CAAC;AAE3E,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,GAAI,sBAAkB,KAAG,MACA,CAAC;AAEvD,MAAM,MAAM,sBAAsB,GAAG;IACnC,qEAAqE;IACrE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oFAAoF;IACpF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,IAAI,CAAC;KACpB,CAAC;IACF,oEAAoE;IACpE,MAAM,EAAE;QACN,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,gLActC,sBAAsB,KAAG,uBAmF3B,CAAC;AAQF,MAAM,MAAM,qBAAqB,GAAG;IAClC,sEAAsE;IACtE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,oEAAoE;IACpE,MAAM,EAAE;QACN,WAAW,EAAE,GAAG,GAAG,GAAG,CAAC;QACvB,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;QACrC,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;KACtC,GAAG,IAAI,CAAC;IACT,qEAAqE;IACrE,uBAAuB,EAAE,MAAM,CAAC;IAChC,wFAAwF;IACxF,KAAK,EAAE;QACL,IAAI,EAAE,WAAW,CAAC;QAClB,CAAC,EAAE,MAAM,CAAC;QACV,OAAO,EAAE,KAAK,CAAC;QACf,GAAG,EAAE;YAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACpB,CAAC;CACH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,oMAerC,qBAAqB,KAAG,sBA8F1B,CAAC"}
|