I have a code for standard area-spline highchart where I made a function for prediction based on previous data. Prediction / forecasting is showing next 4 values in a trendline where the first prediction point is counting with real data, second point with real data plus first prediction point and the next two points about the same plus previous predictions. Otherwise it would be only a line with same values. But my data are increasing so the forecasting must be about the same.
Data in highchart are connected to Microsoft SQL Server.
Prediction is based on this code, just with few changes:
Forecast formula from Excel in Javascript
The highchart is now showing increasing data (values of resistance) as a decimal in yAxis and datetime in xAxis. Prediction is working as well but the thing is that not all data are relevant.There is always a point which is very different (lower than previous) and thats the place from where I need to count new prediction. The plotline is generated in the last high value, then starting the new (low) - and that is from where I need to count.
So here is what I do have:
-the function 'average' is counting average from values
-second function 'forecast' as you can expect is counting the forecasting (based on the code from link above)
-third function 'test' is already putting all together
-the 'results' (2,3,4) are the counted points of prediction
-'vlastnidata' are the data from mssql
-'datumek' is for the date
Now the condition for plotline (as you can see there) is that the previous point in chart must be 20 higher and then the plotline is generated - this is also working, just need to find a way how to count only with new data behind the plotline.
And here you can reach the connection function to mssql in php - if needed
Is there a way how to dynamically create a plotline in highchart when the value is lower than previous one?
As I said everything is working, plotlines and the prediction. But to see clear prediction I need to count only with relevant data.
Hope everything is clear. Thank you in advance for any recommendations.
function average(ar)
{
var r=0;
for (i=0;i<ar.length;i++)
{
r = r+ar[i];
}
return r/ar.length;
}
function forecast(x, ky, kx)
{
var i=0, nr=0, dr=0,ax=0,ay=0,a=0,b=0, result=0;
ax=average(kx);
ay=average(ky);
for (i=0;i<kx.length;i++)
{
nr = nr + ((kx[i]-ax) * (ky[i]-ay));
dr = dr + ((kx[i]-ax)*(kx[i]-ax))
}
b=nr/dr;
a=ay-b*ax;
result = (a+b*x);
return result;
}
function test(container,nazev,rtop,vlastnidata,colorSeries)
{
var result = 0, result2 = 0, result3 = 0, result4 = 0, datumek=[],hodnoty=[];
for (a=0;a<vlastnidata.length;a++)
{
datumek[a]=vlastnidata[a][0];
hodnoty[a]=vlastnidata[a][1];
}
kalkulace=(datumek[vlastnidata.length-1]-datumek[vlastnidata.length-2]);
hodnoty_nove=hodnoty;
datumek_nove=datumek;
result = forecast((datumek[vlastnidata.length-1]+kalkulace), hodnoty, datumek);
hodnoty_nove[hodnoty_nove.length]=result;
datumek_nove[datumek_nove.length]=(datumek[vlastnidata.length-1]+kalkulace);
result2 = forecast((datumek[vlastnidata.length-1]+2*kalkulace), hodnoty_nove, datumek_nove);
hodnoty_nove[hodnoty_nove.length]=result2;
datumek_nove[datumek_nove.length]=(datumek[vlastnidata.length-1]+2*kalkulace);
result3 = forecast((datumek[vlastnidata.length-1]+3*kalkulace), hodnoty_nove, datumek_nove);
hodnoty_nove[hodnoty_nove.length]=result3;
datumek_nove[datumek_nove.length]=(datumek[vlastnidata.length-1]+3*kalkulace);
result4 = forecast((datumek[vlastnidata.length-1]+4*kalkulace), hodnoty_nove, datumek_nove);
Highcharts.chart(container, {chart: {type: 'areaspline',
events: {
load:function(){
let points = this.series[0].points;
let plotLines = [];
console.log(this)
let previousPoint = points[0];
points.forEach(function(point) {
if(point.y < previousPoint.y/100*80) {
plotLines.push({
value: previousPoint.x,
color: 'red',
width: 3
});
}
previousPoint = point;
});
this.xAxis[0].update({
plotLines: plotLines
})
}
}
},
title: {text: 'Average of resistance per month, '+rtop},
legend: {layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 150,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'},
xAxis: { type: 'datetime'},
yAxis: {title: {text: 'Resistance: in ohms'}},
tooltip: {shared: true,valueSuffix: ' ohms',valueDecimals: 2},
credits: {enabled: false},
plotOptions: {areaspline: {fillOpacity: 0.5}},
series: [{ name: nazev,
color: colorSeries,
data: vlastnidata},
{name: 'Prediction',
color: '#001a33',
data: [[(datumek[vlastnidata.length-1]+kalkulace),result], [(datumek[vlastnidata.length-1]+2*kalkulace),result2], [(datumek[vlastnidata.length-1]+3*kalkulace),result3], [(datumek[vlastnidata.length-1]+4*kalkulace),result4]]
}]
});
}
I have created a Bar graph using C3 JS plugin, The graph is working fine but the problem is with the x-axis labels looks too congested like as shown below
Working JSFiddle
My Code is as given below
var chart = c3.generate({
bindto: "#chart",
data: {
x : 'x',
columns: [
['x', "2016-04-01","2016-04-08","2016-04-15","2016-04-22","2016-04-29","2016-05-06","2016-05-13","2016-05-20","2016-05-27","2016-06-03","2016-06-10","2016-06-17","2016-06-24","2016-07-09","2016-07-10","2016-07-11","2016-07-12","2016-07-13","2016-07-15","2016-07-16","2016-07-17","2016-07-18","2016-07-19","2016-07-20","2016-07-21","2016-07-22","2016-07-23","2016-07-24","2016-07-25","2016-07-26","2016-07-27","2016-07-28","2016-07-29","2016-07-30","2016-07-31","2016-08-01","2016-08-02","2016-08-03","2016-08-04","2016-08-05","2016-08-06","2016-08-07","2016-08-08","2016-08-09","2016-08-10","2016-08-11","2016-08-12","2016-08-13","2016-08-14","2016-08-15","2016-08-16","2016-08-17","2016-08-18","2016-08-19","2016-08-20","2016-08-21","2016-08-22","2016-08-23","2016-08-24","2016-08-25","2016-08-26","2016-08-27","2016-08-28","2016-08-29","2016-08-30","2016-08-31","2016-09-01","2016-09-02","2016-09-03","2016-09-04","2016-09-05","2016-09-06","2016-09-07","2016-09-08","2016-09-09","2016-09-10","2016-09-11","2016-09-12","2016-09-13","2016-09-14","2016-09-15","2016-09-16","2016-09-17","2016-09-18","2016-09-19","2016-09-20","2016-09-21","2016-09-22","2016-09-23","2016-09-24","2016-09-25","2016-09-26","2016-09-27","2016-09-28","2016-09-29","2016-09-30","2016-10-01","2016-10-02","2016-10-03","2016-10-04","2016-10-05","2016-10-06","2016-10-07","2016-10-08","2016-10-09","2016-10-10","2016-10-11","2016-10-12","2016-10-13","2016-10-14","2016-10-15","2016-10-16","2016-10-17","2016-10-18","2016-10-19","2016-10-20","2016-10-21","2016-10-22","2016-10-23","2016-10-24","2016-10-25","2016-10-26","2016-10-27","2016-10-28","2016-10-29","2016-10-30","2016-10-31","2016-11-01","2016-11-02","2016-11-03","2016-11-04","2016-11-09"],
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2748,2748,2694,2694,2694,2694,2694,2694,2694,2668,2668,2668,2668,2576,2572,2572,3043,3084,3084,3084,3084,3084,3156,3521,3521,3550,3542,3542,3573,3580,3629,3579,3584,3542,2757,2791,2696,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3369,3376,3371,3373,3371,3379,3363,3373,3347,3348,3382,3402,3410,3434,2579,2579,2369],
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,2375,2425,2475,2500,2500,2087,2087,2087,2087,2091,2087,1767,1767,1767,1633,1498,1498,1642,1637,1633,1609,1841,1713,1702,1862,1888,1888,1888,1949,1976,1977,2014,2014,2014,1946,1966,1973,2224,2252,2318,2318,2318,2327,2373,2513,2535,2543,2534,2539,2823,2849,2990,3142,3142,3108,2513,2687,2678,2856,2860,2861,2862,2866,2869,2870,2875,2874,2874,2874,2879,2885,2886,2883,2889,2896,2895,2899,2903,2909,2911,2913,2913,2913,2916,2922,2933,2937,2943,2942,2943,2947,1811,1826,1837,1840,1840,1841,1843,1511,1854,1853,1851,1852,1853,1849,1852,1874,1857,1883,1886,1888,1904,1903,1924,1947,2060,2068,2068,2082,1582,1344,836,839,788]
],
type: 'bar'
},
axis: {
x: {
type: 'category',
tick: {
rotate: -60,
multiline: false
},
height: 130
}
}
});
Can anyone please tell me some solution for this
What I did to solve it
I have used timeseries type instead of category type, after that the label issue got resolved but the graph was been plottted with more white spaces for the month of march like as shown below
Working JSFiddle
You can use c3's tick count setting for this, so here we say 20 labels.
However there is an added gotcha in that ticks that now resolve to a fractional category value won't show - i.e. the 2nd equally spaced tick out of 20 may be the 2.6667th element in the x category axis - so you need to have a little format function that adjusts for this, otherwise you just get the end and start labels. (Or you could figure out a tick count that divides into your data count + 1 as a whole number.)
tick: {
format: function (x) {
var cats = this.api.categories();
return cats[Math.round(x)];
},
count: 20,
rotate: -60,
multiline: false
},
http://jsfiddle.net/fz0t10yb/7/
One of the possible solution could be to use x-axis labels at required indexes only & leaving others blank.
['x', "2016-04-01","","","","2016-04-29","","","",...]
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,...]
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,...]
You can position labels so that it would capture the date and at same time it looks good also.
Does anyone know how to make "y-axis" values start from 0 in Jqplot....by default it starts with negative values for eg: -500, 0, 500, 1000 and so on....Please help
Set min: object (minimum) to 0 within axes: object
$(document).ready(function(){
// your code here... //
axes:{
yaxis: {min:0}
}
})
As rsapru suggested, a max: object (maximum) value is recommended to bound the graph to your preferred range. For example, if you wanted the minimum to be 0 and maximum to be 7500
axes:{
yaxis: {min:0, max: 7500}
}
If you want to specify the graduations of the ticks you can do so manually by specifying ticks with the ticks: object or have jqPlot calculate tick spacing automatically (nothing other than min and max objects would be needed in that case) or by your specific number of ticks (using numberTicks: object)
Example: For tick 100 units apart, from 0 to 1000, using 11 ticks (0,100,200,300,400,500,600,700,800,900,1000) jqPlot automatic calculation:
axes:{
yaxis: {min:0, max: 1000, numberTicks: 11}
}
Example: For tick 100 units apart, from 0 to 1000, using 11 ticks (0,100,200,300,400,500,600,700,800,900,1000) manual specification:
axes:{
yaxis: {min:0, max: 1000, Ticks: [[0],[100],[200],[300],[400],[500],[600],[700],[800],[900],[1000]]}
}
var plot2 = $.jqplot ('chartdiv', getRequestStats(), {
// Give the plot a title.
title: 'Daily Request Status',
// You can specify options for all axes on the plot at once with
// the axesDefaults object. Here, we're using a canvas renderer
// to draw the axis label which allows rotated text.
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
// An axes object holds options for all axes.
// Allowable axes are xaxis, x2axis, yaxis, y2axis, y3axis, ...
// Up to 9 y axes are supported.
axes: {
// options for each axis are specified in seperate option objects.
xaxis: {
label: "Hour",
// Turn off "padding". This will allow data point to lie on the
// edges of the grid. Default padding is 1.2 and will keep all
// points inside the bounds of the grid.
pad: 0
},
yaxis: {
label: "Count",
pad: 0
}
}
});
pad: 0 will star the Y axis to start from 0.
Refer to http://www.jqplot.com/docs/files/jqPlotOptions-txt.html
set yaxis: {min: 0, max: 500, numberTicks:5}
add yaxis: {min:0} in your yaxis
The following solution work for me.
-> Add zero value in array also.
-> set the data render to $.jqplot.CanvasAxisLabelRenderer
yaxis: {
renderer: $.jqplot.CanvasAxisLabelRenderer
.....
}
Thanks
Adnan
Add the following to the script:
yaxis: {
minimum:0
}
in your yaxis. I tried it and it works.