Update chart data in Dojo - json

I have the below function which reads JSON data and puts it on a chart. I would like to automatically update the chart data every say 10 seconds.
I have looked at dojo/timing and chart.updateSeries and I believe the combination of the two would do the trick but I'm not sure how I can implement this. Any help would be greatly appreciated.
function(xhr, json, arrayUtil, number, Chart, theme) {
var def = xhr.get({
url: "cpuusage.json",
handleAs: "json"
});
def.then(function(res){
var chartData = [];
arrayUtil.forEach(res.chart, function(chart){
chartData[chart.x] = number.parse(chart.y);
});
//Draw chart
var chart = new Chart("chartNode2");
chart.setTheme(theme);
chart.addPlot("default", {
type: "Columns",
markers: true,
gap: 5
});
chart.addAxis("x");
chart.addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major" });
chart.addSeries("Monthly Sales",chartData);
chart.render();
}, function(err){
console.error("Failed to load JSON data");
});
}

Try something like that:
var interval = setInterval(function(){
// let's get new data
xhr.get({
url: "cpuusage.json",
handleAs: "json"
}).then(function(res){
// data prep step - just like before
var chartData = [];
arrayUtil.forEach(res.chart, function(chart){
chartData[chart.x] = number.parse(chart.y);
});
// update chart (it was created before)
chart.updateSeries("Monthly Sales", chartData);
chart.render();
}, function(err){
console.error("Failed to load updated JSON data");
});
}, 10000); // 10s
...
// when we want to cancel updates
clearInterval(interval);
Sorry, I didn't use dojo/timing, I don't see much reason for it here, and prefer simple ways to do simple things.

Related

Displaying JSON data into a pie chart using chart.js

my first time using chart.js and am running into a small bug that I can't seem to work around it. Below is my code, however, its just displaying the labels but not rendering the pie chart itself.
Am following samples from the chart.js documentation here http://www.chartjs.org/docs/#doughnut-pie-chart-example-usage
Your help will be appreciated.
<canvas id="myChart" width="200" height="200"></canvas>
$(document).ready(function () {
/*
-> #47A508 = green (wins)
-> #ff6a00 = orange (losses)
-> #ffd800 = yellow (draws)
*/
var DataArray = [];
var ctx = document.getElementById("myChart");
$.ajax({
url: 'http://api.football-data.org/v1/competitions/426/leagueTable',
dataType: 'json',
type: 'GET',
}).done(function (result) {
$.each(result.standing, function () {
var name = "Manchester United FC";
if (this.teamName == name) {
DataArray.push([this.wins, this.losses, this.draws]);
}
});
var myChart = new Chart(ctx, {
type: 'pie',
data: {
label: 'Manchester United Current Form',
labels: [
"Wins",
"Losses",
"Draws"
],
datasets: [
{
data: DataArray,
backgroundColor: [
"#47A508",
"#ff6a00",
"#ffd800"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
},
options: { responsive: true }
});
});
}
maybe it is because of the jquery each, it fills DataArray async and the array is not ready, when you want to use it as chart data.
Change the $.each to a simple js for loop
for(var i = 0; i < result.standing; i++){
var name = "Manchester United FC";
var team = result.standing[i];
if (team.teamName == name) {
DataArray.push(team.wins, team.losses, team.draws);
}
}
try callbacks for you ajax or do the below (which is a dirty solution):
$.ajax({
url: 'http://api.football-data.org/v1/competitions/426/leagueTable',
dataType: 'json',
cache: false, //add this
async: false, //add this
type: 'GET',
Also
the result of your ajax could be returned using the below code instead of using an array.
jQuery.parseJSON(result);
The issue lies in your DataArray. The way it is implemented is is an array with a single entry. Which is another array itself.
[[<wins>, <losses>, <draws>]]
instead of
[<wins>, <losses>, <draws>]
That is because you instantiate an array and then push into it an array object.
To fix this try using the following function:
(...)
$.each(result.standing, function () {
var name = "Manchester United FC";
if (this.teamName == name) {
DataArray = ([this.wins, this.losses, this.draws]);
console.log("This team name");
}
});
(...)
I got this solved, well sadly, with no magic at all to brag about. There was nothing wrong with the code initially, however, it was a problem with the DOM rendering performance. Thank you #alwaysVBNET and #Aniko Litvanyi for your inputs as well.
This link helped me out, hopefully it does to someone out there.

Create HighCharts-Column type from JSON

I am trying to create a column type highchart using data from json in the following format:
[{"id":7,"dateV":"2015-11-16","count":10},{"id":6,"dateV":"2015-11-15","count":3},{"id":5,"dateV":"2015-11-14","count":15},{"id":4,"dateV":"2015-11-13","count":10},{"id":3,"dateV":"2015-11-12","count":6},{"id":2,"dateV":"2015-11-11","count":8},{"id":1,"dateV":"2015-11-10","count":5}]
X axis should show the date values and the Y axis should show the count. Somehow i am not able to transform this JSON in the format required.
Here is my code.
<script type="text/javascript">
$('#myButton').click(function() {
var options = {
chart: {
renderTo: 'chartContainerDiv',
type: 'column'
},
series: [{}]
};
var url = "callToControllerURL";
$.getJSON(url, function(data) {
console.log(JSON.stringify(data));
options.series[0].data = JSON.stringify(data);
var chart = new Highcharts.Chart(options);
});
});
</script>
console log shows the JSON in format specified above. I am guessing i have to form the x and y axis values from the options array. How do i do it?
You need to iterate over the json data and create category data and series by pushing values.
var jsonData = [{"id":7,"dateV":"2015-11-16","count":10},{"id":6,"dateV":"2015-11-15","count":3},{"id":5,"dateV":"2015-11-14","count":15},{"id":4,"dateV":"2015-11-13","count":10},{"id":3,"dateV":"2015-11-12","count":6},{"id":2,"dateV":"2015-11-11","count":8},{"id":1,"dateV":"2015-11-10","count":5}];
var categoryData= [];
var seriesData= [];
$.each(jsonData, function(i,item){
seriesData.push(jsonData[i].count);
categoryData.push(jsonData[i].dateV);
console.log("seriesData"+JSON.stringify(seriesData));
});
See Working demo with your json here

Extjs 5 Lock on grid columns

I wanted to lock the first few columns of my grid and provide horizontal scrolling for the rest of the columns. Am making use of column header gruping.
I have used locked : true property and set a static width to those columns. Yet nothing is happening. I have checked all possible docs. Not sure where the mistake lies. Could someone please help me?
Code is as given below
View.js'
Ext.define('MyModel.view.graphPanel', {
extend: 'Ext.grid.Panel',
layout:'border',
alias: 'widget.graphPanel',
name:'graphPanel',
title: 'Tests',
store: 'MyModel.store.settingStore',
viewConfig: {
stripeRows: true
},
columnLines: true,
split:true,
frame: true
});
Controller.js
Ext.define('MyModel.controller.myController', {
extend:'Ext.app.Controller',
models:['MyModel.model.settingModel'],
stores:['MyModel.store.settingStore'],
init: function() {
Ext.Ajax.request({
url: 'Sample.xml',
success: function(response, opts) {
var txt = response.responseText;
parser=new DOMParser();
xmlDoc=parser.parseFromString(txt,"text/xml");
var columnArr = [];
var outercolumnarr = [];
var fieldArr = [];
modelfieldArr = [];
completeDataArr=[];
//This builds all locked set of columns
var headerArr = xmlDoc.getElementsByTagName('HEADER1');
Ext.each(headerArr[0].getElementsByTagName('HEADER2'), function(header, index) {
columnArr.push({
text: header.getAttribute('TEXT'),
dataIndex: header.getAttribute('DATAINDEX'),
locked:true,
width:100,
forceFit: true
});
});
outercolumnarr.push({
text:"General data",
width:400,
columns:columnArr,
locked:true
});
//Building scrollable columns
var days = ['Sun','Mon',Tue'];
Ext.each(days, function(day, index) {
columnArr = [];
Ext.each(headerArr[1].getElementsByTagName('HEADER2'), function(innerHeader, index) {
columnArr.push({
text: innerHeader.getAttribute('TEXT'),
dataIndex: innerHeader.getAttribute('DATAINDEX')
});
});
outercolumnarr.push({
text:day,
columns:columnArr,
});
});
//outercolumnarr contains the final column array
//Similarly build data array, model and field array for stores and models.
var store = Ext.data.StoreManager.lookup('MyModel.store.settingStore');
store.setFields(modelfieldArr);
store.setData(completeDataArr);
//Reconfigure the grid
var gridview = Ext.ComponentQuery.query('graphPanel')[0];
gridview.reconfigure(store,outercolumnarr);
}
});
}
});
Because you are adding columns using reconfigure, enableLocking is not enabled implicitly. You must enable it manually. You may enable it in MyModel.view.graphPanel definition, but probably you'll also need to add empty column definition (columns: []), because I've had error from framework without that.
Working sample: http://jsfiddle.net/nj4nk/11/

How to get multiple data series into Highcharts

The following code works:
var options1 = {
chart: {
renderTo: 'container1'
},
series: [{}]
};
$.getJSON('tokyo.jsn', function(data){
options1.series[0].data = data;
var chart = new Highcharts.Chart(options1);
});
I want to be able to add a number of data series, so I am trying to take the reference to ‘new Highcharts’ out of the getJSON, but I don't seem to get it right. This following code does not work:
$.getJSON('tokyo.jsn', function(data){
options1.series[0].data = data;
});
var chart = new Highcharts.Chart(options1);
I have also tried tackling it a different way but again the following code does not work:
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container1'
},
series: [{}]
});
$.getJSON('tokyo.jsn', function(data){
chart1.series[0].data = data;
});
Can anyone point me in the correct direction. I need to be able to support multiple data series by doing a second getJSON call like the following:
$.getJSON('sydney.jsn', function(data){
options1.series[1].data = data;
});
The JSON code I'm using is as follows:
[ 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 ]
Thanks
$.getJSON is an asynchronous request. Once you receive the data, then you can pass it to Highcharts, thus you have to call that code from within the callback function of $.getJSON().
Try this, use a helper function to process your data and draw the chart, see drawChart() below:
var options1 = {
chart: {
renderTo: 'container1'
},
series: []
};
var drawChart = function(data, name) {
// 'series' is an array of objects with keys:
// - 'name' (string)
// - 'data' (array)
var newSeriesData = {
name: name,
data: data
};
// Add the new data to the series array
options1.series.push(newSeriesData);
// If you want to remove old series data, you can do that here too
// Render the chart
var chart = new Highcharts.Chart(options1);
};
$.getJSON('tokyo.jsn', function(data){
drawChart(data, 'Tokyo');
});
$.getJSON('sydney.jsn', function(data){
drawChart(data, 'Sydney');
});
See fiddle: http://jsfiddle.net/amyamy86/pUM7s/
You can use solution used by Highcharts in that example: http://www.highcharts.com/stock/demo/compare
Or first create empty chart, without any series, and then use addSeries() function in each callback, see: http://api.highcharts.com/highcharts#Chart.addSeries()

How to update mulitple series in Highcharts simultaneously

I'm using Highcharts to graph multiple series on a single chart. The series data is read from a file containing the data in JSON format. The file will get updated with new data every few seconds and I've a function to re-read the file.
Here's the data in the file:
[{"name": "series1", "data": [[1,109],[2,313],[3,192]]},{"name": "series2", "data": [[1,111],[2,112],[3,777]]}]
The code I've got is:
//Read JSON data from a file
$(function () {
function getSeriesData(file) {
var data = null;
$.ajax({
async: false,
cache: false,
url: file,
method: 'GET',
dataType: 'json',
success: function(datasets){
data = datasets;
},
error: function(error,text,http){
alert("Error retrieving " + url + ".");
}
});
return data;
}
var graphData = getSeriesData("seriesData.json");
var graphOptions = {
chart: {
type: 'line',
renderTo: "container",
},
series: graphData
};
var graph = new Highcharts.Chart(graphOptions);
var updateInterval = 1000 * 5; // 5 seconds
function update() {
//Need to refresh series data here.
//Something like:
graph.series = getSeriesData("series.json");
graph.redraw();
setTimeout(update, updateInterval);
}
update();});
Looking at the documentation there doesn't seem to be a way to set all the series data again at the same time using my getSeriesData function to reread the file. Most of the examples here and elsewhere have ways to set the data for individual series by going through the series[] array. But thats not what I'm looking for. Maybe I'll have to redo the code to do it that way but thought I'd check here first in the hope that there's an easier way! Thanks in advance.
I can't see a way to do all series with one call. I can see two options.
If the number of series is fixed, you can iterate over them calling series.setData with the redraw option set to false, and then call redraw().
If the number of series may change, you will have to iterate over the chart.series calling remove, and then iterate over your series array calling chart.addSeries.