Javascript d3美国地图加载时缩放至标记状态
使用Mike Bostock的示例,使用d3.v3绘制美国地图: 我希望在加载页面时,地图最初会放大到标记的位置,但应该呈现整个地图,以便用户可以在需要时缩小Javascript d3美国地图加载时缩放至标记状态,javascript,angularjs,d3.js,Javascript,Angularjs,D3.js,使用Mike Bostock的示例,使用d3.v3绘制美国地图: 我希望在加载页面时,地图最初会放大到标记的位置,但应该呈现整个地图,以便用户可以在需要时缩小 var w = 300; var h = 280; //Define map projection var projection = d3.geo.albersUsa() .translate([w/2, h/2]) .scale([300]); //Defi
var w = 300;
var h = 280;
//Define map projection
var projection = d3.geo.albersUsa()
.translate([w/2, h/2])
.scale([300]);
//Define path generator
var path = d3.geo.path()
.projection(projection);
//Create SVG element
var svg = d3.select("#map1").append("svg")
.attr("width", w)
.attr("height", h)
var g = svg.append("g");
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "1000")
.style('opacity', 0)
.style("font-family", "sans-serif")
.style("background-color", "white")
.style("border-radius", "5px")
.style("padding", "10px")
.style('color', '#000')
.style("font-size", "12px");
//Load in GeoJSON data
d3.json("us-states.json", function(json) {
d3.csv("cities.csv", function(error, data) {
g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.longi, d.lati])[0];
})
.attr("cy", function(d) {
return projection([d.longi, d.lati])[1];
})
.attr("r", 4)
.style("fill", "#4F6D88")
.on("mouseover", function(d){
tooltip.transition().style("opacity", 0.9)
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pageY) + 'px')
.text(d.city)
})
.on("mousemove", function(event){
tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");
})
.on("mouseout", function(){
tooltip.transition().delay(500).style("opacity", 0);
});
});
//Bind data and create one path per GeoJSON feature
g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path);
});
var zoom = d3.behavior.zoom()
.scaleExtent([1, 50])
.on("zoom", function() {
var e = d3.event,
tx = Math.min(0, Math.max(e.translate[0], w - w * e.scale)),
ty = Math.min(0, Math.max(e.translate[1], h - h * e.scale));
zoom.translate([tx, ty]);
g.attr("transform", [
"translate(" + [tx, ty] + ")",
"scale(" + e.scale + ")"
].join(" "));
});
svg.call(zoom)
我有代码放大与滚动,我已经贴在上面,但我想它放大加载到这些特定的位置。我希望它是怎样的:
在d3中缩放地图有两种主要方法:
- 修改将重新绘制路径的投影,或
- 使用缩放和变换修改绘制的路径
首先,您需要确定点的x和y坐标之间的最大差值。如果处理两点,这将相当容易:
var data = [[-100,45],[-110,45]];
var p1 = projection(data[0]);
var p2 = projection(data[1]);
var dx = Math.abs(p1[0] - p2[0]);
var dy = Math.abs(p1[1] - p2[1]);
为了得到一个简短的答案,我假设使用一种简单的数据格式。另外,如果要处理许多问题,这将有点复杂。一个可能的选择是将点放置在geojson中,并获取点的边界框
现在我们需要找出点的质心-在两个点的情况下,这只是x和y值的平均值:
var x = (p1[0] + p2[0])/2;
var y = (p1[1] + p2[1])/2;
接下来,我们需要计算一个新的比例,同时还要确定比例是否受到坐标x值差或坐标y值差的限制:
var scale = 0.9 / Math.max( dx/w , dy/h );
0.9略微减小了刻度,它与0.9*刻度相同,并允许可变的余量。dx/w
返回的值比我们需要在svg容器的宽度上拉伸差值的比例值高一倍
(这样写可能更有意义:var scale=0.9*Math.min(w/dx,h/dy);
-我们希望将缩放限制在最小的缩放值上,并将其乘以某个百分比以获得边距。但另一种表示形式在在线示例中随处可见)
现在我们有了一个标尺,我们只需要确定一个平移。为此,我们了解需要将x
和y
变量中的值重新定位到多大程度,以便将这些值居中:
var translate = [w/2 - scale * x, h/2-scale*y];
现在可以设置地图的初始比例和平移:
g.attr("transform", "translate("+translate+")scale("+scale+")");
但是,您可能希望在页面加载时更新缩放参数,以反映初始缩放和平移:
zoom.translate(translate);
zoom.scale(scale);
这样,当您从初始视图放大或缩小时,更改相对于初始缩放
现在,您所要做的就是在添加点时包含上述代码。请注意,如果要返回初始位置,可能需要对该技术进行一些修改