@rowsncolumns/charts 28.1.8 → 28.1.10

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.
Files changed (47) hide show
  1. package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
  2. package/dist/cjs/basic-chart/basic-chart.js +483 -417
  3. package/dist/cjs/basic-chart/helpers.d.ts.map +1 -1
  4. package/dist/cjs/basic-chart/helpers.js +2 -0
  5. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  6. package/dist/cjs/plotly/basic-chart/basic-chart.js +315 -184
  7. package/dist/cjs/plotly/basic-chart/helpers.d.ts.map +1 -1
  8. package/dist/cjs/plotly/basic-chart/helpers.js +2 -0
  9. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  10. package/dist/cjs/utils/bubble.d.ts +34 -1
  11. package/dist/cjs/utils/bubble.d.ts.map +1 -1
  12. package/dist/cjs/utils/bubble.js +39 -13
  13. package/dist/cjs/utils/echarts-overlays.d.ts +46 -0
  14. package/dist/cjs/utils/echarts-overlays.d.ts.map +1 -0
  15. package/dist/cjs/utils/echarts-overlays.js +134 -0
  16. package/dist/cjs/utils/hierarchy.d.ts +23 -1
  17. package/dist/cjs/utils/hierarchy.d.ts.map +1 -1
  18. package/dist/cjs/utils/hierarchy.js +179 -55
  19. package/dist/cjs/utils/overrides.d.ts.map +1 -1
  20. package/dist/cjs/utils/overrides.js +9 -2
  21. package/dist/cjs/utils/trendline.d.ts +7 -1
  22. package/dist/cjs/utils/trendline.d.ts.map +1 -1
  23. package/dist/cjs/utils/trendline.js +82 -18
  24. package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
  25. package/dist/esm/basic-chart/basic-chart.js +320 -239
  26. package/dist/esm/basic-chart/helpers.d.ts.map +1 -1
  27. package/dist/esm/basic-chart/helpers.js +2 -0
  28. package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
  29. package/dist/esm/plotly/basic-chart/basic-chart.js +235 -58
  30. package/dist/esm/plotly/basic-chart/helpers.d.ts.map +1 -1
  31. package/dist/esm/plotly/basic-chart/helpers.js +2 -0
  32. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  33. package/dist/esm/utils/bubble.d.ts +34 -1
  34. package/dist/esm/utils/bubble.d.ts.map +1 -1
  35. package/dist/esm/utils/bubble.js +35 -11
  36. package/dist/esm/utils/echarts-overlays.d.ts +46 -0
  37. package/dist/esm/utils/echarts-overlays.d.ts.map +1 -0
  38. package/dist/esm/utils/echarts-overlays.js +135 -0
  39. package/dist/esm/utils/hierarchy.d.ts +23 -1
  40. package/dist/esm/utils/hierarchy.d.ts.map +1 -1
  41. package/dist/esm/utils/hierarchy.js +168 -50
  42. package/dist/esm/utils/overrides.d.ts.map +1 -1
  43. package/dist/esm/utils/overrides.js +9 -2
  44. package/dist/esm/utils/trendline.d.ts +7 -1
  45. package/dist/esm/utils/trendline.d.ts.map +1 -1
  46. package/dist/esm/utils/trendline.js +67 -14
  47. package/package.json +3 -3
@@ -29,15 +29,25 @@ const isFiniteNum = (v) => typeof v === "number" && Number.isFinite(v);
29
29
  * position as x (the first category is x = 1, see the module comment).
30
30
  * Non-finite y-values are dropped (they cannot be fitted).
31
31
  */
32
- const toPairs = (values) => {
32
+ const toPairs = (values, xValues) => {
33
33
  const pairs = [];
34
34
  for (let i = 0; i < values.length; i++) {
35
35
  const y = values[i];
36
- if (isFiniteNum(y))
36
+ if (!isFiniteNum(y))
37
+ continue;
38
+ if (xValues) {
39
+ const x = xValues[i];
40
+ if (isFiniteNum(x))
41
+ pairs.push({ x, y });
42
+ }
43
+ else {
37
44
  pairs.push({ x: i + 1, y });
45
+ }
38
46
  }
39
47
  return pairs;
40
48
  };
49
+ /** Samples along a scatter trendline's x range: enough for the curved fits to read as curves. */
50
+ const XY_TRENDLINE_SAMPLES = 64;
41
51
  /** Compute R² between observed y and predicted f(x) over the fit pairs. */
42
52
  const rSquaredOf = (pairs, predict) => {
43
53
  if (pairs.length < 2)
@@ -177,14 +187,22 @@ const fitPower = (pairs) => {
177
187
  * @param values Raw y-values; the 1-based category position is used as x
178
188
  * for the fit, the 0-based index is reported in the points.
179
189
  * @param spec Trendline parameters (type/order/period/forecast).
190
+ * @param xValues Scatter / bubble only — the series' real X values, index-
191
+ * aligned with `values`. The fit then runs on (x, y) pairs
192
+ * (a regression of Y on X, what Excel draws on an XY chart;
193
+ * the point index is wrong for unevenly spaced X), the
194
+ * forecast extends the X range by that many X units, and the
195
+ * points carry real X coordinates sampled across the range.
180
196
  */
181
- export const computeTrendline = (values, spec = {}) => {
182
- const pairs = toPairs(values);
197
+ export const computeTrendline = (values, spec = {}, xValues) => {
198
+ const pairs = toPairs(values, xValues);
183
199
  if (pairs.length < 2)
184
200
  return null;
185
201
  const type = spec.type ?? "linear";
186
- const forward = Math.max(0, Math.floor(spec.forecastForward ?? 0));
187
- const backward = Math.max(0, Math.floor(spec.forecastBackward ?? 0));
202
+ const forwardRaw = Math.max(0, spec.forecastForward ?? 0);
203
+ const backwardRaw = Math.max(0, spec.forecastBackward ?? 0);
204
+ const forward = xValues ? forwardRaw : Math.floor(forwardRaw);
205
+ const backward = xValues ? backwardRaw : Math.floor(backwardRaw);
188
206
  // Moving average is a smoothing of the observed values, not a fitted
189
207
  // function, so it is handled separately and ignores forecasting.
190
208
  if (type === "movingAvg") {
@@ -200,17 +218,51 @@ export const computeTrendline = (values, spec = {}) => {
200
218
  count++;
201
219
  }
202
220
  }
203
- if (count > 0)
221
+ if (count === 0)
222
+ continue;
223
+ if (xValues) {
224
+ const x = xValues[i];
225
+ if (isFiniteNum(x))
226
+ points.push({ x, y: sum / count });
227
+ }
228
+ else {
204
229
  points.push({ x: i, y: sum / count });
230
+ }
205
231
  }
232
+ if (xValues)
233
+ points.sort((a, b) => a.x - b.x);
206
234
  return { points, rSquared: null, equation: null };
207
235
  }
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;
211
236
  const xs = [];
212
- for (let x = xStart; x <= xEnd; x++)
213
- xs.push(x);
237
+ if (xValues) {
238
+ // Sample the fitted curve across the data's X range, extended by the
239
+ // forecast in X units.
240
+ let minX = Infinity;
241
+ let maxX = -Infinity;
242
+ for (const p of pairs) {
243
+ if (p.x < minX)
244
+ minX = p.x;
245
+ if (p.x > maxX)
246
+ maxX = p.x;
247
+ }
248
+ const xStart = minX - backward;
249
+ const xEnd = maxX + forward;
250
+ if (xEnd > xStart) {
251
+ for (let i = 0; i <= XY_TRENDLINE_SAMPLES; i++) {
252
+ xs.push(xStart + ((xEnd - xStart) * i) / XY_TRENDLINE_SAMPLES);
253
+ }
254
+ }
255
+ else {
256
+ xs.push(xStart);
257
+ }
258
+ }
259
+ else {
260
+ // Fit domain is 1..n; a forecast of k periods extends it to 1−k / n+k.
261
+ const xStart = 1 - backward;
262
+ const xEnd = values.length + forward;
263
+ for (let x = xStart; x <= xEnd; x++)
264
+ xs.push(x);
265
+ }
214
266
  let predict = null;
215
267
  let equation = null;
216
268
  switch (type) {
@@ -263,9 +315,10 @@ export const computeTrendline = (values, spec = {}) => {
263
315
  default:
264
316
  return null;
265
317
  }
266
- // Report the renderer-facing 0-based category index (see module comment).
318
+ // Report the renderer-facing 0-based category index (see module comment);
319
+ // an XY fit reports the real X it was sampled at.
267
320
  const points = xs
268
- .map((x) => ({ x: x - 1, y: predict(x) }))
321
+ .map((x) => ({ x: xValues ? x : x - 1, y: predict(x) }))
269
322
  .filter((p) => Number.isFinite(p.y));
270
323
  if (points.length < 2)
271
324
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/charts",
3
- "version": "28.1.8",
3
+ "version": "28.1.10",
4
4
  "author": "Vinay M",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "main": "./dist/cjs/index.js",
@@ -70,9 +70,9 @@
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.7",
73
+ "@rowsncolumns/spreadsheet": ">=10.4.8",
74
74
  "@rowsncolumns/spreadsheet-state": ">=29.1.8",
75
- "@rowsncolumns/toolkit": ">=24.5.9",
75
+ "@rowsncolumns/toolkit": ">=24.5.10",
76
76
  "@rowsncolumns/ui": ">=16.0.4",
77
77
  "@rowsncolumns/utils": ">=9.5.5",
78
78
  "@types/react-plotly.js": "^2.6.3",