Remove borders and gridlines around google chart timeline - javascript

I need to remove the border and the gridlines from the google charts timetable (see documentation)
Right now it looks like this: with borders
It should look like this: without borders
I made a stackblitz for it: https://stackblitz.com/edit/js-ozv5hr?file=index.html
It seems like the config options that you can use for example with line charts do not work with timelines.

there are no config options available for removing the borders,
but we can remove them manually on the chart's 'ready' event.
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: "Label" });
dataTable.addColumn({ type: "string", id: "Type" });
dataTable.addColumn({ type: "date", id: "Start" });
dataTable.addColumn({ type: "date", id: "End" });
dataTable.addRows([
["A", "A", new Date(2021, 0, 0, 0), new Date(2021, 0, 0, 1)],
["A", "B", new Date(2021, 0, 0, 1), new Date(2021, 0, 0, 2)],
["A", "C", new Date(2021, 0, 0, 2), new Date(2021, 0, 0, 3)]
]);
var options = {
timeline: {
groupByRowLabel: true,
showRowLabels: false,
showBarLabels: false
},
avoidOverlappingGridLines: false,
hAxis: {
format: "HH:mm"
},
gridlines: {
color: "none"
}
};
google.visualization.events.addListener(chart, 'ready', function () {
// find <rect> elements
var rects = container.getElementsByTagName('rect');
Array.prototype.forEach.call(rects, function(rect) {
if (rect.getAttribute('stroke') === '#9a9a9a') {
// remove border
rect.setAttribute('stroke-width', '0');
}
});
// find <path> elements
var paths = container.getElementsByTagName('path');
Array.prototype.forEach.call(paths, function(path) {
if ((path.getAttribute('stroke') === '#ffffff') || (path.getAttribute('stroke') === '#e6e6e6')) {
// remove border
path.setAttribute('stroke-width', '0');
}
});
});
chart.draw(dataTable, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Related

Google Chart Resize on Window Resize

How can I get my google chart to resize properly, currently it gets bigger when I expand the window but it does not shrink when i shrink the window. Essentially I've wrapped the entire google chart in a resize function but it isn't quite right:
function resize() {
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: 'Type' });
dataTable.addColumn({ type: 'string', id: 'Organisation' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Work Experience', 'GE', new Date(2010, 8, 1 ), new Date(2011, 8, 30) ],
[ 'Work Experience', 'Shell', new Date(2015, 2, 1), new Date(2016, 1, 1) ],
[ 'Work Experience', 'British Gas', new Date(2016, 1, 1), new Date(2017, 9, 1) ],
[ 'Work Experience', 'British Telecom', new Date(2017, 9, 1), new Date() ],
[ 'Work Experience', 'University', new Date(2011, 8, 30), new Date(2015, 2,1) ]
]);
var options = {
timeline: {showRowLabels: false},
backgroundColor: '#161616',
barLabelStyle: { fontName: 'Roboto', color: '#ffffff' },
height: 100,
hAxis: {textStyle:{color: '#ffffff'}}
};
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
label.setAttribute('fill', '#ffffff');
}
});
});
google.visualization.events.addListener(chart, 'ready', function () {
var rects = container.getElementsByTagName('rect');
Array.prototype.forEach.call(rects, function(rect) {
// find chart <rect> element
if ((rect.getAttribute('x') === '0') && (rect.getAttribute('y') === '0')) {
// remove stroke from last <rect> element
rect.setAttribute('stroke', 'none');
rect.setAttribute('stroke-width', '0');
}
});
});
chart.draw(dataTable, options);
}
}
window.onload = resize;
window.onresize = resize;
when resizing, you need to clear the chart, before re-drawing.
if the chart is not cleared, it can prevent the chart's container from shrinking.
then when re-drawn, it is the same size.
(this all depends on the page layout, but clearing will resolve most issues)
use method --> chart.clearChart()
also, the load callback only needs to be called once per page load.
no need to include the load statement in the resize event handler.
and, google's load statement will wait for the page to load by default.
and can be used in place of --> window.onload
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: 'Type' });
dataTable.addColumn({ type: 'string', id: 'Organisation' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['Work Experience', 'GE', new Date(2010, 8, 1 ), new Date(2011, 8, 30)],
['Work Experience', 'Shell', new Date(2015, 2, 1), new Date(2016, 1, 1)],
['Work Experience', 'British Gas', new Date(2016, 1, 1), new Date(2017, 9, 1)],
['Work Experience', 'British Telecom', new Date(2017, 9, 1), new Date()],
['Work Experience', 'University', new Date(2011, 8, 30), new Date(2015, 2,1)]
]);
var options = {
timeline: {showRowLabels: false},
backgroundColor: '#161616',
barLabelStyle: {fontName: 'Roboto', color: '#ffffff'},
height: 100,
hAxis: {textStyle:{color: '#ffffff'}}
};
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
label.setAttribute('fill', '#ffffff');
}
});
var rects = container.getElementsByTagName('rect');
Array.prototype.forEach.call(rects, function(rect) {
// find chart <rect> element
if ((rect.getAttribute('x') === '0') && (rect.getAttribute('y') === '0')) {
// remove stroke from last <rect> element
rect.setAttribute('stroke', 'none');
rect.setAttribute('stroke-width', '0');
}
});
});
window.addEventListener('resize', drawChart);
drawChart();
function drawChart() {
chart.clearChart();
chart.draw(dataTable, options);
}
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Change color of column stroke in Google Visualization Timeline

I'm attempting to change the stroke color for columns in the Google Visualization Timeline.
I am able to do that but I can't specify that only the vertical stroke lines should be changed not the horizontal lines.
Is there a way to identify just the vertical lines? The svg calls both horizontal lines and vertical "path d".
google.charts.load('current', {
callback: drawChart,
packages: ['timeline']
});
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) ]
]);
var observer = new MutationObserver(setcolumnstroke);
google.visualization.events.addListener(chart, 'ready', function () {
setcolumnstroke();
observer.observe(container, {
childList: true,
subtree: true
});
});
function setcolumnstroke() {
Array.prototype.forEach.call(container.getElementsByTagName('path'), function (path) {
path.setAttribute('stroke', '#000000');
});
}
chart.draw(dataTable);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
Here's one way: Take the X coordinate from the d attribute (the first digit after M and the first digit after L) if they are the same, it is a vertical line.
Regex Answer
Using regex to match the first numbers after M to the numbers after L: M(\d+).*L\1
google.charts.load('current', {
callback: drawChart,
packages: ['timeline']
});
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) ]
]);
var observer = new MutationObserver(setcolumnstroke);
google.visualization.events.addListener(chart, 'ready', function () {
setcolumnstroke();
observer.observe(container, {
childList: true,
subtree: true
});
});
function setcolumnstroke() {
Array.prototype.forEach.call(container.getElementsByTagName('path'), function (path) {
// Check for vertical lines
if ( path.getAttribute('d').match(/M(\d+).*L\1/) ) {
path.setAttribute('stroke', '#FF0000');
} else {
path.setAttribute('stroke', '#000000');
}
});
}
chart.draw(dataTable);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
Old Answer:
Using substring method: if (d.substring(1, 4) == d.substring(d.indexOf('L')+1, d.indexOf('L')+4))
// The X coordinate of the M (move) command
d.substring(1, 4)
// The X coordinate of the L (line) command
d.substring(d.indexOf('L')+1, d.indexOf('L')+4))
Note this would break if it is not formatted exactly as M...L... but perhaps google charts path output is always in that format.
google.charts.load('current', {
callback: drawChart,
packages: ['timeline']
});
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) ]
]);
var observer = new MutationObserver(setcolumnstroke);
google.visualization.events.addListener(chart, 'ready', function () {
setcolumnstroke();
observer.observe(container, {
childList: true,
subtree: true
});
});
function setcolumnstroke() {
Array.prototype.forEach.call(container.getElementsByTagName('path'), function (path) {
let d = path.getAttribute('d');
let dl = d.indexOf('L');
if ( d.substring(1, d.indexOf(',')) == d.substring(dl+1, d.indexOf(',', dl)) ) {
path.setAttribute('stroke', '#FF0000');
} else {
path.setAttribute('stroke', '#000000');
}
});
}
chart.draw(dataTable);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Google Timeline Chart Change HAxis to string value

I would like to ask if it is possible that the haxis value (The one with dates below) for Google Timeline change to string format?
For example, Oct. 30 will be changed to Week 1, Nov. 6 to Week 2, and so on.
Any help and suggestions are welcomed and appreciated.
Thanks in advance!
the timeline chart is very limited compared to the core charts
both in terms of options available and helper methods for finding chart coordinates, etc...
but like core charts, timelines produce svg, which can be modified using javascript
see following working snippet...
once the chart's 'ready' event fires, all of the haxis labels are removed
then custom labels are added back for the week numbers
before removing all the labels, one is cloned, in order to keep the same font, color, y-coordinate, etc...
then the timeline bars are used to find the x-coordinate and add the new label
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: 'Category'});
dataTable.addColumn({type: 'date', id: 'Start'});
dataTable.addColumn({type: 'date', id: 'End'});
dataTable.addRows([
['Category A', new Date(2016, 9, 30), new Date(2016, 10, 5)],
['Category B', new Date(2016, 10, 6), new Date(2016, 10, 12)],
['Category C', new Date(2016, 10, 13), new Date(2016, 10, 19)]
]);
google.visualization.events.addListener(chart, 'ready', function () {
var rowIndex = 0; // data table row index
var weekLabel = null; // clone of text node - keep font settings, y-coord, etc...
// remove haxis labels
var labels = container.getElementsByTagName('text');
while (labels.length > dataTable.getNumberOfRows()) {
// ignore "category" labels
if (dataTable.getFilteredRows([{column: 0, value: labels[labels.length - 1].innerHTML}]).length === 0) {
if (weekLabel === null) {
weekLabel = labels[labels.length - 1].cloneNode(true);
}
labels[labels.length - 1].parentNode.removeChild(labels[labels.length - 1]);
}
}
// use timeline bars to find x coordinate for week labels
rowIndex = 0;
var svgParent = container.getElementsByTagName('svg')[0];
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(bar) {
var bounds; // bounding box of text element
// ignore rect if not a timeline bar
if (parseFloat(bar.getAttribute('x')) > 0) {
weekLabel = weekLabel.cloneNode(true);
weekLabel.innerHTML = 'Week ' + (rowIndex + 1);
svgParent.appendChild(weekLabel);
bounds = weekLabel.getBBox();
weekLabel.setAttribute('x', parseFloat(bar.getAttribute('x')) + bounds.width);
rowIndex++;
}
});
});
chart.draw(dataTable);
},
packages:['timeline']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
google.charts.load("current", {packages:["timeline"], callback: drawChart});
function drawChart() {
var container = document.getElementById('chart_div');
var chart = new google.visualization.Timeline(container);
// hAxis put on top
google.visualization.events.addListener(chart, 'ready', afterDraw);
// Link in tooltip
google.visualization.events.addListener(chart, 'select', function(e) {
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
chart.ttclone = tooltip.cloneNode(true);
chart.ttclone.setAttribute('clone', true);
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
});
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Name' });
// for colorMap
dataTable.addColumn({ type: 'string', id: 'Course' });
dataTable.addColumn({ type: 'string', id: 'Subject' });
dataTable.addColumn({ type: 'string', id: 'ToolTip', role: 'tooltip', p:{html:true} });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
// Timeline Start
['Student 1', 'ENGR', 'Trigonometry', 'Trigonometry', new Date(2016, 9, 30), new Date(2016, 10, 06)],
['Student 2', 'IT', 'DB Management', 'DB Management', new Date(2016, 9, 30), new Date(2016, 10, 13)],
['Student 3', 'CS', 'Introduction to Programming', 'Introduction to Programming', new Date(2016, 9, 30), new Date(2016, 10, 27)],
]);
var colors = [];
var colorMap = {
ENGR: '#2ECC71', // Green
IT: '#E67E22', // Brown
CS: '#9B59B6', // Violet
}
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
colors.push(colorMap[dataTable.getValue(i, 1)]);
}
var rowHeight = 41;
var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;
var options = {
timeline: {
groupByRowLabel: true,
rowLabelStyle: {
fontName: 'Century Gothic',
fontSize: 14,
color: '#333333',
bold: 'true',
},
barLabelStyle: {
fontName: 'Century Gothic',
fontSize: 11,
},
showRowLabels: true,
showBarLabels: true,
},
hAxis: {
minValue: new Date(2016, 9, 30),
maxValue: new Date(2017, 9, 28),
},
avoidOverlappingGridLines: true,
height: chartHeight,
width: '100%',
colors: colors,
};
// use a DataView to hide the category column from the Timeline
var view = new google.visualization.DataView(dataTable);
view.setColumns([0, 2, 3, 4, 5]);
// Change HAxis labels to Week
google.visualization.events.addListener(chart, 'ready', function () {
var rowIndex = 0; // data table row index
var weekLabel = null; // clone of text node - keep font settings, y-coord, etc...
// remove haxis labels
var labels = container.getElementsByTagName('text');
while (labels.length > dataTable.getNumberOfRows()) {
// ignore "category" labels
if (dataTable.getFilteredRows([{column: 5, value: labels[labels.length - 1].innerHTML}]).length === 0) {
if (weekLabel === null) {
weekLabel = labels[labels.length - 1].cloneNode(true);
}
labels[labels.length - 1].parentNode.removeChild(labels[labels.length - 1]);
}
}
// use timeline bars to find x coordinate for week labels
rowIndex = 0;
var svgParent = container.getElementsByTagName('svg')[0];
Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(bar) {
var bounds; // bounding box of text element
// ignore rect if not a timeline bar
if (parseFloat(bar.getAttribute('x')) > 0) {
weekLabel = weekLabel.cloneNode(true);
weekLabel.innerHTML = 'WW 70' + (rowIndex + 1);
svgParent.appendChild(weekLabel);
bounds = weekLabel.getBBox();
weekLabel.setAttribute('x', parseFloat(bar.getAttribute('x')) + bounds.width);
rowIndex++;
}
});
});
chart.draw(
view,
options,
dataTable, {
tooltip: {
isHtml: true,
},
timeline: {
showBarLabels: false,
}
});
}
// hAxis put on top
function afterDraw() {
var g = document.getElementsByTagName("svg")[0].getElementsByTagName("g")[1];
document.getElementsByTagName("svg")[0].parentNode.style.top = '40px';
document.getElementsByTagName("svg")[0].style.overflow = 'visible';
var height = Number(g.getElementsByTagName("text")[0].getAttribute('y')) + 15;
g.setAttribute('transform','translate(0,-'+height+')');
g = null;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

How to reload data in Google Charts Calendar while keeping selected cell?

I use jQuery and I use the following JS function to load and reload / redraw the Google Chart Calendar.
It works, however, it also removes the border from the selected item. I want to reload the calendar data, while keeping the currently selected item selected.
Any ideas?
function refreshCalendar( rows)
{
//if( calendar != 0 )
{
calendar = new google.visualization.Calendar(document.getElementById('calendar_basic'))
google.visualization.events.addListener(calendar, 'select', calendarSelectHandler);
calendarData = new google.visualization.DataTable();
calendarData.addColumn({ type: 'date', id: 'Date' });
calendarData.addColumn({ type: 'number', id: 'Logs' });
calendarData.addRows( rows );
calendarOptions = {
title: "Logs",
height: 175,
colorAxis: {minValue: 0, colors: ['#FFFFFF', '#FF0000']},
calendar: {
focusedCellColor: {
background: '#00FF00',
stroke: '#004400',
strokeOpacity: 1,
strokeWidth: 2,
},
cellColor: {
stroke: '#76a7fa',
strokeOpacity: 0.5,
strokeWidth: 1,
}
}
};
calendar.draw(calendarData, calendarOptions);
}
}
Normally, you would use chart.getSelection and chart.setSelection.
Get selection on 'select' event
Set selection on 'ready' event
getSelection works fine, but setSelection doesn't work with the Calendar chart.
No error is thrown, but nothing is selected.
I tried versions '41' thru 'current'...
To demonstrate, the following example uses both a Calendar chart and a Column chart.
Make a selection on both charts, then click "Redraw Chart".
The selection for the Column chart remains but not on the Calendar.
google.charts.load('current', {
callback: drawChart,
packages: ['calendar', 'corechart']
});
function drawChart() {
var selectionCal;
var selectionCol;
var calendar = new google.visualization.Calendar(document.getElementById('calendar'))
google.visualization.events.addListener(calendar, 'select', function () {
selectionCal = calendar.getSelection();
});
google.visualization.events.addListener(calendar, 'ready', function () {
if (selectionCal) {
calendar.setSelection(selectionCal);
}
});
var column = new google.visualization.ColumnChart(document.getElementById('column'))
google.visualization.events.addListener(column, 'select', function () {
selectionCol = column.getSelection();
});
google.visualization.events.addListener(column, 'ready', function () {
if (selectionCol) {
column.setSelection(selectionCol);
}
});
document.getElementById('test_button').addEventListener('click', function () {
calendar.draw(calendarData, calendarOptions);
column.draw(calendarData, {});
}, false);
var calendarData = new google.visualization.DataTable();
calendarData.addColumn({ type: 'date', id: 'Date' });
calendarData.addColumn({ type: 'number', id: 'Logs' });
calendarData.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 ],
]);
var calendarOptions = {
title: "Logs",
height: 175,
colorAxis: {minValue: 0, colors: ['#FFFFFF', '#FF0000']},
calendar: {
focusedCellColor: {
background: '#00FF00',
stroke: '#004400',
strokeOpacity: 1,
strokeWidth: 2,
},
cellColor: {
stroke: '#76a7fa',
strokeOpacity: 0.5,
strokeWidth: 1,
}
}
};
calendar.draw(calendarData, calendarOptions);
column.draw(calendarData, {});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="calendar"></div>
<div id="column"></div>
<input type="button" id="test_button" value="Redraw Chart" />
I can also confirm that the setSelection() method doesn't change anything on the UI for the calendar chart.
So I looked up what happens after selecting a day in the chart with the mouse. Then I implemented a simple DOM manipulation logic which does the same. You can use that logic as a replacement of the setSelection() use case. (It is just a quick prototype, but I hope it helps you, too).
For a litte demo I adjusted #WhiteHat snippet / the selected day survives now the refresh action (doesn't work with charts which needs to display more than one year!):
google.charts.load('current', {
callback: drawChart,
packages: ['calendar', 'corechart']
});
function drawChart() {
var selectionCal;
var selectionDate;
var selectionCol;
var calendar = new google.visualization.Calendar(document.getElementById('calendar'))
google.visualization.events.addListener(calendar, 'select', function () {
selectionCal = calendar.getSelection();
selectionDate = new Date(selectionCal[0].date);
});
google.visualization.events.addListener(calendar, 'ready', function () {
if (selectionDate) {
// google calendar setSelection BUG :/
// https://stackoverflow.com/a/36093217/810944
// do it manually
var doy = selectionDate.getDOY();
markDayInChart(doy);
}
});
var column = new google.visualization.ColumnChart(document.getElementById('column'))
google.visualization.events.addListener(column, 'select', function () {
selectionCol = column.getSelection();
});
google.visualization.events.addListener(column, 'ready', function () {
if (selectionCol) {
column.setSelection(selectionCol);
}
});
document.getElementById('test_button').addEventListener('click', function () {
calendar.draw(calendarData, calendarOptions);
column.draw(calendarData, {});
}, false);
var calendarData = new google.visualization.DataTable();
calendarData.addColumn({ type: 'date', id: 'Date' });
calendarData.addColumn({ type: 'number', id: 'Logs' });
calendarData.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 ],
]);
var calendarOptions = {
title: "Logs",
height: 175,
colorAxis: {minValue: 0, colors: ['#FFFFFF', '#FF0000']},
calendar: {
focusedCellColor: {
background: '#00FF00',
stroke: '#004400',
strokeOpacity: 1,
strokeWidth: 2,
},
cellColor: {
stroke: '#76a7fa',
strokeOpacity: 0.5,
strokeWidth: 1,
}
}
};
calendar.draw(calendarData, calendarOptions);
column.draw(calendarData, {});
}
function markDayInChart(dayOfYear) {
// clones the logic for clicking / selecting a day via mouse
// keep in mind to clean up the adjusted and added `rect`-elements if you do not use full page reloads!
// doesn't work with charts which needs to display more than one year!
var days_all_svg_group = $('#calendar svg').children('g')[1];
var days_marked_svg_group = $('#calendar svg').children('g')[4];
var day_svg_rect = $('rect:nth-of-type('+dayOfYear+')',$(days_all_svg_group));
// hide the original rect
$(day_svg_rect).css('display: none;');
// add a cloned rect with a different stroke
var day_marked_svg_rect = $(day_svg_rect).clone();
$(day_marked_svg_rect).attr({stroke: '#000000', 'stroke-width': 2});
$(day_marked_svg_rect).attr('stroke-opacity', null);
$(days_marked_svg_group).append(day_marked_svg_rect);
}
// https://stackoverflow.com/a/26426761/810944
Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
if((year & 3) != 0) return false;
return ((year % 100) != 0 || (year % 400) == 0);
};
// Get Day of Year
Date.prototype.getDOY = function() {
var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var mn = this.getMonth();
var dn = this.getDate();
var dayOfYear = dayCount[mn] + dn;
if(mn > 1 && this.isLeapYear()) dayOfYear++;
return dayOfYear;
};
<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="calendar"></div>
<div id="column"></div>
<input type="button" id="test_button" value="Redraw Chart" />

Google column chart - set selected column color

I have simple column chart and I need to change color of selected (clicked) column. By default it adds white line around the column.
var options = {
title: 'Motivation and Energy Level Throughout the Day',
hAxis: {
title: 'Time of Day',
format: 'h:mm a',
viewWindow: {
min: [7, 30, 0],
max: [17, 30, 0]
}
},
vAxis: {
title: 'Rating (scale of 1-10)'
}
};
Here is simple example on jSFiddle
So if I click any column how to change its color to black?
I can't use Material Charts.
Thanks
Finally I found an answer here
Frankly I thought that there is simpler option, like setting configuration option e.g. hAxis.selected.color: '#000000'.
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
dataTable: data,
options: {
// setting the "isStacked" option to true fixes the spacing problem
isStacked: true,
height: 300,
width: 600,
series: {
1: {
// set the color to change to
color: '00A0D0',
// don't show this in the legend
visibleInLegend: false
}
}
}
});
google.visualization.events.addListener(chart, 'select', function () {
var selection = chart.getChart().getSelection();
if (selection.length > 0) {
var newSelection = [];
// if row is undefined, we selected the entire series
// otherwise, just a single element
if (typeof(selection[0].row) == 'undefined') {
newSelection.push({
column: 2
});
chart.setView({
columns: [0, {
type: 'number',
label: data.getColumnLabel(1),
calc: function () {
// this series is just a placeholder
return 0;
}
}, 1]
});
}
else {
var rows = [];
for (var i = 0; i < selection.length; i++) {
rows.push(selection[i].row);
// move the selected elements to column 2
newSelection.push({
row: selection[i].row,
column: 2
});
}
// set the view to remove the selected elements from the first series and add them to the second series
chart.setView({
columns: [0, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
return (rows.indexOf(row) >= 0) ? null : {v: dt.getValue(row, 1), f: dt.getFormattedValue(row, 1)};
}
}, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
return (rows.indexOf(row) >= 0) ? {v: dt.getValue(row, 1), f: dt.getFormattedValue(row, 1)} : null;
}
}]
});
}
// re-set the selection when the chart is done drawing
var runOnce = google.visualization.events.addListener(chart, 'ready', function () {
google.visualization.events.removeListener(runOnce);
chart.getChart().setSelection(newSelection);
});
}
else {
// if nothing is selected, clear the view to draw the base chart
chart.setView();
}
chart.draw();
});
chart.draw();
}
UPDATE:
Above solution works only if you are using a ChartWrapper.
I actually needed solution just for chart.
Finally I solved this by adding style.color to the data row. If my selected index = rowIndex then I change the color. Simple and works like a charm.
I hope it will help others.
var data = new google.visualization.DataTable();
data.addColumn({ id: 'name', type: 'string' });
data.addColumn({ id: 'm1', type: 'number' });
data.addColumn({type: 'string', role:'tooltip', 'p': {'html': true}});
data.addColumn({type: 'string', role:'style'});
$.each(scatterData.data, function (index, value) {
if (index == chartSelectedIndex) {
data.addRow([ {v:value.park}, {v:value.m1}, {v:getColumnChartHTMLTooltip(value.park,value.name,value.m1)}, 'color: #32CCFF' ]);
} else{
data.addRow([ {v:value.park}, {v:value.m1}, {v:getColumnChartHTMLTooltip(value.park,value.name,value.m1)}, null ]);
};
});
This worked for me
.my-div svg>g>g>g>g>rect {
fill: #79baeb;
}

Categories

Resources