Customizing tooltip on Google Timeline Chart - javascript

I created a Google Timeline Chart to see my musical listening history. It looks like this:
I want to remove duration part from the tooltip, but couldn't find any option for it. I tried adding these lines:
dataTable.addColumn({type: 'string', role:'tooltip'});
and a row in my dataTable.addRows([]) function looks like this:
['25 August', 'Kasabian - La Fee Verte', new Date(2016,01,01, 13,37,32), new Date(2016,01,01, 13,43,19), 'tooltip example'],
but it still shows the same tooltip as in the image. I actually want to show Kasabian - La Fee Verte and 25 August: 1:37 pm - 1:43 pm just like in the image, but I want to remove duration.

according to the data format for a Timeline chart, the tooltip should be in the 3rd column.
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: 'RowLabel'});
dataTable.addColumn({type: 'string', id: 'BarLabel'});
dataTable.addColumn({type: 'date', id: 'Start'});
dataTable.addColumn({type: 'date', id: 'End'});
dataTable.addRows([
['25 August', 'Kasabian - La Fee Verte', new Date(2016,01,01, 13,37,32), new Date(2016,01,01, 13,43,19)],
['26 August', 'Test Data 1', new Date(2016,01,01, 13,37,32), new Date(2016,01,01, 13,43,19)],
['27 August', 'Test Data 2', new Date(2016,01,01, 13,37,32), new Date(2016,01,01, 13,43,19)],
]);
dataTable.insertColumn(2, {type: 'string', role: 'tooltip', p: {html: true}});
var dateFormat = new google.visualization.DateFormat({
pattern: 'h:mm a'
});
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
var tooltip = '<div class="ggl-tooltip"><span>' +
dataTable.getValue(i, 1) + '</span></div><div class="ggl-tooltip"><span>' +
dataTable.getValue(i, 0) + '</span>: ' +
dateFormat.formatValue(dataTable.getValue(i, 3)) + ' - ' +
dateFormat.formatValue(dataTable.getValue(i, 4)) + '</div>';
dataTable.setValue(i, 2, tooltip);
}
chart.draw(dataTable, {
tooltip: {
isHtml: true
}
});
},
packages: ['timeline']
});
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
padding: 6px 6px 6px 6px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></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>

How to add a background color to a specific row in Google Charts

I would like to add a background color to a specific row(s) in my Google Timeline Chart. I know there's a global setting to set the background of the entire chart, but how would I do this for a specific row. Here's an example of what I mean:
I would like the "Willow Room" row (and only that row) to have a background as follows:
Here is a jsfiddle example of the above (without the red background that I'm trying to get): https://jsfiddle.net/0f86vLrg/3/.
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: 'Platform' });
dataTable.addColumn({ type: 'string', id: 'Status' });
dataTable.addColumn({ type: 'string', role: 'style' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
// set the background of a missing item
dataTable.addRows([
[ 'Magnolia Room', '', null, new Date(0,0,0,12,0,0), new Date(0,0,0,13,30,0) ],
[ 'Magnolia Room', '', null, new Date(0,0,0,14,0,0), new Date(0,0,0,15,30,0) ],
[ 'Willow Room', '', 'error', new Date(0,0,0,12,30,0), new Date(0,0,0,14,0,0) ],
[ 'X Room', '', 'opacity: 0', new Date(0,0,0,0,0,0), new Date(0,0,1,0,0,0)]]);
var options = {
timeline: { colorByRowLabel: true },
backgroundColor: '#ffd'
};
chart.draw(dataTable, {
hAxis: {
minValue: new Date(0,0,0,0,0,0),
maxValue: new Date(0,0,0,24,0,0),
}
});
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height: 180px;"></div>
How would I add in a background color for a specific row based on the "style" setting of that row (or if there's a better way to give it a class or something.) For example in the above code the style is called "error" for the "Willow Room" item.
there are no options for styling a specific bar on the timeline chart.
and the data format does not support the 'style' role, only the 'tooltip' role.
but we can still use the data table column to specify the error rows.
and we'll need to change their color manually, on the chart's 'ready' event.
the thing that makes this difficult, the chart will combine data table rows onto a single bar,
depending on the row label or even possibly the date range.
so the number of bars in the chart will not always match the number of bars in the data table.
however, they will be drawn in the same order as found in the data table.
as such, we must first find the corresponding data table row for the label.
then check to see if the label's row has an error.
then find the bar with the same index as the label and change the color.
see following working snippet...
google.charts.load('current', {
packages:['timeline']
}).then(function () {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Platform' });
dataTable.addColumn({ type: 'string', id: 'Status' });
dataTable.addColumn({ type: 'string', role: 'style' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['Magnolia Room', '', null, new Date(0,0,0,12,0,0), new Date(0,0,0,13,30,0)],
['Magnolia Room', '', null, new Date(0,0,0,14,0,0), new Date(0,0,0,15,30,0)],
['Willow Room', '', 'error', new Date(0,0,0,12,30,0), new Date(0,0,0,14,0,0)],
['X Room', '', null, new Date(0,0,0,0,0,0), new Date(0,0,1,0,0,0)]
]);
var options = {
timeline: {colorByRowLabel: true},
backgroundColor: '#ffd',
height: 180
};
// change bar color for errors
google.visualization.events.addListener(chart, 'ready', function() {
var rows;
var barIndex;
var labelIndex = 0;
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
// process bar labels
if (label.getAttribute('text-anchor') === 'end') {
// find data rows for label
rows = dataTable.getFilteredRows([{
column: 0,
test: function (value) {
var labelFound;
var labelText;
// chart will cutoff label if not enough width
if (label.textContent.indexOf('…') > -1) {
labelText = label.textContent.replace('…', '');
labelFound = (value.indexOf(labelText) > -1);
} else {
labelText = label.textContent;
labelFound = (value === labelText);
}
return labelFound;
}
}]);
if (rows.length > 0) {
// process label rows
rows.forEach(function (rowIndex) {
// check if row has error
if (dataTable.getValue(rowIndex, 2) === 'error') {
// change color of label
label.setAttribute('fill', '#c62828');
// change color of bar
barIndex = 0;
var bars = container.getElementsByTagName('rect');
Array.prototype.forEach.call(bars, function(bar) {
if ((bar.getAttribute('x') === '0') && (bar.getAttribute('stroke-width') === '0')) {
if (barIndex === labelIndex) {
bar.setAttribute('fill', '#ffcdd2');
}
barIndex++;
}
});
}
});
}
labelIndex++;
}
});
});
chart.draw(dataTable, {
hAxis: {
minValue: new Date(0,0,0,0,0,0),
maxValue: new Date(0,0,0,24,0,0)
}
});
});
#timeline svg g text {
font-weight: normal !important;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

google charts html tooltip issue

When I select one point at chart, tooltip html content is correct, but when select 2 and more points, tooltips merge in one and html of each one is visible. Are smbd know what i do wrong ? Can smbd help me ?
var data = new google.visualization.DataTable();
data.addColumn('date', 'Time');
data.addColumn('number' , "id");
data.addColumn({type: 'string', role: 'tooltip', p: {'html': true}});
var dataArray = [];
tooltipContent = "<div class='google-chart-tooltip'><center class='google-chart-tooltip-date'>Date: " + date + "</center><br /><p>Value1: " + value1 + ";<br />Value2: " + value2 + ".</p></div>";
//fill dataArray
data.addRows(dataArray);
}
var currentChartOptions = {
tooltip: {
isHtml: true,
trigger: 'selection'
},
selectionMode: 'multiple',
interpolateNulls: true,
hAxis: {
title: 'Time'
},
vAxis: {
title: "Values"
}
};
Follows an image of the issue:
looks like a bug, from what i can tell, code looks fine
there are no missing options or anything like that
and it is easily replicated, as in the following example
you could use aggregationTarget: 'none' to force each tooltip to be shown separately
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Time');
data.addColumn('number' , 'id');
data.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
var dataArray = [
[new Date(2016, 11, 18), 1000, 400],
[new Date(2016, 11, 19), 1170, 1170],
[new Date(2016, 11, 20), 660, 1120],
[new Date(2016, 11, 21), 1030, 540]
];
dataArray.forEach(function (row) {
data.addRow([
row[0],
row[1],
'<div class="google-chart-tooltip"><center class="google-chart-tooltip-date">Date: ' + row[0] + '</center><br /><p>Value1: ' + row[1] + ';<br />Value2: ' + row[2] + '.</p></div>'
]);
});
var currentChartOptions = {
aggregationTarget: 'none',
tooltip: {
isHtml: true,
trigger: 'selection'
},
selectionMode: 'multiple',
interpolateNulls: true,
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Values'
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, currentChartOptions);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Removing tooltip for one part of piechart google charts

I have a structure of chart like this:-
data: {
cols: [
{
id: 'Type',
type: 'string'
},
{
id: 'percentage',
type: 'number'
},
{
id: 'tooltip',
role: 'tooltip',
type: 'string',
p: { html: true }
}
],
rows: [
{
c: [
{
v: typeA
},
{
v: 20
},
{
v: 'my Tooltip content'
}
]
},
{
c: [
{
v: 'typeB'
},
{
v: 80
}
]
}
]
},
I want to disable the tooptip only for typeB and but should work with typeA. Is this possible in google charts? (tooptip trigger:none option disable it for whole chart)
when using custom tooltips, if the tooltip column is null or ''
the chart will replace with the default tooltip
to avoid, provide a custom tooltip that is hidden with css
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Type', 'Percent'],
['typeA', 20],
['typeB', 80]
]);
// add tooltip column
data.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// build tooltip
for (var i = 0; i < data.getNumberOfRows(); i++) {
switch (data.getValue(i, 0)) {
// set visible tooltip
case 'typeA':
data.setValue(i, 2,
'<div class="ggl-tooltip"><div><span>' +
data.getValue(i, 0) + '</span></div><div>' +
data.getValue(i, 1) + '</div></div>'
);
break;
// set hidden tooltip
case 'typeB':
data.setValue(i, 2, '<div class="hdn-tooltip"><div>');
break;
}
}
var container = document.getElementById('chart_div');
var pieChart = new google.visualization.PieChart(container);
pieChart.draw(data, {
tooltip: {
isHtml: true
}
});
},
packages: ['corechart']
});
.hdn-tooltip {
display: none;
visibility: hidden;
}
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
font-size: 10pt;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip div {
padding-top: 6px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Disable line that appears on a legend click for Google Line Chart

Whenever a series gets clicked on a legend in a Google Line chart, it seems that a line appears above the data trendline. Is it possible to stop this behavior? I could not find anything in the docs.
An example of this:
when the legend is clicked, the entire series is selected,
which means the row value will be null
chart.getSelection() will return something like...
{row: null, column 1}
vs. when a data point is clicked / selected, the row will have a number reference row: 1, etc...
as such, use the 'select' event listener and cancel the selection when the row is null
chart.setSelection([]);
see following working snippet...
google.charts.load('current', {
callback: function () {
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', label: 'Year'});
// series 0
dataTable.addColumn({type: 'number', label: 'Category A'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 1
dataTable.addColumn({type: 'number', label: 'Category B'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 2
dataTable.addColumn({type: 'number', label: 'Category C'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
dataTable.addRows([
['2014', 1000, null, 2000, null, 3000, null],
['2015', 2000, null, 4000, null, 6000, null],
['2016', 3000, null, 6000, null, 9000, null],
]);
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
dataTable.setValue(i, 2, getTooltip(i, 1));
dataTable.setValue(i, 4, getTooltip(i, 3));
dataTable.setValue(i, 6, getTooltip(i, 5));
}
function getTooltip(rowIndex, columnIndex) {
return '<div class="ggl-tooltip"><span>' +
dataTable.getValue(rowIndex, 0) + ': </span>' +
dataTable.getFormattedValue(rowIndex, columnIndex) + '</div>';
}
// use 'select' listener to disable selection on legend click
google.visualization.events.addListener(chart, 'select', function () {
var selection = chart.getSelection();
if (selection.length > 0) {
if (selection[0].row === null) {
chart.setSelection([]);
}
}
});
chart.draw(dataTable, {
legend: {
position: 'bottom'
},
pointSize: 4,
tooltip: {
isHtml: true
}
});
},
packages: ['corechart']
});
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
font-size: 10pt;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Categories