他の svg 要素と一緒に svg 内に geoJSON マップを配置する予定です。マップをズーム (ズーム + パン) して、境界ボックスを使用してマップを同じ場所に保持できるようにしたいと考えています。これは、clipPath を使用してマップを長方形の領域内に保持することで実現できます。問題は、svg 全体でズームとパンも有効にしたいということです。d3.select("svg").call(myzoom); を実行すると これは、マップに適用したズームを上書きします。SVG 全体とマップの両方にズームを適用するにはどうすればよいですか? つまり、マウスがマップのバウンディング ボックス内にあるときにマップをズーム + パンし、マウスがバウンディング ボックスの外にあるときに、svg 全体をズーム + パンできるようにしたいと考えています。
コード例は次のとおりです: http://bl.ocks.org/nuernber/aeaac0e8edcf7ca93ade .
<svg id="svg" width="640" height="480" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<clipPath id="rectClip">
<rect x="150" y="25" width="400" height="400" style="stroke: gray; fill: none;"/>
</clipPath>
</defs>
<g id="outer_group">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
<g id="svg_map" style="clip-path: url(#rectClip);">
</g>
</g>
</svg><br/>
<script type="text/javascript">
var svg = d3.select("#svg_map");
var mapGroup = svg.append("g");
var projection = d3.geo.mercator();
var path = d3.geo.path().projection(projection);
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.on("zoom", zoomed);
mapGroup.call(zoom);
var pan = d3.behavior.zoom()
.on("zoom", panned);
d3.select("svg").call(pan);
mapGroup.attr("transform", "translate(200,0) scale(2,2)");
d3.json("ne_110m_admin_0_countries/ne_110m_admin_0_countries.geojson", function(collection) {
mapGroup.selectAll("path").data(collection.features)
.enter().append("path")
.attr("d", path)
.attr("id", function(d) { return d.properties.name.replace(/\s+/g, "")})
.style("fill", "gray").style("stroke", "white").style("stroke-width",1);
}
);
function panned() {
var x = d3.event.translate[0];
var y = d3.event.translate[1];
d3.select("#outer_group").attr("transform", "translate("+x+","+y+") scale(" + d3.event.scale + ")");
}
function zoomed() {
previousScale = d3.event.scale;
projection.translate(d3.event.translate).scale(d3.event.scale);
translationOffset = d3.event.translate;
mapGroup.selectAll("path").attr("d", path);
}
</script>