Skip to content

Instantly share code, notes, and snippets.

@jakevdp
Last active January 1, 2016 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakevdp/8211270 to your computer and use it in GitHub Desktop.
Save jakevdp/8211270 to your computer and use it in GitHub Desktop.
Zooming/Panning example with D3
<html>
<head>
<style>
.axis line, .axis path {
shape-rendering: crispEdges;
stroke: black;
stroke-width: 1;
fill: none;
}
.axes.axis text {
font-family: sans-serif;
font-size: 11px;
fill: black;
stroke: none;
}
.axesbg{
fill: #EEEEEE;
}
.grid .tick {
fill: none;
stroke: white;
stroke-dasharray: 10,0;
stroke-width: 1;
}
.grid path {
stroke-width: 0;
}
</style>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
function Figure(figid, width, height){
this.figid = figid;
this.root = d3.select(figid);
this.width = width;
this.height = height;
this.axes = [];
}
Figure.prototype.add_axes = function(bbox, xlim, ylim, xgrid, ygrid){
this.axes.push(new Axes(this, bbox, xlim, ylim, xgrid, ygrid));
};
Figure.prototype.draw = function(){
this.canvas = this.root.append('svg:svg')
.attr('class', 'figure')
.attr('width', this.width)
.attr('height', this.height);
for (var i=0; i<this.axes.length; i++){
this.axes[i].draw();
}
};
function Axes(fig, bbox, xlim, ylim, xgridOn, ygridOn){
this.fig = fig;
this.bbox = bbox;
this.xlim = xlim;
this.ylim = ylim;
this.xgridOn = xgridOn;
this.ygridOn = ygridOn;
this.elements = [];
this.position = [this.bbox[0] * this.fig.width,
(1 - this.bbox[1] - this.bbox[3]) * this.fig.height];
this.width = bbox[2] * this.fig.width;
this.height = bbox[3] * this.fig.height;
}
Axes.prototype.draw = function(){
this.x = d3.scale.linear()
.domain(this.xlim)
.range([0, this.width]);
this.y = d3.scale.linear()
.domain(this.ylim)
.range([this.height, 0]);
// hack to get context right. There has to be a better way...
var that = this;
var zoomed = function(){that.zoomed();};
this.zoom = d3.behavior.zoom()
.x(this.x)
.y(this.y)
.on("zoom", zoomed);
this.baseaxes = this.fig.canvas.append("g")
.attr('transform', 'translate('
+ this.position[0] + ','
+ this.position[1] + ')')
.attr('width', this.width)
.attr('height', this.height)
.attr('class', "axes")
.call(this.zoom);
this.axesbg = this.baseaxes.append("svg:rect")
.attr("width", this.width)
.attr("height", this.height)
.attr("class", "axesbg");
this.xAxis = d3.svg.axis().scale(this.x).orient("bottom");
this.yAxis = d3.svg.axis().scale(this.y).orient("left");
this.baseaxes.append('g')
.attr('transform', 'translate(0,' + this.height + ')')
.attr("class", "x axis")
.call(this.xAxis);
this.baseaxes.append('g')
.attr("class", "y axis")
.call(this.yAxis);
this.clip = this.baseaxes.append("svg:clipPath")
.attr("id", "myClip")
.append("svg:rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", this.width)
.attr("height", this.height)
this.axes = this.baseaxes.append("g")
.attr("clip-path", "url(#myClip)");
if(this.xgridOn){
this.xGrid = d3.svg.axis()
.scale(this.x)
.orient("bottom")
.tickSize(-this.height, 0, 0)
.tickFormat("");
this.baseaxes.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + this.height + ")")
.call(this.xGrid);
}
if(this.ygridOn){
this.yGrid = d3.svg.axis()
.scale(this.y)
.orient("left")
.tickSize(-this.width, 0, 0)
.tickFormat("")
this.baseaxes.append("g")
.attr("class", "y grid")
.call(d3.svg.axis()
.scale(this.y)
.orient("left")
.tickSize(-this.width, 0, 0)
.tickFormat(""));
}
for(var i=0; i<this.elements.length; i++){
this.elements[i].draw();
}
};
Axes.prototype.zoomed = function(){
//console.log(this.zoom.translate());
//console.log(this.zoom.scale());
this.baseaxes.select('.x.axis').call(this.xAxis);
this.baseaxes.select('.y.axis').call(this.yAxis);
this.baseaxes.select('.x.grid').call(this.xGrid);
this.baseaxes.select('.y.grid').call(this.yGrid);
for(var i=0; i<this.elements.length; i++){
this.elements[i].zoomed();
}
};
Axes.prototype.add_element = function(element){
this.elements.push(element);
}
</script>
</head>
<body>
<div id="figure01"></div>
<script type="text/javascript">
// create a figure
setTimeout(function(){
var fig = new Figure("div#figure01", 800, 600);
fig.add_axes([0.1, 0.1, 0.8, 0.8], [0, 1], [0, 1], true, true);
fig.draw();
}, 0)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment