how to customize Google Chart calendar? - javascript

I want to add comment in Google chart (calendar chart).
but, I don't understand Google chart's options and How to use.
when I add addcolumn, This work can not.
Please give me some help..
enter image description here
<<<source code>>>>
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["calendar"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'date', id: 'Date' });
dataTable.addColumn({ type: 'number', id: 'Won/Loss' });
// dataTable.addColumn({ type: 'string', id:'comment'}); // Error
dataTable.addRows([
[ new Date(2015, 3, 11), 4], // I want to add comment
[ new Date(2015, 3, 12), 3],
[ new Date(2015, 3, 10), 8],
[ new Date(2015, 1, 13), 5],
[ new Date(2015, 3, 14), 7]
]);
var chart = new google.visualization.Calendar(document.getElementById('calendar_basic'));
var options = {
title: "Red Sox Attendance",
height: 1050,
};
chart.draw(dataTable, options);
}
</script>
</head>
<body>
<div id="calendar_basic" style="width: 1000px; height: 350px;"></div>
</body>
</html>
enter code here

Are you trying to get your comment to appear in a tooltip? How would you like to see the comment information rendered?

Related

A way to set custom start and end time for Google Timeline Chart

Couldn't find answer in the official documentation.
By default, Google Timeline "shrinks" the chart area, so that first bar touches the left edge, and last bar touches the right:
|XXXXX-----YYYY---------|
|----ZZZ---YYYY----AAAAA|
Apr May Jun Jul
I want to override this behaviour and manually set start and end time for chart (override the scale), like this:
|------------XXXXX-----YYYY----------------|
|---------------ZZZ----YYYY-----AAAAA------|
Jan Feb Mar Apr May Jun Jul Aug
In my example, I want to show the chart from January till August.
listed in the Release Notes from October 2, 2015
use options hAxis.minValue & hAxis.maxValue
hAxis: {
minValue: new Date(2017, 0, 1),
maxValue: new Date(2017, 7, 1)
}
see following working snippet...
google.charts.load('current', {
callback: function () {
var container = document.getElementById('chart_div');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Room' });
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ '1', 'A', new Date(2017, 1, 1), new Date(2017, 1, 10) ],
[ '2', 'B', new Date(2017, 3, 1), new Date(2017, 3, 10) ],
[ '3', 'C', new Date(2017, 5, 1), new Date(2017, 5, 10) ],
]);
function drawChart() {
chart.draw(dataTable, {
hAxis: {
minValue: new Date(2017, 0, 1),
maxValue: new Date(2017, 7, 1)
}
});
}
$(window).resize(drawChart);
drawChart();
},
packages: ['timeline']
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google visualization set column dock

I am struggling with google charts. I want bars to be displayed from bottom, rather than from top. Currently they are "hanging" like on the image below:
I don't see proper setting in docs, if it is there, please correct me. This is the code responsible for handling the display:
function parseInterval(value) {
var result = new Date(1,1,1);
result.setMilliseconds(value*1000);
return result;
}
(function($) {
$(document).ready(function(){
var loading = $('#loading');
$.getJSON("/api/v1/users", function(result) {
var dropdown = $("#user_id");
$.each(result, function(item) {
dropdown.append($("<option />").val(this.user_id).text(this.name));
});
dropdown.show();
loading.hide();
});
$('#user_id').change(function(){
var selected_user = $("#user_id").val();
var chart_div = $('#chart_div');
if(selected_user) {
loading.show();
chart_div.hide();
$.getJSON("/api/v1/mean_time_month/"+selected_user, function(result) {
$.each(result, function(index, value) {
value[1] = parseInterval(value[1]);
});
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows(result);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
},
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
chart_div.show();
loading.hide();
var chart = new google.visualization.ColumnChart(chart_div[0]);
chart.draw(data, options);
});
}
});
});
})(jQuery);
try using option vAxis.direction...
The direction in which the values along the vertical axis grow. Specify -1 to reverse the order of the values.
vAxis: {
direction: -1
}
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows([
['Jan', new Date(1, 1, 1, 8, 16, 13)],
['Feb', new Date(1, 1, 1, 9, 24, 45)],
['Mar', new Date(1, 1, 1, 7, 36, 56)],
['Apr', new Date(1, 1, 1, 4, 20, 42)],
['May', new Date(1, 1, 1, 6, 51, 16)]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
direction: -1,
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
but i think the real problem lies within the data
notice the y-axis values the chart displays in the example above,
the order doesn't seem right, as well as the range (10am - 12am)
it appears you're only interested in the time values
as such, recommend using 'timeofday' vs. 'datetime'
(see --> working with timeofday)
The DataTable 'timeofday' column data type takes an array of either 3 or 4 numbers, representing hours, minutes, seconds, and optionally milliseconds, respectively. Using timeofday is different than using date and datetime in that the values are not specific to a date, whereas date and datetime always specify a date.
For example, the time 8:30am would be: [8, 30, 0, 0], with the 4th value being optional ([8, 30, 0] would output the same 'timeofday' value).
see following working snippet for example using 'timeofday'...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('timeofday', 'Mean time (h:m:s)');
data.addRows([
['Jan', [8, 16, 13]],
['Feb', [9, 24, 45]],
['Mar', [7, 36, 56]],
['Apr', [4, 20, 42]],
['May', [6, 51, 16]]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: [0, 0, 0]
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Chart Range Filter for Google Charts LineChart

I am using Google Charts Line Charts, I am having some trouble binding it to a Chart Range Filter.
Here is what I have tried:
The containers:
<div id="dashboard_div">
<!--Divs that will hold each control and chart-->
<div id="control_div" style="width: 100%; height: 100%"></div>
<div id="daily_container_count_lineChart" style="width: 100%; height: 100%"></div>
</div>
The JS part:
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'daily_container_count_lineChart',
options: {
theme: 'maximized'
}
});
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0
}
});
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));
dashboard.bind([control], [chart]);
dashboard.draw(data);
I get the following error in place of the dashboard in the webpage. No error in the console.
One or more participants failed to draw()
You called the draw() method with the wrong type of data rather than a DataTable or DataView
You called the draw() method with the wrong type of data rather than a DataTable or DataView
If I try to just draw a line graph without the chart Range filter like below, it works just fine with out any errors:
Drawing just a line graph without ChartRangeFilter:
var dailyContainerChart = new google.charts.Line(document.getElementById('daily_container_count_lineChart'));
dailyContainerChart.draw(data, {allowHtml: true, width: '100%', height: '100%'});
Loading the data:
var getDailyContainerLineData = function (sourceData)
{
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'VIC - STH CRT');
data.addColumn('number', 'NSW - MINTO');
data.addColumn('number', 'QLD - PINKENBA');
data.addColumn('number', 'WA - HAZELMERE');
for(k =1;k< sourceData.getNumberOfColumns();k++)
{
var rowData = new Array();
var rowStart = sourceData.getColumnLabel(k);
rowData.push(new Date(rowStart));
for(l =0;l<sourceData.getNumberOfRows()-1;l++) // we don't want the 'total' row from the daily container table
{
var test = sourceData.getValue(l, k);
if(typeof test === 'string')
{
var date = Date.parse(test);
rowData.push(date);
}
else
{
rowData.push(test);
}
}
data.addRow(rowData);
}
return data;
}
The data that is returned from above is used to draw the dashboard and and the LineGraph.
My questions is:
Why am I getting a wrong data type error when I try to draw the line graph with the ChartRangeFilter, but not when I draw only the line graph
Can I get the ChartRangeFiler to filter 2 graphs(a table and line graph) with different data sources at the same time ?
Cheers.
A dashboard accepts the same data format as a regular chart.
Building a DataTable from the sample data provided seems to draw just fine.
Didn't see the load statement, check to see that all the necessary packages are being loaded when drawing the dashboard.
As for second question...
Although you cannot bind a single control to more than one data source, you can use the 'statechange' event to control other sources.
See following example...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'VIC - STH CRT');
data.addColumn('number', 'NSW - MINTO');
data.addColumn('number', 'QLD - PINKENBA');
data.addColumn('number', 'WA - HAZELMERE');
data.addRow([new Date('04/01/2001'), 3, 4, 7, 6]);
data.addRow([new Date('04/02/2001'), 0, 9, 8, 7]);
data.addRow([new Date('04/03/2001'), 9, 9, 0, 7]);
data.addRow([new Date('04/04/2001'), 5, 5, 5, 2]);
data.addRow([new Date('04/05/2001'), 6, 7, 1, 1]);
data.addRow([new Date('04/06/2001'), 4, 4, 1, 9]);
data.addRow([new Date('04/07/2001'), 4, 5, 9, 0]);
var dataOther = new google.visualization.DataTable();
dataOther.addColumn('date', 'Date');
dataOther.addColumn('number', 'HLS - FLORENCE');
dataOther.addColumn('number', 'FGT - GAY');
dataOther.addColumn('number', 'KNX - FULTON');
dataOther.addColumn('number', 'TN - VOLS');
dataOther.addRow([new Date('04/01/2001'), 1, 8, 5, 2]);
dataOther.addRow([new Date('04/02/2001'), 2, 9, 6, 3]);
dataOther.addRow([new Date('04/03/2001'), 3, 0, 7, 4]);
dataOther.addRow([new Date('04/04/2001'), 4, 1, 8, 5]);
dataOther.addRow([new Date('04/05/2001'), 5, 2, 9, 6]);
dataOther.addRow([new Date('04/06/2001'), 6, 3, 0, 7]);
dataOther.addRow([new Date('04/07/2001'), 7, 4, 1, 8]);
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'daily_container_count_lineChart',
options: {
theme: 'maximized'
}
});
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table_div',
dataTable: dataOther,
options: {
sortColumn: 1
}
});
google.visualization.events.addListener(control, 'statechange', function () {
var state = control.getState();
var view = new google.visualization.DataView(dataOther);
view.setRows(view.getFilteredRows([{column: 0, minValue: state.range.start, maxValue: state.range.end}]));
table.setDataTable(view);
table.draw();
});
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));
dashboard.bind([control], [chart]);
dashboard.draw(data);
table.draw();
},
packages: ['controls', 'corechart', 'table']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="control_div" style="width: 100%; height: 100%"></div>
<div id="daily_container_count_lineChart" style="width: 100%; height: 100%"></div>
</div>
<div id="table_div"></div>

Can't embed Google Chart Service in a modal dialog

In a Google Spreadhseet I have code.gs:
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('index')
.setWidth(900)
.setHeight(700);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My custom dialog');
}
And index.html:
<script src="https://www.google.com/jsapi"></script>
<script>
try{
google.load("visualization", "1.1", {packages:["calendar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'date', id: 'Date' });
dataTable.addColumn({ type: 'number', id: 'Won/Loss' });
dataTable.addRows([
[ new Date(2012, 3, 13), 37032 ],
[ new Date(2012, 3, 14), 38024 ],
[ new Date(2012, 3, 15), 38024 ],
[ new Date(2012, 3, 16), 38108 ],
[ new Date(2012, 3, 17), 38229 ],
// Many rows omitted for brevity.
[ new Date(2013, 9, 4), 38177 ],
[ new Date(2013, 9, 5), 38705 ],
[ new Date(2013, 9, 12), 38210 ],
[ new Date(2013, 9, 13), 38029 ],
[ new Date(2013, 9, 19), 38823 ],
[ new Date(2013, 9, 23), 38345 ],
[ new Date(2013, 9, 24), 38436 ],
[ new Date(2013, 9, 30), 38447 ]
]);
var chart = new google.visualization.Calendar(document.getElementById('calendar_basic'));
var options = {
title: "Red Sox Attendance",
height: 350,
};
chart.draw(dataTable, options);
}
} catch(e){
alert(e);
}
</script>
<div id="calendar_basic" style="width: 1000px; height: 350px;"></div>
I want to display the chart in a dialog box using the example code from: https://google-developers.appspot.com/chart/interactive/docs/gallery/calendar
But this is returning an empty dialog. No errors are thrown.
What can I do to fix this?
Since very recently you have been able to use the Visualisation service in HTMLService created dialog:
An exciting new development in the HTMLService is the addition of the iFrame sandbox mode which removes a lot of the Caja restrictions, one of them being that you can use the Visualisation Service. You just need to add:
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
to your HTMLService call.
So using this in code.gs (I've added a menu item for the dialog):
function onOpen() {
SpreadsheetApp
.getUi()
.createMenu('Show Dialog')
.addItem('Show dialog...', 'showDialog')
.addToUi()
}
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(900)
.setHeight(700);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My custom dialog');
}
and this in index.html (note you need to bring your Doctype, html, body and back in as it's raw HTML again, not Cajaised):
<!DOCTYPE html>
<html>
<body>
<div id="calendar_basic" style="width: 1000px; height: 350px;"></div>
<script src="https://www.google.com/jsapi"></script>
<script>
try{
google.load("visualization", "1.1", {packages:["calendar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'date', id: 'Date' });
dataTable.addColumn({ type: 'number', id: 'Won/Loss' });
dataTable.addRows([
[ new Date(2012, 3, 13), 37032 ],
[ new Date(2012, 3, 14), 38024 ],
[ new Date(2012, 3, 15), 38024 ],
[ new Date(2012, 3, 16), 38108 ],
[ new Date(2012, 3, 17), 38229 ],
// Many rows omitted for brevity.
[ new Date(2013, 9, 4), 38177 ],
[ new Date(2013, 9, 5), 38705 ],
[ new Date(2013, 9, 12), 38210 ],
[ new Date(2013, 9, 13), 38029 ],
[ new Date(2013, 9, 19), 38823 ],
[ new Date(2013, 9, 23), 38345 ],
[ new Date(2013, 9, 24), 38436 ],
[ new Date(2013, 9, 30), 38447 ]
]);
var chart = new google.visualization.Calendar(document.getElementById('calendar_basic'));
var options = {
title: "Red Sox Attendance",
height: 350,
};
chart.draw(dataTable, options);
}
} catch(e){
alert(e);
}
</script>
</body>
</html>
You'll be able to see your chart in the dialog box ... I'm sorry but that is just too cool!
I've created a quick demo if you wanted to see it action. Make a copy if you want to play with the code.
Unfortunately, App Script is not able to add the Google Visualization Library. Since App Script is based on the Caja Compiler (https://code.google.com/p/google-caja/), it is not guaranteed that external JS libraries will properly work.
You can read more details on the following link:
https://developers.google.com/apps-script/guides/html/restrictions#javascript

How do I get more specific duration using Google Charts Timeline?

So, I'm using the following code to create a timeline from Google charts.
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['timeline']}]}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById("example1");
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: "string", id: "RowName" });
dataTable.addColumn({ type: "string", id: "Label" });
dataTable.addColumn({ type: "date", id: "Start" });
dataTable.addColumn({ type: "date", id: "End" });
dataTable.addRows([
["Row1", "Step 1", new Date(2013, 11, 4, 2, 45, 0), new Date(2013, 11, 4, 4, 5, 15)],
["Row1", "Step 2", new Date(2013, 11, 4, 4, 5, 15), new Date(2013, 11, 7, 8, 34, 55)],
["Row1", "Step 3", new Date(2013, 11, 7, 8, 34, 55), new Date(2013, 11, 12, 11, 28, 49)],
["Row1", "Step 4", new Date(2013, 11, 12, 11, 28, 49), new Date(2013, 11, 14, 9, 27, 17)]
]);
var options = {
timeline: {
groupByRowLabel: true,
showRowLabels: true
}
};
chart.draw(dataTable, options);
}
</script>
<div id="example1" style="width: 900px; height: 180px;"></div>
I would like to get more detailed with the mouse over popup Duration. If you look at Step 1, it just says Duration: 1 day. But, if you look at the code, it was only an hour 20 minutes and 15 seconds. Is there any way to get this to show?
Link of code running: http://jsfiddle.net/ifandelse/FdFM3/
It's correct what user asgallant said. But still you can get some information.
Add one element after you chart div:
<div id="example1" style="width: 900px; height: 180px;"></div>
<div id='duration'></div>
Add event listener before call to draw chart:
google.visualization.events.addListener(chart, 'onmouseover', function (obj) {
var startDate = dataTable.getValue(obj.row, 2);
var endDate = dataTable.getValue(obj.row, 3);
var timeDiff = Math.abs(startDate.getTime() - endDate.getTime());
var diffDays = (timeDiff / (1000 * 3600 * 24));
var durationEl = document.getElementById('duration');
durationEl.innerHTML = 'Duration: ' + diffDays.toFixed(4);
});
chart.draw(dataTable, options);
You will get now for the 1st step 0.0557. This solution is little ugly but at least you get an idea. You can even calculate hours if you want and do some styling.
See example at jsBin.

Categories