google charts timeline - cannot read property length of null - javascript

Following there are 2 examples of google charts code. The only difference in the last example is the start second. Does anybody know, why I get "cannot read property 'length' of null" in the last example? Also if I shorten the name of row 2 and 3 from "Second Test entry number 2" to a shorter, the chart is displayed.
Working: https://jsfiddle.net/5rotomyc/
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: 'Group' });
dataTable.addColumn({ type: 'string', id: 'Role' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['First', null, new Date(2017,1,15, 22, 40, 27), new Date(2017,10,29, 23, 59, 59)],
['Second Test entry number 2', null, new Date(2017,8,4, 0, 0, 0), new Date(2018,0,16, 23, 59, 59)],
['Second Test entry number 2', null, new Date(2018,0,25, 0, 0, 0), new Date(2018,1,06, 23, 59, 59)]
]);
chart.draw(dataTable);
}
Second example which is not working https://jsfiddle.net/ypz095g9/:
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: 'Group' });
dataTable.addColumn({ type: 'string', id: 'Role' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['First', null, new Date(2017,1,15, 22, 40, 26), new Date(2017,10,29, 23, 59, 59)],
['Second Test entry number 2', null, new Date(2017,8,4, 0, 0, 0), new Date(2018,0,16, 23, 59, 59)],
['Second Test entry number 2', null, new Date(2018,0,25, 0, 0, 0), new Date(2018,1,06, 23, 59, 59)]
]);
chart.draw(dataTable);
}
I'm getting desperate right here. hope somebody can help with this bug. Thank you.

looks like a problem with addRows
seen weird stuff happen when an entire column only has null values
(the code actually works for me as-is in chrome)
the 'Role' column is optional, you can remove it...
see following working snippet...
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: 'Group' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['First', new Date(2017,1,15, 22, 40, 26), new Date(2017,10,29, 23, 59, 59)],
['Second Test entry number 2', new Date(2017,8,4, 0, 0, 0), new Date(2018,0,16, 23, 59, 59)],
['Second Test entry number 2', new Date(2018,0,25, 0, 0, 0), new Date(2018,1,06, 23, 59, 59)]
]);
chart.draw(dataTable);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
or use a blank string '' instead...
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: 'Group' });
dataTable.addColumn({ type: 'string', id: 'Role' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['First', '', new Date(2017,1,15, 22, 40, 26), new Date(2017,10,29, 23, 59, 59)],
['Second Test entry number 2', '', new Date(2017,8,4, 0, 0, 0), new Date(2018,0,16, 23, 59, 59)],
['Second Test entry number 2', '', new Date(2018,0,25, 0, 0, 0), new Date(2018,1,06, 23, 59, 59)]
]);
chart.draw(dataTable);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Related

Transforming DataTable to Google Spreadsheet

I have made a simple timetable using Google Charts, although right now i use DataTable inside the code. Instead i want to use Google Spreadsheet as the source.
But i am struggling even though i follow https://developers.google.com/chart/interactive/docs/spreadsheets. I dont quite understand in which format should my datas be in the spreadsheet (such as columns and rows)
Here is the code:
<head>
<h1>Vehicle Plan Time Table</h1>
<style>
h1 {
color: #3e74ab;
text-shadow: 1px 1px;
font-family: "Times New Roman", Times, serif;
text-align: center;
}
</style>
</head>
<body>
<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('timechart');
var chart = new google.visualization.Timeline(container);
var options = {
colors: ['#113477', '#C0C0C0','#adc6e5', '#72aae4','#518cc2','#4A7FB0'],
timeline: { rowLabelStyle: {fontName: 'Arial', fontSize: 20, color: '#0000' },
barLabelStyle: { fontName: 'Times New Roman', fontSize: 25 } },
'width':2650,
'height':1200,
avoidOverlappingGridLines: false
};
chart.draw(dataTable, options);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Position' });
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ Date(), 'Now', new Date(), new Date()],
[ 'Project #1', 'F2', new Date(2022, 10, 30), new Date(2022, 11, 30) ],
[ 'Project #1', 'F3', new Date(2022, 11, 30), new Date(2023, 5, 17) ],
[ 'Project #1', 'F3.1', new Date(2023, 5, 17), new Date(2023, 9, 29) ],
]);
chart.draw(dataTable,options);
nowLine('timeline');
google.visualization.events.addListener(chart, 'onmouseover', function(obj){
if(obj.row == 0){
$('.google-visualization-tooltip').css('display', 'none');
}
nowLine('timeline');
})
google.visualization.events.addListener(chart, 'onmouseout', function(obj){
nowLine('timeline');
})
}
function nowLine(div){
var height;
$('#' + div + ' rect').each(function(index){
var x = parseFloat($(this).attr('x'));
var y = parseFloat($(this).attr('y'));
if(x == 0 & y == 0) {height = parseFloat($(this).attr('height'))}
})
var nowWord = $('#' + div + ' text:contains("Now")');
nowWord.prev().first().attr('height', height + 'px').attr('width', '1px').attr('y', '0');
}
</script>
<div id="timechart" style="height: 400px;"></div>

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>

Change Google Chart Timeline bar color according boolean condition from data table

My dataTable has 6 columns. Column 5 is boolean. I would like to color the bars according to the column 2 as I already did, however if column 5 is false, color should be grey (no matter the string in column 2).
I tried to use " dataTable.addColumn({ type: 'boolean', role: 'scope' });"
But it does not work with Timelines. I also tried to send string with the color for each bar in column 5 but it also did not work.
Could you please help me with this?
var timeLineGraph = 'timeLineGraph';
var arrayDataTimeline = [
[ 'Debora', 'Pharmacist', 1, new Date(2017,2,1,06,0,0), new Date(2017,2,1,11,0,0), true],
[ 'Debora', 'Pharmacist', 1, new Date(2017,2,1,12,00,0), new Date(2017,2,1,15,0,0), true],
[ 'Gabriela', 'Pharmacist', 2, new Date(2017,2,1,07,00,0), new Date(2017,2,1,13,0,0), false ],
[ 'Gabriela', 'Pharmacist',2, new Date(2017,2,1,14,00,0), new Date(2017,2,1,16,0,0), false],
[ 'Andrieli', 'Teller', 3, new Date(2017,2,1,15,00,0), new Date(2017,2,1,18,0,0), true],
[ 'Andrieli', 'Teller', 3, new Date(2017,2,1,19,00,0), new Date(2017,2,1,24,0,0), true],
[ 'Alex', 'Teller', 4, new Date(2017,2,1,15,00,0), new Date(2017,2,1,18,0,0), true],
[ 'Alex', 'Teller', 4, new Date(2017,2,1,19,00,0), new Date(2017,2,1,24,0,0),true]];
google.charts.load("current", {packages:["timeline"]});
function drawTimeline(timeLineGraph, arrayDataTimeline) {
var container = document.getElementById(timeLineGraph);
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Nome'});
dataTable.addColumn({ type: 'string', id: 'Cargo' });
dataTable.addColumn({ type: 'number', role: 'id' });
dataTable.addColumn({ type: 'date', id: 'Começo' });
dataTable.addColumn({ type: 'date', id: 'Fim' });
dataTable.addColumn({ type: 'boolean', role: 'scope' });
dataTable.addRows(arrayDataTimeline);
var options = {
showBarLabels: false,
groupByRowLabel: true, // novo
rowLabelStyle: {fontName: 'sans-serif'},
hAxis: {
format: 'HH:mm'
}
};
}
drawTimeline(timeLineGraph, arrayDataTimeline);
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<div id="timeLineGraph" style="height: 500px;"></div>
</body>
</html>
first, when drawing the chart, the data table must match the data format
which is why adding the boolean column doesn't work
to keep the boolean column, use a DataView to hide it from the chart...
var dataView = new google.visualization.DataView(dataTable);
dataView.hideColumns([5]);
then use the dataView to draw the chart
chart.draw(dataView, options);
next, since there are no standard options to color a bar, "one off" from the rest
the color can be changed manually with script, once the chart's 'ready' event fires
however, on any interactivity, the chart will revert the bars back to their original colors
such as select, mouse over, etc...
to force the chart to keep the new color,
use a MutationObserver to know when the chart has interactivity,
and change the bar to the desired color
finally, to find the bars to change,
look through the <rect> elements created by the chart
the timeline bars (<rect> elements) will have an 'x' attribute greater than zero
also, the order of the elements in the dom, will follow the order of the rows in the data table
so once the first bar is found, it will relate back to the first row in the data table, and so on...
however, separate bars are drawn when the mouse hovers the bar, for highlighting
these equate to extra bars, and will not have a relation back to the data table
as such, when the 'ready' event fires, find the bars and save the coordinates to an array
then in the MutationObserver, if a bar is found that matches the coordinates saved in the array, change the color
see following working snippet...
google.charts.load('current', {
callback: function () {
var timeLineGraph = 'timeLineGraph';
var arrayDataTimeline = [
['Debora', 'Pharmacist', 1, new Date(2017,2,1,06,0,0), new Date(2017,2,1,11,0,0), true],
['Debora', 'Pharmacist', 1, new Date(2017,2,1,12,00,0), new Date(2017,2,1,15,0,0), true],
['Gabriela', 'Pharmacist', 2, new Date(2017,2,1,07,00,0), new Date(2017,2,1,13,0,0), false],
['Gabriela', 'Pharmacist',2, new Date(2017,2,1,14,00,0), new Date(2017,2,1,16,0,0), false],
['Andrieli', 'Teller', 3, new Date(2017,2,1,15,00,0), new Date(2017,2,1,18,0,0), true],
['Andrieli', 'Teller', 3, new Date(2017,2,1,19,00,0), new Date(2017,2,1,24,0,0), true],
['Alex', 'Teller', 4, new Date(2017,2,1,15,00,0), new Date(2017,2,1,18,0,0), true],
['Alex', 'Teller', 4, new Date(2017,2,1,19,00,0), new Date(2017,2,1,24,0,0),true]
];
drawTimeline(timeLineGraph, arrayDataTimeline);
},
packages:['timeline']
});
function drawTimeline(timeLineGraph, arrayDataTimeline) {
var container = document.getElementById(timeLineGraph);
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'Nome'});
dataTable.addColumn({type: 'string', id: 'Cargo'});
dataTable.addColumn({type: 'number', role: 'id'});
dataTable.addColumn({type: 'date', id: 'Começo'});
dataTable.addColumn({type: 'date', id: 'Fim'});
dataTable.addColumn({type: 'boolean', role: 'scope'});
dataTable.addRows(arrayDataTimeline);
var dataView = new google.visualization.DataView(dataTable);
dataView.hideColumns([5]);
var options = {
showBarLabels: false,
groupByRowLabel: true,
rowLabelStyle: {fontName: 'sans-serif'},
hAxis: {
format: 'HH:mm'
}
};
var observer = new MutationObserver(setScope);
var outOfScope = [];
google.visualization.events.addListener(chart, 'ready', function () {
var rowIndex = 0;
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function (bar) {
if (parseFloat(bar.getAttribute('x')) > 0) {
if (!dataTable.getValue(rowIndex, 5)) {
bar.setAttribute('fill', '#9e9e9e');
outOfScope.push([
bar.getAttribute('x'),
bar.getAttribute('y')
]);
}
rowIndex++;
}
});
observer.observe(container, {
childList: true,
subtree: true
});
});
function setScope() {
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function (bar) {
outOfScope.forEach(function (coords) {
if ((bar.getAttribute('x') === coords[0]) && (bar.getAttribute('y') === coords[1])) {
bar.setAttribute('fill', '#9e9e9e');
}
});
});
}
chart.draw(dataView, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeLineGraph"></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?

create a custom info window in google scatter

I have a google scatter, and I would like when mouse is over on circle then open a info window containing a custom string.
for example in tutorial https://developers.google.com/chart/interactive/docs/events#Event_Listeners
when click on circle open a info window with a custom string.
Thanks
EDIT:
I try this code:
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'SVD1');
dataTable.addColumn('number', 'SVD2');
dataTable.addColumn('number', 'SVD3');
// A column for custom tooltip content
dataTable.addColumn({type: 'string', role: 'tooltip'});
dataTable.addRows([
[2010, 600, null ,'test1'],
[2011, 1500, null , 'test2'],
[2012, null, 800, 'test3'],
[2013, null, 1000, 'test4']
]);
var options = {
tooltip: {isHtml: true},
legend: 'none'
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(dataTable, options);
}
Using tooltip the Strings "test 3" and "test4" appear right. The string "test1" and " "test2" disappear. Why???
I found it!!! Βelow give a solution to the problem.
Sample Code:
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'SVD1');
dataTable.addColumn('number', 'SVD2');
dataTable.addColumn({type: 'string', role: 'tooltip'});
dataTable.addColumn('number', 'SVD3');
// A column for custom tooltip content
dataTable.addColumn({type: 'string', role: 'tooltip'});
dataTable.addRows([
[2010, 600, 'test1' ,null, null],
[2011, 1500, 'test2' ,null, null ],
[2012, null, null, 800, 'test3'],
[2013, null, null, 1000, 'test4']
]);
var options = {
tooltip: {isHtml: true},
legend: 'none'
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(dataTable, options);
}

Categories