Skip to content

Instantly share code, notes, and snippets.

@jasondavies
Created September 10, 2012 08:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jasondavies/3689677 to your computer and use it in GitHub Desktop.
Save jasondavies/3689677 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.v3.min.js"></script>
<script src="longscroll.js"></script>
<script>
d3.select("body").selectAll("div.longscroll")
.data([0, 1])
.enter().append("div")
.attr("class", "longscroll")
.call(d3.longscroll()
.size(1e6)
.render(function(g) { g.text(String); }));
</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);
g.each(function() {
var g = d3.select(this);
g.property("scrollTop", +g.select(".before").style("height").replace("px", ""));
});
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(d3.range(position0, Math.min(position1, size)), String);
div.enter().append("div")
.attr("class", "row");
div.exit().remove();
div.order().call(render);
});
}
}
longscroll.render = function(_) {
return arguments.length ? (render = _, longscroll) : render;
};
longscroll.rowHeight = function(_) {
return arguments.length ? (rowHeight = +_, longscroll) : rowHeight;
};
longscroll.position = function(_) {
return arguments.length ? (position = +_, longscroll) : position;
};
longscroll.size = function(_) {
return arguments.length ? (size = +_, longscroll) : size;
};
return longscroll;
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment