Created
April 11, 2014 19:47
-
-
Save bendytree/10495984 to your computer and use it in GitHub Desktop.
HighCharts Trend Line Series Maker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Originally this code was from: | |
| * https://github.com/virtualstaticvoid/highcharts_trendline | |
| * | |
| * But it dropped a lot in the global namespace, so I added a closure and exposed: | |
| * | |
| * window.BuildHighChartsTrendLineSeriesFromSeries(series); | |
| * | |
| * If you want, I can make the name longer. | |
| * | |
| * Here's how I use it: | |
| * | |
| * $graph.highcharts({ | |
| * ... | |
| * series: [ | |
| * window.BuildHighChartsTrendLineSeriesFromSeries(mySeries), | |
| * mySeries | |
| * ] | |
| * }); | |
| * | |
| */ | |
| /** | |
| * Code for regression extracted from jqplot.trendline.js | |
| * | |
| * Version: 1.0.0a_r701 | |
| * | |
| * Copyright (c) 2009-2011 Chris Leonello | |
| * jqPlot is currently available for use in all personal or commercial projects | |
| * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL | |
| * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can | |
| * choose the license that best suits your project and use it accordingly. | |
| * | |
| **/ | |
| (function(){ | |
| function regression(x, y, typ) { | |
| var type = (typ == null) ? 'linear' : typ; | |
| var N = x.length; | |
| var slope; | |
| var intercept; | |
| var SX = 0; | |
| var SY = 0; | |
| var SXX = 0; | |
| var SXY = 0; | |
| var SYY = 0; | |
| var Y = []; | |
| var X = []; | |
| if (type == 'linear') { | |
| X = x; | |
| Y = y; | |
| } | |
| else if (type == 'exp' || type == 'exponential') { | |
| for (var i = 0; i < y.length; i++) { | |
| // ignore points <= 0, log undefined. | |
| if (y[i] <= 0) { | |
| N--; | |
| } | |
| else { | |
| X.push(x[i]); | |
| Y.push(Math.log(y[i])); | |
| } | |
| } | |
| } | |
| for (var i = 0; i < N; i++) { | |
| SX = SX + X[i]; | |
| SY = SY + Y[i]; | |
| SXY = SXY + X[i] * Y[i]; | |
| SXX = SXX + X[i] * X[i]; | |
| SYY = SYY + Y[i] * Y[i]; | |
| } | |
| slope = (N * SXY - SX * SY) / (N * SXX - SX * SX); | |
| intercept = (SY - slope * SX) / N; | |
| return [slope, intercept]; | |
| } | |
| function linearRegression(X, Y) { | |
| var ret; | |
| ret = regression(X, Y, 'linear'); | |
| return [ret[0], ret[1]]; | |
| } | |
| function expRegression(X, Y) { | |
| var ret; | |
| var x = X; | |
| var y = Y; | |
| ret = regression(x, y, 'exp'); | |
| var base = Math.exp(ret[0]); | |
| var coeff = Math.exp(ret[1]); | |
| return [base, coeff]; | |
| } | |
| /* | |
| TODO: this function is quite inefficient. | |
| Refactor it if there is problem with speed. | |
| */ | |
| function fitData(data, typ) { | |
| var type = (typ == null) ? 'linear' : typ; | |
| var ret; | |
| var res; | |
| var x = []; | |
| var y = []; | |
| var ypred = []; | |
| for (i = 0; i < data.length; i++) { | |
| if (data[i] != null && Object.prototype.toString.call(data[i]) === '[object Array]') { | |
| if (data[i] != null && data[i][0] != null && data[i][1] != null) { | |
| x.push(data[i][0]); | |
| y.push(data[i][1]); | |
| } | |
| } | |
| else if(data[i] != null && typeof data[i] === 'number' ){//If type of X axis is category | |
| x.push(i); | |
| y.push(data[i]); | |
| } | |
| else if(data[i] != null && Object.prototype.toString.call(data[i]) === '[object Object]'){ | |
| if (data[i] != null && data[i].x != null && data[i].y != null) { | |
| x.push(data[i].x); | |
| y.push(data[i].y); | |
| } | |
| } | |
| } | |
| if (type == 'linear') { | |
| ret = linearRegression(x, y); | |
| for (var i = 0; i < x.length; i++) { | |
| res = ret[0] * x[i] + ret[1]; | |
| ypred.push([x[i], res]); | |
| } | |
| return { | |
| data: ypred, | |
| slope: ret[0], | |
| intercept: ret[1], | |
| y: function(x) { | |
| return (this.slope * x) + this.intercept; | |
| }, | |
| x: function(y) { | |
| return (y - this.intercept) / this.slope; | |
| } | |
| }; | |
| } | |
| else if (type == 'exp' || type == 'exponential') { | |
| ret = expRegression(x, y); | |
| for (var i = 0; i < x.length; i++) { | |
| res = ret[1] * Math.pow(ret[0], x[i]); | |
| ypred.push([x[i], res]); | |
| } | |
| ypred.sort(); | |
| return { | |
| data: ypred, | |
| base: ret[0], | |
| coeff: ret[1] | |
| }; | |
| } | |
| } | |
| window.BuildHighChartsTrendLineSeriesFromSeries = function(series){ | |
| return { | |
| type: 'line', | |
| marker: { enabled: false }, | |
| data: fitData(series.data).data, | |
| enableMouseTracking: false, | |
| color: '#66ccff', | |
| dashStyle: 'ShortDash' | |
| }; | |
| }; | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment