Create HighCharts-Column type from JSON - 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

Related

How to reset coordinates into an Ajax call after having initialized a map?

I inserted a map on my webpage by using the Leaflet library. What I want to do is to show a map zoomed on a specific region according to which city the user types into a text field.
I firstly initialized my map on my JS file:
function initMaps(){
map = L.map('leaflet').setView([0, 0], 13);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
'attribution': 'Map data © OpenStreetMap contributors'
}).addTo(map);
}
My javascript code also has an Ajax call.
What I want to do now is to reset the coordinates on the Ajax call.
I wrote the following:
var readCoordinates = function(){
$.ajax({
url: "https://nominatim.openstreetmap.org/search?q=" + encodeURIComponent($("#inlineFormInputCitta").val()) + "+Italy&format=geocodejson",
dataType: "json",
success: function (data) {
setTimeout(function () {
for (let i = 0; i < data.features.length; i++) {
let coordinate = data.features[i].geometry.coordinates;
console.log(coordinate);
map.setView(coordinate, 13);
console.log("ajax and for loop have been activated");
console.log(coordinate.geometry.coordinates);
};
$("#ristoranti").prop("disabled", false);
}, 1000);
}
});
};
The API I'm referring to in the URL is the following: https://nominatim.openstreetmap.org/search?q=Roma%20Italy&format=geocodejson
What I did is trying to reset the coordinates here: map.setView(coordinate, 13);
after having cycled the elements in the JSON object, see the following:
for (let i = 0; i < data.features.length; i++) {
let coordinate = data.features[i].geometry.coordinates;
I may display several coordinates in the console, see the following:
That's because in the JSON file I get through the API request there are several:
The result of this is the following map, which isn't zoomed anywhere:
Which coordinates should I take in order to display that specific region?
EDIT - - -
I changed the code because I'm trying to get a specific subobject, i.e. the one in the screen below (which has "type" = "city"):
The new snippet is the one below, where I add an if statement:
var readCoordinates = function(){
$.ajax({
url: "https://nominatim.openstreetmap.org/search?q=" + encodeURIComponent($("#inlineFormInputCitta").val()) + "+Italy&format=geocodejson",
dataType: "json",
success: function (data) {
setTimeout(function() {
for (let i = 0; i < data.features.length; i++) {
debugger;
let type = data.features[i].properties.geocoding.type;
if( $(type).val() === "city") {
let coordinate = data.features[i].geometry.coordinates;
let lng = coordinate[0];
let lat = coordinate[1];
map.setView([lng, lat], 13);
console.log("ajax and for loop have been activated");
console.log(coordinate);}
};
$("#ristoranti").prop("disabled", false);
}, 1000);
}
});
};
I'm doing the debugger and get many undefined values:
I would do something like that:
if (typeof data.features[0] !== 'undefined') {
let coordinate = data.features[0].geometry.coordinates;
var latlng = L.latLng(coordinate.reverse());
map.flyTo(latlng, 12)
}
Be sure to have something in your array
Get data from the first item since it should be the correct one in most case
Create a latlng with those coordinates. Be careful, sometime you need to reverse the array to have the correct position.
Use flyTo to have a smooth transition to your coordinates. 12 is the zoom level
You don't need to loop over the data since you need only one position. You can replace the for with that.
You're having two problems here:
The response from the Nominatim API is returning several search results, each of them in one GeoJSON Feature inside the response FeatureCollection. It's up to you to choose which search result you want to focus in the map (the first?), or let the user do so.
You're not aware that GeoJSON uses longitude-latitude (or x-y) coordinates, whereas Leaflet uses latitude-longitude (or y-x)

Google charts csv ignore first rows

I have the below google charts code which reads from a local CSV file on my web server.
This is great & works well.
However, the files I will be using when this goes 'live' will be auto-generated and have a header of 10 rows, which I want to ignore (data should not be read).
Is there any way to alter this script to ignore the first 10 lines of the CSV file?
<script type='text/javascript'>
// load the visualization library from Google and set a listener
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChartfromCSV);
function drawChartfromCSV(){
// grab the CSV
$.get("EDU_INST_SCHOOL_EXPENDTR_29_1.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// this view can select a subset of the data at a time
var view = new google.visualization.DataView(data);
view.setColumns([0,2]);
var options = {
title: "EDUCATIONAL INSTITUTIONS, SCHOOLS AND EXPENDITURE - INDIA",
hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
vAxis: {title: data.getColumnLabel(2), minValue: data.getColumnRange(2).min, maxValue: data.getColumnRange(2).max},
legend: 'none'
};
var chart = new google.visualization.LineChart(document.getElementById('csv2chart'));
chart.draw(view, options);
});
}
</script>
you could remove the elements from the array before creating the DataTable...
Array.prototype.shift() removes the first element from an array
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// remove unwanted headers
var removeRows = 10;
while (removeRows--) {
arrayData.shift();
}
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);

Highcharts : using JSON data as label to xaxis

I want to give name to xaxis as the data coming from JSON which will change dynamically
following is the code but it not labeling xaxis with the values store in key[obj] :
xAxis: {
categories: function(){
var data;
var obj = data[$("#host").val()].stats_vol.result.sectoutput;
for(var key in obj){
data.push({
name: key[obj],
categories : key[obj]
})
};
return data;
},
Can anyone please help to make this code work ??
Use setCategories method to update dynamically:
chart.xAxis[0].setCategories(categories);
Update
Here is working fiddle

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()

Update chart data in Dojo

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.