Skip to content

Instantly share code, notes, and snippets.

@jo
Forked from jasondavies/index.html
Created November 15, 2012 14:07
Show Gist options
  • Save jo/4078785 to your computer and use it in GitHub Desktop.
Save jo/4078785 to your computer and use it in GitHub Desktop.
longscroll.js
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.longscroll {
overflow-y: auto;
width: 480px;
height: 500px;
float: left;
}
.longscroll .row {
height: 19px;
padding: 0 8px;
border-bottom: solid #eee 1px;
}
</style>
<body>
<script src="http://d3js.org/d3.v2.min.js?2.10.1"></script>
<script src="longscroll.js"></script>
<script>
var numbers = [
d3.range(0, 1e6)
];
d3.select("body").selectAll("div.longscroll")
.data([numbers, numbers])
.enter().append("div")
.attr("class", "longscroll")
.call(d3.longscroll()
.size(1e6)
.render(function(g) {
g.text(function(d) { return d; });
}));
</script>
(function() {
// Virtual rendering for rows taking up to 1e7px of vertical space.
// By Jason Davies, http://www.jasondavies.com/
d3.longscroll = function() {
var render = null,
size = 0,
position = 0,
rowHeight = 20;
function longscroll(g) {
g.selectAll("div.before").data([0]).enter().append("div").attr("class", "before");
var current = g.selectAll("div.current").data([0]);
current.enter().append("div").attr("class", "current");
g.selectAll("div.after").data([0]).enter().append("div").attr("class", "after");
g.on("scroll.longscroll", function() {
position = Math.floor(this.scrollTop / rowHeight);
scroll(this.scrollTop);
});
scroll(0);
current.each(function() {
this.scrollIntoView();
});
function scroll(scrollTop) {
g.each(function() {
this.scrollTop = scrollTop;
var g = d3.select(this),
rows = 1 + Math.ceil(this.clientHeight / rowHeight),
position0 = Math.max(0, Math.min(size - rows, position)),
position1 = position0 + rows;
g.select(".before").style("height", position0 * rowHeight + "px");
g.select(".after").style("height", (size - position1) * rowHeight + "px");
var div = g.select(".current").selectAll("div.row")
.data(function(d, i) { return d[i].slice(position0, Math.min(position1, size)); })
div.enter().append("div")
.attr("class", "row");
div.exit().remove();
div.order().call(render);
});
}
}
longscroll.render = function(_) {
if (!arguments.length) return render;
render = _;
return longscroll;
};
longscroll.rowHeight = function(_) {
if (!arguments.length) return rowHeight;
rowHeight = +_;
return longscroll;
};
longscroll.position = function(_) {
if (!arguments.length) return position;
position = +_;
return longscroll;
};
longscroll.size = function(_) {
if (!arguments.length) return size;
size = +_;
return longscroll;
};
return longscroll;
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment