chartjs-plugin-trendline 3.2.0 → 3.2.3

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 (43) hide show
  1. package/.github/copilot-instructions.md +40 -40
  2. package/.github/workflows/release.yml +64 -61
  3. package/.github/workflows/tests.yml +26 -26
  4. package/.prettierrc +5 -5
  5. package/CLAUDE.md +44 -44
  6. package/GEMINI.md +40 -40
  7. package/LICENSE +21 -21
  8. package/MIGRATION.md +126 -126
  9. package/README.md +166 -166
  10. package/babel.config.js +3 -3
  11. package/changelog.md +39 -39
  12. package/dist/chartjs-plugin-trendline.cjs +884 -885
  13. package/dist/chartjs-plugin-trendline.esm.js +882 -883
  14. package/dist/chartjs-plugin-trendline.js +890 -891
  15. package/dist/chartjs-plugin-trendline.min.js +8 -8
  16. package/dist/chartjs-plugin-trendline.min.js.map +1 -1
  17. package/example/barChart.html +165 -165
  18. package/example/barChartWithNullValues.html +168 -168
  19. package/example/barChart_label.html +174 -174
  20. package/example/exponentialChart.html +244 -244
  21. package/example/lineChart.html +210 -210
  22. package/example/lineChartProjection.html +261 -261
  23. package/example/lineChartTypeTime.html +190 -190
  24. package/example/scatterChart.html +136 -136
  25. package/example/scatterProjection.html +141 -141
  26. package/example/test-null-handling.html +59 -59
  27. package/index.html +215 -215
  28. package/jest.config.js +4 -4
  29. package/package.json +45 -40
  30. package/rollup.config.js +54 -54
  31. package/src/components/label.js +56 -56
  32. package/src/components/label.test.js +129 -129
  33. package/src/components/trendline.js +375 -375
  34. package/src/components/trendline.test.js +789 -789
  35. package/src/core/plugin.js +78 -79
  36. package/src/core/plugin.test.js +307 -0
  37. package/src/index.js +12 -12
  38. package/src/utils/drawing.js +125 -125
  39. package/src/utils/drawing.test.js +308 -308
  40. package/src/utils/exponentialFitter.js +146 -146
  41. package/src/utils/exponentialFitter.test.js +362 -362
  42. package/src/utils/lineFitter.js +86 -86
  43. package/src/utils/lineFitter.test.js +340 -340
@@ -1,126 +1,126 @@
1
- /**
2
- * Retrieves the x and y scales from the chart instance.
3
- * @param {Chart} chartInstance - The chart instance.
4
- * @returns {Object} - The xScale and yScale of the chart.
5
- */
6
- export const getScales = (chartInstance) => {
7
- let xScale, yScale;
8
- for (const scale of Object.values(chartInstance.scales)) {
9
- if (scale.isHorizontal()) xScale = scale;
10
- else yScale = scale;
11
- if (xScale && yScale) break;
12
- }
13
- return { xScale, yScale };
14
- };
15
-
16
- /**
17
- * Sets the line style (dashed, dotted, solid) for the canvas context.
18
- * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
19
- * @param {string} lineStyle - The style of the line ('dotted', 'dashed', 'solid', etc.).
20
- */
21
- export const setLineStyle = (ctx, lineStyle) => {
22
- switch (lineStyle) {
23
- case 'dotted':
24
- ctx.setLineDash([2, 2]);
25
- break;
26
- case 'dashed':
27
- ctx.setLineDash([8, 3]);
28
- break;
29
- case 'dashdot':
30
- ctx.setLineDash([8, 3, 2, 3]);
31
- break;
32
- case 'solid':
33
- default:
34
- ctx.setLineDash([]);
35
- break;
36
- }
37
- };
38
-
39
- /**
40
- * Draws the trendline on the canvas context.
41
- * @param {Object} params - The trendline parameters.
42
- * @param {CanvasRenderingContext2D} params.ctx - The canvas rendering context.
43
- * @param {number} params.x1 - Starting x-coordinate of the trendline.
44
- * @param {number} params.y1 - Starting y-coordinate of the trendline.
45
- * @param {number} params.x2 - Ending x-coordinate of the trendline.
46
- * @param {number} params.y2 - Ending y-coordinate of the trendline.
47
- * @param {string} params.colorMin - The starting color of the trendline gradient.
48
- * @param {string} params.colorMax - The ending color of the trendline gradient.
49
- */
50
- export const drawTrendline = ({ ctx, x1, y1, x2, y2, colorMin, colorMax }) => {
51
- // Ensure all values are finite numbers
52
- if (!isFinite(x1) || !isFinite(y1) || !isFinite(x2) || !isFinite(y2)) {
53
- console.warn(
54
- 'Cannot draw trendline: coordinates contain non-finite values',
55
- { x1, y1, x2, y2 }
56
- );
57
- return;
58
- }
59
-
60
- ctx.beginPath();
61
- ctx.moveTo(x1, y1);
62
- ctx.lineTo(x2, y2);
63
-
64
- try {
65
- // Additional validation for degenerate gradients
66
- const dx = x2 - x1;
67
- const dy = y2 - y1;
68
- const gradientLength = Math.sqrt(dx * dx + dy * dy);
69
-
70
- // If the gradient vector is too small, createLinearGradient may fail
71
- if (gradientLength < 0.01) {
72
- console.warn('Gradient vector too small, using solid color:', { x1, y1, x2, y2, length: gradientLength });
73
- ctx.strokeStyle = colorMin;
74
- } else {
75
- let gradient = ctx.createLinearGradient(x1, y1, x2, y2);
76
- gradient.addColorStop(0, colorMin);
77
- gradient.addColorStop(1, colorMax);
78
- ctx.strokeStyle = gradient;
79
- }
80
- } catch (e) {
81
- // Fallback to solid color if gradient creation fails
82
- console.warn('Gradient creation failed, using solid color:', e);
83
- ctx.strokeStyle = colorMin;
84
- }
85
-
86
- ctx.stroke();
87
- ctx.closePath();
88
- };
89
-
90
- /**
91
- * Fills the area below the trendline with the specified color.
92
- * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
93
- * @param {number} x1 - Starting x-coordinate of the trendline.
94
- * @param {number} y1 - Starting y-coordinate of the trendline.
95
- * @param {number} x2 - Ending x-coordinate of the trendline.
96
- * @param {number} y2 - Ending y-coordinate of the trendline.
97
- * @param {number} drawBottom - The bottom boundary of the chart.
98
- * @param {string} fillColor - The color to fill below the trendline.
99
- */
100
- export const fillBelowTrendline = (ctx, x1, y1, x2, y2, drawBottom, fillColor) => {
101
- // Ensure all values are finite numbers
102
- if (
103
- !isFinite(x1) ||
104
- !isFinite(y1) ||
105
- !isFinite(x2) ||
106
- !isFinite(y2) ||
107
- !isFinite(drawBottom)
108
- ) {
109
- console.warn(
110
- 'Cannot fill below trendline: coordinates contain non-finite values',
111
- { x1, y1, x2, y2, drawBottom }
112
- );
113
- return;
114
- }
115
-
116
- ctx.beginPath();
117
- ctx.moveTo(x1, y1);
118
- ctx.lineTo(x2, y2);
119
- ctx.lineTo(x2, drawBottom);
120
- ctx.lineTo(x1, drawBottom);
121
- ctx.lineTo(x1, y1);
122
- ctx.closePath();
123
-
124
- ctx.fillStyle = fillColor;
125
- ctx.fill();
1
+ /**
2
+ * Retrieves the x and y scales from the chart instance.
3
+ * @param {Chart} chartInstance - The chart instance.
4
+ * @returns {Object} - The xScale and yScale of the chart.
5
+ */
6
+ export const getScales = (chartInstance) => {
7
+ let xScale, yScale;
8
+ for (const scale of Object.values(chartInstance.scales)) {
9
+ if (scale.isHorizontal()) xScale = scale;
10
+ else yScale = scale;
11
+ if (xScale && yScale) break;
12
+ }
13
+ return { xScale, yScale };
14
+ };
15
+
16
+ /**
17
+ * Sets the line style (dashed, dotted, solid) for the canvas context.
18
+ * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
19
+ * @param {string} lineStyle - The style of the line ('dotted', 'dashed', 'solid', etc.).
20
+ */
21
+ export const setLineStyle = (ctx, lineStyle) => {
22
+ switch (lineStyle) {
23
+ case 'dotted':
24
+ ctx.setLineDash([2, 2]);
25
+ break;
26
+ case 'dashed':
27
+ ctx.setLineDash([8, 3]);
28
+ break;
29
+ case 'dashdot':
30
+ ctx.setLineDash([8, 3, 2, 3]);
31
+ break;
32
+ case 'solid':
33
+ default:
34
+ ctx.setLineDash([]);
35
+ break;
36
+ }
37
+ };
38
+
39
+ /**
40
+ * Draws the trendline on the canvas context.
41
+ * @param {Object} params - The trendline parameters.
42
+ * @param {CanvasRenderingContext2D} params.ctx - The canvas rendering context.
43
+ * @param {number} params.x1 - Starting x-coordinate of the trendline.
44
+ * @param {number} params.y1 - Starting y-coordinate of the trendline.
45
+ * @param {number} params.x2 - Ending x-coordinate of the trendline.
46
+ * @param {number} params.y2 - Ending y-coordinate of the trendline.
47
+ * @param {string} params.colorMin - The starting color of the trendline gradient.
48
+ * @param {string} params.colorMax - The ending color of the trendline gradient.
49
+ */
50
+ export const drawTrendline = ({ ctx, x1, y1, x2, y2, colorMin, colorMax }) => {
51
+ // Ensure all values are finite numbers
52
+ if (!isFinite(x1) || !isFinite(y1) || !isFinite(x2) || !isFinite(y2)) {
53
+ console.warn(
54
+ 'Cannot draw trendline: coordinates contain non-finite values',
55
+ { x1, y1, x2, y2 }
56
+ );
57
+ return;
58
+ }
59
+
60
+ ctx.beginPath();
61
+ ctx.moveTo(x1, y1);
62
+ ctx.lineTo(x2, y2);
63
+
64
+ try {
65
+ // Additional validation for degenerate gradients
66
+ const dx = x2 - x1;
67
+ const dy = y2 - y1;
68
+ const gradientLength = Math.sqrt(dx * dx + dy * dy);
69
+
70
+ // If the gradient vector is too small, createLinearGradient may fail
71
+ if (gradientLength < 0.01) {
72
+ console.warn('Gradient vector too small, using solid color:', { x1, y1, x2, y2, length: gradientLength });
73
+ ctx.strokeStyle = colorMin;
74
+ } else {
75
+ let gradient = ctx.createLinearGradient(x1, y1, x2, y2);
76
+ gradient.addColorStop(0, colorMin);
77
+ gradient.addColorStop(1, colorMax);
78
+ ctx.strokeStyle = gradient;
79
+ }
80
+ } catch (e) {
81
+ // Fallback to solid color if gradient creation fails
82
+ console.warn('Gradient creation failed, using solid color:', e);
83
+ ctx.strokeStyle = colorMin;
84
+ }
85
+
86
+ ctx.stroke();
87
+ ctx.closePath();
88
+ };
89
+
90
+ /**
91
+ * Fills the area below the trendline with the specified color.
92
+ * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
93
+ * @param {number} x1 - Starting x-coordinate of the trendline.
94
+ * @param {number} y1 - Starting y-coordinate of the trendline.
95
+ * @param {number} x2 - Ending x-coordinate of the trendline.
96
+ * @param {number} y2 - Ending y-coordinate of the trendline.
97
+ * @param {number} drawBottom - The bottom boundary of the chart.
98
+ * @param {string} fillColor - The color to fill below the trendline.
99
+ */
100
+ export const fillBelowTrendline = (ctx, x1, y1, x2, y2, drawBottom, fillColor) => {
101
+ // Ensure all values are finite numbers
102
+ if (
103
+ !isFinite(x1) ||
104
+ !isFinite(y1) ||
105
+ !isFinite(x2) ||
106
+ !isFinite(y2) ||
107
+ !isFinite(drawBottom)
108
+ ) {
109
+ console.warn(
110
+ 'Cannot fill below trendline: coordinates contain non-finite values',
111
+ { x1, y1, x2, y2, drawBottom }
112
+ );
113
+ return;
114
+ }
115
+
116
+ ctx.beginPath();
117
+ ctx.moveTo(x1, y1);
118
+ ctx.lineTo(x2, y2);
119
+ ctx.lineTo(x2, drawBottom);
120
+ ctx.lineTo(x1, drawBottom);
121
+ ctx.lineTo(x1, y1);
122
+ ctx.closePath();
123
+
124
+ ctx.fillStyle = fillColor;
125
+ ctx.fill();
126
126
  };