Retrieving JSON data in highcharts - javascript

I have been trying to customize an excellent jsfiddle that I was fortunate enough to be directed to in an earlier question here: Switching between many Highcharts using buttons or link text
I am very new to javascript programming (and highcharts also) and I am having some difficulties in retrieving my own data from a database. Currently I have set up my charts like the following:
$('chart1').ready(function() {
var options = {
chart: {
renderTo: 'chart1',
type: 'column',
marginTop: 40,
marginBottom: 75
},
legend: {
enabled: false
},
title: {
text: 'Revenues',
x: 25 //center
},
xAxis: {
title: {
text: ''
},
categories: []
},
yAxis: {
showInLegend: false,
tickAmount: 11,
endOnTick: false,
startOnTick: true,
labels: {
formatter: function () {
return Highcharts.numberFormat(this.value, 0, '.', ',');
}
},
title: {
text: '<?php echo $unitCurr; ?>'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ Highcharts.numberFormat(this.y, 0,'.',',');
}
},
series: []
}
var tableName = '<?php echo $tableName; ?>'
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
At the bottom you will notice that I am using JSON to retrieve information from my database and everything works just fine. In my earlier question I was asking about how to switch charts using buttons instead and was directed to the following jsfiddle: http://jsfiddle.net/jlbriggs/7ntyzo6u/
This example consists of 3 charts but I have just been trying to manipulate the first chart in order to find out if I could make my own data display instead of the random data that is being generated:
var chart,
chartOptions = {},
chartData = {};
chartData.chart1 = randomData(25);
chartData.chart2 = randomData(10, true);
chartData.chart3 = randomData(65, true, 300);
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
But no matter how much I tried, I just can't seem to change the "data: chartData.chart1" in such a way that it retrieve the arrays I get from my $.getJSON function. Can any of you help me explain why, for instance, the below code doesn't work?. Here I try to exchange the ChartData.chart1 array for my database data. I'm not experienced enough to tell whether its the whole random number generation part of the code that prevents it from working or if it's my understanding thats severely lacking. (I have made sure that the data from data.php is indeed available, since I can display it in a normal array when I try).
var chart,
chartOptions = {},
chartData = {};
chartData.chart2 = randomData(10, true);
chartData.chart3 = randomData(65, true, 300);
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
chartData.chart1 = json[6]['data'];
});
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
Any assistance you can provide will be greatly appreciated!

You're actually very close to something that will work. Your problem is related to the timing of async calls relative to inline code, and also the way assignments work in javascript.
As a quick example, here's some code:
x = {foo:5};
y = x.foo;
x.foo = 9;
At the end of this, x.foo is 9, but y is still 5.
Your line of code
chartData.chart1 = json[6]['data'];
doesn't execute until after the call to the server completes; it's contained within a call back function. However, this section of code
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
executes immediately. See the problem? You've cooked the current value of chartData.chart into chartOptions.chart1 BEFORE the server call has completed. That's why you're not seeing your data.
Instead, try something like this:
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: []
}]
};
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
chartOptions.chart1.series[0].data = json[6]['data'];
});
Now when your data comes back, you're putting it into the object that is actually being used to render the chart (once you click on the right button). Keep in mind that it's going to be empty until the server call completes.

Related

How to use the same data set for multiple series in Highcharts?

I'm fairly new to Highcharts. We were previously using Logi Analytics, which did
a lot of stuff in the background that we had no control over. Now that were trying to re-create the same charts, were running into issues on how to do some of these things. I am trying to use the same data set for multiple series elements. For example, I will have a column chart, then a line chart on top of it. If it helps, I keep this code in a .ts file and compile into JS to deploy. Here's what I currently have that works:
let myChart = Highcharts.chart('container', {
chart: {
type: 'column'
},
plotOptions: {
series: {
events: {
//do something
}
}
},
title: {
text: 'My Title'
},
xAxis: {
categories: dataCategories
},
yAxis: {
title: {
text: 'Percentages'
}
},
series: [
{
name: 'Data Table',
data: data,
cursor: 'pointer'
}
]
});
My data is embedded with Java. Example of data:
let data =
[
{
'location': 'someplace',
'dept': '999',
'deptDescription': '999 DEPT',
'code': '',
'name': 'NO NAME',
'hours1': 32.5,
'hours2': 4.7,
'hours3': 0.0,
'hours4': 0.0
}
];
How I set my yAxis and categories:
for (let row of data) {
row.y = row.hours1;
dataCategories.push(row.deptDescription);
}
I want to use the same data because I have the same x axis and my data contains the new y axis as well. Possibly something like this:
series: [
{
type: 'column'
name: 'Data Table',
data: data,
cursor: 'pointer'
},
{
type: 'line',
name: 'Data Table2',
data: data,
cursor: 'pointer'
}
]

Changing yAxis and plotOptions for drilldown

I am using HighCharts to visualize percentages from projects, which are downdrilled into variables which make the percentages!
I will give my code :
$(function () {
// Create the chart
var options = {
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: 'Comparison'
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
enabled: true,
text: 'Percentages',
style: {
fontWeight: 'normal'
}
},
labels: {
format: '{value}%'
}
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y:.1f}%'
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<br/>'
},
series: [{
name: '',
colorByPoint: true,
data: []
}],
credits: {
enabled: false
},
drilldown: {
series: [{
name : '',
id: '',
data: []
}]
}
};
$.getJSON('/uploads/fraction.json', function (list) {
options.series = list;
});
$.getJSON('/uploads/drilldown.json', function (list2) {
options.drilldown.series = list2;
var chart = new Highcharts.Chart(options);
});
});
Example of the JSONs:
fraction.json
[{"name":"","colorByPoint":true,"data":[{"name":1,"y":80,"drilldown":1},{"name":2,"y":87,"drilldown":2},{"name":3,"y":105.71428571429,"drilldown":3},{"name":5,"y":"","drilldown":5},{"name":6,"y":53.160248409091,"drilldown":6}]}]
drilldown.json
[{"name":1,"id":1,"data":[["Total",2],["Estimated",2.5]]},{"name":2,"id":2,"data":[["Total",3.9],["Estimated",4.5]]},{"name":3,"id":3,"data":[["Total",3.7],["Estimated",3.5]]},{"name":5,"id":5,"data":[["Total",""],["Estimated",0.44]]},{"name":6,"id":6,"data":[["Total",0.233905093],["Estimated",0.44]]}]
I would like the graph to show percentages above the column and on the yAxis when the graph is first loaded, but absolute values when the drilldown is activated. I didn't manage to get it until now. Could you help me?
There are two ways of doing those changes - a static and dynamic way. Static way - define data labels and tooltip options for drilldown series.
Dynamic way - apply the options on drilldown/drillup events.
events: {
drilldown: function(options) {
this.yAxis[0].update({
labels: {
format: '{value}'
}
}, false, false);
options.seriesOptions.dataLabels = {
format: '{point.y:.1f}'
};
options.seriesOptions.tooltip = {
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}</b> of total<br/>'
};
},
drillup: function () {
this.yAxis[0].update({
labels: {
format: '{value}%'
}
}, false, false);
}
}
example: http://jsfiddle.net/d4fmaeea/
Two warnings:
In your json files, you have points which has value equals to "" which is not a valid type (must be number/null) and it may cause some issues, e.g. column with value 0 will have the same height as the column with value 10.
$.getJSON() is an asynchronous function. You use getJSON to assign list to options.series but that part may be executed after the chart was created so you would end up with the chart with no top-level series, only the drilldown ones.
Async part of code:
$.getJSON('/uploads/fraction.json', function (list) {
options.series = list;
});
$.getJSON('/uploads/drilldown.json', function (list2) {
options.drilldown.series = list2;
var chart = new Highcharts.Chart(options);
});

How do I set Highcharts categories dynamically?

I've been reading through the documentation and googling for hours and have not made any progress on finding these categories. I am building the grapg.
var udsChart; //global UDS chart variable
function requestData() {
$.ajax({
url: 'getJsonData.aspx?ID=udsLevel1',
success: function (point) {
udsChart.series[0].setData(point, true);
setTimeout(requestData, 1000);
},
cache: false
});
}
udsChart = new Highcharts.Chart({
chart: {
renderTo: 'udsGraphDiv',
defaultSeriesType: 'column',
events: {
load: requestData
}
},
title: {
text: 'Live random data'
},
xAxis: {
text: 'xAxis'
},
yAxis: {
text: 'yAxis'
},
series: [{
name: 'Random data',
data: []
}]
});
Either your categories should fixed and you can setData via setData function with array of values. But if categories also changing , try this
success: function (data) {
var categories= [];
var seriesData = [];
$.each(data,function(item){
categories.push(item[0]);
seriesData.push(item[1]);
});
udsChart.xAxis[0].setCategories(categories); //setting category
udsChart.series[0].setData(seriesData , true); //setting data
setTimeout(requestData, 1000);
}
You just need to set xAxis category property.
Here is an example.
var data = [["01/22/2016",108],["01/24/2016",45],["01/25/2016",261],
["01/26/2016",224],["01/27/2016",307],["01/28/2016",64]];
var cat = [];
data.forEach(function(item) {
cat.push(item[0]);
});
udsChart = new Highcharts.Chart({
chart: {
renderTo: 'udsGraphDiv',
defaultSeriesType: 'column',
events: {
//load: requestData
}
},
title: {
text: 'Live random data'
},
xAxis: {
text: 'xAxis',
categories: cat
},
yAxis: {
text: 'yAxis'
},
series: [{
name: 'Random data',
data: data
}]
});
You are missing simple property: xAxis.type. Set it to category and will work, like this:
xAxis: {
text: 'xAxis',
type: 'category'
},
Try this one
udsChart.xAxis["categories"] = ['a','b','c']

Javascript variable with Comma separated values not working in HighChart

I have been using highchart for graphical display of my records. HighChart works fine with my php variable with comma separated values in it. However, I couldn't get this done using javascript variable with comma separated values. Please help me with this. Your help is much appreciated. Thanks. My codes are shown below.
Javascript
<script type="text/javascript">
var res = [];
var data_graph = [];
function show_graphics(){
$.post("<?php echo base_url(); ?>main_controller/show_monthly_analytics_ajax", '', function(data){
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
data_graph = res.join(",");
console.log(data_graph );
} else{
console.log(data.notify);
}
},'json');
$('#container').highcharts({
chart: {
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 10,
beta: 25,
depth: 70
}
},
title: {
text: '3D chart with null values'
},
subtitle: {
text: 'Notice the difference between a 0 value and a null point'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: Highcharts.getOptions().lang.shortMonths
},
yAxis: {
title: {
text: null
}
},
series: [{
name: 'Sales',
data: [data_graph]
}]
});
}
</script>
When I look at the console, the values being showed of the variable array data_graph seems right but the chart never showed a graph. What is the problem with this?
Modification
<script type="text/javascript">
var res = [];
function show_graphics(){
$.post("<?php echo base_url(); ?>main_controller/show_monthly_analytics_ajax", '', function(data){
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
//aa = res.join(",");
console.log(res);
} else{
console.log(data.notify);
}
},'json');
$('#container').highcharts({
chart: {
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 10,
beta: 25,
depth: 70
}
},
title: {
text: '3D chart with null values'
},
subtitle: {
text: 'Notice the difference between a 0 value and a null point'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: Highcharts.getOptions().lang.shortMonths
},
yAxis: {
title: {
text: null
}
},
series: [{
name: 'Sales',
data: [res]
}]
});
}
</script>
Response
The data part/section for series property should be an array of numbers.
According to your explanation, your implementation is as if you would have the following:
series: [{
name: 'Sales',
data: ['1, 2, 1, 0'] // this is an array with one string element, which is wrong
}]
But, it should be:
series: [{
name: 'Sales',
data: [1, 2, 1, 0]
}]
See JSfiddle demo here
EDIT
Besides the change that I suggested above, consider that the $.post call is an async execution. Then, you should only draw the chart when data is 'ready' by moving $('#container').highcharts(...) block inside the success callback as follows:
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
$('#container').highcharts({
...
...
series: [{
name: 'Sales',
data: res
}]
});
} else {
console.log(data.notify);
}

Simple Highchart works as seperate .js file, but not in view

I'm new to Highcharts, and so far have only have had success getting my test chart to display when it's saved in a seperate .js file. The total highcharts_weight.js code is:
$(function () {
var weightchart = new Highcharts.Chart({
chart: {
renderTo: "weight_chart",
type: 'line'
},
title: {
text: 'weight loss history'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
day: '%e %b'
}
},
yAxis: {
title: {
text: 'Weight'
}
},
series: [{
name: 'Weight loss history',
data: [[Date.UTC(2013, 1, 1), 87.2],[Date.UTC(2013, 0, 1), 90.2]]
}]
});
});
That shows up fine on my webpage.
But, if I try putting the code somewhere else, and change the chart name in the .js file, nothing shows up except a blank space where the chart should be.
I've tried putting this code inside brackets in my root header in application.html.erb and inside brackets in the partial I want to use to render this table in, but then nothing shows up. Right now, I have it in application.html.erb, in the header,
<script>
$(function () {
var weightchart = new Highcharts.Chart({
chart: {
renderTo: "weight_chart",
type: 'line'
},
title: {
text: 'weight loss history'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
day: '%e %b'
}
},
yAxis: {
title: {
text: 'Weight'
}
},
series: [{
name: 'Weight loss history',
data: [[Date.UTC(2013, 1, 1), 87.2],[Date.UTC(2013, 0, 1), 90.2]]
}]
});
});
</script>
and it does not work. Any ideas?
if you want to run the chart soon after your DOM is constructed then better use
$(document).ready(function() {
chart = new Highcharts.Chart({})
});
this may solve the problem.

Categories