Create Pie chart for each Json object - javascript

I have one Json with multiple array and foreach array I want to create Pie chart, but I don't know how to do it.
This is the array thet I have. And this is what I tried :
function Pie() {
$.getJSON("/Admin/Attivita/OreOggi", function (data) {
console.log(data);
var oreTecico = [];
var oreTecico = [];
var oreMalatia = [];
var oreStraordinario = [];
var oreInfortunio = [];
var oreFerie = [];
for (var i = 0; i < data.length; i++) {
nomeTecnico.push(data[i].nome);
oreTecico.push(data[i].odinario);
oreMalatia.push(data[i].malatia);
oreStraordinario.push(data[i].straordinario);
oreInfortunio.push(data[i].infortunio);
oreFerie.push(data[i].ferie);
};
// Build the chart
Highcharts.chart('zdravko', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Ore segnate oggi'
},
tooltip: {
pointFormat: '<b>{point.name}</b>: {point.y:.1f} h.'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
name: nomeTecnico[0],
colorByPoint: true,
data: [{
name: '',
y:0,
sliced: true,
selected: true
}, {
name: 'Odinario',
y: oreTecico[0]
}, {
name: 'Malatia',
y: oreMalatia[0]
}, {
name: 'Straordinario',
y: oreStraordinario[0]
}, {
name: 'Infortunio',
y: oreInfortunio[0]
}, {
name: 'Ferie',
y: oreFerie[0]
}]
}]
});
});
}
It shows only the last "data". I want to make fo each array one pie. If i have 100 arrays I want 100 pies.
UPDATE:
I added this :
data.forEach(function (el) {
var chartData = [el.data1, el.data2];
var chartContainer = document.createElement('div');
document.getElementById('zdravko').append(chartContainer);
Highcharts.chart(chartContainer, {
series: [{
type: 'pie',
data: chartData
}]
});
});
The chartData is array of undefined objects.
Is it possible to make for or foreach inside Highcharts?

You need to use the Highcharts.chart method in a loop, for example:
var data = [{
data1: 12,
data2: 25
}, {
data1: 67,
data2: 11
}];
data.forEach(function(el) {
var chartData = [el.data1, el.data2];
var chartContainer = document.createElement('div');
document.getElementById('container').append(chartContainer);
Highcharts.chart(chartContainer, {
series: [{
type: 'pie',
data: chartData
}]
});
});
Live demo: http://jsfiddle.net/BlackLabel/x95pbw7j/
API Reference: https://api.highcharts.com/class-reference/Highcharts#.chart

Related

Chart JS custom message on tooltip, not x and y axis

I am displaying a bar chart that has 3 different pieces of information, (project name, number of days remaining, and the end date.) I am displaying the project name on one axis, and the number of days remaining determines the height of the bar. Currently, when I hover over a bar the tooltip displays the information already on the x and y axis. I want it to instead have the end date.
ie: project "b" will end in 2 days (August 4th), when I hover over the bar I want the tooltip to say "End date of 2022-08-04" instead of "b Work Days Remaining: 2"
My json of the data looks like this:
[{"po_num": "a", "days_rem": 10, "date_end": "2022-08-16"},
{"po_num": "b", "days_rem": 2, "date_end": "2022-08-04"},
{"po_num": "c", "days_rem": 6, "date_end": "2022-08-10"}]
Here is the link of the current graph.
https://i.stack.imgur.com/HefRz.png
Here is an MS paint rendering of what I am trying to do:
https://i.stack.imgur.com/GAT2I.png
The implementation code:
link = "{{{BASE_BACK_URL}}}";
$.getJSON(link, function (data) {
let po_names = [];
let days_rem = [];
for (let i = 0; i < data.length; i++) {
po_names.push(data[i]["po_num"]);
days_rem.push(data[i]["days_rem"]);
}
const ctx = document.getElementById('po-timeline-chart');
const myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: po_names,
datasets: [{
label: 'Work Days Remaining',
data: days_rem,
backgroundColor: 'rgb(0, 89, 178)'
}],
},
options: {
legend: {
align: "end"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
});
Solution listed below:
$.getJSON(link, function (data) {
let po_names = [];
let days_rem = [];
for (let i = 0; i < data.length; i++) {
po_names.push(data[i]["po_num"]);
days_rem.push(data[i]["days_rem"]);
}
const ctx = document.getElementById("po-timeline-chart");
const myChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: po_names,
datasets: [
{
label: "Work Days Remaining",
data: days_rem,
backgroundColor: "rgb(0, 89, 178)",
},
],
},
options: {
tooltips: {
enabled: true,
callbacks: {
// To change title in tooltip
title: (data) => {
return "This PO will run out on";
},
// To change label in tooltip
label: (data) => {
return date_end[data['index']];
},
},
},
legend: {
align: "end",
},
scales: {
xAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
});

Highcharts: How to display each column as a separate series?

I'm trying to display the data from my json.
My json file looks like this:
0: {OGS: "26", STRM: "1811", ACAD_CAREER: null, YEAR: "2018"}1: {OGS: "4144", STRM: "1801", ACAD_CAREER: null, YEAR: "2018"}2: {OGS: "3935", STRM: "1802", ACAD_CAREER: null, YEAR: "2018"}3: {OGS: "16", STRM: "1812", ACAD_CAREER: null, YEAR: "2018"}length: 4__proto__: Array(0)
And here's my code:
<script>
$(function () {
var categData = [];
var statusACountData = [];
var statusBCountData = [];
var dateVal=[];
var statusVal=[];
var countVal = [];
var jsonvar = [];
$.getJSON('http://localhost:37590/get_OGSDataPerTermYear/ORT/2018', function (jsonData) {
for(i=0;i<jsonData.length;i++){
dateVal[i]=jsonData[i].STRM;
// statusVal[i]=jsonData[i].status;
countVal[i]=jsonData[i].OGS;
}
// jsonData
console.log(jsonData);
console.log(countVal);
console.log(categData);
// $(function () {
Highcharts.chart('container', {
chart: {
type: 'column'
},
xAxis: {
categories: dateVal,
crosshair: true
},
series: [{
name: dateVal,
data: countVal
}]
});
// });
});
});
</script>
The column is not showing and the 4 data which is: 1801 1802 1803 and 1804 only appears in 1 series. I want to make them each series with different data which is OGS number.
To make it as you expect (each column is a separate series) you can follow this approach:
Prepare series and xAxis.categories arrays. Each series.data array should have an appropriate amount of null points before the one with real value. Something like that:
categories:
["1811", "1801", "1802", "1812"]
series:
[{
name: "cat - 0",
data: [2456]
}, {
name: "cat - 1",
data: [null, 4144]
}, {
name: "cat - 2",
data: [null, null, 3935]
}, {
name: "cat - 3",
data: [null, null, null, 2316]
}]
plotOptions.column.grouping should be disabled:
Highcharts.chart('container', {
chart: {
type: 'column'
},
xAxis: {
crosshair: true,
categories: categories
},
plotOptions: {
column: {
grouping: false
}
},
series: series
});
Demo:
https://jsfiddle.net/BlackLabel/ynqjftLk/
API reference:
https://api.highcharts.com/highcharts/plotOptions.column.grouping
enter image description hereYour data is not in right format. If you need to plot STRM is x axis , you will need to put them in a separate array and assign it to xAxis.
The yAxis also accepts an array of objects and the object need to have two keys like name & data where data is an array .
Also OGS values are in string , so adding a + before jsonData[i].OGS will convert it to number.
let jsonData = [{
OGS: "2456",
STRM: "1811",
ACAD_CAREER: null,
YEAR: "2018"
}, {
OGS: "4144",
STRM: "1801",
ACAD_CAREER: null,
YEAR: "2018"
}, {
OGS: "3935",
STRM: "1802",
ACAD_CAREER: null,
YEAR: "2018"
}, {
OGS: "2316",
STRM: "1812",
ACAD_CAREER: null,
YEAR: "2018"
}]
var categData = [];
var statusACountData = [];
var statusBCountData = [];
var dateVal = [];
var statusVal = [];
var countVal = [];
var jsonvar = [];
for (let i = 0; i < jsonData.length; i++) {
dateVal[i] = jsonData[i].STRM;
countVal.push({
name: 'someText',
data: [+jsonData[i].OGS]
})
}
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Some Text'
},
subtitle: {
text: 'someTExt'
},
xAxis: {
categories: dateVal,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'OGS'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: countVal
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
can you guys check my code for drilldown? it only display 1 data series right after i clicked the column on the first chart,.
$.getJSON('http://localhost:37590/get_OGSDataPerTermYear/' + strCampus + "/" +
data[i].YEAR, function (jsonDataDrill) {
const datadrill = jsonDataDrill
console.log(jsonDataDrill);
for (d = 0; d < datadrill.length; d++) {
categories = datadrill[d].STRM
dataseries.push({
id: datadrill[d].YEAR,
name: +datadrill[d].STRM,
data: [{
y: +datadrill[d].OGS
}]
})
}
});

Highcharts data value from variable array string

Got a column called ChartData in database with a string value of 4,11,25,36,50. Trying to assign this value to a hidden variable so JS can read the value of this and put this value in the data option using high charts. I have console.log the variable and looks like its appearing as a string rather than an array when being parsed across the server side to the client side.
C# code
string str = reader["ChartData"].ToString();
string[] strList = str.Split(','); //seperate the hobbies by comma
// convert it in json
dataStr = JsonConvert.SerializeObject(strList, Formatting.None);
hiddenvariable.Value = dataStr;
JS code:
function CreateBoxPlot() {
var hv = $('#hiddenvariable').val();
alert(hv); //["40","61","65","74","77"]
var chart;
var titleText = 'Test Chart Title';
var subTitleText = 'Test Chart Subtitle';
var type = 'boxplot';
var data = hv;
console.log(data); //["40","61","65","74","77"]
$(function () {
$('#container').highcharts({
chart: { type: type, inverted: true },
title: { text: titleText },
subtitle: { text: subTitleText },
legend: { enabled: false },
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
pointWidth: 50
}
},
xAxis: {
visible: false
},
yAxis: {
visible: true,
title: {
text: 'Values'
},
plotLines: [{
value: 80,
color: 'red',
width: 2
}]
}
});
chart = $('#container').highcharts();
chart.addSeries({ data: data });
});
}
However when i hardcode data to the below value this works. How do i format this correctly when its parsed over to the JS side:
var data = [[40,61,65,74,77]]
You have to convert the string '["40","61","65","74","77"]' to js array with numbers. To make it work on each browser you can follow this approach:
Parse the string to js array using JSON.parse()
Loop through the created array and convert each element to number:
var json = '["40","61","65","74","77"]',
dataString = JSON.parse(json),
data = [],
i;
for (i = 0; i < dataString.length; i++) {
data[i] = +dataString[i];
}
Code:
$(function() {
var json = '["40","61","65","74","77"]',
dataString = JSON.parse(json),
data = [],
i;
for (i = 0; i < dataString.length; i++) {
data[i] = +dataString[i];
}
$('#container').highcharts({
chart: {
inverted: true
},
legend: {
enabled: false
},
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
pointWidth: 50
}
},
xAxis: {
visible: false
},
yAxis: {
visible: true,
title: {
text: 'Values'
},
plotLines: [{
value: 80,
color: 'red',
width: 2
}]
}
});
chart = $('#container').highcharts();
chart.addSeries({
data: data
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/ay1xmgoc/
Taking reference from the comments, add this to your code and then try.
var data = hv.map(function (element) {
return +element;
});

incorrect callback function string

I am using this code belong to plot currency change values but there is a problem while plotting chart.
$(document).ready(function () {
localhost1 = {}; //our global namespace variable
localhost1.chg_percent = [];
localhost1.currency =[];
localhost1.chart1 = {yAxisMin : null, yAxisMax : null }; //this object holds things belonging to this chart1
var url1 = 'http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json&view=basic';
$.ajax({
url: url1,
cache: false,
dataType: 'jsonp',
context: localhost1,
success: function(data) {
for(var i=0; i<data.list.resources.length; i++) {
this.currencyObj = data.list.resources[i].fields;
this.chg_percent.push(parseFloat(data.list.resources[i].resource.fields.chg_percent));
this.currency.push(data.list.resources[i].resource.fields.name);
}
this.chart1.yAxisMax = (function(array){
var number_array = [];
for(var i=0; i<array; i++){
if(array[i] != null){
number_array.push(array[i]);
}
}
return math.max.apply(Math, number_array);
})(this.chg_percent);
this.chart1.yAxisMin = (function(array){
var number_array = [];
for(var i=0; i<array; i++){
if(array[i] != null){
number_array.push(array[i]);
}
}
return math.min.apply(Math, number_array);
})(this.chg_percent);
this.chart1.data.series[0].data = this.chg_percent;
this.chart1.data.xAxis.categories = this.currency;
chart = new Highcharts.Chart(this.chart1.data);
console.log(data);
}
});
localhost1.chart1.data = {
chart: {
renderTo: 'container',
type: 'bar'
},
title: {
text: 'Historic World Population by Region'
},
subtitle: {
text: 'Source: Source : yahoo'
},
xAxis: {
categories: null,
title: {
text: null
}
},
yAxis: {
min: localhost1.chart1.yAxisMin,
max: localhost1.chart1.yAxisMax,
title: {
text: 'Daily Percentage Change',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
formatter: function(){
return ''+
this.series.name +': '+ this.y +' %';
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -1,
y: 1,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: 'Daily Change',
data: null
}]
};
});
when i run this code, i get an error message in console "Not acceptable : http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json&view=basic&callback=jQuery18203581249208157574_1452451202663&_=1452451202773".
though the api i have used is correct but the string that callback function returns seems to be incorrect.

highcharts with only javascript and no jquery

So without jquery I want to update highcharts with new data live. I have a chart that displays data from a database, and I am doing a http get request to get the data every few seconds. I am able to grab the data correctly, but when I push the new data onto the series variable for the chart, the graph doesn't update in real time. It only updates when I refresh. How can I fix this? I am using highcharts in angularjs.
you should call series.addPoint() instead of just updating the data array
please see here http://jsfiddle.net/9m3fg/1
js:
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.addPoints = function () {
var seriesArray = $scope.chartConfig.series
var newValue = Math.floor((Math.random() * 10) + 1);
$scope.chartConfig.xAxis.currentMax++;
//if you've got one series push new value to that series
seriesArray[0].data.push(newValue);
};
$scope.chartConfig = {
options: {
chart: {
type: 'line',
zoomType: 'x'
}
},
series: [{
data: [10, 15, 12, 8, 7, 1, 1, 19, 15, 10]
}],
title: {
text: 'Hello'
},
xAxis: {
currentMin: 0,
currentMax: 10,
minRange: 1
},
loading: false
}
});
From your code it looks like you want to add new series rather then new data if yes please see here: http://jsfiddle.net/bYx4a/
var app = angular.module('app', ["highcharts-ng"]);
app.controller("myCtrl", ['$scope', '$http', function ($scope, $http) {
var count = 0;
$scope.chartOptions = {
chart: {
type: 'line'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4]
}]
};
$scope.addSeries = function () {
var newData = {
name: 'John',
data: [1, 4, 3]
};
$scope.chartOptions.series.push({
name: newData.name,
data: newData.data
})
};
}]);
Here is my solution for using Highcharts addPoint function in the highcharts-ng directive:
$scope.chart_realtimeForceConfig = {
options: {
chart: {
type: 'line',
},
plotOptions: {
series: {
animation: false
},
},
},
series: [
{
name: 'Fx',
data: []
},
],
func: function(chart) {
$timeout(function() {
chart.reflow();
$scope.highchart = chart;
}, 300);
socket.on('ati_sensordata', function(data) {
if (data) {
var splited = data.split('|');
if (splited.length >= 6) {
var val = parseFloat(splited[5]);
var shift = chart.series[0].data.length > 100;
chart.series[0].addPoint(val, true, shift, false);
}
}
});
},
loading: false
}

Categories

Resources