Basically I have a object which defines some properties for a Highchart chart:
var options = {
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y + '°C';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'Tokyo',
data: aCosts
}]
};
And I want to update this object from a file (ajax call) like so:
$.getJSON(
"handler.php",
function (oJSON) {
var sName,
sCost,
aRow;
for (sName in oJSON) {
aRow = [];
//categories = [];
if (oJSON.hasOwnProperty(sName)) {
aRow.push(sName);
categories.push(sName);
}
// Create the chart
var chart = new Highcharts.Chart(options);
}
}
);
The problem is, I can't pass the new value to options as it states that categories is not defined. I've tried using:
options.categories.push(sName)
options[categories].push(sName)
And none work.
How can I update the value of categories inside my options object?
Assuming that options is visible from the $.JSON call, this should work:
options.xAxis.categories.push( sName );
If you look at the structure of your options object, you see, that categories is below the property xAxis. Thus you should address is like that.
You just need to define categories first like so:
options.categories = [];
then you can push things into this array.
Edit: You could place categories: [] in your json to begin with also.
Related
Here is my js code:
Highcharts.stockChart('utilizations', {
chart: {
zoomType: 'x'
},
title: {
text: 'KPI'
},
subtitle: {
text: 'CCE & PRB Utilization (%)'
},
rangeSelector: {
buttons: [{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 3,
text: '3d'
}, {
type: 'day',
count: 7,
text: '1w'
}, {
type: 'day',
count: 14,
text: '2w'
}, {
type: 'all',
text: 'All'
}],
selected: 1
},
yAxis: {
labels: {
formatter: function () {return this.value + '%';}
},
max: 100,
min: 0,
tickInterval: 20,
plotLines: [{
value: 0,
width: 2,
color: 'silver'
},{
value: 70,
width: 1,
color: 'red'
}]
},
tooltip: {
crosshairs: true,
shared: true
},
plotOptions: {
series: {
compare: 'value',
showInNavigator: true
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'CCE Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["cce"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
},{
name: 'PRB Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["prb"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
And my plot:
While dragging the navigator bar, sometimes the plot goes to the right position and sometimes it looks like the capture above. According to my experience, the plot position is related to the left end (let's note this as A) position of the navigator selector. When A is on the lowest part of the whole plot in navigator, the shown plot positioned well; and when A goes like the capture above, the plot shown sunk.
Please refer to a short demo with 100 data here: https://jsfiddle.net/ghqyvo0x/
How can I make my plot stable?
Your problem is caused by series.compare: property, which you set in plotOptions configuration object. If you delete this line of code, everything should work as you need. We could read in Highstock API:
Compare the values of the series against the first non-null, non- zero value in the visible range.
plotOptions: {
series: {
//compare: 'percent',
showInNavigator: true
}
}
JSFiddle example
API Reference
I want to use my series names as xAxis. I have tried it like the code below. This code is creating multiple series but only one x axis value. Let's say in my code I want to create series for every fund and plot fund values in xAxis as well.
function draw(fund, zreturn) {
zreturn = [12.75, 11.77, 13.76];
fund = ['abc', 'xyz', 'pqr'];
var options = {};
options = {
chart: {
renderTo: 'graphDiv',
type: 'line',
Height: '400px'
},
credits: {
enabled: false
},
title: {
text: 'Fund Performance Graph',
x: -20
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: fund
}
},
yAxis: {
labels: {
enabled: true,
format: function () {
return (this.value + '%')
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0,
},
series: zreturn.filter(function (zreturn, i) {
return fund[i]
}).map(function (zreturn, i) {
/* Then return as series */
return {
//type: 'line',
name: fund[i],
data: zreturn,
dataLabels: {
align: 'center',
enabled: true,
format: "{y:.2f}" + '%',
style: {
fontSize: "8px",
fontFamily: 'Arial',
},
}
}
})
}
var chart = new Highcharts.Chart(options);
};
I think that right now you have small mistakes in your code.
First of all you are using yAxis.labels.format as a function. It should be formatter if you want to use it as a function:
yAxis: {
labels: {
enabled: true,
formatter: function() {
return (this.value + '%')
}
}
},
Next, you have mistake in your data, it should be an array:
data: [
[i, zreturn]
],
I am here adding x value of your point as well as y value. If I will not add x value, points will always start from 0 and because you have added only one point to every series, all of them will be on the first category.
Here you can find an example how your chart may work with these small corrections:
http://jsfiddle.net/worg6jLz/29/
This screenshot - http://imgur.com/oBsFLvZ - shows the following items
a) what I'm currently getting (no data points)
b) what I would like my results to look like
c) what my SharePoint list looks like
(Sorry, I don't have enough stackOverflow points to post pictures yet)
Below is the code I currently have
$(document).ready(function() {
var yearmontharray = [];
var valuesarray = [];
$().SPServices({
operation: "GetListItems",
async: false,
listName: "List",
CAMLViewFields: "<viewfields><fieldref Name='Title' /><fieldref Name='values' /></ViewFields>",
CAMLQuery: "<query><orderby><fieldref Name='Title' Ascending='True' /></OrderBy></Query>",
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
var yearmonth = ($(this).attr("ows_Title"));
var values = Math.round($(this).attr("ows_values"));
yearmontharray.push(yearmonth);
valuesarray.push(values);
});
}
});
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Total values',
x: -20
},
subtitle: {
text: 'This chart shows value from SharePoint',
x: -20
},
xAxis: {
categories: yearmontharray
},
yAxis: {
title: {
text: 'values'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'values',
data: valuesarray
}]
});
});
Any help would be greatly appreciated!
You have to include contraction of chart inside complete function. Otherwise the call to Hightchart are made BEFORE getting data.
$(document).ready(function () {
var yearmontharray = [];
var valuesarray = [];
$().SPServices({
operation: "GetListItems",
async: false,
listName: "List",
CAMLViewFields: "<viewfields><fieldref Name='Title' /><fieldref Name='values' /></ViewFields>",
CAMLQuery: "<query><orderby><fieldref Name='Title' Ascending='True' /></OrderBy></Query>",
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function () {
var yearmonth = ($(this).attr("ows_Title"));
var values = Math.round($(this).attr("ows_values"));
yearmontharray.push(yearmonth);
valuesarray.push(values);
});
// Inside complete func <-----
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Total values',
x: -20
},
subtitle: {
text: 'This chart shows value from SharePoint',
x: -20
},
xAxis: {
categories: yearmontharray
},
yAxis: {
title: {
text: 'values'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'values',
data: valuesarray
}]
});
}
});
});
chart3 = new Highcharts.Chart({
chart: {
renderTo: 'container3',
type: 'column'
},
title: {
text: 'Cumplimiento de los Programas del PMA-Contratistas'
},
subtitle: {
text: ''
},
xAxis: {
categories: [
'Nº Charlas ambientales',
'Nº personal capacitado'
]
},
yAxis: {
min: 0,
title: {
text: '%'
}
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
shadow: true
},
tooltip: {
formatter: function() {
return ''+
this.x +': '+ this.y +' mm';
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{name: 'Semana',data: [12 , 321] }, {name: 'Acum',data: [85, 65]}]
});
this is my Highchart code
when I am using javascript variable
like this
g311 = $("#g311").val();
g312 = $("#g312").val();
g321 = $("#g321").val();
g322 = $("#g322").val();
and pass this in series
series: [{name: 'Semana',data: [g311, g312] }, {name: 'Acum',data: [g321, g322]}]
it is not showing me graph please give me some way how to pass jquery variable in series (not static or PHP variable)
Seems to me you need to convert them to numbers first because input elems have values as strings:
g311 = +$("#g311").val();
g312 = +$("#g312").val();
g321 = +$("#g321").val();
g322 = +$("#g322").val();
and you need to declare these above the chart.
prefixing + converts a string to number.
I think it is because my global var chart hasn't been set yet when my function requestData is called.
This is my code of highcharts inside a $(document).ready(function()
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
marginRight: 130,
marginBottom: 25,
events: {
load: requestData()
}
},
title: {
text: 'Reporte PMU',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom : 20 * 1000,
title: {
text: 'tiempo'
},
labels : { y : 0, rotation: -60 }
},
yAxis: {
title: {
text: 'Amount'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'serieTension',
data: []
}]
});
});
and this is my requestData ()
$.ajax({
url: 'data2.php',
success: function(point) {
var series =chart.series[0],
shift = series.data.length > 20; //shift if the series is longer than 20
//add point
chart.series[0].addPoint(point, true, shift);
setTimeout(requestData, 1000);
},
cache : false
});
}
Just place
var chart;
outside all functions, next to your document ready handler to make it global.
EDIT:
Also, add a reference inside the load call
load: function() {
chart = this; // `this` is the reference to the chart
requestData();
}