chartjs-plugin-trendline 2.0.5 → 2.1.0

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # chartjs-plugin-trendline
2
2
 
3
3
  This plugin draws an linear trendline in your Chart.
4
- It has been tested with Chart.js version 4.3.0.
4
+ It has been tested with Chart.js version 4.4.0.
5
5
 
6
6
  ## Installation
7
7
 
@@ -10,7 +10,7 @@ It has been tested with Chart.js version 4.3.0.
10
10
  Load Chart.js first, then the plugin which will automatically register itself with Chart.js
11
11
 
12
12
  ```html
13
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.min.js"></script>
13
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.min.js"></script>
14
14
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-trendline"></script>
15
15
  ```
16
16
 
@@ -38,6 +38,8 @@ To configure the trendline plugin you simply add a new config options to your da
38
38
  colorMax: "green",
39
39
  lineStyle: "dotted|solid",
40
40
  width: 2,
41
+ xAxisKey: "time" (optional),
42
+ yAxisKey: "usage" (optional),
41
43
  projection: true|false (optional)
42
44
  }
43
45
  }
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see chartjs-plugin-trendline.min.js.LICENSE.txt */
2
- (()=>{var t={460:(t,i)=>{var e={id:"chartjs-plugin-trendline",afterDatasetsDraw:function(t){var i,e;for(var a in t.scales)if("x"==a[0]?e=t.scales[a]:i=t.scales[a],e&&i)break;var r=t.ctx;t.data.datasets.forEach((function(i,a){var n=i.alwaysShowTrendline||t.isDatasetVisible(a);if(i.trendlineLinear&&n&&i.data.length>1){var o=t.getDatasetMeta(a);!function(t,i,e,a,r){var n=e.borderColor||"rgba(169,169,169, .6)",o=e.trendlineLinear.colorMin||n,h=e.trendlineLinear.colorMax||n,l=e.trendlineLinear.width||e.borderWidth,u=e.trendlineLinear.lineStyle||"solid",d=e.trendlineLinear.fillColor;l=void 0!==l?l:3;var m=new s,x=e.data.findIndex((t=>null!=t)),c=e.data.length-1,f=t.data[x].x,X=t.data[c].x,v="object"==typeof e.data[x];e.data.forEach((function(t,i){if(null!=t)if(["time","timeseries"].includes(a.options.type)){var e=null!=t.x?t.x:t.t;void 0!==e?m.add(new Date(e).getTime(),t.y):m.add(i,t)}else v?isNaN(t.x)||isNaN(t.y)?isNaN(t.x)?isNaN(t.y)||m.add(i,t.y):m.add(i,t.x):m.add(t.x,t.y):m.add(i,t)}));var p,y,g=a.getPixelForValue(m.minx),w=r.getPixelForValue(m.f(m.minx));if(e.trendlineLinear.projection&&m.scale()<0){var Y=m.fo();Y<m.minx&&(Y=m.maxx),p=a.getPixelForValue(Y),y=r.getPixelForValue(m.f(Y))}else p=a.getPixelForValue(m.maxx),y=r.getPixelForValue(m.f(m.maxx));v||(g=f,p=X);var L=t.controller.chart.chartArea.bottom,P=t.controller.chart.width;if(w>L){var C=w-L,b=w-y;w=L,g+=P*(C/b)}else y>L&&(C=y-L,b=y-w,y=L,p=P-(p-(P-P*(C/b))));i.lineWidth=l,"dotted"===u?i.setLineDash([2,3]):i.setLineDash([]),i.beginPath(),i.moveTo(g,w),i.lineTo(p,y);var D=i.createLinearGradient(g,w,p,y);y<w?(D.addColorStop(0,h),D.addColorStop(1,o)):(D.addColorStop(0,o),D.addColorStop(1,h)),i.strokeStyle=D,i.stroke(),i.closePath(),!d||(i.fillStyle=d,i.beginPath(),i.moveTo(g,w),i.lineTo(p,y),i.lineTo(p,L),i.lineTo(g,L),i.closePath(),i.fill())}(o,r,i,e,t.scales[o.yAxisID])}})),r.setLineDash([])}};function s(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0,this.minx=1e100,this.maxx=-1e100,this.maxy=-1e100}s.prototype={add:function(t,i){t=parseFloat(t),i=parseFloat(i),this.count++,this.sumX+=t,this.sumX2+=t*t,this.sumXY+=t*i,this.sumY+=i,t<this.minx&&(this.minx=t),t>this.maxx&&(this.maxx=t),i>this.maxy&&(this.maxy=i)},f:function(t){t=parseFloat(t);var i=this.count*this.sumX2-this.sumX*this.sumX;return(this.sumX2*this.sumY-this.sumX*this.sumXY)/i+t*((this.count*this.sumXY-this.sumX*this.sumY)/i)},fo:function(){var 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:function(){var 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(e):window.Chart.plugins.register(e));try{t.exports=e}catch(t){}}},i={};!function e(s){var a=i[s];if(void 0!==a)return a.exports;var r=i[s]={exports:{}};return t[s](r,r.exports,e),r.exports}(460)})();
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,o)=>{const r=e.alwaysShowTrendline||t.isDatasetVisible(o);if(e.trendlineLinear&&r&&e.data.length>1){const r=t.getDatasetMeta(o);i(r,a,e,s,t.scales[r.yAxisID])}})),a.setLineDash([])}},i=(t,e,s,i,o)=>{let r=s.borderColor||"rgba(169,169,169, .6)",n=s.trendlineLinear.colorMin||r,l=s.trendlineLinear.colorMax||r,h=s.trendlineLinear.width||s.borderWidth,d=s.trendlineLinear.lineStyle||"solid",u=s.trendlineLinear.fillColor;const m="object"==typeof t.controller.chart.options.parsing?t.controller.chart.options.parsing:void 0,x=s.trendlineLinear.xAxisKey||m?m.xAxisKey:"x",c=s.trendlineLinear.yAxisKey||m?m.yAxisKey:"y";h=void 0!==h?h:3;let f=new a,X=s.data.findIndex((t=>null!=t)),p=s.data.length-1,y=t.data[X][x],g=t.data[p][x],w="object"==typeof s.data[X];s.data.forEach(((t,e)=>{if(null!=t)if(["time","timeseries"].includes(i.options.type)){let s=null!=t[x]?t[x]:t.t;void 0!==s?f.add(new Date(s).getTime(),t[c]):f.add(e,t)}else w?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 Y,L,P=i.getPixelForValue(f.minx),b=o.getPixelForValue(f.f(f.minx));if(s.trendlineLinear.projection&&f.scale()<0){let t=f.fo();t<f.minx&&(t=f.maxx),Y=i.getPixelForValue(t),L=o.getPixelForValue(f.f(t))}else Y=i.getPixelForValue(f.maxx),L=o.getPixelForValue(f.f(f.maxx));w||(P=y,Y=g);let C=t.controller.chart.chartArea.bottom,v=t.controller.chart.width;if(b>C){let t=b-C,e=b-L;b=C,P+=v*(t/e)}else if(L>C){let t=L-C,e=L-b;L=C,Y=v-(Y-(v-v*(t/e)))}e.lineWidth=h,"dotted"===d?e.setLineDash([2,3]):e.setLineDash([]),e.beginPath(),e.moveTo(P,b),e.lineTo(Y,L);let D=e.createLinearGradient(P,b,Y,L);L<b?(D.addColorStop(0,l),D.addColorStop(1,n)):(D.addColorStop(0,n),D.addColorStop(1,l)),e.strokeStyle=D,e.stroke(),e.closePath(),u&&(e.fillStyle=u,e.beginPath(),e.moveTo(P,b),e.lineTo(Y,L),e.lineTo(Y,C),e.lineTo(P,C),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 o=e[i]={exports:{}};return t[i](o,o.exports,s),o.exports}(460)})();
@@ -1,8 +1,8 @@
1
1
  /*!
2
2
  * chartjs-plugin-trendline.js
3
- * Version: 2.0.5
3
+ * Version: 2.1.0
4
4
  *
5
- * Copyright 2023 Marcus Alsterfjord
5
+ * Copyright 2024 Marcus Alsterfjord
6
6
  * Released under the MIT license
7
7
  * https://github.com/Makanz/chartjs-plugin-trendline/blob/master/README.md
8
8
  *
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>BarChart Example</title>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
9
9
  <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>BarChart Example</title>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
9
9
  <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <title>LineChart Example</title>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
9
+ <script src="./../src/chartjs-plugin-trendline.js"></script>
10
+ <script>
11
+ document.addEventListener("DOMContentLoaded", function(event) {
12
+ new Chart(document.getElementById("line-chart"), {
13
+ type: 'line',
14
+ data: {
15
+ labels: [1500,1600,1700,1750,1800,1850,1900,1950,1999,2050],
16
+ datasets: [{
17
+ data: [86,114,106,106,107,111,133,221,783,2478],
18
+ label: "Africa",
19
+ borderColor: "#3e95cd",
20
+ fill: false,
21
+ trendlineLinear: {
22
+ colorMin: "#3e95cd",
23
+ lineStyle: "line",
24
+ width: 1
25
+ }
26
+ }, {
27
+ data: [282,350,411,502,635,809,947,1402,3700,5267],
28
+ label: "Asia",
29
+ borderColor: "#8e5ea2",
30
+ fill: false,
31
+ trendlineLinear: {
32
+ colorMin: "red",
33
+ colorMax: "green",
34
+ lineStyle: "line",
35
+ width: 1
36
+ }
37
+ }, {
38
+ data: [168,170,178,190,203,276,408,547,675,734],
39
+ label: "Europe",
40
+ borderColor: "#3cba9f",
41
+ fill: false
42
+ }, {
43
+ data: [40,20,10,16,24,38,74,167,508,784],
44
+ label: "Latin America",
45
+ borderColor: "#e8c3b9",
46
+ fill: false
47
+ }, {
48
+ data: [6,3,2,2,7,26,82,172,312,433],
49
+ label: "North America",
50
+ borderColor: "#c45850",
51
+ fill: false
52
+ }
53
+ ]
54
+ },
55
+ options: {
56
+ title: {
57
+ display: true,
58
+ text: 'World population per region (in millions)'
59
+ }
60
+ }
61
+ });
62
+ });
63
+ </script>
64
+ </head>
65
+ <body>
66
+ <h1>Line Chart</h1>
67
+
68
+ <div style="width: 800px;">
69
+ <canvas id="line-chart"></canvas>
70
+ </div>
71
+
72
+ </body>
73
+ </html>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>XYlineChart Projection Example</title>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
9
9
  <script src="./../src/chartjs-plugin-trendline.js"></script>
10
10
  <script>
11
11
  document.addEventListener("DOMContentLoaded", function(event) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chartjs-plugin-trendline",
3
- "version": "2.0.5",
3
+ "version": "2.1.0",
4
4
  "description": "Trendline for Chart.js",
5
5
  "main": "src/chartjs-plugin-trendline.js",
6
6
  "scripts": {
@@ -1,37 +1,36 @@
1
1
  /*!
2
2
  * chartjs-plugin-trendline.js
3
- * Version: 2.0.5
3
+ * Version: 2.1.0
4
4
  *
5
- * Copyright 2023 Marcus Alsterfjord
5
+ * Copyright 2024 Marcus Alsterfjord
6
6
  * Released under the MIT license
7
7
  * https://github.com/Makanz/chartjs-plugin-trendline/blob/master/README.md
8
8
  *
9
9
  * Mod by: vesal: accept also xy-data so works with scatter
10
10
  */
11
- var pluginTrendlineLinear = {
11
+ const pluginTrendlineLinear = {
12
12
  id: 'chartjs-plugin-trendline',
13
- afterDatasetsDraw: function (chartInstance) {
14
- var yScale;
15
- var xScale;
16
- for (var axis in chartInstance.scales) {
13
+ afterDatasetsDraw: (chartInstance) => {
14
+ let yScale;
15
+ let xScale;
16
+ for (let axis in chartInstance.scales) {
17
17
  if (axis[0] == 'x') xScale = chartInstance.scales[axis];
18
18
  else yScale = chartInstance.scales[axis];
19
19
  if (xScale && yScale) break;
20
20
  }
21
- var ctx = chartInstance.ctx;
21
+ const ctx = chartInstance.ctx;
22
22
 
23
- chartInstance.data.datasets.forEach(function (dataset, index) {
24
- var showTrendline =
23
+ chartInstance.data.datasets.forEach((dataset, index) => {
24
+ const showTrendline =
25
25
  dataset.alwaysShowTrendline ||
26
26
  chartInstance.isDatasetVisible(index);
27
27
 
28
- // TODO: Add support for objects
29
28
  if (
30
29
  dataset.trendlineLinear &&
31
30
  showTrendline &&
32
31
  dataset.data.length > 1
33
32
  ) {
34
- var datasetMeta = chartInstance.getDatasetMeta(index);
33
+ const datasetMeta = chartInstance.getDatasetMeta(index);
35
34
  addFitter(
36
35
  datasetMeta,
37
36
  ctx,
@@ -46,33 +45,37 @@ var pluginTrendlineLinear = {
46
45
  },
47
46
  };
48
47
 
49
- function addFitter(datasetMeta, ctx, dataset, xScale, yScale) {
50
- var defaultColor = dataset.borderColor || 'rgba(169,169,169, .6)';
51
- var colorMin = dataset.trendlineLinear.colorMin || defaultColor;
52
- var colorMax = dataset.trendlineLinear.colorMax || defaultColor;
53
- var lineWidth = dataset.trendlineLinear.width || dataset.borderWidth;
54
- var lineStyle = dataset.trendlineLinear.lineStyle || 'solid';
55
- var fillColor = dataset.trendlineLinear.fillColor;
48
+ const addFitter = (datasetMeta, ctx, dataset, xScale, yScale) => {
49
+ let defaultColor = dataset.borderColor || 'rgba(169,169,169, .6)';
50
+ let colorMin = dataset.trendlineLinear.colorMin || defaultColor;
51
+ let colorMax = dataset.trendlineLinear.colorMax || defaultColor;
52
+ let lineWidth = dataset.trendlineLinear.width || dataset.borderWidth;
53
+ let lineStyle = dataset.trendlineLinear.lineStyle || 'solid';
54
+ let fillColor = dataset.trendlineLinear.fillColor;
55
+
56
+ const parsing = typeof datasetMeta.controller.chart.options.parsing === "object" ?
57
+ datasetMeta.controller.chart.options.parsing : undefined;
58
+ const xAxisKey = dataset.trendlineLinear.xAxisKey || parsing ? parsing.xAxisKey : "x";
59
+ const yAxisKey = dataset.trendlineLinear.yAxisKey || parsing ? parsing.yAxisKey : "y";
56
60
 
57
61
  lineWidth = lineWidth !== undefined ? lineWidth : 3;
58
62
 
59
- var fitter = new LineFitter();
60
- var firstIndex = dataset.data.findIndex((d) => {
63
+ let fitter = new LineFitter();
64
+ let firstIndex = dataset.data.findIndex((d) => {
61
65
  return d !== undefined && d !== null;
62
66
  });
63
- var lastIndex = dataset.data.length - 1;
64
- var startPos = datasetMeta.data[firstIndex].x;
65
- var endPos = datasetMeta.data[lastIndex].x;
66
- var xy = typeof dataset.data[firstIndex] === 'object';
67
+ let lastIndex = dataset.data.length - 1;
68
+ let startPos = datasetMeta.data[firstIndex][xAxisKey];
69
+ let endPos = datasetMeta.data[lastIndex][xAxisKey];
70
+ let xy = typeof dataset.data[firstIndex] === 'object';
67
71
 
68
- dataset.data.forEach(function (data, index) {
69
- console.log('forEach');
72
+ dataset.data.forEach((data, index) => {
70
73
  if (data == null) return;
71
74
 
72
75
  if (['time', 'timeseries'].includes(xScale.options.type)) {
73
- var x = data.x != null ? data.x : data.t;
76
+ let x = data[xAxisKey] != null ? data[xAxisKey] : data.t;
74
77
  if (x !== undefined) {
75
- fitter.add(new Date(x).getTime(), data.y);
78
+ fitter.add(new Date(x).getTime(), data[yAxisKey]);
76
79
  } else {
77
80
  fitter.add(index, data);
78
81
  }
@@ -89,16 +92,16 @@ function addFitter(datasetMeta, ctx, dataset, xScale, yScale) {
89
92
  }
90
93
  });
91
94
 
92
- var x1 = xScale.getPixelForValue(fitter.minx);
93
- var y1 = yScale.getPixelForValue(fitter.f(fitter.minx));
95
+ let x1 = xScale.getPixelForValue(fitter.minx);
96
+ let y1 = yScale.getPixelForValue(fitter.f(fitter.minx));
94
97
 
95
- var x2;
96
- var y2;
98
+ let x2;
99
+ let y2;
97
100
 
98
101
  // Project only on x axes, do not project if trendline will never hit x axes
99
102
  if (dataset.trendlineLinear.projection && fitter.scale() < 0) {
100
103
  // X
101
- var x2value = fitter.fo();
104
+ let x2value = fitter.fo();
102
105
  if (x2value < fitter.minx) x2value = fitter.maxx;
103
106
  x2 = xScale.getPixelForValue(x2value);
104
107
 
@@ -114,24 +117,24 @@ function addFitter(datasetMeta, ctx, dataset, xScale, yScale) {
114
117
  x2 = endPos;
115
118
  }
116
119
 
117
- var drawBottom = datasetMeta.controller.chart.chartArea.bottom;
118
- var chartWidth = datasetMeta.controller.chart.width;
120
+ let drawBottom = datasetMeta.controller.chart.chartArea.bottom;
121
+ let chartWidth = datasetMeta.controller.chart.width;
119
122
 
120
123
  if (y1 > drawBottom) {
121
124
  // Left side is below zero
122
- var diff = y1 - drawBottom;
123
- var lineHeight = y1 - y2;
124
- var overlapPercentage = diff / lineHeight;
125
- var addition = chartWidth * overlapPercentage;
125
+ let diff = y1 - drawBottom;
126
+ let lineHeight = y1 - y2;
127
+ let overlapPercentage = diff / lineHeight;
128
+ let addition = chartWidth * overlapPercentage;
126
129
 
127
130
  y1 = drawBottom;
128
131
  x1 = x1 + addition;
129
132
  } else if (y2 > drawBottom) {
130
133
  // right side is below zero
131
- var diff = y2 - drawBottom;
132
- var lineHeight = y2 - y1;
133
- var overlapPercentage = diff / lineHeight;
134
- var subtraction = chartWidth - chartWidth * overlapPercentage;
134
+ let diff = y2 - drawBottom;
135
+ let lineHeight = y2 - y1;
136
+ let overlapPercentage = diff / lineHeight;
137
+ let subtraction = chartWidth - chartWidth * overlapPercentage;
135
138
 
136
139
  y2 = drawBottom;
137
140
  x2 = chartWidth - (x2 - subtraction);
@@ -149,7 +152,7 @@ function addFitter(datasetMeta, ctx, dataset, xScale, yScale) {
149
152
  ctx.moveTo(x1, y1);
150
153
  ctx.lineTo(x2, y2);
151
154
 
152
- var gradient = ctx.createLinearGradient(x1, y1, x2, y2);
155
+ let gradient = ctx.createLinearGradient(x1, y1, x2, y2);
153
156
  if (y2 < y1) {
154
157
  gradient.addColorStop(0, colorMax);
155
158
  gradient.addColorStop(1, colorMin);
@@ -173,21 +176,21 @@ function addFitter(datasetMeta, ctx, dataset, xScale, yScale) {
173
176
  ctx.closePath();
174
177
  ctx.fill();
175
178
  }
176
- }
179
+ };
177
180
 
178
- function LineFitter() {
179
- this.count = 0;
180
- this.sumX = 0;
181
- this.sumX2 = 0;
182
- this.sumXY = 0;
183
- this.sumY = 0;
184
- this.minx = 1e100;
185
- this.maxx = -1e100;
186
- this.maxy = -1e100;
187
- }
181
+ class LineFitter {
182
+ constructor() {
183
+ this.count = 0;
184
+ this.sumX = 0;
185
+ this.sumX2 = 0;
186
+ this.sumXY = 0;
187
+ this.sumY = 0;
188
+ this.minx = 1e100;
189
+ this.maxx = -1e100;
190
+ this.maxy = -1e100;
191
+ }
188
192
 
189
- LineFitter.prototype = {
190
- add: function (x, y) {
193
+ add(x, y) {
191
194
  x = parseFloat(x);
192
195
  y = parseFloat(y);
193
196
 
@@ -199,31 +202,34 @@ LineFitter.prototype = {
199
202
  if (x < this.minx) this.minx = x;
200
203
  if (x > this.maxx) this.maxx = x;
201
204
  if (y > this.maxy) this.maxy = y;
202
- },
203
- f: function (x) {
205
+ }
206
+
207
+ f(x) {
204
208
  x = parseFloat(x);
205
209
 
206
- var det = this.count * this.sumX2 - this.sumX * this.sumX;
207
- var offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
208
- var scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
210
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
211
+ let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
212
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
209
213
  return offset + x * scale;
210
- },
211
- fo: function () {
212
- var det = this.count * this.sumX2 - this.sumX * this.sumX;
213
- var offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
214
- var scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
214
+ }
215
+
216
+ fo() {
217
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
218
+ let offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
219
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
215
220
 
216
- // Get x when y = 0
217
- var xo = -offset / scale;
221
+ // Get x when y = 0
222
+ let xo = -offset / scale;
218
223
  return xo;
219
- },
220
- scale: function () {
221
- var det = this.count * this.sumX2 - this.sumX * this.sumX;
222
- var scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
224
+ }
225
+
226
+ scale() {
227
+ let det = this.count * this.sumX2 - this.sumX * this.sumX;
228
+ let scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
223
229
 
224
230
  return scale;
225
- },
226
- };
231
+ }
232
+ }
227
233
 
228
234
  // If we're in the browser and have access to the global Chart obj, register plugin automatically
229
235
  if (typeof window !== 'undefined' && window.Chart) {
@@ -1,72 +0,0 @@
1
- <html>
2
-
3
- <head>
4
- <title>Time scale chart.js</title>
5
- </head>
6
- <style>
7
- .chartBox {
8
- width: 700px
9
- }
10
- </style>
11
-
12
- <body>
13
- <div class="chartBox">
14
- <canvas id="myChart"></canvas>
15
- </div>
16
-
17
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
18
-
19
- <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
20
-
21
- <script src="./../src/chartjs-plugin-trendline.js"></script>
22
-
23
- <script>
24
- const data = {
25
- "labels": [
26
- "2023-08-10 20:00:00",
27
- "2023-08-10 21:30:00",
28
- "2023-08-10 22:30:30",
29
- "2023-08-11 07:00:00",
30
- "2023-08-11 07:15:00",
31
- "2023-08-11 08:00:00"
32
- ],
33
- "datasets": [
34
- {
35
- "type": "line",
36
- "label": "Blood Sugar",
37
- "data": {
38
- "2023-08-10 21:30:00": "6.20",
39
- "2023-08-10 22:30:30": "6.60",
40
- "2023-08-11 07:00:00": "5.90",
41
- "2023-08-11 08:00:00": "4.60",
42
- "2023-08-11 11:17:00": "5.10",
43
- "2023-08-11 12:15:00": "4.90"
44
- },
45
- "backgroundColor": "#A9CCE3",
46
- "pointStyle": "circle",
47
- "pointRadius": 6,
48
- "pointHoverRadius": 12,
49
- "borderColor": "#5DADE2",
50
- "trendlineLinear": {
51
- "colorMin": "red",
52
- "colorMax": "green",
53
- "lineStyle": "dotted",
54
- "width": 3,
55
- "projection": true
56
- }
57
- }
58
- ],
59
- };
60
- const config = {
61
- type: 'line',
62
- data
63
- };
64
- console.log("Loaded");
65
- const myChart = new Chart(
66
- document.getElementById('myChart'),
67
- config,
68
- );
69
- </script>
70
- </body>
71
-
72
- </html>
@@ -1,111 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
- <title>LineChart Example</title>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.js"></script>
9
- <script src="./../src/chartjs-plugin-trendline.js"></script>
10
- <script>
11
- let data = {
12
- "labels": [
13
- 202303,
14
- 202304,
15
- 202305,
16
- 202306,
17
- 202307,
18
- 202308,
19
- 202309
20
- ],
21
- "datasets": [
22
- {
23
- "label": "Dataset 1",
24
- "data": [
25
- 10,
26
- 30,
27
- 50,
28
- 20,
29
- 25,
30
- 44,
31
- -10
32
- ],
33
- "borderColor": "#4dc9f6",
34
- "backgroundColor": "#4dc9f6",
35
- "trendlineLinear": {
36
- "colorMin": "#4dc9f6",
37
- "colorMax": "#4dc9f6",
38
- "lineStyle": "dotted",
39
- "width": 2,
40
- "projection": false
41
- }
42
- },
43
- {
44
- "label": "Dataset 2",
45
- "data": [
46
- 100,
47
- 33,
48
- 22,
49
- 19,
50
- 11,
51
- 49,
52
- 200
53
- ],
54
- "borderColor": "#f67019",
55
- "backgroundColor": "#f67019",
56
- "trendlineLinear": {
57
- "colorMin": "#f67019",
58
- "colorMax": "#f67019",
59
- "lineStyle": "solid",
60
- "width": 2,
61
- "projection": false
62
- }
63
- }
64
- ]
65
- };
66
-
67
- var lineOptions = {
68
- plugins: {
69
- legend: {
70
- display: true,
71
- labels: {
72
- fontSize: 10,
73
- fontColor: "#000",
74
- },
75
- },
76
- },
77
- scales: {
78
- x:
79
- {
80
- gridLines: {
81
- display: true,
82
- },
83
- display: true,
84
- color: "rgba(255, 255, 255, 0.1)",
85
- },
86
- y:
87
- {
88
- display: false,
89
- },
90
- },
91
- responsive: true,
92
- maintainAspectRatio: true,
93
- };
94
- document.addEventListener("DOMContentLoaded", function(event) {
95
- new Chart(document.getElementById("line-chart"), {
96
- type: 'line',
97
- data: data,
98
- options:lineOptions
99
- });
100
- });
101
- </script>
102
- </head>
103
- <body>
104
- <h1>Line Chart</h1>
105
-
106
- <div style="width: 800px;">
107
- <canvas id="line-chart"></canvas>
108
- </div>
109
-
110
- </body>
111
- </html>
@@ -1,67 +0,0 @@
1
- <html>
2
-
3
- <head>
4
- <title>Time scale chart.js</title>
5
- </head>
6
- <style>
7
- .chartBox {
8
- width: 700px
9
- }
10
- </style>
11
-
12
- <body>
13
- <div class="chartBox">
14
- <canvas id="myChart"></canvas>
15
- </div>
16
-
17
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
18
-
19
- <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
20
-
21
- <script src="./../src/chartjs-plugin-trendline.js"></script>
22
-
23
- <script>
24
- const data = {
25
- labels: [
26
- "2023-01-01T08:00:00.000Z",
27
- "2023-01-02T08:00:00.000Z",
28
- "2023-01-03T08:00:00.000Z",
29
- "2023-01-04T08:00:00.000Z",
30
- ],
31
- datasets: [{
32
- label: "Default",
33
- data: [65, 59, 80, 81],
34
- trendlineLinear: {
35
- colorMin: "red",
36
- colorMax: "green",
37
- lineStyle: "dotted",
38
- width: 2,
39
- projection: false,
40
- },
41
- }],
42
- };
43
- const config = {
44
- type: 'line',
45
- data,
46
- options: {
47
- scales: {
48
- x: {
49
- type: 'time',
50
- time: {
51
- unit: 'day',
52
- },
53
- },
54
- y: {
55
- beginAtZero: true
56
- }
57
- }
58
- }
59
- };
60
- const myChart = new Chart(
61
- document.getElementById('myChart'),
62
- config,
63
- );
64
- </script>
65
- </body>
66
-
67
- </html>