I've already searched for this on StackOverflow. There are no answers that cover this scenario. Usually, it's either horizontal or vertical, this example is horizontal, vertical and frozen row and frozen column.
Basically, I have 3 elements. A div with a chart in the middle, a div with names to the left and a div with dates headings. The table with names to the left is fixed. (frozen column) The header should stay fixed but scrollable (frozen row). And the chart should be able to scroll vertically and horizontally.
I managed with some help to implement vertical scrolling but I can't for the life of me figure out why is there no horizontal scrolling.
Here's the fiddle :
google.charts.load('current', {
packages:['timeline']
}).then(function () {
var data = new google.visualization.DataTable({
cols: [
{id: 'team', label: 'Team', type: 'string'},
{id: 'start', label: 'Season Start Date', type: 'date'},
{id: 'end', label: 'Season End Date', type: 'date'}
],
rows: [
{c: [{v: 'Baltimore Ravens'}, {v: 'Date(2000, 8, 5)'}, {v: 'Date(2001, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
{c: [{v: 'Tampa Bay Buccaneers'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers'}, {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
{c: [{v: 'Indianapolis Colts'}, {v: 'Date(2006, 8, 5)'}, {v: 'Date(2007, 1, 5)'}]},
{c: [{v: 'New York Giants'}, {v: 'Date(2007, 8, 5)'}, {v: 'Date(2008, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers'}, {v: 'Date(2008, 8, 5)'}, {v: 'Date(2009, 1, 5)'}]},
{c: [{v: 'New Orleans Saints'}, {v: 'Date(2009, 8, 5)'}, {v: 'Date(2010, 1, 5)'}]},
{c: [{v: 'Green Bay Packers'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'Green Bay Packers'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
{c: [{v: 'Tampa Bay Buccaneers'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
{c: [{v: 'New England Patriots'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers'}, {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
{c: [{v: 'New York Giants'}, {v: 'Date(2007, 8, 5)'}, {v: 'Date(2008, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers3'}, {v: 'Date(2008, 8, 5)'}, {v: 'Date(2009, 1, 5)'}]},
{c: [{v: 'New Orleans Saints2'}, {v: 'Date(2009, 8, 5)'}, {v: 'Date(2010, 1, 5)'}]},
{c: [{v: 'Green Bay Packers'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'Green Bay Packers4'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'New England Patriots5'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
{c: [{v: 'Tampa Bay Buccaneers6'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
{c: [{v: 'New England Patriots7'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
{c: [{v: 'New England Patriots8'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers9'}, {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
{c: [{v: 'New York Giants10'}, {v: 'Date(2007, 8, 5)'}, {v: 'Date(2008, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers11'}, {v: 'Date(2008, 8, 5)'}, {v: 'Date(2009, 1, 5)'}]},
{c: [{v: 'New Orleans Saints12'}, {v: 'Date(2009, 8, 5)'}, {v: 'Date(2010, 1, 5)'}]},
{c: [{v: 'Green Bay Packers13'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'Green Bay Packers14'}, {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
{c: [{v: 'New England Patriots15'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
{c: [{v: 'Tampa Bay Buccaneers16'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
{c: [{v: 'New England Patriots17'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
{c: [{v: 'New England Patriots18'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
{c: [{v: 'Pittsburgh Steelers19'}, {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
]
});
var group = google.visualization.data.group(
data,
[0, 1],
[{
column: 0,
type: 'number',
label: data.getColumnLabel(0),
aggregation: google.visualization.data.count
}]
);
group.sort([{column: 1}]);
var rowLabels = [];
var rowElements = [];
var labels = document.getElementById('labels');
for (var i = 0; i < group.getNumberOfRows(); i++) {
var team = group.getValue(i, 0);
if (rowLabels.indexOf(team) === -1) {
rowLabels.push(team);
var label = labels.appendChild(document.createElement('div'));
label.className = 'label';
label.innerHTML = team;
rowElements.push(label);
}
}
var options = {
height: 1300,
timeline: {
groupByRowLabel: true,
showRowLabels: false
},
width: 1800
};
var container = document.getElementById('chart');
var chart = new google.visualization.Timeline(container);
google.visualization.events.addListener(chart, 'ready', afterDraw);
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
function afterDraw() {
var header = document.getElementById('header');
header.innerHTML = '';
var svg = document.getElementsByTagName('svg')[0];
var g = svg.getElementsByTagName('g')[1];
var svgNew = header.appendChild(svg.cloneNode());
var gNew = svgNew.appendChild(g.cloneNode(true));
var height = parseFloat(gNew.getElementsByTagName('text')[0].getAttribute('y')) - 25;
gNew.setAttribute('transform','translate(0,-'+height+')');
g.parentNode.removeChild(g);
var rows = container.getElementsByTagName('rect');
var rowIndex = -1;
Array.prototype.forEach.call(rows, function(rect) {
if (rect.getAttribute('x') === '0') {
rowIndex++;
if (rowIndex < rowElements.length) {
var rowHeight = (parseFloat(rect.getAttribute('height')) - 1) + 'px';
rowElements[rowIndex].style.height = rowHeight;
rowElements[rowIndex].style.lineHeight = rowHeight;
}
}
});
}
});
#header {
height: 56px;
position: fixed;
-webkit-overflow-scrolling: touch;
display: block;
top: 0px;
margin-top: 0px;
z-index: 99;
background: white;
}
#chart {
-webkit-overflow-scrolling: touch;
margin-top: 57px;
}
#labels {
border: 1px solid #b7b7b7;
margin-top: 56px;
}
.label {
border-top: 1px solid #b7b7b7;
font-family: Arial;
font-size: 13px;
text-align: right;
padding-left: 8px;
padding-right: 8px;
}
.label:first-child {
border: none;
}
.label:nth-child(even) {
background-color: #e6e6e6;
}
.label:nth-child(odd) {
background-color: #ffffff;
}
.scroll {
max-width: 100%;
-webkit-overflow-scrolling: touch;
height: 100%;
overflow-y: scroll;
}
.inline {
display: inline-block;
vertical-align: top;
-webkit-overflow-scrolling: touch;
}
.nowrap {
white-space: nowrap;
overflow-x: hidden;
overflow-y: hidden;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="nowrap">
<div class="inline" id="labels"></div>
<div class="inline scroll">
<div id="header"></div>
<div id="chart"></div>
</div>
</div>
Here's a codepen: https://codepen.io/anon/pen/bZmKpo