Highcharts - Multiple pie charts from json
Let's say I have a server with 4 hard drives. How do I show 4 pie charts, one for each hard drive? It works if the chart type is stacked column (code below).
JSON produces this output:
[{
"name":"Drive",
"data":["C:","D:","E:","F:"]},{
"name":"Free",
"data":[673869,2267920,105627,307096]},{
"name":"Used",
"data":[94029,2264810,6373,104]
}]
And my script code (for stacked column):
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Stacked column chart with data from MySQL using Highcharts</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
colors: ['#50B432', '#ED561B'],
chart: {
renderTo: 'container',
type: 'column',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Server',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Used / Free'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +' '+ Highcharts.numberFormat(this.percentage, 2) +' %';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: '#000000',
formatter: function() {
return bytes(this.point.y, true);
}
}
}
},
series: []
}
$.getJSON("data2.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
options.series[1] = json[2];
chart = new Highcharts.Chart(options);
});
});
function bytes(bytes, label) {
if (bytes == 0) return '';
var s = ['MB', 'GB', 'TB', 'PB'];
var e = Math.floor(Math.log(bytes)/Math.log(1024));
var value = ((bytes/Math.pow(1024, Math.floor(e))).toFixed(2));
e = (e<0) ? (-e) : e;
if (label) value += ' ' + s[e];
return value;
}
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
Thank you for any suggestions.
You can iterate on each json item and create new div (by for example append) and init chart.
What is important, all values in data should be numbers, not strings like you have.
Example:
http://jsfiddle.net/9ov3en2t/
$(function () {
var json = [{
"name": "Drive",
"data": ["C:", "D:", "E:", "F:"]
}, {
"name": "Free",
"data": [673869, 2267920, 105627, 307096]
}, {
"name": "Used",
"data": [94029, 2264810, 6373, 104]
}];
var each = Highcharts.each,
$charts = $('#charts');
each(json,function(item, i) {
$charts.append('<div id="container' + i + '"></div>');
var $chart = $('#container' + i);
$chart.highcharts({
chart:{
type:'pie'
},
series:[{
name: item.name,
data: item.data
}]
});
});
});
Related
I am trying to draw a dynamic, mixed bar and line graph using Highchart.js. I am getting live data to my webpage using socket.io (I'm using Flask as my webserver so using Flask-socketIO).
I am able to print the data coming to my webpage using console.log, but I am missing something for which it is not rendered in the chart.
I am trying to add xAxis as well as both the Series value.
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<link href="../static/css/authz.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var myChart = Highcharts.chart('containerX', {
chart: {
zoomType: 'xy',
events: {
load: function () {
// set up the updating of the chart on each sample
var categories = this.xAxis[0].categories;
var socket = io.connect('http://' + document.domain + ':' + location.port + '/test');
var series1 = this.series[0]
var series2 = this.series[1]
socket.on('my_response_data', function (sample) {
//add chart data to series
var x = sample.logTime
var y = sample.logDuration
var z = sample.totalSession
console.log( x + " " + y + " " + z) //Printing properly to console e.g 2018-01-25T03:58:35.781 3 211
categories.push(sample.logTime)
series1.addPoint(y, false, true);
series2.addPoint(z, false, true);
myChart.redraw();
});
}
},
},
title: {
text: 'Sacred Tests'
},
subtitle: {
text: 'Source: My Secret Source'
},
xAxis: [{
categories: [],
crosshair: true
}],
yAxis: [{ // Primary yAxis
title: {
text: 'Sessions',
style: {
color: Highcharts.getOptions().colors[1]
}
},
labels: {
format: '{value}',
style: {
color: Highcharts.getOptions().colors[1]
}
}
}, { // Secondary yAxis
title: {
text: 'Duration',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} ms',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}],
tooltip: {
shared: true
},
legend: {
layout: 'vertical',
align: 'left',
x: 120,
verticalAlign: 'top',
y: 100,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
},
series: [{
name: 'Sessions',
type: 'column',
yAxis: 1,
data: [],
tooltip: {
valueSuffix: ''
}
}, {
name: 'Duration',
type: 'spline',
data: [],
tooltip: {
valueSuffix: 'ms'
}
}]
});
});
</script>
</head>
<body>
<div id="containerX" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
It's a problem with displaying only one point at a time with addPoint(point, redraw, shift, animation) and setting shift=true. That will remove previous point and chart will look empty.
Simple solution is to use:
series1.addPoint(y, false, false, false);
series2.addPoint(z, false, false, false);
myChart.redraw();
I am new to HighCharts and I am trying to display 2 graphs on the same x-axis) axis like shown here: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/combo-multi-axes/.
However, I get an error message: This error happens when you set a series' xAxis or yAxis property to point to an axis that does not exist.
The error occurs in "chart1"
The html and JAVASCRIPT code is as follows:
$(function updat() {
var url = "https://xpm4zyor39.execute-api.us-west-2.amazonaws.com/prod/entries";
var humid = [],
date = [],
high=[],
day=[],
chanceOfRain=[],
humid_final = [],
day_final=[],
high_final=[],
chanceOfRain_final=[]
$.getJSON(url, function (json) {
$(json['Items']).each(function(i, data) {
//Store indicator name
// fill the date array
humid.push(data.humidity);
// fill the string data array
date.push(data.Date);
high.push(data.high);
day.push(data.Day);
chanceOfRain.push(data.chanceOfRain);
});
console.log(date);
// query send string that we need to convert into numbers
for (var i = 0; i < humid.length; i++) {
if (humid[i] != null) {
humid_final.push(parseFloat(humid[i]));
high_final.push(parseFloat(high[i]));
day_final.push(parseFloat(day[i]));
chanceOfRain_final.push(parseFloat(chanceOfRain[i]));
} else {
humid_final.push(null)
};
}
console.log("day_final", day_final);
var chart = new Highcharts.chart({
chart: {
type: 'spline',
renderTo: 'light',
marginBottom: 200
},
title: {
text: 'indicatorName'
},
tooltip: {
valueDecimals: 2,
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}%</b><br/>'
},
plotOptions: {
series: {
marker: {
enabled: false
}
}
},
subtitle: {
text: 'Ambient Light Level'
},
xAxis: {
categories: day_final //.reverse() to have the min year on the left
},
series: [{
name: 'light level',
data: high_final //
}]
});
var chart1= Highcharts.chart('temp&humid',{
chart: {
zoomType:'xy'
},
title:{
text:'Humidity and temperature'
},
xAxis:{
categories: [1,2,3],
crosshair: true
},
yAxis: [{
labels:{
format: '{value}°C',
style: {
color: Highcharts.getOptions().colors[2]
}
},
title:{
text: 'Temperature',
style:{
color: Highcharts.getOptions().colors[2]
}
},
opposite: true
},
{ //secondary Y AXIS
gridLineWidth: 0,
title:{
text: 'Humidity',
style:{
color: Highcharts.getOptions().colors[0]
}
},
labels:{
format: '{value}%',
style:{
color:Highcharts.getOptions().colors[0]
}
}
}]
,
tooltip:{shared:true},
legend:{
layout: 'vertical',
align:'left',
x:80,
verticalAlign: 'top',
y: 55,
floating:true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
},
series:[{
name:'Humidity',
type: 'column',
yAxis:1,
data:[12,3],
tooltip:{valueSuffix: ' %'}
},
{
name:'Temperature',
type:'spline',
yAxis:2,
data: [1,2,3],
tooltip:{valueSuffix: ' °C'}
}]
});
}); //getJSON method
setTimeout(updat, 3000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src= "Ag.js"></script>
<div id="light" style="min-width: 310px; height: 400px; left:10px"></div>
<div id="temp&humid" style="min-width: 310px; height: 400px; left:10px"></div>
You are doing the following:
series:[{
yAxis:1,
},
{
yAxis:2,
}]
You need to do:
series:[{
yAxis:0,
},
{
yAxis:1,
}]
The problem is that axes start indexing at 0. So your index where you set temperature to axis 2 does not work because there is no axis 2. In the demo there are 3 axes, which is why it works with these definitions.
I am creating a stacked bar chart with help of highcharts.
When I click on any part of bar I want to open a new page that displays containing data. How can I achieve this?
As shown in this image the graph is not stacked as it should be. It is displayed as different three vertical bars. How can I fix this?
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Stacked column chart with data from MySQL using Highcharts</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'column',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Account Status',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'No of Accounts'
},
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
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [],
plotOptions: {
seriessss: {
cursor: 'pointer',
point: {
events: {
click: function () {
document.location.href = 'page.php?cat=' + this.category;
}
}
}
}
},
}
$.getJSON("data.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
options.series[1] = json[2];
options.series[2] = json[3];
chart = new Highcharts.Chart(options);
});
});
</script>
<script src="highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
Highcharts drilldown is not working . Scenario is From graph, if i click any point It needs to show another graph using avgTimes.testIds (check below json). But i am unable to get testId value when i click on the point.
Please check Json and Javascript for reference .
"this.series.data.indexOf( this.point )" code is not working to get the indexValue, it is giving "undefined" as response.Please check javascript code
Response json Json:
{
"testid": {
"name": "testId",
"data": [
208,
207,
206,
205,
202
]
},
"xaxis": {
"xaxis": "xaxis",
"data": [
"2016/03/21 01:50:04",
"2016/03/20 04:56:20",
"2016/03/20 04:41:56",
"2016/03/18 11:09:53",
"2016/03/18 09:33:15"
]
},
"avgTimes": {
"name": "avgTime",
"units": "ms",
"data": [
1894,
3141,
44966,
1792,
22929
],
"testIds": [
208,
207,
206,
205,
202
]
}
}
Below is the javascript which i am using
var options;
var chart;
$(document).ready(function() {
init();
});
function init() {
$('#back_btn').hide();
options = {
chart: {
renderTo: 'container',
type: 'line',
zoomType: 'x',
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: [],
labels: {
align: 'center',
x: -3,
y: 20,
formatter: function() {
return Highcharts.dateFormat('%b-%d', Date.parse(this.value));
}
}
},
yAxis: {
title: {
text: ''
}
},
tooltip: {
enabled: true,
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
'<b>'+ this.x +': '+ this.y+' '+'</b><br/>'+
'TestId: '+this.series.options.testIds[this.series.data.indexOf(this.point)];
}
},
plotOptions: {
line: {
cursor: 'pointer',
point: {
events: {
click: function() {
//document.write(this.series.options.testIds[this.series.data.indexOf( this.point )]);
$('#dateDisplay').text(this.series.options.testIds[this.series.data.indexOf( this.point )]);
$.getJSON("http://localhost:8080/reports/graph/transaction?testId="+this.series.options.testIds[this.series.data.indexOf( this.point )], function(json){
options.xAxis.categories = json.xAxis.xaxisList;
options.series[0] = json.avgTimes;
options.series[1] = json.tps;
options.series[2] = json.minTimes;
options.series[3] = json.maxTimes;
options.xAxis.labels = {
formatter: function() {
//return Highcharts.dateFormat('%l%p', Date.parse(this.value +' UTC'));
return Highcharts.dateFormat('%l%p', Date.parse(this.value));
//return this.value;
}
}
options = new Highcharts.Chart(options);
$('#back_btn').show();
});
}
}
},
dataLabels: {
enabled: true
}
}
},
series: [{
type: 'line',
name: '',
data: []
}]
}
$.getJSON("http://localhost:8080/reports/graph/tests?limit=10&offset=1&env=stg&project=MarketplaceOffers&userCount=10", function(json){
options.xAxis.categories = json.xaxis.data;
options.series[0]= json.avgTimes;
//options.series[1]=json.testid;
//options.series[1].extra= json.testid;
chart = new Highcharts.Chart(options);
});
}
function goback() {
init();
$('#dateDisplay').text("2013-02");
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Dynamic Drill Down in Highcharts</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.1/themes/base/jquery-ui.css" />
<style>
body,h1,h2,h3,h4,h5,h6,p,ul,ol,dl,input,textarea { font-family: 'Lucida Grande', Tahoma, Verdana, sans-serif; }
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.1/jquery-ui.js"></script>
<script src="date.js"></script>
<script src="dynamicChats.js"></script>
</head>
<body>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<strong><div id="dateDisplay">2013-02</div></strong>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
Back
</body>
</html>
this.point is undefined that's why you can't retrieve the index from this.series.data array. It seems that when a point is clicked on the graph, this refers to the point object itself in the click handler.
You should replace the line bellow :
this.series.options.testIds[this.series.data.indexOf(this.point)]
by this one :
this.series.options.testIds[this.series.data.indexOf(this)]
I also moved the creation of the object options inside the getJSON callback function :
<script>
var chart;
$(document).ready(function () {
init();
});
function init() {
$('#back_btn').hide();
$.getJSON("http://localhost:8080/reports/graph/tests?limit=10&offset=1&env=stg&project=MarketplaceOffers&userCount=10", function (json) {
var options = {
chart: {
renderTo: 'container',
type: 'line',
zoomType: 'x',
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: [],
labels: {
align: 'center',
x: -3,
y: 20,
formatter: function () {
return Highcharts.dateFormat('%b-%d', Date.parse(this.value));
}
}
},
yAxis: {
title: {
text: ''
}
},
tooltip: {
enabled: true,
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
'<b>' + this.x + ': ' + this.y + ' ' + '</b><br/>' +
'TestId: ' + this.series.options.testIds[this.series.data.indexOf(this.point)];
}
},
plotOptions: {
line: {
cursor: 'pointer',
point: {
events: {
click: function () {
//document.write(this.series.options.testIds[this.series.data.indexOf( this.point )]);
$('#dateDisplay').text(this.series.options.testIds[this.series.data.indexOf(this.point)]);
$.getJSON("http://localhost:8080/reports/graph/transaction?testId=" + this.series.options.testIds[this.series.data.indexOf(this)], function (json) {
options.xAxis.categories = json.xAxis.xaxisList;
options.series[0] = json.avgTimes;
options.series[1] = json.tps;
options.series[2] = json.minTimes;
options.series[3] = json.maxTimes;
options.xAxis.labels = {
formatter: function () {
//return Highcharts.dateFormat('%l%p', Date.parse(this.value +' UTC'));
return Highcharts.dateFormat('%l%p', Date.parse(this.value));
//return this.value;
}
}
options = new Highcharts.Chart(options);
$('#back_btn').show();
});
}
}
},
dataLabels: {
enabled: true
}
}
},
series: [{
type: 'line',
name: '',
data: []
}]
};
options.xAxis.categories = json.xaxis.data;
options.series[0] = json.avgTimes;
chart = new Highcharts.Chart(options);
});
}
function goback() {
init();
$('#dateDisplay').text("2013-02");
}
</script>
I would like to add new points to the scatter plot in a async manner. For that, there is an api in scatter plot "addpoint" that adds newly sent data to the chart without refreshing the scatter plot. The code used in this is
<!doctype html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script>
$(document).ready(function(){
$('#container').highcharts({
chart: {
type: 'scatter',
zoomType: 'xy'
},
title: {
text: 'Height Versus Weight of 507 Individuals by Gender'
},
subtitle: {
text: 'Source: Heinz 2003'
},
xAxis: {
title: {
enabled: true,
text: 'Height (cm)'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
},
yAxis: {
title: {
text: 'Weight (kg)'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
backgroundColor: '#FFFFFF',
borderWidth: 1
},
plotOptions: {
scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} cm, {point.y} kg'
}
}
},
series: [{
name: 'Female',
color: 'rgba(223, 83, 83, .5)',
data: [[161.2, 51.6], [167.5, 59.0], [159.5, 49.2], [157.0, 63.0], [155.8, 53.6],
]
}, {
name: 'Male',
color: 'rgba(119, 152, 191, .5)',
data: [[174.0, 65.6], [175.3, 71.8], [193.5, 80.7], [186.5, 72.6], [187.2, 78.8],
]
}]
});
function requestData() {
var chart = $('#container').highcharts();
var points = [
{
x: Math.random() * 100,
y:Math.random() * 80
}
]
var series = chart.series[0];
var data;
chart.series[1].addPoint([Math.random() * 100,Math.random() * 80]);
// call it again after one second
setTimeout(requestData, 1000);
}
requestData();
});
</script>
</head>
<body>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>
The fiddle is here : http://jsfiddle.net/anirbankundu/T8GT3/1/
Can anyone let me know if there is any possible way to add an array of points instead of adding each point step by step. I will be fetching around 1000 points for each call and the total number of points can go above 100K
Thanks,
Anirban
Use chart.series[1].data to get the current serie data and then use chart.series[1].setData to update it's data.
function requestData() {
var chart = $('#container').highcharts(),
serie = chart.series[1];
// get serie data
var data = serie.data;
// append points to data
for (var i = 0; i < 1000; i++) {
data.push([
Math.random() * 100,
Math.random() * 80
]);
}
// update serie data
serie.setData(data);
}
You can see it working here.
Update - Append points to the current data
function requestData() {
var chart = $('#container').highcharts();
// append points to data
for (var i = 0; i < 1000; i++) {
chart.series[1].addPoint([
Math.random() * 100,
Math.random() * 80
], false);
}
chart.redraw();
}
Demo