Can't embed Google Chart Service in a modal dialog - javascript

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

Related

Vue - Calendar chart is not working in vue-google-charts

I am using vue-google-charts package to display google charts, but unable to use Calendar chart in it.
HTML Template:
<GChart
type="CalendarChart"
:data="chartData"
:options="chartOptions"
/>
Script:
<script>
import { GChart } from "vue-google-charts";
export default {
name: "App",
components: {
GChart
},
data() {
return {
chartData: [
['a','b'],
[ 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 ]
],
chartOptions: {
chart: {
title: "Red Sox Attendance",
height: 350,
}
}
};
}
};
It shows this error
Uncaught (in promise) TypeError: chartsLib.visualization[this.type] is not a constructor
at VueComponent.createChartObject (vue-google-charts.common.js:1)
at eval (vue-google-charts.common.js:1)
How to fix this issue? Thank you.
There seems to be :settings property to chart. Its working with that.
<GChart
:settings="{packages: ['calendar']}"
type="Calendar"
:data="chartData"
:options="chartOptions"
/>

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>

how to customize Google Chart calendar?

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?

Dual y axes in Google charts

I am trying to use dual y axes with Google charts.I understand the basics and how it works.
On one y axis, I want BMI values and on other Weight Values.
I am taking out data from SQL database. However, BMI and Weight are itself values in a column called ReadingName.
So, if I use the query,
select * from table where ReadingName = 'BMI' or ReadingName = Weight
I get the result set which is serialized into JSON and then forwarded to render charts which again would be retrieved using column Name only.
Now, to have observation values for BMI on one yaxis and Weight on other, as per the example on GoogleCharts website, I need to have them as columns.
But I have them only as different values of same column called ReadingType.Is there a work around possible ?
This is how it should look like :
Unfortunately, you'll have to massage the data into a format it understands. The DataTable class provides lots of methods for populating but here is an example:
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Start with long data
var rawData = [
[new Date(2014, 8, 1), "Weight", 140],
[new Date(2014, 8, 1), "BMI", 5],
[new Date(2014, 8, 15), "Weight", 130],
[new Date(2014, 8, 15), "BMI", 4],
[new Date(2014, 9, 1), "Weight", 120],
[new Date(2014, 9, 1), "BMI", 3],
[new Date(2014, 9, 15), "Weight", 120],
[new Date(2014, 9, 15), "BMI", 3]
];
// Create a wide table from the long data
var data = new google.visualization.DataTable();
data.addColumn("date", "Date");
data.addColumn("number", "BMI");
data.addColumn("number", "Weight");
var lastDate = null;
var currentRow = null;
for (var i=0; i < rawData.length; i++) {
var date=rawData[i][0];
var col=rawData[i][1];
var value=rawData[i][2];
if (lastDate == null) {
// First pass
currentRow = [date, null, null];
}
else if (lastDate != date) {
data.addRow(currentRow);
currentRow = [date, null, null];
}
if (col=="BMI") currentRow[1] = value;
else if (col=="Weight") currentRow[2] = value;
lastDate = date;
}
if (currentRow != null) data.addRow(currentRow);
var options = {
title: 'Wight & BMI',
vAxes: [{
title: "Weight",
minValue: 0
}, {
title: "BMI",
minValue: 0
}],
series: {
0: { targetAxisIndex:0 },
1: { targetAxisIndex:1 }
},
interpolateNulls: true
}
var chart = new google.visualization.LineChart(document.getElementById("chart"));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart" style="width: 900px; height: 300px;"></div>

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