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

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>

Related

Pass google script variable/array to HTML

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>

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>

timeline charts not working in Google Apps Script

I'm trying to draw some charts with Google Visualization API in Apps Script.
All charts work fine (PieChart, ComboChart...) but timeline.
If I copy/paste my code in a HTML file works fine however in an Apps Script project throw this error when a call the builder (new google.visualization.Timeline(container): "undefined is not a function".
Here my code:
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart','timeline']});
function pintarGraficaTimeline(){
var chart = new google.visualization.Timeline(document.getElementById('divGrafica'));
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, 29), new Date(1797, 2, 3) ],
[ 'Adams', new Date(1797, 2, 3), new Date(1801, 2, 3) ],
[ 'Jefferson', new Date(1801, 2, 3), new Date(1809, 2, 3) ]]);
chart.draw(dataTable);
}
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="divGraficaTimeline" style="float:right;display:block;">
<div style="float: right;"> <input type="button" value="Buscar" style="float: right;margin-right: 4%;" onclick="pintarGraficaTimeline()" /></div>
</div>
<div id="divGrafica" > </div>
Doesn't Timeline package work in Apps Scripts??
The Timeline package is not yet available in Apps Script, though that shouldn't be an issue since you are not using Apps Script to drive the visualizations. This seems likely to be caused by trying to draw the chart before the API finishes loading. Try assigning your button click event in a callback from the google loader:
function init () {
var el = document.querySelector('#divGraficaTimeline input');
if (document.addEventListener) {
el.addEventListener('click', pintarGraficaTimeline);
}
else if (document.attachEvent) {
el.attachEvent('onclick', pintarGraficaTimeline);
}
else {
el.onclick = pintarGraficaTimeline;
}
}
google.load('visualization', '1', {packages: ['corechart','timeline'], callback: init});

Categories

Resources