How to use Google Chart with data from a csv - javascript

I have a csv file that looks like that:
week,value1,value2
1,2,3
2,7,9
I would like to plot a stacked graph of it using google chart (week being my x (horizontal) values and values1 and values2 being the two set of y's). Unfortunately, I didn't find any easy way to do so. That probably relates to me being a complete noob in js.
Is there any simple way to do that?

The jquery-csv library provides the ability to translate a string of csv into an array to be used by google.visualization.arrayToDataTable() (their example here). To make this work, add jquery.csv.js to your server (in the example below I assume it is in the same folder as your HTML) and link to it in your <head>. The following is a simple script you can add to your <head> to get started. I assume a scatter chart, but this process works for any of the charts here. You will also need a <div> with id="chart" for this to work.
// load the visualization library from Google and set a listener
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
// this has to be a global function
function drawChart() {
// grab the CSV
$.get("example.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,1]);
// set chart options
var options = {
title: "A Chart from a CSV!",
hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
legend: 'none'
};
// create the chart object and draw it
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(view, options);
});
}

I have been searching for a while, and found the solution on a Google group discussion.
https://groups.google.com/forum/#!topic/google-visualization-api/cnXYDr411tQ
I have tried it, and it works!
In this case, we have to specify the header types of our csv file.
var queryOptions = {
csvColumns: ['number', 'number', 'number' /* Or whatever the columns in the CSV file are */],
csvHasHeader: true /* This should be false if your CSV file doesn't have a header */
}
/* csvUrl is the path to your csv */
var query = new google.visualization.Query(csvUrl, queryOptions);
query.send(handleQueryResponse);
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var chart = new google.visualization.ColumnChart(document.getElementById('your div'));
// Draw your chart with the data table here.
// chart.draw(view, queryOptions);
}

What server side scripting language are you working in (php, asp)?
One option could be to import the data from a spreadsheet saved in Google Drive, see here for a PHP based example of saving and extracting data from Google Docs. This would then enable you to update the spreadsheet and the chart would automatically plot the new data.

Related

How to display Dynamic Object Arrays into chart using Anychart.js

What i am trying to do is i want to display a chart based on my dynamic data i used Angular ForEach to loop through all my objects array see my code below:
var parse = JSON.parse(jsondata);
angular.forEach(parse, function (value, key) {
var dataSet = anychart.data.set(value);
var chart = anychart.column();
var series = chart.column(value);
chart.title("Data Sets: Array of Objects");
chart.container("container");
chart.draw();
});
it correctly display the count of my chart but the data of each object array is not showing up see picture below
but if put a static data like this :
var data = [
{x:"January", value: 12000},
{x:"February", value: 15000},
{x:"March", value: 16000},
{x:"April", value: 14000},
{x:"May", value: 10000}
];
the chart displays correctly.
can anyone help me with this ? any help will greatly appreciated.
Everything depends on the value content inside the loop. You are applying the value to the series and dataSet as well.
If you are using dataSet, you should apply the value to the dataSet, map the data, then apply the mapping to the series. Like this:
var dataSet = anychart.data.set(value);
var mapping = dataSet.mapAs({'x': 0, 'value': 1}); // for example
var chart = anychart.column();
var series = chart.column(dataSet);
The mapping depends on your data. If the value includes ready-to-use data that matches the default mapping you can apply it directly to the series.
Can you share the value content?
The chart can work with dynamic data. All you need is to apply new data to the existing dataSet, like this:
dataSet.data(newData);
And that's it! There's no need to recreate chart/series/dataSet.

Drawing multiple Google Charts on a single page?

Basically my JavaScript receives data like this: year = {month1, ...., month12}. Each month stores data for 3 graphs. month1 = {graph1_data,..., graph3_data}
I wish to draw charts for all of them using Google Charts. So that makes it 12 * 3 = 36 charts. I have written the following code logic. But it fails to work.
for ( month in year )
{
google.charts.setOnLoadCallback(function(){
// draw graph1
var data = new google.visualization.DataTable();
// code
// code
// data.addColumn()
// data.addColumn()
data.addRows(data_table);
var options = {title: month, height:100};
var chart = new google.visualization.ColumnChart(
document.querySelector('#'+month+' .graph1'));
chart.draw(data, options);
});
google.charts.setOnLoadCallback(function(){
// draw graph2
google.charts.setOnLoadCallback(function(){
var data = new google.visualization.DataTable();
// code
// code
// data.addColumn()
// data.addColumn()
data.addRows(data_table);
var options = {title: month, height:100};
var chart = new google.visualization.ColumnChart(
document.querySelector('#'+month+' .graph2'));
chart.draw(data, options);
});
google.charts.setOnLoadCallback(function(){
// draw graph3
google.charts.setOnLoadCallback(function(){
var data = new google.visualization.DataTable();
// code
// code
// data.addColumn()
// data.addColumn()
data.addRows(data_table);
var options = {title: month, height:100};
var chart = new google.visualization.ColumnChart(
document.querySelector('#'+month+' .graph3));
chart.draw(data, options);
});
}
It draws 3 charts for month12. Now why does this happen? Does this mean I must call setOnLoadCallback 36 times? Isn't there any alternative way?
Edit
It looks like once Google Chart API is loaded, the callbacks in all the setOnLoadCallbacks is called once. Which probably explains why I get only one graph, since at the time of execution of the function, the loop would have stopped at month12.
So I finally figured out what is going wrong here.
You are only registering a callback with the Google Charts API, not actually calling it in your for(month in year) loop. The callback is called (as you can guess) when relevant resources have finished loading and the Charts API can start drawing. Unfortunately your globally defined var month is now equal to month12. This is the state after your for loop completes:
month = year.month12;
callback_for_graph_1 = <anonymous function 1>
callback_for_graph_2 = <anonymous function 2>
callback_for_graph_3 = <anonymous function 3>
As you can imagine, now when the callbacks, they are each called only once, with month = year.month12. Hence the three graphs, all with month12 data.
So how do you fix this? Here's how:
Initialise three callbacks only once. No need to keep them anonymous.
google.charts.setOnLoadCallback(callbackForGraph1);
google.charts.setOnLoadCallback(callbackForGraph2);
google.charts.setOnLoadCallback(callbackForGraph3);
function callbackForGraph1 {
// do your thing
}
function callbackForGraph2 {
// do your thing
}
function callbackForGraph3 {
// do your thing
}
Iterate over all the months inside each callback, and create a new Chart instance for each month. Also draw it.
function callbackForGraph1() {
for(month in year) {
// draw graph1
var data = new google.visualization.DataTable();
// code
// code
// data.addColumn()
// data.addColumn()
data.addRows(data_table);
var options = {title: month, height:100};
// this is your Chart instance ->
var chart = new google.visualization.ColumnChart(document.querySelector('#'+month+' .graph1'));
// draw it!
chart.draw(data, options);
}
}
Profit?
You might also want to store each Chart instance in a array or dictionary style object. That way you can later make changes to your plots, instead of having to regenerate and replace them.
OLD ANSWER: This happens because you draw the chart for graph_1 in the same HTML element for each month. So the chart for graph_1[month2] overwrites the chart for graph_1[month1]. Since graph_1[month12] is the last data to be processed, you get the chart for month12. Likewise occurs for graph_2 and graph_3.
What you can try is appending a new svg or vml element to your HTML document every time the plotting callback is called. This can be done from within the callback itself. That way you get a new chart for every month for every graph.

Google Charts - No data available - Able to display a blank chart?

How can I still have Google Charts still show a line chart if my data array looks like this?
[['Date','Line']]
i.e. just the axis are defined. Most of my charts have data imported but some have nil on the data. I would like to display a blank chart. With data above I get an error message instead of a chart.
Here is code in my view
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable(#{#visiting_spread_movement_array});
var options = {
title: 'Point Spread Movements for #{#event.visiting_team}'
};
var chart = new google.visualization.LineChart(document.getElementById('show-spread-visiting'));
chart.draw(data, options);
}
Well, to draw the chart you need at least one data point. To archieve this, you could use this workaround:
var data = google.visualization.arrayToDataTable([
[{
f: 'Date',
type: 'date' // wont work whithout this
}, {
f: 'Line',
type: 'number' // wont work whithout this
}], ]);
var options = {
title: 'Company Performance'
};
if (data.getNumberOfRows() == 0) { // if you have no data, add a data point and make the series transparent
data.addRow([new Date(), 0])
options.series = {
0: {
color: 'transparent'
}
}
}
Full fiddle: http://jsfiddle.net/qaLgh955/

I need to only show two rows on my Google Charts table

I need to only show two rows on my Google Charts table. I currently have the following that is being called:
function drawTable() {
var jsonData = '#Html.Raw(ViewData["totalsTable"])';
var table;
var data;
var options;
data = new google.visualization.DataTable(jsonData);
table = new google.visualization.Table(document.getElementById('table_div'));
options = { 'pageSize': 2 };
table.draw(data, options);
}
The problem being that this is showing a table with all of the values from the DataTable. I just want to show the first two rows. options = { 'pageSize': 2 } is supposed to achieve this. I'm not sure what I'm doing wrong. Thanks!
Paging is disabled by default; you have to enable it by setting the page option to 'enable':
options = {
page: 'enable',
pageSize: 2
};
[Edit - instructions on how to display a specific set of rows only, without paging]
If you want to display a specific set of rows, you can use a DataView to restrict the rows displayed:
var view = new google.visualization.DataView(data);
// the #setRows method takes an array of row indices as an argument
// display the first two rows only (indices 0 and 1):
view.setRows([0, 1]);
// use the view to draw your table instead of the DataTable:
table.draw(view, options);
Incidentally, you don't have to put quotes around the output of #Html.Raw(ViewData["totalsTable"]) if it is valid JSON. Leaving them out is moderately more efficient, as the Visualization API won't have to convert your JSON into a javascript object:
var jsonData = #Html.Raw(ViewData["totalsTable"]);
For the 'pageSize' option to work, paging must be enabled.
options = { 'pageSize': 2 };
Based on your post, I think you need the setColumns method. Documentation here:
https://developers.google.com/chart/interactive/docs/reference?hl=ja#DataView_setColumns

Error "Row given with size different than 2" when using Google Visualization

I have a template that uses jQuery/AJAX to pull some data. Getting the data isn't an issue, but I can't seem to use it in a way that GoogleVis wants. The line causing problems for me is mapdata.addRows([gapidata]);. It seems there's an issue with the array but I'm not sure how to fix it. Any help is greatly appreciated!
The jQuery/AJAX I'm using:
var gapidata = new Array();
$.ajax({
url: "inc/index.gapi.inc.php",
cache: false,
dataType: "text",
success: function(html){
gapidata = html;
}
});
The data I get from the AJAX call:
['Korea, Republic of', 50],['Japan', 38]
The code I use to display the data:
// Geo Map Chart
var mapWidth = Math.round(((screenWidth / 12) * 10) * 0.8);
var mapHeight = Math.round(mapWidth * 0.5);
$('#dashboard-visit-map').width(mapWidth*1.1);
$('#dashboard-visit-map').height(mapHeight*1.1);
var mapdata = new google.visualization.DataTable();
mapdata.addColumn('string','Country');
mapdata.addColumn('number','IPs Listed');
mapdata.addRows([gapidata]);
var geochart = new google.visualization.GeoChart(document.getElementById('dashboard-visit-map'));
geochart.draw(mapdata, {width: mapWidth, height: mapHeight,backgroundColor: { fill:'transparent' }});
Currently the map doesn't populate with any data. If I remove the brackets around gapidata I receive the following error on my JavaScript console:
Uncaught Error: Row given with size different than 2 (the number of columns in the table).
I just normalized my data frame before calling the rendering function; it worked fine for me.
Normalizes data frame:
data <- as.data.frame.matrix(data)
I had same problem.
the solution is.
re-initialize your chat visulization object mapdata for each ajax request;
i.e.
// before calling ajax
mapdata = null;
mapdata = new google.visualization.DataTable();
// ajax codeenter code here
I know that my answer may not be related to your code format, but it may help other people, as it is for the same issue. If you make an AJAX call to json data and then you loop over them, then you must be sure that you include all the columns of the JSON data in the addCollumn() method. If you don't want to include all of the data, then you should use the delete command in the for-loop like this:
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string','category');
dataTable.addColumn('string','context');
dataTable.addColumn('string','id');
dataTable.addColumn('number','location_subtype');
dataTable.addColumn('string','location_type');
dataTable.addColumn('string','month');
dataTable.addColumn('string','persistent_id');
var json=JSON.parse(jsonData);
for (var i=0;i<json.length;i++) {
//Deleted rows
delete json[i].location;
delete json[i].outcome_status;
var row = [];
for (var item in json[i]) {
row.push(json[i][item]);
}
dataTable.addRow(row);
}
If you don't delete them, then it is assumed that you need those data and the table takes an unexpected size by default. Therefore, you will encounter the error in the console. I hope that this may be helpful for some people. Cheers

Categories