Google Table Chart: Date Format - google-visualization

I am returning data to the chart using JSON.
I've managed to format the date for the x-axiz of the Line Chart, using;
var options = {
hAxis: {
format: ' dd MMM yy'
},
}
But I need help doing the same for a Table Chart where one of the columns should be of date format.
At the moment it is displaying "/Date(1372761341103)/"
How do I format this option?
As I understand it, the "options" variable setting is not available for the Table Chart.
Also, when I add my columns, setting my 'Date' column's data type to 'date' doesn't work...no chart is returned.
This is my code currently:
function drawChart3() {
$.get('/MyMall/GetAdRunData', {},
function (data) {
/* Add data */
var tdata = new google.visualization.DataTable()
tdata.addColumn('number', 'Id');
tdata.addColumn('string','Date');
tdata.addColumn('number', 'Opens');
for (var i = 0; i < data.length; i++) {
tdata.addRow([data[i].Id, data[i].Date, data[i].Opens]);
}
/* Draw chart */
var chart = new google.visualization.Table(document.getElementById('chart_adRun'));
//var formatter = new google.visualization.ColorFormat();
//var monthYearFormatter = new google.visualization.DateFormat({ pattern: "MMM yyyy" });
monthYearFormatter.format(tdata, 0);
formatter.addRange(-1, 1, 'white', 'orange');
formatter.addRange(0, 2, 'red', '#33ff33');
formatter.addRange(1, 10, 'red', 'pink');
formatter.format(tdata, 1); // Apply formatter to second column
chart.draw(tdata, { allowHtml: true, showRowNumber: false });
}
)
}

I solved it this way...
for (var i = 0; i < data.length; i++) {
var date = new Date(parseInt(data[i].Date.substr(6)));
tdata.addRow([data[i].Id, date, data[i].Opens]);
}

Related

Type Mismatch error when altering a google.visualization.DataTable() column value even after explicitly changing its data type

I have a datatable that's being returned by google.visualization.data.group()
var aggData = google.visualization.data.group(
view,
[0],
aggColumns
);
I want to set several columns to be of type string with a tooltip role, and converting values in them to an html string
for (var col=2; col < aggData.getNumberOfColumns(); col = col + 2){
aggData.setColumnProperties(col,{'type':'string', 'role':'tooltip', 'p':{'html':true}});
//looking to see if the column type was actually changed
console.log('Column '+col+' type: ' + aggData.getColumnProperty(col, 'type'))
for (var row = 0; row < aggData.getNumberOfRows(); row = row + 1){
aggData.setValue(row, col, getHTML(aggData.getValue(row, col)))
}
}
function getHTML(count) {;
return 'Projects Completed: <b>' + count + '</b>';
}
I checked the column data type in the log and it does return a string but when i set the value to a string it throws a type mismatch error.
Column 2 type: string
Uncaught Error: Type mismatch. Value Projects Completed: <b>2</b> does not match type number in column index 2
I also tried setting the column type using setColumnProperty() method but it's the same result. What am I missing?
================================================================================================
Below is a snippet of the larger script if needed
Sample input data looks like
"Oct 1, 2019, 12:00:00 AM",Team C,68
"Sep 23, 2019, 12:00:00 AM",Team C,68
"Nov 29, 2019, 12:00:00 AM",Team C,87
"Dec 31, 2019, 12:00:00 AM",Team C,62
....................................
"Nov 21, 2018, 12:00:00 AM",Team A,79
"Dec 29, 2018, 12:00:00 AM",Team A,58
"Nov 15, 2018, 12:00:00 AM",Team B,96
"Dec 29, 2018, 12:00:00 AM",Team B,77
The data is being read into a data table
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Year');
data.addColumn('string', 'Team');
data.addColumn('number', 'Total Score');
var groupData = google.visualization.data.group(
data,
[
{
column: 0,
modifier: getYear,
type: 'number'
},
1
],
[
{
column: 2,
aggregation: google.visualization.data.sum,
type: 'number'
},
{
column: 2,
aggregation: google.visualization.data.count,
type: 'number',
role: 'tooltip'
}
]
);
// create data view from groupData
var view = new google.visualization.DataView(groupData);
// sum column array
var aggColumns = [];
// use year (column 0) as first view column
var viewColumns = [0];
// build calculated view & agg columns for each team
groupData.getDistinctValues(1).forEach(function (team, index) {
// add a column to the view for each team
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === team) {
return dt.getValue(row, 2);
}
return null;
},
label: team,
type: 'number'
});
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === team) {
return dt.getValue(row, 3);
}
return null;
},
label: 'Number of Projects',
type: 'number'
});
// add sum column for each team
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index*2 + 1,
label: team,
type: 'number'
});
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index*2 + 2,
type: 'number',
role: 'tooltip',
});
});
// set view columns
view.setColumns(viewColumns);
var aggData = google.visualization.data.group(
view,
[0],
aggColumns
);
/*
The aggData looks like
"2,018",137,2,173,2,0,0
"2,019",864,12,"1,028",12,610,12
*/
for (var col=2; col < aggData.getNumberOfColumns(); col = col + 2){
aggData.setColumnProperties(col,{'type':'string', 'role':'tooltip', 'p':{'html':true}});
console.log('Column '+col+' type: ' + aggData.getColumnProperty(col, 'type'))
for (var row = 0; row < aggData.getNumberOfRows(); row = row + 1){
aggData.setValue(row, col, getHTML(aggData.getValue(row, col)))
}
}
data table method setColumnProperties isn't doing what you expect.
it only sets the properties portion of the column --> 'p':{'html':true}
so after your code runs, you end up with the following in your column properties.
'p': {'type':'string', 'role':'tooltip', 'p':{'html':true}}
and in fact, it is not possible to change a column's type,
once it has been created.
instead, you'll need to either use the addColumn or insertColumn method.
another option would be to use a data view.
then you could use a calculated column for the tooltip,
and exclude the original column you are trying to change,
using the setColumns method on the data view.

Create aggregation function to report most popular in Google DataTable

I have a Google DataTable which looks like this:
var data = new google.visualization.DataTable();
data.addColumn('string', 'City');
data.addColumn('string', 'Model');
data.addColumn('number', 'Sold');
data.addRows([
["Melbourne","Ford",10],
["Perth","Ford",2],
["Melbourne","Ford",7],
["Melbourne","Holden",25],
["Perth","Holden",25],
["Melbourne","Holden",12],
["Melbourne","Ford",11]
]);
What I would like to do is group by City and report the Model with the highest cumulative Sold value for that City.
The result returned would be :
City Model
Melbourne Holden
Perth Ford
From my reading of the Google Visualisation API it is possible to write a custom aggregation function but that is beyond my limited experience.
Any assistance would be greatly appreciated.
This would require a double grouping: the first time to get total sold per model per city, and the second time to get the most popular model.
var g1 = google.visualization.data.group(data, [0, 1], [{
type: 'number',
label: 'Total Sold',
column: 2,
aggregation: google.visualization.data.sum
}]);
// create a view to merge columns 1 and 2 together for the grouping below
var view = new google.visualization.DataView(g1);
view.setColumns([0, {
type: 'string',
label: 'Model QTy Sold',
calc: function (dt, row) {
var o = {model: dt.getValue(row, 1), sold: dt.getValue(row, 2)};
return JSON.stringify(o);
}
}]);
var g2 = google.visualization.data.group(data, [0], [{
type: 'string'
label: 'Most Popular'
aggregation: function (values) {
var max = null, ret = null;
for (var i = 0; i < values; i++) {
var o = JSON.parse(values[i]);
if (max == null || o.sold > max) {
max = o.sold;
ret = o.model;
}
}
return ret;
}
}]);
g2 should contain model with highest sales grouped by city. If there is a tie between two models, this will return the first model in the values array (likely values will be ordered by model name, but this is not guaranteed).
The edits I made to asgallant's second grouping were:
var g2 = google.visualization.data.group(view, [0], [{
type: 'string',
label: 'Most Popular',
column: 1,
aggregation: function (values) {
var max = null, ret = null;
for (var i = 0; i < values.length; i++) {
var o = JSON.parse(values[i]);
if (max == null || o.sold > max) {
max = o.sold;
ret = o.model;
}
}
return ret;
}
}]);

google visualization query limit

I have a Google visualization query for which data is coming from fusion table as,
var query = new google.visualization.Query("https://www.google.com/fusiontables/gvizdata?tq=select * from *******************");
But it select only first 500 rows of data. How to overcome this limitation?
The Fusion Tables SQL queries are deprecated. The new version of the API is not limited to 500 rows, see the Fusion Tables API for details.
Edit:
Here is an example Dashboard using the Google Fusion Tables code Odi posted in comments below:
function drawTable(response) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Country Name');
data.addColumn('number', 'Population in 1960');
data.addColumn('number', 'Population in 2000');
var rows = [];
for (var i = 0; i < response.rows.length; i++) {
rows.push([response.rows[i][0], parseInt(response.rows[i][1]), parseInt(response.rows[i][2])]);
}
data.addRows(rows);
var table = new google.visualization.ChartWrapper({
containerId: 'table_div',
chartType: 'Table',
options: {
}
});
var control = new google.visualization.ControlWrapper({
containerId: 'control_div',
controlType: 'StringFilter',
options: {
filterColumnIndex: 0
}
});
var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard'));
dashboard.bind([control], [table]);
dashboard.draw(data);
}
function getData() {
// Builds a Fusion Tables SQL query and hands the result to dataHandler
var queryUrlHead = 'https://www.googleapis.com/fusiontables/v1/query?sql=';
var queryUrlTail = '&key=AIzaSyCAI2GoGWfLBvgygLKQp5suUk3RCG7r_ME';
var tableId = '17jbXdqXSInoNOOm4ZwMKEII0sT_9ukkqt_zuPwU';
// write your SQL as normal, then encode it
var query = "SELECT 'Country Name', '1960' as 'Population in 1960', '2000' as 'Population in 2000' FROM " + tableId + " ORDER BY 'Country Name' LIMIT 10";
var queryurl = encodeURI(queryUrlHead + query + queryUrlTail);
var jqxhr = $.get(queryurl, drawTable, "jsonp");
}
google.load('visualization', '1', {packages:['controls'], callback: getData});
See it working here: http://jsfiddle.net/asgallant/6BXsy/
Give the date format yyy-mm-dd, this is how you would create Date objects from it:
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
// other columns
var rows = [], dateArray, year, month, day;
for (var i = 0; i < response.rows.length; i++) {
dateArray = response.rows[i][0].split('-');
year = parseInt(dateArray[0]);
month = parseInt(dateArray[1]) - 1;
day = parseInt(dateArray[2]);
rows.push([new Date(year, month, day) /*, other data */]);
}
data.addRows(rows);

How to interact with a table in a dashboard drawn by using google graphs api?

I have a dashboard containing a table and a string filtering box. I would like to interact with the table to be able to select rows and retrieve respective data from it.
after slight changes I got the getSelection() method working but there appeared another problem.. With the code below I try to filter the table and then select and get row data.. It all seems okay but when I do so the filtered table row numbers and the row numbers in the actual data does not match. that is I end up alerting the row data with reference to the pre-filtered table... Again any suggestion is highly valued.. thanks..
var dashboard, table, data;
function drawVisualization() {
var array = new Array(['ticker','time','bid','open','high','low','volume']);
var ticker, time, bid, open, high, low, volume;
$.get('php/getdata.php', {input: 'stocklist'}, function(data1){
$.each(data1, function(index, value){
ticker = value.ticker;
time = value.time;
bid = parseFloat(value.bid);
open = parseFloat(value.open);
high = parseFloat(value.high);
low = parseFloat(value.low);
volume = parseFloat(value.volume);
array.push([ticker, time, bid, open, high, low, volume]);
});
data = google.visualization.arrayToDataTable(array);
var stringFilter = new google.visualization.ControlWrapper({
'controlType': 'StringFilter',
'containerId': 'control1',
'options': {
'filterColumnLabel': 'ticker'
}
});
table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'chart1',
'options': {'showRowNumber': false, 'height': '130px', 'width': '1000px'}
});
dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'))
dashboard.bind(stringFilter, table);
dashboard.draw(data);
google.visualization.events.addListener(table, 'select', selectHandler);
}, "json");
}
function selectHandler() {
var selection = table.getChart().getSelection();
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
} else if (item.row != null) {
stockID = data.getFormattedValue(item.row, 0);
} else if (item.column != null) {
stockID = data.getFormattedValue(0, item.column);
}
}
if (stockID == '') {
return;
}
alert(stockID);
}
google.setOnLoadCallback(drawVisualization);
I've had a similar problem.
You have to get the new DataTable after applying the filter. Try changing
stockID = data.getFormattedValue(item.row, 0);
to
stockID = table.getDataTable().getFormattedValue(item.row, 0);
and the same for the other case.
cheers

Google Chart Api - Custom Axis Step

I have my chart working ok, however I would like to use a custom step for my vertical y-axis. At the moment it seems to be automatic and is spaced out as below:
1,500,000
3,000,000
4,500,000
I would prefer it to be:
100,000
200,000
300,000
and so on...
Is there any way I can set this, I have looked through all the documentation but can't figure it out.
Here is my code:
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(chartData, { width: 1600, height: 900, title: 'Company Performance',
yAxis: { gridlineColor: '#ff0000' },
xAxis: { gridlineColor: '#ff0000' }
}
);
My data is company profit for each week of the year, y-axis is profit, x-axis is the week number.
Hope somebody can help.
Paul
this is how I do it:
var options = {
vAxis: { // same thing for horisontal, just use hAxis
viewWindow: { // what range will be visible
max: 120,
min: 0
},
gridlines: {
count: 12 // how many gridlines. You can set not the step, but total count of gridlines.
}
}
};
all the best ;)
For as far as I know this cannot be done automatically with Google Charts settings.
I've written a javascript function to do this.
To use it you can create a nice sequence that can be used as ticks for the vertical axis:
var prettyTicks = getChartTicks(0, chartData.getColumnRange(1).max);
The line for the xAxis should be changed to apply the ticks:
yAxis: { gridlineColor: '#ff0000', ticks: prettyTicks },
Here is the javascript method to create the ticks. It will create a tick for each value of 10 and if that creates too many ticks then it will do this for each 100 or 1000 etc.
// Creates an array of values that can be used for the tick property of the Google Charts vAxis
// The values provide a nice scale to have a clean view.
var getChartTicks = function (min, max) {
// settings
var maxTicks = 8;
var tickSize = 10;
// determine the range of the values and the number of ticks
var newMin;
var newMax;
var nrOfTicks;
var appliedTickSize = 1;
while (newMin == null || nrOfTicks > maxTicks) {
appliedTickSize *= tickSize;
newMin = Math.floor(min / appliedTickSize) * appliedTickSize;
newMax = Math.ceil(max / appliedTickSize) * appliedTickSize;
nrOfTicks = (newMax - newMin) / appliedTickSize;
}
// generate the tick values which will be applied to the axis
var ticks = new Array();
var i = 0;
for (var v = newMin; v <= newMax; v += appliedTickSize) {
ticks[i++] = v;
}
return ticks;
}
So to summarize, after adding this method your code could then be changed to:
var prettyTicks = getChartTicks(0, chartData.getColumnRange(1).max);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(chartData, { width: 1600, height: 900, title: 'Company Performance',
yAxis: { gridlineColor: '#ff0000', ticks: prettyTicks },
xAxis: { gridlineColor: '#ff0000' }
}
);
Hi Please refer google chart api.There are several parameters available according to your requirement like
chbh = Bar width and spacing ...
chco = Series colors ...
chd = Chart data string...
chdl,chdlp, chdls=Chart legend text and style...
chds Scale for text format with custom range...
chem = Dynamic icon markers...
for more information
http://code.google.com/apis/chart/image/docs/chart_params.html