Google Charts - number/string issue on hAxis (Jquery ajax JSON data) - javascript

What I want to do
I am trying to show data from a MySQL database in a "ComboChart" using Google Charts. In order to do that I followed this tutorial, made some alterations and came up with the code as shown on the very bottom of this post.
Actual behavior
The data displays correctly. I do have to tell Google Charts however that the "year" is a number what throws it into continuous "mode". That leads to the year on the hAxis displaying with decimal places, in particular if I don't have data for all consecutive years. (i.e. 2,010.5)
Desired behavior
I want Google Charts to display the year as if it was a string and operate in discrete "mode".
What I think the problem is
I think the problem, I am encountering is mostly due to the fact that the year (to be shown on the hAxis) is a int(11) in the database and that the json that is provided by a controller also has the year as a number. To clarify below an example of what the json could look like:
[
{
"year_data": 2010,
"data_1": 125895,
"data_2": 25158.5
}
]
As I use the controller for a bunch of other stuff, I would preferably not make any alterations to it.
What I tried to fix it
I tried the bold move of just changing data.addColumn('number', 'year_data'); to data.addColumn('string', 'year_data');. It didn't work and I got a "type mismatch".
I tried to come up with a workaround mostly involving hAxis.showTextEvery: and some sort of row count. It didn't work but that might very well be due to my lack of experience/knowledge.
The question in one sentence
How can I turn the year data into a string in JavaScript or having Google Charts behave as if it was a string?
Code
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
<script src="/googlecharts/ajaxGetPost.js" type="text/javascript"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
function charts(data, ChartType) {
var jsonData = data;
google.load("visualization", "1", {
packages: ["corechart"],
callback: drawVisualization
});
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'year_data');
data.addColumn('number', 'Data 1');
data.addColumn('number', 'Data 2');
$.each(jsonData, function(i, jsonData) {
var year = jsonData.year_data;
var data1 = jsonData.data_1;
var data2 = jsonData.data_2;
data.addRows([
[year, data1, data2]
]);
});
var options = {
colorAxis: {
colors: ['#54C492', '#cc0000']
},
datalessRegionColor: '#dedede',
defaultColor: '#dedede',
legend: {
position: 'bottom',
alignment: 'start'
},
seriesType: 'bars',
series: {
1: {
type: 'line'
}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
}
$(document).ready(function() {
url = '/data/get';
ajax_data('GET', url, function(data) {
charts(data)
});
});
</script>

toString should work just fine, see following snippet...
var data = new google.visualization.DataTable();
data.addColumn('string', 'year_data');
data.addColumn('number', 'Data 1');
data.addColumn('number', 'Data 2');
$.each(jsonData, function(i, jsonData) {
var year = jsonData.year_data.toString();
var data1 = jsonData.data_1;
var data2 = jsonData.data_2;
data.addRows([
[year, data1, data2]
]);
});

Related

Google charts in aspnet

Hy, I want to generate a barchart in my pagemodel. The data is provided from my database.
public JsonResult GetData()
{
DataSet ds = GetViews();
List<Alliances> listAllianceforCharts = new List<Alliances>();
foreach(DataRow dr in ds.Tables[0].Rows)
{
listAllianceforCharts.Add(new Alliances
{
Al = Convert.ToString(dr["Al"]),
Ci = Convert.ToInt32(dr["Ci"]),
So = Convert.ToInt32(dr["So"]),
Ta = Convert.ToInt32(dr["Ta"]),
Ai = Convert.ToInt32(dr["Ai"]),
Sh = Convert.ToInt32(dr["Sh"])
});
}
return new JsonResult(listAllianceforCharts);
}
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
//Create our data table out of JSON data loaded from server.
var jsonData = $.ajax({
url: "/Index/GetData",
dataType: "json",
type: "POST"
});
var data = new google.visualization.DataTable();
data.addColumn('string', 'Al');
data.addColumn('number', 'Ci');
data.addColumn('number', 'So');
data.addColumn('number', 'Ta');
data.addColumn('number', 'Ai');
data.addColumn('number', 'Shs');
for (var i = 0; i < jsonData.length; i++) {
data.addRow([jsonData[i].Al, jsonData[i].Ci, jsonData[i].So, jsonData[i].Ta, jsonData[i].Ai, jsonData[i].Sh]);
};
var options = {
title: 'Mil Levels'
};
//Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
A chart without bars is created. I can see a data is returned to GetData. However, a chart is not being generated as expected. I wonder where I am doing wrong ? Is there a way for me to debug cshtml and see where did I go wrong >? How do I check if the page is getting data from pagemodel?
After you learn to use F12 debugging, you will find that jsonData variable does not accept the json data returned by GetData, so jsonData variable will not be able to add data in the loop.
What you need to understand is that when the execution of ajax is completed, that is, after entering the GetData method to return json data, if there is no error, the program will immediately enter the success method of ajax, if you want to get the data returned by GetData, you must get it in the success method of ajax instead of your current jsonData variable.
And it should be noted that if you are using the core 3.1 version, the field names of the passed json data will become camel case, that is, the fields such as Al, Ci will become ai, ci in js.
To prevent this behavior, you need to add the following code to ConfigureServices in startup.cs file:
services.AddMvc().AddJsonOptions(opts => opts.JsonSerializerOptions.PropertyNamingPolicy = null);
Here is the complete code:
Controller:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public JsonResult GetData()
{
DataSet ds = GetViews();
List<Alliances> listAllianceforCharts = new List<Alliances>();
foreach(DataRow dr in ds.Tables[0].Rows)
{
listAllianceforCharts.Add(new Alliances
{
Al = Convert.ToString(dr["Al"]),
Ci = Convert.ToInt32(dr["Ci"]),
So = Convert.ToInt32(dr["So"]),
Ta = Convert.ToInt32(dr["Ta"]),
Ai = Convert.ToInt32(dr["Ai"]),
Sh = Convert.ToInt32(dr["Sh"])
});
}
return new JsonResult(listAllianceforCharts);
}
}
Index View:
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<div id="chart_div"></div>
#section Scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
$.ajax({
url: "/Home/GetData", //url should be '/Controller/Action'
dataType: "json",
type: "POST",
success: MyChart
});
}
//here jsonData received the json data from GetData action
function MyChart(jsonData) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Al');
data.addColumn('number', 'Ci');
data.addColumn('number', 'So');
data.addColumn('number', 'Ta');
data.addColumn('number', 'Ai');
data.addColumn('number', 'Shs');
for (var i = 0; i < jsonData.length; i++) {
data.addRow([jsonData[i].Al, jsonData[i].Ci, jsonData[i].So, jsonData[i].Ta, jsonData[i].Ai, jsonData[i].Sh]);
};
var options = {
title: 'Mil Levels'
};
//Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
}
Here is the test result:

Googlecharts - Annotation Chart - First column must contain date or date time

I'm trying to plot an annotation chart with google chart. However, I get the error "First column must be date or datetime". If I were to change the chart type to be area or line for example, it works fine.
Here's the javascript section of the "View page source" content of the final HTML page on which I'm expecting a graph to be drawn
<script type="text/javascript">
google.load('visualization', '1', {'packages':['annotationchart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded FROM server.
var data_1 = google.visualization.arrayToDataTable([['ACTIVITY DATE TIME','ACTIVITY DURATION'],['2015-10-31 02:00:00',503],['2015-11-01 09:26:00',4],['2015-11-01 11:30:00',2],['2015-11-01 19:33:00',2],['2015-11-02 01:15:00',2],['2015-11-02 03:09:00',2],['2015-11-02 07:04:00',2],['2015-11-02 09:47:00',2],['2015-11-02 11:10:00',2]]);
var options = {
displayAnnotations: true
};
var chart_1 = new google.visualization.AnnotationChart(document.getElementById('plot1'));
chart_1.draw(data_1, options);
}
;
</script>
Could I request help please to figure out the problem? Is there any typecasting needed or anything whatsoever to get this working please?
UPDATED CODE
<script type="text/javascript">
google.load('visualization', '1', {'packages': ['annotationchart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded FROM server.
var data_1 = google.visualization.arrayToDataTable([<?php echo (implode(",", $chart_array_1)); ?>]);
var options = {
displayAnnotations: true
};
var chart_1 = new google.visualization.AnnotationChart(document.getElementById('plot1'));
chart_1.draw(data_1, options);
}
;
Yes, you have to cast those strings as Dates.
var data = [
['ACTIVITY DATE TIME', 'ACTIVITY DURATION'],
['2015-10-31 02:00:00', 503],
['2015-11-01 09:26:00', 4],
['2015-11-01 11:30:00', 2],
['2015-11-01 19:33:00', 2],
['2015-11-02 01:15:00', 2],
['2015-11-02 03:09:00', 2],
['2015-11-02 07:04:00', 2],
['2015-11-02 09:47:00', 2],
['2015-11-02 11:10:00', 2]
];
// or var data = [<?php echo (implode(",", $chart_array_1)); ?>]
for(var i = 1; i < data.length; i++)
data[i][0] = new Date(data[i][0]); // converting strings to Dates
google.load('visualization', '1', {
'packages': ['annotationchart']
});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded FROM server.
var data_1 = google.visualization.arrayToDataTable(data);
var options = {
displayAnnotations: true
};
var chart_1 = new google.visualization.AnnotationChart(document.getElementById('plot1'));
chart_1.draw(data_1, options);
};
JSFiddle

Google Charts Error 'Not An Array' on Ajax Update

I have a simple Google chart which renders fine with the following data on initial page load:
[['days','AA','BB'], ['270',15,15],['240',19,19],['210',23,23],['180',31,31],['150',34,34],['120',47,47],['90',57,57],['60',71,71],['30',81,81],['0',94,94]]
When I attempt to refresh it via an Ajax call which currently returns exactly the same data I get an error 'not an array'.
This is my initial function which draws the chart correctly:
<script type="text/javascript">
var chart;
var options;
google.load("visualization", "1.1", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var dataArray = ${initialChartData};
var data = google.visualization.arrayToDataTable(dataArray);
options = {
chart: {
title: 'Bookings by Days Before Holiday Start Date',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, options);
}
</script>
My Ajax Handler:
$('#dataAnalysisForm').ajaxForm({
success : function(responseText) {
//error here as responseText 'is not an array'
//it is the same String returned via Ajax as was
//used to render the initial chart
//the initial data was written to the page server side.
var data = google.visualization.arrayToDataTable(responseText);
chart.draw(data, options);
}
});
What needs to change in the above code to make this work on initial page load and update correctly on Ajax response?
Just do this again:
var chart = new google.visualization.Bar(document.getElementById('columnchart_material'));
chart.draw(data, options);
If your data is already in the right format there is no need to convert it, so you can use chart.draw(responseText, options)

Google Visualization-Invalid row type for row 0

I have to visualize url json data on a pie chart with google visualization. My code seems to be as it has to be for the purpose, but I am getting an 'Invalid row type for row 0' error in the console. Is there any problem with the format of the data? If there is anyone that could help, that would be much appreciated. Here is my code:
PHP:
<?php
$json = file_get_contents('http://data.police.uk/api/crimes-street/all-crime?lat=52.629729&lng=-1.131592&date=2013-01');
$json = str_replace("\xe2\x80\xa8", '\\u2028', $json);
$json = str_replace("\xe2\x80\xa9", '\\u2029', $json);
echo $json;
?>
JavaScript:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType:"json",
async: false
}).responseText;
//Create an array of the JSON data and then create our data table out of JSON data loaded from server.
var array = JSON.parse(jsonData);
var dataTableData = new google.visualization.arrayToDataTable(array);
var table = google.visualization.DataTable(dataTableData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
Thank you.
The JSON does not represent data which can be transformed to a 2-dimensional array google.visualization.DataTable can simply not interpret this. Each item contains complex subitems like location and outcome_status.
You must include columns - arrayToDataTable is very specific about that.
The most important : How on earth do you imagine those data to be presented as a piechart? There is only one specfic number-field at first level, location_subtype. You cannot produce a piechart based on various strings.
But, you can sanitize the data and show them as a google.visualization.Table :
First create a DataTable with some columns :
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');
convert your jsonData to JSON
var json=JSON.parse(jsonData);
sanitize and insert the data. Here I just delete the location and outcome_status subitems, but you may want to extract values from those subitems instead and insert them as columns in the dataTable :
for (var i=0;i<json.length;i++) {
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);
}
finally create the Table() :
var chart = new google.visualization.Table(document.getElementById('chart_div'));
chart.draw(dataTable, {width: 1000, height: 300});
the result will look like this :
update
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string','category');
dataTable.addColumn('string','context');
dataTable.addColumn('number','id');
dataTable.addColumn('string','location_subtype');
dataTable.addColumn('string','location_type');
dataTable.addColumn('string','month');
dataTable.addColumn('string','persistent_id');
dataTable.addColumn('string','street name');
dataTable.addColumn('string','outcome status');
json=JSON.parse(jsonData);
for (var i=0;i<json.length;i++) {
var row = [];
row.push(json[i].category);
row.push(json[i].context);
row.push(json[i].id);
row.push(json[i].location_subtype);
row.push(json[i].location_type);
row.push(json[i].month);
row.push(json[i].persistent_id);
row.push(json[i].location.street.name);
row.push(json[i].outcome_status ? json[i].outcome_status.category : "null");
dataTable.addRow(row);
}

Google Charts - graph not displaying

This bit of code is meant to display a chart, but doesn't:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
data.addcColumn('string', 'Type');
data.addColumn('number', 'Job Registration');
data.addRows([
<?php foreach ($chart_result as $result) {
echo $result;
}?>
]);
var options = {
title: 'Job Registration by Type',
hAxis: {title: '', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('visualization'));
chart.draw(data, options);
}
When I submit the form and view page source, this is the result for data.addRows:
data.addRows([
[' Engineer',1],['Assistant',1],['Developer',4],[' Ninja!',1],['Web Application Developer',1],
]);
This looks right to me, but this is the first time I've used Google Analytics (or JavaScript...) and I was following an example of an existing chart rather closely, so maybe it's not right at all. Any ideas why this might not be working?
Cheers
You have two issues.
The first is that you don't define the data.
Add the following line to your code:
var data = new google.visualization.DataTable();
The second is a silly syntax error:
data.addcColumn('string', 'Type');
Should be:
data.addColumn('string', 'Type');
And with those, like magic, it works:
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Type');
data.addColumn('number', 'Job Registration');
data.addRows([
[' Engineer',1],
['Assistant',1],
['Developer',4],
[' Ninja!',1],
['Web Application Developer',1],
]);
var options = {
title: 'Job Registration by Type',
hAxis: {title: '', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('visualization'));
chart.draw(data, options);
}

Categories