chartjs-plugin-trendline 2.1.1 → 2.1.2

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Marcus Alsterfjord
3
+ Copyright (c) 2024 Marcus Alsterfjord
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -11,7 +11,7 @@ Load Chart.js first, then the plugin which will automatically register itself wi
11
11
 
12
12
  ```html
13
13
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.min.js"></script>
14
- <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-trendline"></script>
14
+ <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-trendline/dist/chartjs-plugin-trendline.min.js"></script>
15
15
  ```
16
16
 
17
17
  #### As a Chart.JS plugin
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see chartjs-plugin-trendline.min.js.LICENSE.txt */
2
- (()=>{"use strict";var t={228:(t,e,s)=>{class i{constructor(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0,this.minx=1e100,this.maxx=-1e100,this.maxy=-1e100}add=(t,e)=>{t=parseFloat(t),e=parseFloat(e),this.count++,this.sumX+=t,this.sumX2+=t*t,this.sumXY+=t*e,this.sumY+=e,t<this.minx&&(this.minx=t),t>this.maxx&&(this.maxx=t),e>this.maxy&&(this.maxy=e)};f=t=>{t=parseFloat(t);let e=this.count*this.sumX2-this.sumX*this.sumX;return(this.sumX2*this.sumY-this.sumX*this.sumXY)/e+t*((this.count*this.sumXY-this.sumX*this.sumY)/e)};fo=()=>{let t=this.count*this.sumX2-this.sumX*this.sumX;return-(this.sumX2*this.sumY-this.sumX*this.sumXY)/t/((this.count*this.sumXY-this.sumX*this.sumY)/t)};scale=()=>{let t=this.count*this.sumX2-this.sumX*this.sumX;return(this.count*this.sumXY-this.sumX*this.sumY)/t}}t=s.hmd(t);const a={id:"chartjs-plugin-trendline",afterDatasetsDraw:t=>{let e,s;for(let i in t.scales)if("x"==i[0]?s=t.scales[i]:e=t.scales[i],s&&e)break;const i=t.ctx;t.data.datasets.forEach(((e,a)=>{const o=e.alwaysShowTrendline||t.isDatasetVisible(a);if(e.trendlineLinear&&o&&e.data.length>1){const o=t.getDatasetMeta(a);r(o,i,e,s,t.scales[o.yAxisID])}})),i.setLineDash([])}},r=(t,e,s,a,r)=>{let o=s.borderColor||"rgba(169,169,169, .6)",n=s.trendlineLinear.colorMin||o,l=s.trendlineLinear.colorMax||o,h=s.trendlineLinear.width??s.borderWidth??3,d=s.trendlineLinear.lineStyle||"solid",u=s.trendlineLinear.fillColor;const m=t.controller.chart.options,x="object"==typeof m.parsing?m.parsing:void 0,c=s.trendlineLinear.xAxisKey||x?.xAxisKey||"x",p=s.trendlineLinear.yAxisKey||x?.yAxisKey||"y";let f=new i,y=s.data.findIndex((t=>null!=t)),X=s.data.length-1,g=t.data[y][c],w=t.data[X][c],Y="object"==typeof s.data[y];s.data.forEach(((t,e)=>{if(null!=t)if(["time","timeseries"].includes(a.options.type)){let s=null!=t[c]?t[c]:t.t;void 0!==s?f.add(new Date(s).getTime(),t[p]):f.add(e,t)}else Y?isNaN(t.x)||isNaN(t.y)?isNaN(t.x)?isNaN(t.y)||f.add(e,t.y):f.add(e,t.x):f.add(t.x,t.y):f.add(e,t)}));let b,L,P=a.getPixelForValue(f.minx),C=r.getPixelForValue(f.f(f.minx));if(s.trendlineLinear.projection&&f.scale()<0){let t=f.fo();t<f.minx&&(t=f.maxx),b=a.getPixelForValue(t),L=r.getPixelForValue(f.f(t))}else b=a.getPixelForValue(f.maxx),L=r.getPixelForValue(f.f(f.maxx));Y||(P=g,b=w);let S=t.controller.chart.chartArea.bottom,D=t.controller.chart.width;if(C>S){let t=C-S,e=C-L;C=S,P+=D*(t/e)}else if(L>S){let t=L-S,e=L-C;L=S,b=D-(b-(D-D*(t/e)))}e.lineWidth=h,"dotted"===d?e.setLineDash([2,3]):e.setLineDash([]),e.beginPath(),e.moveTo(P,C),e.lineTo(b,L);let F=e.createLinearGradient(P,C,b,L);L<C?(F.addColorStop(0,l),F.addColorStop(1,n)):(F.addColorStop(0,n),F.addColorStop(1,l)),e.strokeStyle=F,e.stroke(),e.closePath(),u&&(e.fillStyle=u,e.beginPath(),e.moveTo(P,C),e.lineTo(b,L),e.lineTo(b,S),e.lineTo(P,S),e.closePath(),e.fill())};"undefined"!=typeof window&&window.Chart&&(window.Chart.hasOwnProperty("register")?window.Chart.register(a):window.Chart.plugins.register(a));try{t.exports=exports=a}catch(t){}}},e={};function s(i){var a=e[i];if(void 0!==a)return a.exports;var r=e[i]={id:i,loaded:!1,exports:{}};return t[i](r,r.exports,s),r.loaded=!0,r.exports}s.hmd=t=>((t=Object.create(t)).children||(t.children=[]),Object.defineProperty(t,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+t.id)}}),t),s(228)})();
2
+ (()=>{var t={460:(t,e)=>{const s={id:"chartjs-plugin-trendline",afterDatasetsDraw:t=>{let e,s;for(let i in t.scales)if("x"==i[0]?s=t.scales[i]:e=t.scales[i],s&&e)break;const a=t.ctx;t.data.datasets.forEach(((e,r)=>{const n=e.alwaysShowTrendline||t.isDatasetVisible(r);if(e.trendlineLinear&&n&&e.data.length>1){const n=t.getDatasetMeta(r);i(n,a,e,s,t.scales[n.yAxisID])}})),a.setLineDash([])}},i=(t,e,s,i,r)=>{let n=s.borderColor||"rgba(169,169,169, .6)",o=s.trendlineLinear.colorMin||n,l=s.trendlineLinear.colorMax||n,h=s.trendlineLinear.width??s.borderWidth??3,d=s.trendlineLinear.lineStyle||"solid",u=s.trendlineLinear.fillColor;const m=t.controller.chart.options,x="object"==typeof m.parsing?m.parsing:void 0,c=s.trendlineLinear.xAxisKey||x?.xAxisKey||"x",f=s.trendlineLinear.yAxisKey||x?.yAxisKey||"y";let X=new a,y=s.data.findIndex((t=>null!=t)),p=s.data.length-1,g=t.data[y][c],w=t.data[p][c],Y="object"==typeof s.data[y];s.data.forEach(((t,e)=>{if(null!=t)if(["time","timeseries"].includes(i.options.type)){let s=null!=t[c]?t[c]:t.t;void 0!==s?X.add(new Date(s).getTime(),t[f]):X.add(e,t)}else Y?isNaN(t.x)||isNaN(t.y)?isNaN(t.x)?isNaN(t.y)||X.add(e,t.y):X.add(e,t.x):X.add(t.x,t.y):X.add(e,t)}));let L,P,b=i.getPixelForValue(X.minx),C=r.getPixelForValue(X.f(X.minx));if(s.trendlineLinear.projection&&X.scale()<0){let t=X.fo();t<X.minx&&(t=X.maxx),L=i.getPixelForValue(t),P=r.getPixelForValue(X.f(t))}else L=i.getPixelForValue(X.maxx),P=r.getPixelForValue(X.f(X.maxx));Y||(b=g,L=w);let D=t.controller.chart.chartArea.bottom,F=t.controller.chart.width;if(C>D){let t=C-D,e=C-P;C=D,b+=F*(t/e)}else if(P>D){let t=P-D,e=P-C;P=D,L=F-(L-(F-F*(t/e)))}e.lineWidth=h,"dotted"===d?e.setLineDash([2,3]):e.setLineDash([]),e.beginPath(),e.moveTo(b,C),e.lineTo(L,P);let v=e.createLinearGradient(b,C,L,P);P<C?(v.addColorStop(0,l),v.addColorStop(1,o)):(v.addColorStop(0,o),v.addColorStop(1,l)),e.strokeStyle=v,e.stroke(),e.closePath(),u&&(e.fillStyle=u,e.beginPath(),e.moveTo(b,C),e.lineTo(L,P),e.lineTo(L,D),e.lineTo(b,D),e.closePath(),e.fill())};class a{constructor(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0,this.minx=1e100,this.maxx=-1e100,this.maxy=-1e100}add(t,e){t=parseFloat(t),e=parseFloat(e),this.count++,this.sumX+=t,this.sumX2+=t*t,this.sumXY+=t*e,this.sumY+=e,t<this.minx&&(this.minx=t),t>this.maxx&&(this.maxx=t),e>this.maxy&&(this.maxy=e)}f(t){t=parseFloat(t);let e=this.count*this.sumX2-this.sumX*this.sumX;return(this.sumX2*this.sumY-this.sumX*this.sumXY)/e+t*((this.count*this.sumXY-this.sumX*this.sumY)/e)}fo(){let t=this.count*this.sumX2-this.sumX*this.sumX;return-(this.sumX2*this.sumY-this.sumX*this.sumXY)/t/((this.count*this.sumXY-this.sumX*this.sumY)/t)}scale(){let t=this.count*this.sumX2-this.sumX*this.sumX;return(this.count*this.sumXY-this.sumX*this.sumY)/t}}"undefined"!=typeof window&&window.Chart&&(window.Chart.hasOwnProperty("register")?window.Chart.register(s):window.Chart.plugins.register(s));try{t.exports=s}catch(t){}}},e={};!function s(i){var a=e[i];if(void 0!==a)return a.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,s),r.exports}(460)})();
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * chartjs-plugin-trendline.js
3
- * Version: 2.1.1
3
+ * Version: 2.1.2
4
4
  *
5
5
  * Copyright 2024 Marcus Alsterfjord
6
6
  * Released under the MIT license
@@ -6,7 +6,7 @@
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>BarChart Example</title>
8
8
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.js"></script>
9
- <script src="./../dist/chartjs-plugin-trendline.min.js"></script>
9
+ <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
12
12
  // Bar chart
@@ -6,7 +6,7 @@
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>BarChart Example</title>
8
8
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.js"></script>
9
- <script src="./../dist/chartjs-plugin-trendline.min.js"></script>
9
+ <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
12
12
  // Bar chart
@@ -6,7 +6,7 @@
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>LineChart Example</title>
8
8
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.js"></script>
9
- <script src="./../dist/chartjs-plugin-trendline.min.js"></script>
9
+ <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
12
12
  new Chart(document.getElementById("line-chart"), {
@@ -6,7 +6,7 @@
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>XYlineChart Projection Example</title>
8
8
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.js"></script>
9
- <script src="./../dist/chartjs-plugin-trendline.min.js"></script>
9
+ <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
12
12
  new Chart(document.getElementById("line-chart"), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chartjs-plugin-trendline",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Trendline for Chart.js",
5
5
  "main": "src/chartjs-plugin-trendline.js",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "homepage": "https://github.com/Makanz/chartjs-plugin-trendline#readme",
19
19
  "devDependencies": {
20
- "webpack": "^5.90.0",
20
+ "webpack": "^5.92.1",
21
21
  "webpack-cli": "^5.1.4"
22
22
  }
23
23
  }
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * chartjs-plugin-trendline.js
3
- * Version: 2.1.1
3
+ * Version: 2.1.2
4
4
  *
5
5
  * Copyright 2024 Marcus Alsterfjord
6
6
  * Released under the MIT license
@@ -8,8 +8,6 @@
8
8
  *
9
9
  * Mod by: vesal: accept also xy-data so works with scatter
10
10
  */
11
- import { LineFitter } from './classes/lineFitter.js';
12
-
13
11
  const pluginTrendlineLinear = {
14
12
  id: 'chartjs-plugin-trendline',
15
13
  afterDatasetsDraw: (chartInstance) => {
@@ -56,9 +54,14 @@ const addFitter = (datasetMeta, ctx, dataset, xScale, yScale) => {
56
54
  let fillColor = dataset.trendlineLinear.fillColor;
57
55
 
58
56
  const chartOptions = datasetMeta.controller.chart.options;
59
- const parsingOptions = typeof chartOptions.parsing === 'object' ? chartOptions.parsing : undefined;
60
- const xAxisKey = dataset.trendlineLinear.xAxisKey || parsingOptions?.xAxisKey || 'x';
61
- const yAxisKey = dataset.trendlineLinear.yAxisKey || parsingOptions?.yAxisKey || 'y';
57
+ const parsingOptions =
58
+ typeof chartOptions.parsing === 'object'
59
+ ? chartOptions.parsing
60
+ : undefined;
61
+ const xAxisKey =
62
+ dataset.trendlineLinear.xAxisKey || parsingOptions?.xAxisKey || 'x';
63
+ const yAxisKey =
64
+ dataset.trendlineLinear.yAxisKey || parsingOptions?.yAxisKey || 'y';
62
65
 
63
66
  let fitter = new LineFitter();
64
67
  let firstIndex = dataset.data.findIndex((d) => {
@@ -178,6 +181,59 @@ const addFitter = (datasetMeta, ctx, dataset, xScale, yScale) => {
178
181
  }
179
182
  };
180
183
 
184
+ class LineFitter {
185
+ constructor() {
186
+ this.count = 0;
187
+ this.sumX = 0;
188
+ this.sumX2 = 0;
189
+ this.sumXY = 0;
190
+ this.sumY = 0;
191
+ this.minx = 1e100;
192
+ this.maxx = -1e100;
193
+ this.maxy = -1e100;
194
+ }
195
+
196
+ add(x, y) {
197
+ x = parseFloat(x);
198
+ y = parseFloat(y);
199
+
200
+ this.count++;
201
+ this.sumX += x;
202
+ this.sumX2 += x * x;
203
+ this.sumXY += x * y;
204
+ this.sumY += y;
205
+ if (x < this.minx) this.minx = x;
206
+ if (x > this.maxx) this.maxx = x;
207
+ if (y > this.maxy) this.maxy = y;
208
+ }
209
+
210
+ f(x) {
211
+ x = parseFloat(x);
212
+
213
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
214
+ let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
215
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
216
+ return offset + x * scale;
217
+ }
218
+
219
+ fo() {
220
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
221
+ let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
222
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
223
+
224
+ // Get x when y = 0
225
+ let xo = -offset / scale;
226
+ return xo;
227
+ }
228
+
229
+ scale() {
230
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
231
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
232
+
233
+ return scale;
234
+ }
235
+ }
236
+
181
237
  // If we're in the browser and have access to the global Chart obj, register plugin automatically
182
238
  if (typeof window !== 'undefined' && window.Chart) {
183
239
  if (window.Chart.hasOwnProperty('register')) {
@@ -1,52 +0,0 @@
1
- export class LineFitter {
2
- constructor() {
3
- this.count = 0;
4
- this.sumX = 0;
5
- this.sumX2 = 0;
6
- this.sumXY = 0;
7
- this.sumY = 0;
8
- this.minx = 1e100;
9
- this.maxx = -1e100;
10
- this.maxy = -1e100;
11
- }
12
-
13
- add = (x, y) => {
14
- x = parseFloat(x);
15
- y = parseFloat(y);
16
-
17
- this.count++;
18
- this.sumX += x;
19
- this.sumX2 += x * x;
20
- this.sumXY += x * y;
21
- this.sumY += y;
22
- if (x < this.minx) this.minx = x;
23
- if (x > this.maxx) this.maxx = x;
24
- if (y > this.maxy) this.maxy = y;
25
- };
26
-
27
- f = (x) => {
28
- x = parseFloat(x);
29
-
30
- let det = this.count * this.sumX2 - this.sumX * this.sumX;
31
- let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
32
- let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
33
- return offset + x * scale;
34
- };
35
-
36
- fo = () => {
37
- let det = this.count * this.sumX2 - this.sumX * this.sumX;
38
- let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
39
- let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
40
-
41
- // Get x when y = 0
42
- let xo = -offset / scale;
43
- return xo;
44
- };
45
-
46
- scale = () => {
47
- let det = this.count * this.sumX2 - this.sumX * this.sumX;
48
- let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
49
-
50
- return scale;
51
- };
52
- }