Pass google script variable/array to HTML - javascript

I'm building a web app that is google's chart Timeline. I have a script that returns me the correct array from google sheets. I want to pass this result to HTML in a specific place. I'm using google app scripts.
function doGet(e) {
return HtmlService.createTemplateFromFile('timeline3').evaluate();
}
function useDataRange() {
var rows = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
var test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getRange(3, 7, rows.getLastRow(), 1).getValues();
test = test.slice(0,rows.getLastRow()-2);
JSON.stringify(test);
Logger.log(test);
return test;
}
Here is my HTML code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
</head>
<body>
<script type="text/javascript">
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(getData);
function getData(){
return google.script.run.withSuccessHandler(drawChart).useDataRange();
}
function drawChart(arrayFromSheets) {
var container = document.getElementById('timeline-tooltip');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President' });
dataTable.addColumn({ type: 'string', id: 'dummy bar label' });
dataTable.addColumn({ type: 'string', role: 'tooltip' });
dataTable.addColumn({ type: 'string', id: 'style', role: 'style' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows(arrayFromSheets);
chart.draw(dataTable);
}
</script>
<div id="timeline-tooltip" style="height: 400px;"></div>
</body>
</html>
I'm trying to populate dataTable.addRows() with my array. I've looked through google's documentation and this should work. I just don't get it. Please help
Here is an example of array I get returned from useDataRange function:
[['Lady Gita' ,null , 'June 19 -26' , '#176BEF', new Date(2021, 6, 19) , new Date(2021, 6, 26)], ['Lady Gita' ,null , 'Jun 27 - Jul 11' , '#FF3E30', new Date(2021, 6, 27) , new Date(2021, 7, 11)]]
Searching in console I get this:
Console:

Why not just var test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getRange(3, 7, rows.getLastRow()-2, 1).getValues(); The third param is number of rows not last row

Arrays weren't being passed as arrays because I had a function inside them. They were all being passed as undefined. I had to change a bit my sheet but it works now. Also null was showing as BarLabel so I turned BarLabel off with options. It works great now!
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(getData);
function getData(){
google.script.run.withSuccessHandler(drawChart).useDataRange();
}
function drawChart(data) {
var container = document.getElementById('timeline-tooltip');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President'});
dataTable.addColumn({ type: 'string', id: 'dummy bar label'});
dataTable.addColumn({ type: 'string', role: 'tooltip'});
dataTable.addColumn({ type: 'string', id: 'style', role: 'style'});
dataTable.addColumn({ type: 'date', id: 'Start'});
dataTable.addColumn({ type: 'date', id: 'End'});
var rows = [];
//Loop through the data you loaded and push it to the rows array
for(var i=0; i<data.length; i++){
var currentElement = data[i];
var transformFirstDate = new Date(currentElement[4]);
var transformSecondDate = new Date(currentElement[5]);
rows.push([currentElement[0],currentElement[1],currentElement[2],currentElement[3],transformFirstDate,transformSecondDate]);
}
dataTable.addRows(rows);
var options = {
timeline: { showBarLabels: false }
};
chart.draw(dataTable, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="timeline-tooltip" style="height: 400px;"></div>
</body>
</html>

Related

Using Years Only (Without Months or Days) with Google Timeline Charts

I want to show a timeline (with Google Charts) with years only.
However, the examples on Google Charts Timelines' webpage always comprise years, months and days (for instance, new Date(1789, 3, 30)).
I have tried reducing the new Date() to just a year (e.g. new Date(2019)), but Google Charts interprets it as seconds (2.019 seconds).
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["timeline"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('div_timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Nr' });
dataTable.addColumn({ type: 'string', id: 'Journal' });
dataTable.addColumn({ type: 'date', id: 'Founded' });
dataTable.addColumn({ type: 'date', id: 'Now' });
dataTable.addRows([
[ '1', 'Journal of Leisure Research', new Date(1969), new Date(2019) ],
[ '2', 'Critical Sociology', new Date(2009), new Date(2019) ],
[ '3', 'Geographical Analysis', new Date(1909), new Date(2019) ]
]);
chart.draw(dataTable,options);
}
</script>
With this code, Journal of Leisure Research is now 1.969 seconds to 2.019 seconds.
Instead, I want the chart to assign the years 1969 to 2019.
How can I do that? Thanks for your help!
Simply set the date to January 1st:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Nr' });
dataTable.addColumn({ type: 'string', id: 'Journal' });
dataTable.addColumn({ type: 'date', id: 'Founded' });
dataTable.addColumn({ type: 'date', id: 'Now' });
dataTable.addRows([
[ '1', 'Journal of Leisure Research', new Date(1969,1,0), new Date(2019,1,0) ],
[ '2', 'Critical Sociology', new Date(2009,1,0), new Date(2019,1,0) ],
[ '3', 'Geographical Analysis', new Date(1909,1,0), new Date(2019,1,0) ]]);
chart.draw(dataTable);
}
</script>
</head>
<body>
<div id="timeline" style="height: 180px;"></div>
</body>
</html>

Dummy rows for Google Charts Timelines?

I'm looking for a way to add a dummy row to Google Charts Timelines. Here is what I'm trying to accomplish:
However, the dummy row should be transparent and should not have interactivity (no tooltip, no select event, etc.).
Here is my workaround:
This requires adding three more columns and you lose the tooltip generated by Charts. While this isn't an issue for me (as I will be customizing the tooltips), it may be for others. Furthermore, although the dummy row is transparent, there is still interactivity (as indicated by the empty tooltip I circled). The workaround for this is to add the following code immediately before chart.draw(dataTable):
function onMouseOver(e) {
var tooltips = document.getElementsByClassName('google-visualization-tooltip');
for (var i = 0; i < tooltips.length; i++) {
if (!tooltips[i].innerHTML) {
tooltips[i].style.display = 'none';
}
}
}
function onReady() {
google.visualization.events.addListener(chart, 'onmouseover', onMouseOver);
}
google.visualization.events.addListener(chart, 'ready', onReady);
While this is technically a solution to my problem, it's a hack at best. Is there no straightforward way to accomplish this with the API?
This is already a year old question, but maybe someone else will have the same problem. Your solution from second screen was very close. You need to set tooltip value on normal rows to null (will display standard tooltip) and empty string on dummy items (tooltip will be hidden). The style column must have opacity set to 0 on dummy rows to hide the bar. Below is rewritten and fixed code from your example.
google.charts.load('current', { packages: ['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
const container = document.getElementById('timeline');
const chart = new google.visualization.Timeline(container);
const dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', label: 'President', id: 'President' });
dataTable.addColumn({ type: 'string', id: 'Empty label' });
dataTable.addColumn({ type: 'string', id: 'style', role: 'style' });
dataTable.addColumn({ type: 'string', id: 'tooltip', role: 'tooltip', p: { html: true } });
dataTable.addColumn({ type: 'date', label: 'Start', id: 'Start' });
dataTable.addColumn({ type: 'date', label: 'End', id: 'End' });
dataTable.addRows([
['A', '', 'opacity: 0', '', new Date('2018-06-05T00:00:00'), new Date('2018-06-05T00:00:00')],
['B', '', 'opacity: 0', '', new Date('2018-06-05T00:00:00'), new Date('2018-06-05T00:00:00')],
['C', '', 'opacity: 0', '', new Date('2018-06-05T00:00:00'), new Date('2018-06-05T00:00:00')],
['A', '', null, null, new Date('2018-06-05T01:00:00'), new Date('2018-06-05T02:00:00')],
['B', '', null, null, new Date('2018-06-05T01:00:00'), new Date('2018-06-05T02:00:00')],
['C', '', null, null, new Date('2018-06-05T01:00:00'), new Date('2018-06-05T02:00:00')],
]);
}
After tackling with this problem I prefer to use apexcharts package for timeline chart creating. This package has more flexible interface to control the charts, min and max values of axis, tooltips, etc.

How to insert complex code using DOM manipulation

I am still learning javascript.
Here is the site I am playing with. http://keysoft.keydesign-themes.com/demo1/
I want to insert google visualization chart code using DOM manipulation (insertAdjacentHTML) into this site.
Here is the code of google's timeline chart:
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ 'Adams', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ 'Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4) ]]);
chart.draw(dataTable);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height: 180px;"></div>
I tried the code below in Chrome's console in order to insert it into this site but I think there are a lot of mistakes. Could you help me please how to improve the code below?
document.getElementsByClassName('container')[5].getElementsByClassName('row')[0].insertAdjacentHTML('afterend', '<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height: 180px;"></div>
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ 'Adams', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ 'Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4) ]]);
chart.draw(dataTable);
}');
You can turn this into a string literal by using back ticks (`) instead of single quotes. And to ensure it doesn't jam up on the script tags you will want to change the closing script tag inside the literal to
<\/script>
I don't know the rest of your HTML structure so there may also be some issues with selecting the elements you want to place the tag inside.
Here's a complete example of a simple page that works for me:
</head>
<body>
<div id="container" class='container'>
<div class="row"></div>
</div>
</body>
<script>'use strict';
document.getElementsByClassName('container')[0].getElementsByClassName('row')[0].insertAdjacentHTML('afterend', `<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"><\/script>
<div id="timeline" style="height: 180px;"></div>\n\n <script> google.charts.load(\'current\', {\'packages\':[\'timeline\']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById(\'timeline\');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: \'string\', id: \'President\' });
dataTable.addColumn({ type: \'date\', id: \'Start\' });
dataTable.addColumn({ type: \'date\', id: \'End\' });
dataTable.addRows([
[ \'Washington\', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ \'Adams\', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ \'Jefferson\', new Date(1801, 2, 4), new Date(1809, 2, 4) ]]);
chart.draw(dataTable);
}<\/script>`);
</script>
I changed the number of containers from 5 to 0 for simplicity's sake but in the browser this runs without issue and injects the JS code after the row element. The back ticks (`) are important .

Google Charts ColumnChart date format not showing minutes and hours

I'm trying to make a column chat, using Google charts with the numbers up the vertical axis, and dates across the horizontal axis. For some reason the date format does not print the hours, minutes or seconds. It does work just fine with year, month and day.
I'm using the format "M-d, HH:mm:ss" to format and print this timestamp: "2017-07-15 20:10:30" but instead it prints
7-17,00:00:00 instead of 7-17, 20:10:30
Is this a bug or have i missed something?
<html>
<head>
<script src="https://www.google.com/jsapi?ext.js"></script>
</head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart()
{
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Present');
data.addRows([
[new Date("2017-07-15 20:10:30"), 5]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}]);
var options = {
width: 600,
height: 400,
//bar: {groupWidth: "95%"},
legend: { position: "none" },
vAxis: {title: 'Times occured'},
hAxis: {
format: "M-d, HH:mm:ss", // <------- This shows: "7-17,00:00:00" not "7-17, 20:10:30"
//format: "HH:mm",
//format:'M-d H:mm',
title: 'Date',
},
};
var chart = new google.visualization.ColumnChart(document.getElementById("chart_div"));
chart.draw(view, options);
}
</script>
<body class="chart">
<div id="chart_div"></div>
</body>
</html>
looks like some sort of bug,
recommend using a discrete axis (string) for column charts anyway
you could use a data formatter to convert the x-axis
see following working snippet...
google.charts.load("current", {
callback: drawChart,
packages:["corechart"]
});
function drawChart() {
var formatDate = new google.visualization.DateFormat({
pattern: 'M-d, HH:mm:ss'
});
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Present');
data.addRows([
[new Date("2017-07-15 20:10:30"), 5]
]);
var view = new google.visualization.DataView(data);
view.setColumns([{
calc: function (dt, row) {
return formatDate.formatValue(dt.getValue(row, 0))
},
type: "string",
label: data.getColumnLabel(0)
}, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}]);
var options = {
width: 600,
height: 400,
legend: { position: "none" },
vAxis: {title: 'Times occured'},
hAxis: {
title: 'Date'
}
};
var chart = new google.visualization.ColumnChart(document.getElementById("chart_div"));
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google Charts Timeline - PHP array as input

I am working on a Google Charts Timeline plot, showing the duration periods of a number of tasks, located in a table in a MySQL database. Using PHP there is a number of ways to retrieve and store this, for instance as a 2-dimensional array. However, is there a way to pass such an array (or other easily created data containing objects), in the way that the Google Charts Timeline can handle, through the dataTable.addrows() method?
Or if I should describe it as an example:
function drawChart() {
// Nothing to see here, move along now...
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
// The column heading can be fixed or variable, this doesnt matter.
dataTable.addColumn({ type: 'string', id: 'Opgave ID' });
dataTable.addColumn({ type: 'string', id: 'Opgavetitel' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
/* I would like to replace the fixed input of dataTable.addRows, with a
*variable input, for instance a 2-dimensional PHP-array.
*/
dataTable.addRows([
[ '1', 'Some task', new Date(2015, 3, 9), new Date(2015, 3, 23) ],
[ '2', 'Another task', new Date(2015, 3, 13), new Date(2015, 3, 20) ],
[ '3', 'A different task', new Date(2015, 3, 16), new Date(2015, 3, 30) ]]);
// No questions for any of this
var options = {
timeline: {showRowLabels: false, singleColor: '#8d8'}
};
chart.draw(dataTable, options);
}
Doing a quick google search, I found this article:
http://www.dyn-web.com/tutorials/php-js/json/multidim-arrays.php
I'm not a PHP programmer, so this isn't tested but should work:
<?
$timeData = array(
array('1', 'Some task', new DateTime('2015-04-09'), new DateTime('2015-04-23')),
array('2', 'Another task', new DateTime('2015-04-13'), new DateTime('2015-04-20')),
array('3', 'A different task', new DateTime('2015-04-16'), new Date('2015-04-30))
);
?>
function drawChart() {
// Nothing to see here, move along now...
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
// The column heading can be fixed or variable, this doesnt matter.
dataTable.addColumn({ type: 'string', id: 'Opgave ID' });
dataTable.addColumn({ type: 'string', id: 'Opgavetitel' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows(<? echo json_encode( $timeData ); ?>);
// No questions for any of this
var options = {
timeline: {showRowLabels: false, singleColor: '#8d8'}
};
chart.draw(dataTable, options);
}
You may find it easier to locate existing material if you broaden your search to a more basic concept (passing a PHP 2d array to javascript). Here's an example of an existing Stack Overflow question on that topic:
Best way to pass a 2d array into JavaScript from PHP?
And there are many more like it.
I got the same problem while using Google Charts Timeline while using Laravel 6.0 framework. I passed the query results to the view file as an associative array and the used json_encode() to convert the associative array into a JavaScript array that turned into an array of objects:
<script>
// create a custom data object to pass into the array
// the charter array data is of the format:
//
// Array(5)
// 0: {mn: "2020-02-12 10:03:17", mx: "2022-07-12 10:03:17", cha_booking_id: 1}
// 1: {mn: "2020-02-12 13:33:07", mx: "2020-10-12 13:33:07", cha_booking_id: 2}
// 2: {mn: "2020-02-12 13:39:47", mx: "2020-08-12 13:39:47", cha_booking_id: 3}
// 3: {mn: "2020-04-12 06:21:08", mx: "2020-04-12 06:21:08", cha_booking_id: 4}
// 4: {mn: "2020-05-12 08:44:24", mx: "2020-07-12 08:44:24", cha_booking_id: 5}
var data = [];
charter.forEach(el => {
var arr = [
el.cha_booking_id.toString(),
new Date(
el.mn.substring(0, 4), // get the year from the date format that is passed
el.mn.substring(5, 7), // get the month from the date format that is passed
el.mn.substring(8, 10) // get the day from the date format that is passed
),
new Date(
el.mx.substring(0, 4),
el.mx.substring(5, 7),
el.mx.substring(8, 10)
)
];
data.push(arr);
// The column heading can be fixed or variable, this doesnt matter.
dataTable.addColumn({ type: 'string', id: 'Opgave ID' });
dataTable.addColumn({ type: 'string', id: 'Opgavetitel' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows(data);
// No questions for any of this
var options = {
timeline: {showRowLabels: false, singleColor: '#8d8'}
};
chart.draw(dataTable, options);
</script>

Categories

Resources