I'm currently working on creating an interactive pan/zoom SVG floorplan/map by utilizing the d3.behavior.zoom()
feature. My code is inspired by the concept of Zoom to Bounding Box II.
My approach involves asynchronously loading an SVG using $.get()
and then employing a button.on('click')
function to retrieve the bounding box (.getBBox()
) of a specific <g>
element with the ID #g-1101
(depicted as a red circle in the SVG). I aim to center the viewport of the SVG on the midpoint of the bounding box of #g-1101
.
In my initial attempts, I tried to shift the top-level svg > g
element by using the
.getBBox().x && .getBBox().y
values of g#1101
. However, it appears there might be an error in my calculations.
Furthermore, I experimented with formulas like
(svg.node().getBBox().width / 2) - scale * g.getBBox().x)
to align the center of the bounding box with the viewport, but the translation seems to be way off.
Code
(function(){
var svg, g; $.get('http://layersofcomplexity.com/__fp.svg', function(svg){
$('body').append($(svg));
init();
},'text');
function init() {
console.log('init');
svg = d3.select('svg');
g = d3.select('svg > g');
var zoom = d3.behavior.zoom()
.translate([0, 0])
.scale(1)
.scaleExtent([1, 8])
.on("zoom", zoomed);
svg
.call(zoom)
.call(zoom.event);
$('.pan').on('click', function(){
// var id = '#g-1011';
var scale = 4;
var bbox = $('#g-1101')[0].getBBox();
// d3.select(id).node().getBBox();
var x = bbox.x;
var y = bbox.y;
// var scale = .9 / Math.max(dx / width, dy / height),
// var translate = [width / 2 - scale * x, height / 2 - scale * y];
var width = svg.node().getBBox().width;
var height = svg.node().getBBox().height;
var translate = [-scale*x,-scale*y];
g.transition().duration(750) .call(zoom.translate(translate).scale(scale).event);
});
}
function zoomed() {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
})();
-- EDIT JSBin was broken --
Could you help me figure out what I might be overlooking? JSBin.