Adding trendlines to existing chart Chart.js
Asked Answered
M

4

16

from hours I've been looking for a solution to add trendlines to an existing chart built with Chart.js

I think we can only add logarithmic trendline on Chart.js ?

I don't want to draw a trendline from scratch, but add 2 trendlines based on existing data of these 2 lines ; please see this fiddle example :

THANK YOU https://jsfiddle.net/blueagency/p88mx3nw/

A big thank you in advance for all your help.

Matins answered 4/4, 2017 at 18:19 Comment(0)
A
14

The chartjs-plugin-trendline provides a straight-line trendline that plugs into Chart.js.

NPM: https://www.npmjs.com/package/chartjs-plugin-trendline/v/0.1.1

Download: https://www.jsdelivr.com/package/npm/chartjs-plugin-trendline

Usage is pretty straightforward - just add the following to your dataset:

datasets: [{
            // Other configurations
            // ...
            trendlineLinear: {
                style: "rgb(43 ,66 ,255, 0.3)",
                lineStyle: "dotted|solid",
                width: 2
            }
        }]
Amygdala answered 12/7, 2019 at 17:0 Comment(5)
Im having trouble getting this to work with the current version. Is there other documentation?Hydro
The Github project seems to be here: github.com/Makanz/chartjs-plugin-trendline. Perhaps if you dig around in the examples folder of the package you'll see a working example?Amygdala
I found my answer in the issue list. A user cloned and patched the lib to support dates, so it was actually a bug that was stopping me.Hydro
Great. Can you link to the patch for anyone else with the same issue?Amygdala
this version 0.1.1 is the only one that works in my angular project, thanksUry
T
5

Currently, chart.js does not have a trendline capability at all (not even logarithmic). Perhaps you were getting confused with the custom tick format example at the end of the Common Scale Configuration section?

You could however use the chartjs-plugin-annotation plugin to draw a trendline on your chart, but keep in mind that you would have to implement your own logic to calculate the correct location of the line (and then just use the annotation plugin to actually draw it).

Here is an example demonstrating how to use the plugin (the plugin provides a set of annotation properties that you can add to your charts options. You would then just need to create a function that calculates the trendline and use the result to set the annotation value and endValue properties.

var myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: [0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1],
    datasets: [{
      label: 'Dataset 1',
      borderColor: window.chartColors.blue,
      borderWidth: 2,
      fill: false,
      data: [19304,13433,9341,6931,5169, 3885,2927,2159,1853,1502, 1176,911,724,590,491, 400,335,280,239,200]
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Chart.js Drsw Line on Chart'
    },
    tooltips: {
      mode: 'index',
      intersect: true
    },
    annotation: {
      annotations: [{
        type: 'line',
        mode: 'horizontal',
        scaleID: 'y-axis-0',
        value: 2225,
        endValue: 0,
        borderColor: 'rgb(75, 192, 192)',
        borderWidth: 4,
        label: {
          enabled: true,
          content: 'Trendline',
          yAdjust: -16,
        }
      }]
    }
  }
});

You can see it in action at this codepen.

Trivandrum answered 4/4, 2017 at 19:19 Comment(4)
Yes, you are right, in the chart.js official documentation I thought I could use a logarithmic trendline, it was a too fast reading from me. Thank you for your help and suggest about this chartjs-annotation plugin. However, only 2 values can be specified, so that the trend line can only be "binary" : up or down, indicating a positive or negative trend. Things are a little more complex in the case of data, for example, showing results growing, then falling a little, and then go up again.Matins
I understand. You could also just create another dataset that represents your trendline. Just like in my example, you will have to calculate the trendline yourself and then pick a few points along the line and draw it on the graph just like any other line.Trivandrum
That's I had previously tried to do. But the visual rendering is not pleasant at all, jerky. I think trendlines are absolutely essential functions and should be part of chart libraries.Matins
it's open source. add the feature and submit a pull requestPervade
T
4

Update your chart definition by adding an empty dataset:

    {
        label: "Trend 1",
        borderColor: 'rgba(200,0,0)',
        backgroundColor: 'rgba(200,0,0)',
        data: [],
        fill: false,
    }

Right after your chart definition (in the jsfiddle) add these lines:

arrayForRegression= []; // Declare the array which will contains calculated point of trend line
for (i=0; i < ChartVisits.data.datasets[0].data.length; i++) {
    arrayForRegression.push([i, ChartVisits.data.datasets[0].data[i]]); // Fill the array with the "y" values to be approximated by regression
}
regr = regression("polynomial", arrayForRegression, 2); // Calculare polynomial regression
convertedRegressionArray = []; // Declare an array to hold  the regression line in charts.js format
for (i=0; i < ChartVisits.data.datasets[0].data.length; i++) { // Fill the array with calculated values
    convertedRegressionArray.push(regr.points[i][1]);
}
ChartVisits.config.data.datasets[2].data = convertedRegressionArray; // Put the regression array, converted to charts format, into chart
ChartVisits.update();

In your HTML, add this line IN BODY SECTION to include the library:

<script type="text/javascript" src="js/regression.min.js"></script>

Library from:

https://bl.ocks.org/daluu/5bb59ef3f3fed3de227535da367649ba

https://gist.github.com/daluu/5bb59ef3f3fed3de227535da367649ba

The code of the function is obfuscated/minified, anyway the call syntax is:

var linReg = regression('linear', data);
var polyReg = regression('polynomial', data, 2);
var expoReg = regression('exponential', data);
var powReg = regression('power', data);
var logReg = regression('logarithmic', data);

Data format:

var data = [[500,2.5], [1000,3], [1500,3], [2000,3.3], [3000,3.6], [4000,4], [5500,4.8], [6000,5], [7000,5], [8000,5.5], [9000,6], [12000,7], [14000,8], [15000,8], [18000,9], [20000,10], [21000,10], [24000,11], [28000,12], [30000,13], [50000,18]];

But I don't know exactly how to implement it in charts.js or any other library.

This discovery led me to look for "javascript regression.min.js" , finding many resources.

NOTE: there is an error in index.html:

<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>

should be:

<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

NOTE2:

I think there is a major bug in linear regression part: the returned equation object (an array of coefficients) is in reversed order w.r.t polynomial format.

Examples:

3x^2+2x+1 is returned as array [1, 2, 3] , so each coefficient must be multiplied by Math.pow(x, array position):

y = equation[0] * Math.pow(x,0) +  equation[1] * Math.pow(x,1) + equation[1] * Math.pow(x,1)  ** correct **

2x + 1 should be returned as array [1,2] but it is returned as [2,1] --> bug?

y = equation[0] * Math.pow(x,1) +  equation[1] * Math.pow(x,0)
Tybie answered 12/10, 2020 at 11:28 Comment(3)
Is this related to CHART JS ?Matins
@BlueAgency It applies to any chart library, it's just math.Tybie
added specific source for charts.jsTybie
P
-10

Perhaps think of using Google Charts, instead of Chart.js. Google Charts includes Trendlines - including Linear, Exponential, and Polynomial.

Documentation here: Google Charts Trendlines

Pase answered 1/10, 2019 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.