How to make a chart with highcharts, load data from API - javascript

I am a new programmer and this is my first time using highcharts.
I have code like this using highstocks library too:
Highcharts.getJSON('https://gmlews.com/api/data', function(data) {
console.log(data);
var accelero_x = [],
timestamp = [];
for (var i = 0; i < data.length; i++) {
accelero_x.push(data[i].accelero_x);
timestamp.push(data[i].timestamp);
}
console.log(accelero_x);
console.log(timestamp);
// Create the chart
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'Accelero X'
},
series: [{
name: 'Accelero X',
data: accelero_x,
type: 'spline',
tooltip: {
valueDecimals: 2
}
}]
});
});
You can see the full running code on : https://jsfiddle.net/estri012/y1usoxd7/1/
The problem is how to make the x-axes based on my timestamp?
New problem after get the x-axes right is : in my api, some of the last data is in 19March. But on the chart the last data shows 18March not 19March. Actually there is no one single data on 18March in my API. You can check the api on the URL above. Meanwhile the other data before those are showing the right date on the chart.
This is the capture of the chart :

You need to convert your data to the format required by Highcharts, in your case - an array of arrays or an array of objcts ({ x, y }).
Highcharts.getJSON('https://gmlews.com/api/data', function(data) {
var seriesData = [];
for (var i = 0; i < data.length; i++) {
seriesData.push([
new Date(data[i].timestamp).getTime(),
data[i].accelero_x
]);
}
// Create the chart
...
});
Live demo: https://jsfiddle.net/BlackLabel/82vqcwsr/
API Reference: https://api.highcharts.com/highstock/series.line.data

Related

Update Chart JS with date range selector

I am trying to update a chart depending on the dates and and shifts selected using ajax. My ajax call returns an array like this:
0
date "2017-11-20"
shift "Day Shift"
availability 100
1
date "2017-11-21"
shift "Day Shift"
availability 63.63636363636363
2
date "2017-11-22"
shift "Day Shift"
availability 63.63636363636363
3
date "2017-11-23"
shift "Day Shift"
availability 63.63636363636363
4
date "2017-11-24"
shift "Day Shift"
availability 14.285714285714285
5
date "2017-11-20"
shift "Night Shift"
availability 67.56756756756756
6
date "2017-11-21"
shift "Night Shift"
availability 67.56756756756756
7
date "2017-11-22"
shift "Night Shift"
availability 67.56756756756756
8
date "2017-11-23"
shift "Night Shift"
availability 67.56756756756756
my javascript looks like this:
// on change event
var request;
$('input').on('change', function(event) {
console.log('changed');
event.preventDefault();
// Abort any pending request
if (request) {
request.abort();
}
var rangeStart = moment($('#daterange').data('daterangepicker').startDate).unix();
var rangeEnd = moment($('#daterange').data('daterangepicker').endDate).unix();
var shift = 'all';
request = $.ajax({
url: "report_availability.php",
type: "post",
data: {
rangeStart: rangeStart,
rangeEnd: rangeEnd,
shift: shift
}
});
request.done(function (response, textStatus){
drawChart(response);
});
request.fail(function (textStatus, errorThrown){
// Log the error to the console
console.error(
"The following error occurred: "+
textStatus, errorThrown
);
});
request.always(function () {
console.log('request finished');
});
});
function drawChart(data) {
var dates = [];
var shift1Score = [];
var shift2Score = [];
for(var i in data) {
var found = jQuery.inArray(data[i].date, dates);
if (found < 0) {
dates.push(data[i].date);
}
if(data[i].shift == 'Day Shift' ) {
shift1Score.push(data[i].availability);
} else {
shift2Score.push(data[i].availability);
}
}
// Destroy the chart if it already exists
// NOT WORKING
if(myChart!=null){
myChart.destroy();
console.log('destroy');
}
var ctx = document.getElementById("myChart").getContext('2d');
ctx.canvas.height = 50;
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: dates,
datasets: [
{
label: "Day Shift",
backgroundColor: "#3e95cd",
data: shift1Score
}, {
label: "Night Shift",
backgroundColor: "#8e5ea2",
data: shift2Score
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
responsive: true,
maintainAspectRatio: false
}
});
}
I have 2 problems with this:
problem 1: The chart is not being destroyed so when I redraw it, it just redraws on top of the old chart which causes problems with the hover events. I have tried to use chart.update() to resolve this issue however this seems to just add to the original data instead of replacing it.
EDIT:- I have solved problem 1 by removing the canvas and then creating a new canvas:-
$('#myChart').remove();
$('#chartBar').append('<canvas id="myChart"></canvas>');
Problem 2: There is more than 2 shifts.. sometime upto 5 and I do not want to hard code all of these. I would like to draw each dataset depending on how many shifts are returned in the array, I am open to changing the array structure in php or javascript but just cannot seem to figure out the correct array structrue or how to build a dynamic dataset array for the chart.
the chart should output like this for 2 shifts:
Any help would be great thanks
I had the same problem that you have.
In order to update the graph i am using two functions:
Remove all datasets in current graph:
function removeDataset(chart) {
chart.data.datasets = [];
};
Add a new dataset to the graph:
function addDataset(chart, name, data, background, border, fill) {
var newDataset = {
label: name,
data: [],
backgroundColor: background,
borderColor: border,
fill: fill
};
for (var index = 0; index < data.length; ++index) {
newDataset.data.push(data[index]);
}
chart.data.datasets.push(newDataset);
};
So, when i have the ajax done, i use like this:
removeDataset(ctx1);
addDataset(ctx1, "Dataset Name", resp.dataset_data_json, "#007bff", "#007bff", true);
ctx1.update();
To declare the graph, i use:
var ctx1;
$(document).ready(function () {
var canvas1 = $("#canvas1")[0];
canvas1.height = "300";
ctx1 = new Chart(canvas1, config_ctx1);
});
I hope it helps.

chartjs push array to label not working

Dynamically updating a chartjs chart and creating the labels in an array format (["A","B","C"]). However chartjs doesn't accept a push of the label array unless it is in the format "A","B","C" (without brackets). Anyone else experience this or have I misunderstood? Se code below. Produces this
Instead of this (ok when adding labels as chart.data.labels.push("A","B","C","D")
var chart = new Chart(document.getElementById("element"), {
type: 'bar',
options: {
legend: {
display: false
}
}
});
//PUSH DATA TO GRAPH.
var verserier = [];
var veromslperserie = [];
var stat = seriestat(); //function to retrieve data for labels
$.each(stat, function(i, item) {
verserier.push(i);
veromslperserie.push(item["omsl"]);
});
chart.data.labels.push(verserier); //error occurs here
chart.data.datasets.push({
label: "Omsl",
data: veromslperserie,
backgroundColor: colorarray,
});
chart.update();
When you push outside of the loop you are actually pushing verserier into position [n], which in this case is 0.
If you do not add values again you can do
chart.data.labels = verserier
I don't have the explanation of the "why", but here's a workaround :
var data_array = new Array();
// This doesn't work (but with no error on my side, appart from visually wrong labels)
myChart.data.labels.push(data_array);
// But this works
for(i=0;i<data_array.length;i++)
{
myChart.data.labels.push(data_array[i]);
}

Highcharts - Add a pie chart to a line chart

I'm trying to make a combination Line and Pie chart but I'm using 2 Javascript arrays for data inputs as opposed to hard coded values. The syntax I'm using isn't going through. http://www.highcharts.com/demo/combo
The code below is what's currently implemented and I added the pieData. How do I add this to the series so that it shows up as a pie chart in the corner?
Basically instead of hard coding the series, how do you define 2 series for two graphs using two arrays like the ones below?
Kinda-sorta demo
$.each(fuelObj, function (k, i) {
var genData = [];
genData.type = 'line';
genData.name = i.name;
genData.data = i.flow.sort();
genData.visible = i.visible;
genData.color = i.color;
genData.dashStyle = 'Line';
genData.events = {
click: function (event) {
this.hide();
}
};
seriesData.push(genData);
var pie = [];
pie.name = i.name;
pie.y = i.flow[i.flow.length - 1][1];
pie.color = i.color;
pieData.push(pie);
});
series: genData
EDIT:
I'm already using Objects. fuelObj is built like this above the listed code:
fuelObj['gas'] = {name: 'gasoline', yest: [], today: [], color: '#00B050', visible: true};
series typically takes an array of objects.
For example:
series: [
{
type:'column'
name:'series 1'
data:[1,2,3,4,5]
},
{
type:'spline'
name:'series 2',
data[5,6,7,8,9]
}
]
Make sure genData and pieData are objects and then add them to the series array.

Dojo charting. X-axis labels not sequential order

I have a chart where the X-axis pulls data from a cell in an SQL table. The source data cell for the SQL table is formatted as DATE. The SQL cell is formatted DATETIME. When the data is exported to a .csv the cell format is again DATE and a chart built in the .csv has the X-axis in sequential date order. When the same data is viewed in a chart on our GIS the X-axis dates are out of order making the plotted data impossible to decipher. Here is the code for the chart. Any assistance would be greatly appreciated. Thanks.
function makeChart(featureset) {
dojo.empty("chartDiv");
var dlg = dijit.byId('chartDialog');
// When resources are loaded and the DOM is ready....
dojo.ready(function () {
var data = featureset._jsonData.items;
var store = new dojo.data.ItemFileWriteStore({
data: {
identifier: "TestID",
label: "Parameter",
items: data
}
});
chart = new dojox.charting.DataChart("chartDiv", {
comparative: true
//scroll:stretchToFit
});
chart.setStore(store, { Parameter: '*' }, "Result");
//chart.addAxis("x", {title: "Sample#", titleOrientation: "away", majorLabels:true, minorTicks:true, minorLabels:true,
if (data.length > 2) {
chart.addAxis("x", {
title: "Collection Date",
titleOrientation: "away",
majorTicks: false,
majorLabels: true,
majorTickStep: 5,
minorTicks: false,
from: 0, to: (data.length + 0.5),
labelFunc: function (n) {
// I am assuming that your timestamp needs to be multiplied by 1000.
//var date = new Date(parseInt(data[n].CollectionDate) * 1000);
var date = data[n].CollectionDate;
return date;
}
});
}
chart.addAxis("y", { vertical: true });
var c = dojo.connect(chart, "onData", function () {
dojo.disconnect(c);
if (dijit.byId("chartlegend")) {
dijit.byId("chartlegend").destroy();
dojo.create("div", { id: "chartlegend" }, "chLegHd");
chlegend = new dojox.charting.widget.Legend({ chart: chart }, "chartlegend");
}
else {
chlegend = new dojox.charting.widget.Legend({ chart: chart }, "chartlegend");
chlegend.startup();
}
});
});
dlg.show();
}
I changed the source cell from datatype "datetime" to "date" and that made no difference in how the chart displays. It should show sequential dates i.e. 6/14/2015 7/01/2015 8/13/2015
but it is displaying thusly 8/13/2015 7/01/2015 6/14/2015
I am not very sure I understood your question very clearly. You want to display the date in sequential order retrieved from the DB. Here is what you can do:
You can create the labels array by the data base data retrieved.
var dBDateArray= ["array of dates from the DB in sequential order"];
var labelsArray = [];
for (var i = 0; i < dBDateArray.length; i++,) {
var obj = {};
obj.value = i;
obj.text = dbDateArray[i].name;
labelsArray.push(obj);
}
Set the labels in x Axis to this.labelsArray
this.chart1.addAxis("x", {
title: "Collection Date",
titleOrientation: "away",
labels:labelsArray
})

Not able to draw a Pie Chart with external csv file in HighCharts

I tried drawing a pie chart with external csv in HIGHCHARTS, but its not coming up properly , instead of labels name only slice is coming up.
I have created a fiddle for this pie fiddle, fiddle works for other chart options like 'bar','line' etc but fails for 'pie' option.
below is the graph option that is set in fiddle :
var options = {
chart: {
renderTo: 'container',
type: 'pie'
},
title: {
text: 'Vechicle Sales'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Sales'
}
},
series: []
};
Please let me know what would be reason behind this and what would be correct processing for csv file.
Thanks
Your current code takes each year as a series with each vechile type as an xaxis category. This is inapproapriate for a pie chart since it needs to be a single series of datapoints. So, we'll need to switch up the CSV parsing:
var seriesData = []; // this will be an array of point objects
var lines = csvData.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
if (lineNo === 0) { // first line contains point names
$.each(items, function(itemNo, item) {
//skip first item of first line
if (itemNo > 0) {
seriesData.push({
name: item,
y: 0
}); // create a data point object
}
});
} else {
$.each(items, function(itemNo, item) {
if (itemNo > 0) {
// find our data point and sum the values
seriesData[itemNo - 1]['y'] += parseFloat(item);
}
});
}
});
Finally add this data as a single series:
options.series.push({data: seriesData, name: 'Vehicle'});
Working example.

Categories

Resources