@rowsncolumns/charts 28.1.4 → 28.1.5
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 +16 -14
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +7 -12
- package/dist/cjs/plotly/plot.d.ts +12 -0
- package/dist/cjs/plotly/plot.d.ts.map +1 -0
- package/dist/cjs/plotly/plot.js +8 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/trendline.d.ts +18 -5
- package/dist/cjs/utils/trendline.d.ts.map +1 -1
- package/dist/cjs/utils/trendline.js +38 -16
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +22 -13
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +4 -7
- package/dist/esm/plotly/plot.d.ts +12 -0
- package/dist/esm/plotly/plot.d.ts.map +1 -0
- package/dist/esm/plotly/plot.js +12 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/trendline.d.ts +18 -5
- package/dist/esm/utils/trendline.d.ts.map +1 -1
- package/dist/esm/utils/trendline.js +36 -16
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAmQrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAqEnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,
|
|
1
|
+
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAmQrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAqEnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,sBAmzGjB,CAAC"}
|
|
@@ -367,7 +367,7 @@ var BasicChart = function (_a) {
|
|
|
367
367
|
* Triggers a chart update
|
|
368
368
|
*/
|
|
369
369
|
var updateChart = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
370
|
-
var threeDRenderKind, canRender3D, willRender3D, isRegionMap, regionSpec, geoScope, geo, labels, seriesEntry, values, _a, data, unmatched, min, max, textColor, ramp, noDataColor, borderColor, regionSeriesLabel, seriesName, chartDomains, chartSeries, legend, chartType, position, showAxis, isBubble, isHierarchy, skipHeaders_1, labelValues, perSeriesX, perSeriesSize, seriesInputs, i, seriesEntry, resolvedLabel, _b, xValues, sizeValues_1, sharedXValues, sharedSizeValues, _c, categories_1, preparedSeries, sizeValues, sizeScale_1, xAxisConfig, tooltipFormatter, bubbleSeriesLabel_1, hierarchyRows, headerTitle, hierarchyData, rootName, seriesDisplayName, hierarchyDepth, levels, sizeNumberFormat_1, tooltipFormatter, hierarchyDataLabels, hierarchySeriesLabel, isContour, categories_2, contourSeriesInputs, _d, _e, seriesEntry, dataLabel, _f, _g, values, e_1_1, seriesNames_1, contourPoints, _h, zMin, zMax, contourFormats_1, contourLabel, categories_3, threeDSeriesInputs, _j, _k, seriesEntry, dataLabel, _l, _m, values, e_2_1, seriesNames_2, threeDPalette_1, seriesColorAt_1, categoryAxisLabel, seriesAxisLabel, stackedBar3D_1, threeDFormats_1, threeDTooltipFormatter, threeDSeries, visualMap, xAxis3D, yAxis3D, categoryCount, categoryTotals_1, threeDSeriesInputs_1, threeDSeriesInputs_1_1, entry, isPercent_1, surfacePoints, _o, zMin, zMax, skipHeaders, categories, radarSeriesInputs, _p, _q, seriesEntry, label, values, indicators_1, radarData, radarStyle_1, radarColors_1, radarFormats_1, radarDataLabels_1, radarSeriesLabelFor_1, radarTooltipFormatter, variant_1, categories, seriesValues, stockFormats_1, stockRoleIndex_1, stockFormatFor_1, stockDataLabels_1, stockSeriesLabelFor_1, upColor_1, downColor_1, volumePoints, hasVolume, stockGrid, baseStockXAxis, stockXAxis, volumeYAxis, volumeSeries, stockAxisPointer, candleData, lineSeries, stockColors_1, isStacked, isCircularChart, isOfPie, ofPieLayout, isHorizontalBarChart, shouldAggregate, primaryDomainSource, rawPrimaryDomainValues, aggregateDomainValues, categoryLevels, pushSeriesOverlays, sideBySideBarCount, specBarGap, specBarCategoryGap, _loop_1, _r, _s, _t, specSeriesIndex, series, e_3_1, labels, seriesEntry, rawValues, _u, main_1, secondary, otherTotal, total, ofPieType_1, secondScale, halfAngle_1, hasSecondary, MAIN_CX_1, CY_1, MAIN_RADIUS_PCT_1, SECONDARY_CX_1, secondaryRadiusPct_1, BAR_LEFT_1, BAR_RIGHT, barHalfFrac_1, ofPiePalette_1, paletteAt_1, connectorColor_1, primaryDomainSource_1, rawDomainValues, labels, seriesEntry, rawValues_1, totalIndices, steps, accent_1, decreaseColor_1, totalColor_1, connectors, primaryDomainSource_2, rawDomainValues, labels_1, seriesEntry, rawValues, quartileMethod, showOutliers, showMeanMarker, boxStats, boxLabels, outlierPoints, meanPoints, _v, _w, seriesEntry, label, rawValues, summary, boxIndex, lo, hi, _x, _y, outlier, boxSeries, boxColor, rawValues, _z, labels, counts, isPareto_1, cumulativePercents, pareto, histogramSeries, histogramColor, renderedSeriesCount, replaceMerge, valueAxisBase, isPareto, hasSecondaryAxis, isPercentStackedBars, primaryAxisNumberFormat, secondaryAxisNumberFormat, axisNumberFormatFor, seriesNumberFormats, seriesNumberFormatFor, tooltipConfig, finalLegend, bottomAxisNameGap, legendBand, positionedLegend, gridConfig, dataLabelOptions, seriesLabelOptionFor, isDoughnut, doughnutHoleSize, explosion, explosionOffset, barSeries, len, categoryTotals_2, barSeries_1, barSeries_1_1, s, i, raw, n, barSeries_2, barSeries_2_1, s, seriesWithLabels;
|
|
370
|
+
var threeDRenderKind, canRender3D, willRender3D, isRegionMap, regionSpec, geoScope, geo, labels, seriesEntry, values, _a, data, unmatched, min, max, textColor, ramp, noDataColor, borderColor, regionSeriesLabel, seriesName, chartDomains, chartSeries, legend, chartType, position, showAxis, isBubble, isHierarchy, skipHeaders_1, labelValues, perSeriesX, perSeriesSize, seriesInputs, i, seriesEntry, resolvedLabel, _b, xValues, sizeValues_1, sharedXValues, sharedSizeValues, _c, categories_1, preparedSeries, sizeValues, sizeScale_1, xAxisConfig, tooltipFormatter, bubbleSeriesLabel_1, hierarchyRows, headerTitle, hierarchyData, rootName, seriesDisplayName, hierarchyDepth, levels, sizeNumberFormat_1, tooltipFormatter, hierarchyDataLabels, hierarchySeriesLabel, isContour, categories_2, contourSeriesInputs, _d, _e, seriesEntry, dataLabel, _f, _g, values, e_1_1, seriesNames_1, contourPoints, _h, zMin, zMax, contourFormats_1, contourLabel, categories_3, threeDSeriesInputs, _j, _k, seriesEntry, dataLabel, _l, _m, values, e_2_1, seriesNames_2, threeDPalette_1, seriesColorAt_1, categoryAxisLabel, seriesAxisLabel, stackedBar3D_1, threeDFormats_1, threeDTooltipFormatter, threeDSeries, visualMap, xAxis3D, yAxis3D, categoryCount, categoryTotals_1, threeDSeriesInputs_1, threeDSeriesInputs_1_1, entry, isPercent_1, surfacePoints, _o, zMin, zMax, skipHeaders, categories, radarSeriesInputs, _p, _q, seriesEntry, label, values, indicators_1, radarData, radarStyle_1, radarColors_1, radarFormats_1, radarDataLabels_1, radarSeriesLabelFor_1, radarTooltipFormatter, variant_1, categories, seriesValues, stockFormats_1, stockRoleIndex_1, stockFormatFor_1, stockDataLabels_1, stockSeriesLabelFor_1, upColor_1, downColor_1, volumePoints, hasVolume, stockGrid, baseStockXAxis, stockXAxis, volumeYAxis, volumeSeries, stockAxisPointer, candleData, lineSeries, stockColors_1, isStacked, isCircularChart, isOfPie, ofPieLayout, isHorizontalBarChart, shouldAggregate, primaryDomainSource, rawPrimaryDomainValues, aggregateDomainValues, categoryLevels, pushSeriesOverlays, sideBySideBarCount, specBarGap, specBarCategoryGap, seriesPalette, paletteColorAt, _loop_1, _r, _s, _t, specSeriesIndex, series, e_3_1, labels, seriesEntry, rawValues, _u, main_1, secondary, otherTotal, total, ofPieType_1, secondScale, halfAngle_1, hasSecondary, MAIN_CX_1, CY_1, MAIN_RADIUS_PCT_1, SECONDARY_CX_1, secondaryRadiusPct_1, BAR_LEFT_1, BAR_RIGHT, barHalfFrac_1, ofPiePalette_1, paletteAt_1, connectorColor_1, primaryDomainSource_1, rawDomainValues, labels, seriesEntry, rawValues_1, totalIndices, steps, accent_1, decreaseColor_1, totalColor_1, connectors, primaryDomainSource_2, rawDomainValues, labels_1, seriesEntry, rawValues, quartileMethod, showOutliers, showMeanMarker, boxStats, boxLabels, outlierPoints, meanPoints, _v, _w, seriesEntry, label, rawValues, summary, boxIndex, lo, hi, _x, _y, outlier, boxSeries, boxColor, rawValues, _z, labels, counts, isPareto_1, cumulativePercents, pareto, histogramSeries, histogramColor, renderedSeriesCount, replaceMerge, valueAxisBase, isPareto, hasSecondaryAxis, isPercentStackedBars, primaryAxisNumberFormat, secondaryAxisNumberFormat, axisNumberFormatFor, seriesNumberFormats, seriesNumberFormatFor, tooltipConfig, finalLegend, bottomAxisNameGap, legendBand, positionedLegend, gridConfig, dataLabelOptions, seriesLabelOptionFor, isDoughnut, doughnutHoleSize, explosion, explosionOffset, barSeries, len, categoryTotals_2, barSeries_1, barSeries_1_1, s, i, raw, n, barSeries_2, barSeries_2_1, s, seriesWithLabels;
|
|
371
371
|
var e_1, _0, e_2, _1, e_4, _2, e_5, _3, e_3, _4, e_6, _5, e_7, _6, e_8, _7, e_9, _8;
|
|
372
372
|
var _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128, _129, _130, _131, _132, _133, _134, _135, _136, _137, _138;
|
|
373
373
|
return tslib_1.__generator(this, function (_139) {
|
|
@@ -1615,8 +1615,19 @@ var BasicChart = function (_a) {
|
|
|
1615
1615
|
seriesCount: sideBySideBarCount,
|
|
1616
1616
|
overlap: isStacked ? 0 : spec.overlap,
|
|
1617
1617
|
});
|
|
1618
|
+
seriesPalette = (0, chart_styles_1.getChartPalette)(spec, [
|
|
1619
|
+
theme.themeColors.accent1,
|
|
1620
|
+
theme.themeColors.accent2,
|
|
1621
|
+
theme.themeColors.accent3,
|
|
1622
|
+
theme.themeColors.accent4,
|
|
1623
|
+
theme.themeColors.accent5,
|
|
1624
|
+
theme.themeColors.accent6,
|
|
1625
|
+
]);
|
|
1626
|
+
paletteColorAt = function (index) {
|
|
1627
|
+
return seriesPalette[index % seriesPalette.length];
|
|
1628
|
+
};
|
|
1618
1629
|
_loop_1 = function (specSeriesIndex, series) {
|
|
1619
|
-
var dataLabel, _140, _141, effectiveChartType, lineLike, domainSources, pieDomainLabels, piePointOffset, data, seriesEchartsType, seriesStyleAttrs, seriesEntry, isBarOrColumn, seriesAny, markerSymbol, wantsMarkers, isolated, marked, isolated_1, isolated_1_1, i, gradientArgs, gradient, overrides_2, _142, _143, dp, fallback_1, overrides_3, _144, _145, dp,
|
|
1630
|
+
var dataLabel, _140, _141, effectiveChartType, lineLike, domainSources, pieDomainLabels, piePointOffset, data, seriesEchartsType, seriesStyleAttrs, seriesEntry, isBarOrColumn, seriesAny, markerSymbol, wantsMarkers, isolated, marked, isolated_1, isolated_1_1, i, gradientArgs, gradient, overrides_2, _142, _143, dp, fallback_1, overrides_3, _144, _145, dp, positiveColor_1, negativeColor_1;
|
|
1620
1631
|
var e_11, _146, e_12, _147, e_13, _148;
|
|
1621
1632
|
return tslib_1.__generator(this, function (_149) {
|
|
1622
1633
|
switch (_149.label) {
|
|
@@ -1762,7 +1773,7 @@ var BasicChart = function (_a) {
|
|
|
1762
1773
|
}
|
|
1763
1774
|
finally { if (e_12) throw e_12.error; }
|
|
1764
1775
|
}
|
|
1765
|
-
fallback_1 = (_85 = series.color) !== null && _85 !== void 0 ? _85 :
|
|
1776
|
+
fallback_1 = (_85 = series.color) !== null && _85 !== void 0 ? _85 : paletteColorAt(specSeriesIndex);
|
|
1766
1777
|
seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_86 = seriesEntry.itemStyle) !== null && _86 !== void 0 ? _86 : {})), { color: function (params) { var _a; return (_a = overrides_2.get(params.dataIndex)) !== null && _a !== void 0 ? _a : fallback_1; } });
|
|
1767
1778
|
}
|
|
1768
1779
|
else if (isCircularChart &&
|
|
@@ -1784,23 +1795,14 @@ var BasicChart = function (_a) {
|
|
|
1784
1795
|
}
|
|
1785
1796
|
finally { if (e_13) throw e_13.error; }
|
|
1786
1797
|
}
|
|
1787
|
-
slicePalette_1 = (0, chart_styles_1.getChartPalette)(spec, [
|
|
1788
|
-
theme.themeColors.accent1,
|
|
1789
|
-
theme.themeColors.accent2,
|
|
1790
|
-
theme.themeColors.accent3,
|
|
1791
|
-
theme.themeColors.accent4,
|
|
1792
|
-
theme.themeColors.accent5,
|
|
1793
|
-
theme.themeColors.accent6,
|
|
1794
|
-
]);
|
|
1795
1798
|
seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_87 = seriesEntry.itemStyle) !== null && _87 !== void 0 ? _87 : {})), { color: function (params) {
|
|
1796
1799
|
var _a, _b;
|
|
1797
|
-
return (_b = (_a = overrides_3.get(params.dataIndex)) !== null && _a !== void 0 ? _a : series.color) !== null && _b !== void 0 ? _b :
|
|
1800
|
+
return (_b = (_a = overrides_3.get(params.dataIndex)) !== null && _a !== void 0 ? _a : series.color) !== null && _b !== void 0 ? _b : paletteColorAt(params.dataIndex);
|
|
1798
1801
|
} });
|
|
1799
1802
|
}
|
|
1800
1803
|
else if (isBarOrColumn && series.invertIfNegative) {
|
|
1801
|
-
positiveColor_1 = (_88 = series.color) !== null && _88 !== void 0 ? _88 :
|
|
1804
|
+
positiveColor_1 = (_88 = series.color) !== null && _88 !== void 0 ? _88 : paletteColorAt(specSeriesIndex);
|
|
1802
1805
|
negativeColor_1 = (_89 = series.negativeColor) !== null && _89 !== void 0 ? _89 : "#FF0000";
|
|
1803
|
-
// Use a color function that returns different colors based on value
|
|
1804
1806
|
seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_90 = seriesEntry.itemStyle) !== null && _90 !== void 0 ? _90 : {})), { color: function (params) {
|
|
1805
1807
|
var _a, _b;
|
|
1806
1808
|
var value = Array.isArray(params.data)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAiD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAgXxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AA0FnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,sBA4zEjB,CAAC"}
|
|
@@ -8,7 +8,6 @@ var spreadsheet_state_1 = require("@rowsncolumns/spreadsheet-state");
|
|
|
8
8
|
var ui_1 = require("@rowsncolumns/ui");
|
|
9
9
|
var utils_1 = require("@rowsncolumns/utils");
|
|
10
10
|
var react_1 = tslib_1.__importStar(require("react"));
|
|
11
|
-
var react_plotly_js_1 = tslib_1.__importDefault(require("react-plotly.js"));
|
|
12
11
|
var aggregation_1 = require("../../utils/aggregation");
|
|
13
12
|
var axis_number_format_1 = require("../../utils/axis-number-format");
|
|
14
13
|
var boxplot_1 = require("../../utils/boxplot");
|
|
@@ -34,6 +33,7 @@ var radar_1 = require("../../utils/radar");
|
|
|
34
33
|
var region_map_1 = require("../../utils/region-map");
|
|
35
34
|
var stock_1 = require("../../utils/stock");
|
|
36
35
|
var trendline_1 = require("../../utils/trendline");
|
|
36
|
+
var plot_1 = require("../plot");
|
|
37
37
|
var helpers_1 = require("./helpers");
|
|
38
38
|
var BASIC_CHART_TYPES = new Set([
|
|
39
39
|
"bar",
|
|
@@ -374,7 +374,6 @@ var BasicChart = function (_a) {
|
|
|
374
374
|
var hierarchyTitleRef = (0, react_1.useRef)(undefined);
|
|
375
375
|
var explicitChartTitle = (_b = chart.spec.title) !== null && _b !== void 0 ? _b : undefined;
|
|
376
376
|
var title = explicitChartTitle !== null && explicitChartTitle !== void 0 ? explicitChartTitle : hierarchyTitleRef.current;
|
|
377
|
-
var plotRef = (0, react_1.useRef)(null);
|
|
378
377
|
// The plotted `<div>` plotly hands back on init — what `Plotly.toImage`
|
|
379
378
|
// rasterises for Copy as Picture and the print preview.
|
|
380
379
|
var graphDivRef = (0, react_1.useRef)(null);
|
|
@@ -2001,27 +2000,23 @@ var BasicChart = function (_a) {
|
|
|
2001
2000
|
onUpdateChart(tslib_1.__assign(tslib_1.__assign({}, chart), { spec: next }));
|
|
2002
2001
|
}
|
|
2003
2002
|
: undefined;
|
|
2004
|
-
// Copy as Picture / print preview
|
|
2005
|
-
//
|
|
2006
|
-
// path stays as it was.
|
|
2003
|
+
// Copy as Picture / print preview, through the plotly module the chart
|
|
2004
|
+
// renders with.
|
|
2007
2005
|
var exportChartPng = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
2008
|
-
var graphDiv,
|
|
2006
|
+
var graphDiv, url;
|
|
2009
2007
|
return tslib_1.__generator(this, function (_a) {
|
|
2010
2008
|
switch (_a.label) {
|
|
2011
2009
|
case 0:
|
|
2012
2010
|
graphDiv = graphDivRef.current;
|
|
2013
2011
|
if (!graphDiv)
|
|
2014
2012
|
return [2 /*return*/, undefined];
|
|
2015
|
-
return [4 /*yield*/,
|
|
2016
|
-
case 1:
|
|
2017
|
-
Plotly = (_a.sent()).default;
|
|
2018
|
-
return [4 /*yield*/, Plotly.toImage(graphDiv, {
|
|
2013
|
+
return [4 /*yield*/, plot_1.Plotly.toImage(graphDiv, {
|
|
2019
2014
|
format: "png",
|
|
2020
2015
|
width: graphDiv.clientWidth || width || 600,
|
|
2021
2016
|
height: graphDiv.clientHeight || height || 400,
|
|
2022
2017
|
scale: 2,
|
|
2023
2018
|
})];
|
|
2024
|
-
case
|
|
2019
|
+
case 1:
|
|
2025
2020
|
url = _a.sent();
|
|
2026
2021
|
return [2 /*return*/, (0, chart_image_1.dataUrlToBlob)(url)];
|
|
2027
2022
|
}
|
|
@@ -2054,7 +2049,7 @@ var BasicChart = function (_a) {
|
|
|
2054
2049
|
onDeleteChart === null || onDeleteChart === void 0 ? void 0 : onDeleteChart(chart.chartId);
|
|
2055
2050
|
} }, "Delete chart")))))) : null,
|
|
2056
2051
|
react_1.default.createElement("div", { className: "flex-1 rnc-plotly-chart-container", onPointerDownCapture: handlePointerDownCapture },
|
|
2057
|
-
react_1.default.createElement(
|
|
2052
|
+
react_1.default.createElement(plot_1.Plot, { data: plotData, layout: plotLayout, config: config, onClick: handlePlotClick, onInitialized: function (_figure, graphDiv) {
|
|
2058
2053
|
graphDivRef.current = graphDiv;
|
|
2059
2054
|
}, style: { width: "100%", height: "100%" } }))));
|
|
2060
2055
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Plotly from "plotly.js-dist-min";
|
|
2
|
+
/**
|
|
3
|
+
* The one plotly module the plotly charts render and export with:
|
|
4
|
+
* `plotly.js-dist-min`, the full bundle (every trace type) already minified.
|
|
5
|
+
* react-plotly.js's default entry would load the separate
|
|
6
|
+
* `plotly.js/dist/plotly` build instead, so a host that ships
|
|
7
|
+
* `plotly.js-dist-min` for its own charts would carry two copies of the same
|
|
8
|
+
* plotly release.
|
|
9
|
+
*/
|
|
10
|
+
export { Plotly };
|
|
11
|
+
export declare const Plot: import("react").ComponentType<import("react-plotly.js").PlotParams>;
|
|
12
|
+
//# sourceMappingURL=plot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plot.d.ts","sourceRoot":"","sources":["../../../plotly/plot.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAGxC;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,eAAO,MAAM,IAAI,qEAAgC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Plot = exports.Plotly = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var plotly_js_dist_min_1 = tslib_1.__importDefault(require("plotly.js-dist-min"));
|
|
6
|
+
exports.Plotly = plotly_js_dist_min_1.default;
|
|
7
|
+
var factory_1 = tslib_1.__importDefault(require("react-plotly.js/factory"));
|
|
8
|
+
exports.Plot = (0, factory_1.default)(plotly_js_dist_min_1.default);
|
|
@@ -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/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"}
|
|
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/plot.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"}
|
|
@@ -7,12 +7,24 @@
|
|
|
7
7
|
* so the regressions are hand-rolled here as pure least-squares math and
|
|
8
8
|
* the renderers draw the returned points as an overlay line series.
|
|
9
9
|
*
|
|
10
|
-
* All fits operate on
|
|
11
|
-
* category)
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* All fits operate on Excel's category domain x = 1, 2, …, n (one step per
|
|
11
|
+
* category, first category = 1) — the domain Excel fits and prints for a
|
|
12
|
+
* category-axis chart (line, column, bar, area). Linear, polynomial and
|
|
13
|
+
* exponential curves are invariant to where the domain starts (only the
|
|
14
|
+
* equation text moves), but logarithmic and power fits are not: fitting
|
|
15
|
+
* them on x = 0, 1, … dropped the first category from the fit and evaluated
|
|
16
|
+
* ln(x) at x → 0 for it, which drew the Jan point of a 12-month log trend
|
|
17
|
+
* at about −524 instead of Excel's ≈6.4 (rowsncolumns/spreadsheet#1028).
|
|
18
|
+
*
|
|
19
|
+
* The emitted points keep the renderer-facing 0-based CATEGORY INDEX in `x`
|
|
20
|
+
* (echarts plots `[x, y]` on the category axis, plotly maps `x` onto the
|
|
21
|
+
* category labels), so a forecast of k periods still extends to index
|
|
22
|
+
* n−1+k forward and −k backward. The caller passes the raw y-values; gaps
|
|
23
|
+
* (null/NaN) are skipped during fitting but the fitted curve is still
|
|
24
|
+
* emitted for every x in range.
|
|
14
25
|
*/
|
|
15
26
|
export type TrendlineType = "linear" | "exp" | "log" | "poly" | "power" | "movingAvg";
|
|
27
|
+
/** `x` is the 0-based category index (−k … n−1+k with forecasting), `y` the fitted value. */
|
|
16
28
|
export type TrendlinePoint = {
|
|
17
29
|
x: number;
|
|
18
30
|
y: number;
|
|
@@ -28,7 +40,8 @@ export type TrendlineResult = {
|
|
|
28
40
|
/**
|
|
29
41
|
* Compute a trendline for a series of y-values.
|
|
30
42
|
*
|
|
31
|
-
* @param values Raw y-values; the category
|
|
43
|
+
* @param values Raw y-values; the 1-based category position is used as x
|
|
44
|
+
* for the fit, the 0-based index is reported in the points.
|
|
32
45
|
* @param spec Trendline parameters (type/order/period/forecast).
|
|
33
46
|
*/
|
|
34
47
|
export declare const computeTrendline: (values: (number | null | undefined)[], spec?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,CAAC;AAEhB,6FAA6F;AAC7F,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAsJF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,OAAM;IACJ,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,KACL,eAAe,GAAG,IAiGpB,CAAC"}
|
|
@@ -8,10 +8,21 @@
|
|
|
8
8
|
* so the regressions are hand-rolled here as pure least-squares math and
|
|
9
9
|
* the renderers draw the returned points as an overlay line series.
|
|
10
10
|
*
|
|
11
|
-
* All fits operate on
|
|
12
|
-
* category)
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* All fits operate on Excel's category domain x = 1, 2, …, n (one step per
|
|
12
|
+
* category, first category = 1) — the domain Excel fits and prints for a
|
|
13
|
+
* category-axis chart (line, column, bar, area). Linear, polynomial and
|
|
14
|
+
* exponential curves are invariant to where the domain starts (only the
|
|
15
|
+
* equation text moves), but logarithmic and power fits are not: fitting
|
|
16
|
+
* them on x = 0, 1, … dropped the first category from the fit and evaluated
|
|
17
|
+
* ln(x) at x → 0 for it, which drew the Jan point of a 12-month log trend
|
|
18
|
+
* at about −524 instead of Excel's ≈6.4 (rowsncolumns/spreadsheet#1028).
|
|
19
|
+
*
|
|
20
|
+
* The emitted points keep the renderer-facing 0-based CATEGORY INDEX in `x`
|
|
21
|
+
* (echarts plots `[x, y]` on the category axis, plotly maps `x` onto the
|
|
22
|
+
* category labels), so a forecast of k periods still extends to index
|
|
23
|
+
* n−1+k forward and −k backward. The caller passes the raw y-values; gaps
|
|
24
|
+
* (null/NaN) are skipped during fitting but the fitted curve is still
|
|
25
|
+
* emitted for every x in range.
|
|
15
26
|
*/
|
|
16
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
28
|
exports.computeTrendline = void 0;
|
|
@@ -20,7 +31,8 @@ var isFiniteNum = function (v) {
|
|
|
20
31
|
return typeof v === "number" && Number.isFinite(v);
|
|
21
32
|
};
|
|
22
33
|
/**
|
|
23
|
-
* Build (x, y) pairs from raw y-values using
|
|
34
|
+
* Build (x, y) pairs from raw y-values using Excel's 1-based category
|
|
35
|
+
* position as x (the first category is x = 1, see the module comment).
|
|
24
36
|
* Non-finite y-values are dropped (they cannot be fitted).
|
|
25
37
|
*/
|
|
26
38
|
var toPairs = function (values) {
|
|
@@ -28,7 +40,7 @@ var toPairs = function (values) {
|
|
|
28
40
|
for (var i = 0; i < values.length; i++) {
|
|
29
41
|
var y = values[i];
|
|
30
42
|
if (isFiniteNum(y))
|
|
31
|
-
pairs.push({ x: i, y: y });
|
|
43
|
+
pairs.push({ x: i + 1, y: y });
|
|
32
44
|
}
|
|
33
45
|
return pairs;
|
|
34
46
|
};
|
|
@@ -66,6 +78,11 @@ var round = function (n, digits) {
|
|
|
66
78
|
var f = Math.pow(10, digits);
|
|
67
79
|
return Math.round(n * f) / f;
|
|
68
80
|
};
|
|
81
|
+
/** `+ 2` / `- 2` for an additive term, the way Excel prints an equation. */
|
|
82
|
+
var signed = function (n) {
|
|
83
|
+
var r = round(n);
|
|
84
|
+
return r < 0 ? "- ".concat(Math.abs(r)) : "+ ".concat(r);
|
|
85
|
+
};
|
|
69
86
|
/** Solve a small linear system A·x = b via Gaussian elimination. */
|
|
70
87
|
var solveLinearSystem = function (A, b) {
|
|
71
88
|
var _a;
|
|
@@ -198,7 +215,8 @@ var fitPower = function (pairs) {
|
|
|
198
215
|
/**
|
|
199
216
|
* Compute a trendline for a series of y-values.
|
|
200
217
|
*
|
|
201
|
-
* @param values Raw y-values; the category
|
|
218
|
+
* @param values Raw y-values; the 1-based category position is used as x
|
|
219
|
+
* for the fit, the 0-based index is reported in the points.
|
|
202
220
|
* @param spec Trendline parameters (type/order/period/forecast).
|
|
203
221
|
*/
|
|
204
222
|
var computeTrendline = function (values, spec) {
|
|
@@ -230,9 +248,9 @@ var computeTrendline = function (values, spec) {
|
|
|
230
248
|
}
|
|
231
249
|
return { points: points_1, rSquared: null, equation: null };
|
|
232
250
|
}
|
|
233
|
-
|
|
234
|
-
var xStart = -backward;
|
|
235
|
-
var xEnd =
|
|
251
|
+
// Fit domain is 1..n; a forecast of k periods extends it to 1−k / n+k.
|
|
252
|
+
var xStart = 1 - backward;
|
|
253
|
+
var xEnd = values.length + forward;
|
|
236
254
|
var xs = [];
|
|
237
255
|
for (var x = xStart; x <= xEnd; x++)
|
|
238
256
|
xs.push(x);
|
|
@@ -244,7 +262,7 @@ var computeTrendline = function (values, spec) {
|
|
|
244
262
|
if (!fit_1)
|
|
245
263
|
return null;
|
|
246
264
|
predict = function (x) { return fit_1.m * x + fit_1.b; };
|
|
247
|
-
equation = "y = ".concat(round(fit_1.m), "x
|
|
265
|
+
equation = "y = ".concat(round(fit_1.m), "x ").concat(signed(fit_1.b));
|
|
248
266
|
break;
|
|
249
267
|
}
|
|
250
268
|
case "poly": {
|
|
@@ -257,8 +275,10 @@ var computeTrendline = function (values, spec) {
|
|
|
257
275
|
equation =
|
|
258
276
|
"y = " +
|
|
259
277
|
coeffs_1
|
|
260
|
-
.map(function (c, i) {
|
|
261
|
-
.
|
|
278
|
+
.map(function (c, i) {
|
|
279
|
+
return i === 0 ? "".concat(round(c)) : "".concat(signed(c), "x").concat(i === 1 ? "" : "^".concat(i));
|
|
280
|
+
})
|
|
281
|
+
.join(" ");
|
|
262
282
|
break;
|
|
263
283
|
}
|
|
264
284
|
case "exp": {
|
|
@@ -273,9 +293,10 @@ var computeTrendline = function (values, spec) {
|
|
|
273
293
|
var fit_3 = fitLog(pairs);
|
|
274
294
|
if (!fit_3)
|
|
275
295
|
return null;
|
|
276
|
-
//
|
|
296
|
+
// Only a backward forecast reaches x ≤ 0 (the fit domain starts at 1);
|
|
297
|
+
// ln(0) and ln(negative) are undefined, so clamp x to >0 for the curve.
|
|
277
298
|
predict = function (x) { return fit_3.a + fit_3.b * Math.log(x <= 0 ? 1e-9 : x); };
|
|
278
|
-
equation = "y = ".concat(round(fit_3.
|
|
299
|
+
equation = "y = ".concat(round(fit_3.b), "ln(x) ").concat(signed(fit_3.a));
|
|
279
300
|
break;
|
|
280
301
|
}
|
|
281
302
|
case "power": {
|
|
@@ -289,8 +310,9 @@ var computeTrendline = function (values, spec) {
|
|
|
289
310
|
default:
|
|
290
311
|
return null;
|
|
291
312
|
}
|
|
313
|
+
// Report the renderer-facing 0-based category index (see module comment).
|
|
292
314
|
var points = xs
|
|
293
|
-
.map(function (x) { return ({ x: x, y: predict(x) }); })
|
|
315
|
+
.map(function (x) { return ({ x: x - 1, y: predict(x) }); })
|
|
294
316
|
.filter(function (p) { return Number.isFinite(p.y); });
|
|
295
317
|
if (points.length < 2)
|
|
296
318
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAmQrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAqEnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,
|
|
1
|
+
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAmQrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAqEnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,sBAmzGjB,CAAC"}
|
|
@@ -1675,6 +1675,20 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1675
1675
|
seriesCount: sideBySideBarCount,
|
|
1676
1676
|
overlap: isStacked ? 0 : spec.overlap,
|
|
1677
1677
|
});
|
|
1678
|
+
// The colour a series without its own fill gets: the chart palette entry
|
|
1679
|
+
// for its position, the same cycle the option-level `color` gives echarts'
|
|
1680
|
+
// default path. Excel keeps that colour whatever else is authored on the
|
|
1681
|
+
// series — `<c:dPt>` overrides recolour only their points and
|
|
1682
|
+
// `invertIfNegative` only the negative bars (rowsncolumns/spreadsheet#1030).
|
|
1683
|
+
const seriesPalette = getChartPalette(spec, [
|
|
1684
|
+
theme.themeColors.accent1,
|
|
1685
|
+
theme.themeColors.accent2,
|
|
1686
|
+
theme.themeColors.accent3,
|
|
1687
|
+
theme.themeColors.accent4,
|
|
1688
|
+
theme.themeColors.accent5,
|
|
1689
|
+
theme.themeColors.accent6,
|
|
1690
|
+
]);
|
|
1691
|
+
const paletteColorAt = (index) => seriesPalette[index % seriesPalette.length];
|
|
1678
1692
|
for (const [specSeriesIndex, series] of (spec.series ?? []).entries()) {
|
|
1679
1693
|
const dataLabel = !isNil(series.dataLabel) && isAFormula(series.dataLabel)
|
|
1680
1694
|
? coerceCalculatedLabel(await onRequestCalculate(series.dataLabel, position.sheetId ?? sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex))
|
|
@@ -1822,14 +1836,16 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1822
1836
|
// Per-data-point color overrides — Gantt-style charts colour
|
|
1823
1837
|
// each task differently via `<c:dPt>`. Echarts accepts an
|
|
1824
1838
|
// `itemStyle.color` function that receives the data index;
|
|
1825
|
-
// we look up the override or fall back to the series
|
|
1839
|
+
// we look up the override or fall back to the series colour —
|
|
1840
|
+
// its own, else its palette slot (never a fixed accent1, which
|
|
1841
|
+
// painted every such series alike).
|
|
1826
1842
|
const overrides = new Map();
|
|
1827
1843
|
for (const dp of seriesAny.dataPointColors) {
|
|
1828
1844
|
if (typeof dp.idx === "number" && typeof dp.color === "string") {
|
|
1829
1845
|
overrides.set(dp.idx, dp.color);
|
|
1830
1846
|
}
|
|
1831
1847
|
}
|
|
1832
|
-
const fallback = series.color ??
|
|
1848
|
+
const fallback = series.color ?? paletteColorAt(specSeriesIndex);
|
|
1833
1849
|
seriesEntry.itemStyle = {
|
|
1834
1850
|
...(seriesEntry.itemStyle ?? {}),
|
|
1835
1851
|
color: (params) => overrides.get(params.dataIndex) ?? fallback,
|
|
@@ -1847,25 +1863,18 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1847
1863
|
overrides.set(dp.idx, dp.color);
|
|
1848
1864
|
}
|
|
1849
1865
|
}
|
|
1850
|
-
const slicePalette = getChartPalette(spec, [
|
|
1851
|
-
theme.themeColors.accent1,
|
|
1852
|
-
theme.themeColors.accent2,
|
|
1853
|
-
theme.themeColors.accent3,
|
|
1854
|
-
theme.themeColors.accent4,
|
|
1855
|
-
theme.themeColors.accent5,
|
|
1856
|
-
theme.themeColors.accent6,
|
|
1857
|
-
]);
|
|
1858
1866
|
seriesEntry.itemStyle = {
|
|
1859
1867
|
...(seriesEntry.itemStyle ?? {}),
|
|
1860
1868
|
color: (params) => overrides.get(params.dataIndex) ??
|
|
1861
1869
|
series.color ??
|
|
1862
|
-
|
|
1870
|
+
paletteColorAt(params.dataIndex),
|
|
1863
1871
|
};
|
|
1864
1872
|
}
|
|
1865
1873
|
else if (isBarOrColumn && series.invertIfNegative) {
|
|
1866
|
-
|
|
1874
|
+
// Positive bars keep the series colour (own, else palette slot);
|
|
1875
|
+
// only negative bars take the inverted colour.
|
|
1876
|
+
const positiveColor = series.color ?? paletteColorAt(specSeriesIndex);
|
|
1867
1877
|
const negativeColor = series.negativeColor ?? "#FF0000";
|
|
1868
|
-
// Use a color function that returns different colors based on value
|
|
1869
1878
|
seriesEntry.itemStyle = {
|
|
1870
1879
|
...(seriesEntry.itemStyle ?? {}),
|
|
1871
1880
|
color: (params) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAiD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAgXxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AA0FnD,eAAO,MAAM,UAAU,GAAI,wOAiBxB,eAAe,sBA4zEjB,CAAC"}
|
|
@@ -4,7 +4,6 @@ import { useSubscribeToSheet } from "@rowsncolumns/spreadsheet-state";
|
|
|
4
4
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuTrigger, IconButton, useIsomorphicLayoutEffect, useOnVisibilityChange, } from "@rowsncolumns/ui";
|
|
5
5
|
import { debug, isAFormula, isNil, ssfFormat } from "@rowsncolumns/utils";
|
|
6
6
|
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
7
|
-
import Plot from "react-plotly.js";
|
|
8
7
|
import { aggregateSeriesByDomain, getDomainValuesForAxis, sanitizeDomainValues, shouldAggregateSeries, } from "../../utils/aggregation";
|
|
9
8
|
import { formatAxisValue, numberFormatToPlotlyTicks, resolveSeriesNumberFormats, resolveValueAxisNumberFormat, valueAxisNameGap, } from "../../utils/axis-number-format";
|
|
10
9
|
import { computeBoxplotSummary } from "../../utils/boxplot";
|
|
@@ -30,6 +29,7 @@ import { buildRadarIndicators } from "../../utils/radar";
|
|
|
30
29
|
import { buildSequentialColorRamp, isRegionMapSpec, resolveGeoScope, WORLD_GEO_SCOPE, } from "../../utils/region-map";
|
|
31
30
|
import { assignStockRoles, toLineSeries, toVolumeSeries, } from "../../utils/stock";
|
|
32
31
|
import { computeTrendline } from "../../utils/trendline";
|
|
32
|
+
import { Plot, Plotly } from "../plot";
|
|
33
33
|
import { chartTypeToPlotlyType, getPlotlyTraceStyle, mapMarkerSymbolToPlotly, showXAxis, } from "./helpers";
|
|
34
34
|
const BASIC_CHART_TYPES = new Set([
|
|
35
35
|
"bar",
|
|
@@ -350,7 +350,6 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
350
350
|
const hierarchyTitleRef = useRef(undefined);
|
|
351
351
|
const explicitChartTitle = chart.spec.title ?? undefined;
|
|
352
352
|
const title = explicitChartTitle ?? hierarchyTitleRef.current;
|
|
353
|
-
const plotRef = useRef(null);
|
|
354
353
|
// The plotted `<div>` plotly hands back on init — what `Plotly.toImage`
|
|
355
354
|
// rasterises for Copy as Picture and the print preview.
|
|
356
355
|
const graphDivRef = useRef(null);
|
|
@@ -2158,14 +2157,12 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2158
2157
|
onUpdateChart({ ...chart, spec: next });
|
|
2159
2158
|
}
|
|
2160
2159
|
: undefined;
|
|
2161
|
-
// Copy as Picture / print preview
|
|
2162
|
-
//
|
|
2163
|
-
// path stays as it was.
|
|
2160
|
+
// Copy as Picture / print preview, through the plotly module the chart
|
|
2161
|
+
// renders with.
|
|
2164
2162
|
const exportChartPng = async () => {
|
|
2165
2163
|
const graphDiv = graphDivRef.current;
|
|
2166
2164
|
if (!graphDiv)
|
|
2167
2165
|
return undefined;
|
|
2168
|
-
const { default: Plotly } = await import("plotly.js/dist/plotly");
|
|
2169
2166
|
const url = await Plotly.toImage(graphDiv, {
|
|
2170
2167
|
format: "png",
|
|
2171
2168
|
width: graphDiv.clientWidth || width || 600,
|
|
@@ -2201,7 +2198,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2201
2198
|
onDeleteChart?.(chart.chartId);
|
|
2202
2199
|
} }, "Delete chart")))))) : null,
|
|
2203
2200
|
React.createElement("div", { className: "flex-1 rnc-plotly-chart-container", onPointerDownCapture: handlePointerDownCapture },
|
|
2204
|
-
React.createElement(Plot, {
|
|
2201
|
+
React.createElement(Plot, { data: plotData, layout: plotLayout, config: config, onClick: handlePlotClick, onInitialized: (_figure, graphDiv) => {
|
|
2205
2202
|
graphDivRef.current = graphDiv;
|
|
2206
2203
|
}, style: { width: "100%", height: "100%" } }))));
|
|
2207
2204
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Plotly from "plotly.js-dist-min";
|
|
2
|
+
/**
|
|
3
|
+
* The one plotly module the plotly charts render and export with:
|
|
4
|
+
* `plotly.js-dist-min`, the full bundle (every trace type) already minified.
|
|
5
|
+
* react-plotly.js's default entry would load the separate
|
|
6
|
+
* `plotly.js/dist/plotly` build instead, so a host that ships
|
|
7
|
+
* `plotly.js-dist-min` for its own charts would carry two copies of the same
|
|
8
|
+
* plotly release.
|
|
9
|
+
*/
|
|
10
|
+
export { Plotly };
|
|
11
|
+
export declare const Plot: import("react").ComponentType<import("react-plotly.js").PlotParams>;
|
|
12
|
+
//# sourceMappingURL=plot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plot.d.ts","sourceRoot":"","sources":["../../../plotly/plot.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAGxC;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,eAAO,MAAM,IAAI,qEAAgC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Plotly from "plotly.js-dist-min";
|
|
2
|
+
import createPlotlyComponent from "react-plotly.js/factory";
|
|
3
|
+
/**
|
|
4
|
+
* The one plotly module the plotly charts render and export with:
|
|
5
|
+
* `plotly.js-dist-min`, the full bundle (every trace type) already minified.
|
|
6
|
+
* react-plotly.js's default entry would load the separate
|
|
7
|
+
* `plotly.js/dist/plotly` build instead, so a host that ships
|
|
8
|
+
* `plotly.js-dist-min` for its own charts would carry two copies of the same
|
|
9
|
+
* plotly release.
|
|
10
|
+
*/
|
|
11
|
+
export { Plotly };
|
|
12
|
+
export const Plot = createPlotlyComponent(Plotly);
|
|
@@ -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/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"}
|
|
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/plot.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"}
|
|
@@ -7,12 +7,24 @@
|
|
|
7
7
|
* so the regressions are hand-rolled here as pure least-squares math and
|
|
8
8
|
* the renderers draw the returned points as an overlay line series.
|
|
9
9
|
*
|
|
10
|
-
* All fits operate on
|
|
11
|
-
* category)
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* All fits operate on Excel's category domain x = 1, 2, …, n (one step per
|
|
11
|
+
* category, first category = 1) — the domain Excel fits and prints for a
|
|
12
|
+
* category-axis chart (line, column, bar, area). Linear, polynomial and
|
|
13
|
+
* exponential curves are invariant to where the domain starts (only the
|
|
14
|
+
* equation text moves), but logarithmic and power fits are not: fitting
|
|
15
|
+
* them on x = 0, 1, … dropped the first category from the fit and evaluated
|
|
16
|
+
* ln(x) at x → 0 for it, which drew the Jan point of a 12-month log trend
|
|
17
|
+
* at about −524 instead of Excel's ≈6.4 (rowsncolumns/spreadsheet#1028).
|
|
18
|
+
*
|
|
19
|
+
* The emitted points keep the renderer-facing 0-based CATEGORY INDEX in `x`
|
|
20
|
+
* (echarts plots `[x, y]` on the category axis, plotly maps `x` onto the
|
|
21
|
+
* category labels), so a forecast of k periods still extends to index
|
|
22
|
+
* n−1+k forward and −k backward. The caller passes the raw y-values; gaps
|
|
23
|
+
* (null/NaN) are skipped during fitting but the fitted curve is still
|
|
24
|
+
* emitted for every x in range.
|
|
14
25
|
*/
|
|
15
26
|
export type TrendlineType = "linear" | "exp" | "log" | "poly" | "power" | "movingAvg";
|
|
27
|
+
/** `x` is the 0-based category index (−k … n−1+k with forecasting), `y` the fitted value. */
|
|
16
28
|
export type TrendlinePoint = {
|
|
17
29
|
x: number;
|
|
18
30
|
y: number;
|
|
@@ -28,7 +40,8 @@ export type TrendlineResult = {
|
|
|
28
40
|
/**
|
|
29
41
|
* Compute a trendline for a series of y-values.
|
|
30
42
|
*
|
|
31
|
-
* @param values Raw y-values; the category
|
|
43
|
+
* @param values Raw y-values; the 1-based category position is used as x
|
|
44
|
+
* for the fit, the 0-based index is reported in the points.
|
|
32
45
|
* @param spec Trendline parameters (type/order/period/forecast).
|
|
33
46
|
*/
|
|
34
47
|
export declare const computeTrendline: (values: (number | null | undefined)[], spec?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"trendline.d.ts","sourceRoot":"","sources":["../../../utils/trendline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,CAAC;AAEhB,6FAA6F;AAC7F,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAsJF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,OAAM;IACJ,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,KACL,eAAe,GAAG,IAiGpB,CAAC"}
|
|
@@ -7,14 +7,26 @@
|
|
|
7
7
|
* so the regressions are hand-rolled here as pure least-squares math and
|
|
8
8
|
* the renderers draw the returned points as an overlay line series.
|
|
9
9
|
*
|
|
10
|
-
* All fits operate on
|
|
11
|
-
* category)
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* All fits operate on Excel's category domain x = 1, 2, …, n (one step per
|
|
11
|
+
* category, first category = 1) — the domain Excel fits and prints for a
|
|
12
|
+
* category-axis chart (line, column, bar, area). Linear, polynomial and
|
|
13
|
+
* exponential curves are invariant to where the domain starts (only the
|
|
14
|
+
* equation text moves), but logarithmic and power fits are not: fitting
|
|
15
|
+
* them on x = 0, 1, … dropped the first category from the fit and evaluated
|
|
16
|
+
* ln(x) at x → 0 for it, which drew the Jan point of a 12-month log trend
|
|
17
|
+
* at about −524 instead of Excel's ≈6.4 (rowsncolumns/spreadsheet#1028).
|
|
18
|
+
*
|
|
19
|
+
* The emitted points keep the renderer-facing 0-based CATEGORY INDEX in `x`
|
|
20
|
+
* (echarts plots `[x, y]` on the category axis, plotly maps `x` onto the
|
|
21
|
+
* category labels), so a forecast of k periods still extends to index
|
|
22
|
+
* n−1+k forward and −k backward. The caller passes the raw y-values; gaps
|
|
23
|
+
* (null/NaN) are skipped during fitting but the fitted curve is still
|
|
24
|
+
* emitted for every x in range.
|
|
14
25
|
*/
|
|
15
26
|
const isFiniteNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
16
27
|
/**
|
|
17
|
-
* Build (x, y) pairs from raw y-values using
|
|
28
|
+
* Build (x, y) pairs from raw y-values using Excel's 1-based category
|
|
29
|
+
* position as x (the first category is x = 1, see the module comment).
|
|
18
30
|
* Non-finite y-values are dropped (they cannot be fitted).
|
|
19
31
|
*/
|
|
20
32
|
const toPairs = (values) => {
|
|
@@ -22,7 +34,7 @@ const toPairs = (values) => {
|
|
|
22
34
|
for (let i = 0; i < values.length; i++) {
|
|
23
35
|
const y = values[i];
|
|
24
36
|
if (isFiniteNum(y))
|
|
25
|
-
pairs.push({ x: i, y });
|
|
37
|
+
pairs.push({ x: i + 1, y });
|
|
26
38
|
}
|
|
27
39
|
return pairs;
|
|
28
40
|
};
|
|
@@ -48,6 +60,11 @@ const round = (n, digits = 4) => {
|
|
|
48
60
|
const f = 10 ** digits;
|
|
49
61
|
return Math.round(n * f) / f;
|
|
50
62
|
};
|
|
63
|
+
/** `+ 2` / `- 2` for an additive term, the way Excel prints an equation. */
|
|
64
|
+
const signed = (n) => {
|
|
65
|
+
const r = round(n);
|
|
66
|
+
return r < 0 ? `- ${Math.abs(r)}` : `+ ${r}`;
|
|
67
|
+
};
|
|
51
68
|
/** Solve a small linear system A·x = b via Gaussian elimination. */
|
|
52
69
|
const solveLinearSystem = (A, b) => {
|
|
53
70
|
const n = b.length;
|
|
@@ -157,7 +174,8 @@ const fitPower = (pairs) => {
|
|
|
157
174
|
/**
|
|
158
175
|
* Compute a trendline for a series of y-values.
|
|
159
176
|
*
|
|
160
|
-
* @param values Raw y-values; the category
|
|
177
|
+
* @param values Raw y-values; the 1-based category position is used as x
|
|
178
|
+
* for the fit, the 0-based index is reported in the points.
|
|
161
179
|
* @param spec Trendline parameters (type/order/period/forecast).
|
|
162
180
|
*/
|
|
163
181
|
export const computeTrendline = (values, spec = {}) => {
|
|
@@ -187,9 +205,9 @@ export const computeTrendline = (values, spec = {}) => {
|
|
|
187
205
|
}
|
|
188
206
|
return { points, rSquared: null, equation: null };
|
|
189
207
|
}
|
|
190
|
-
|
|
191
|
-
const xStart = -backward;
|
|
192
|
-
const xEnd =
|
|
208
|
+
// Fit domain is 1..n; a forecast of k periods extends it to 1−k / n+k.
|
|
209
|
+
const xStart = 1 - backward;
|
|
210
|
+
const xEnd = values.length + forward;
|
|
193
211
|
const xs = [];
|
|
194
212
|
for (let x = xStart; x <= xEnd; x++)
|
|
195
213
|
xs.push(x);
|
|
@@ -201,7 +219,7 @@ export const computeTrendline = (values, spec = {}) => {
|
|
|
201
219
|
if (!fit)
|
|
202
220
|
return null;
|
|
203
221
|
predict = (x) => fit.m * x + fit.b;
|
|
204
|
-
equation = `y = ${round(fit.m)}x
|
|
222
|
+
equation = `y = ${round(fit.m)}x ${signed(fit.b)}`;
|
|
205
223
|
break;
|
|
206
224
|
}
|
|
207
225
|
case "poly": {
|
|
@@ -212,8 +230,8 @@ export const computeTrendline = (values, spec = {}) => {
|
|
|
212
230
|
equation =
|
|
213
231
|
"y = " +
|
|
214
232
|
coeffs
|
|
215
|
-
.map((c, i) =>
|
|
216
|
-
.join("
|
|
233
|
+
.map((c, i) => i === 0 ? `${round(c)}` : `${signed(c)}x${i === 1 ? "" : `^${i}`}`)
|
|
234
|
+
.join(" ");
|
|
217
235
|
break;
|
|
218
236
|
}
|
|
219
237
|
case "exp": {
|
|
@@ -228,9 +246,10 @@ export const computeTrendline = (values, spec = {}) => {
|
|
|
228
246
|
const fit = fitLog(pairs);
|
|
229
247
|
if (!fit)
|
|
230
248
|
return null;
|
|
231
|
-
//
|
|
249
|
+
// Only a backward forecast reaches x ≤ 0 (the fit domain starts at 1);
|
|
250
|
+
// ln(0) and ln(negative) are undefined, so clamp x to >0 for the curve.
|
|
232
251
|
predict = (x) => fit.a + fit.b * Math.log(x <= 0 ? 1e-9 : x);
|
|
233
|
-
equation = `y = ${round(fit.
|
|
252
|
+
equation = `y = ${round(fit.b)}ln(x) ${signed(fit.a)}`;
|
|
234
253
|
break;
|
|
235
254
|
}
|
|
236
255
|
case "power": {
|
|
@@ -244,8 +263,9 @@ export const computeTrendline = (values, spec = {}) => {
|
|
|
244
263
|
default:
|
|
245
264
|
return null;
|
|
246
265
|
}
|
|
266
|
+
// Report the renderer-facing 0-based category index (see module comment).
|
|
247
267
|
const points = xs
|
|
248
|
-
.map((x) => ({ x, y: predict(x) }))
|
|
268
|
+
.map((x) => ({ x: x - 1, y: predict(x) }))
|
|
249
269
|
.filter((p) => Number.isFinite(p.y));
|
|
250
270
|
if (points.length < 2)
|
|
251
271
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rowsncolumns/charts",
|
|
3
|
-
"version": "28.1.
|
|
3
|
+
"version": "28.1.5",
|
|
4
4
|
"author": "Vinay M",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -70,16 +70,16 @@
|
|
|
70
70
|
"@rowsncolumns/common-types": ">=5.3.2",
|
|
71
71
|
"@rowsncolumns/grid": ">=13.2.35",
|
|
72
72
|
"@rowsncolumns/icons": ">=7.2.33",
|
|
73
|
-
"@rowsncolumns/spreadsheet": ">=10.4.
|
|
74
|
-
"@rowsncolumns/spreadsheet-state": ">=29.1.
|
|
75
|
-
"@rowsncolumns/toolkit": ">=24.5.
|
|
73
|
+
"@rowsncolumns/spreadsheet": ">=10.4.5",
|
|
74
|
+
"@rowsncolumns/spreadsheet-state": ">=29.1.7",
|
|
75
|
+
"@rowsncolumns/toolkit": ">=24.5.6",
|
|
76
76
|
"@rowsncolumns/ui": ">=16.0.4",
|
|
77
|
-
"@rowsncolumns/utils": ">=9.5.
|
|
77
|
+
"@rowsncolumns/utils": ">=9.5.4",
|
|
78
78
|
"@types/react-plotly.js": "^2.6.3",
|
|
79
79
|
"echarts": "^5.6.0",
|
|
80
80
|
"formik": "^2.4.6",
|
|
81
81
|
"immer": "^10.1.1",
|
|
82
|
-
"plotly.js": "^3.1.1",
|
|
82
|
+
"plotly.js-dist-min": "^3.1.1",
|
|
83
83
|
"react-plotly.js": "^2.6.0"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@rowsncolumns/utils": ">=9.3.0",
|
|
95
95
|
"immer": ">10.0.0",
|
|
96
96
|
"jotai": ">=2.10.3",
|
|
97
|
-
"plotly.js": ">=3",
|
|
97
|
+
"plotly.js-dist-min": ">=3",
|
|
98
98
|
"react": ">=18.0.0",
|
|
99
99
|
"react-dom": ">=18.0.0",
|
|
100
100
|
"react-plotly.js": ">=2"
|