gpt4 book ai didi

javascript - d3 美国 map 缩放加载至标记状态

转载 作者:行者123 更新时间:2023-11-28 03:53:45 30 4
gpt4 key购买 nike

使用 Mike Bostock 示例的 d3.v3 的美国 map :

US map with d3.v3 using mike bostock's example

我希望 map 在页面加载时最初放大到标记的位置,但应该呈现整个 map ,以便用户可以根据需要缩小。

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)

我有使用上面粘贴的滚动放大的代码,但我希望它能够放大加载到这些特定位置。我想要的样子:

How i want it to be

最佳答案

在 d3 中缩放 map 有两种主要方法:

  • 修改将重新绘制路径的投影,或者
  • 通过缩放和变换修改绘制的路径。

在 d3v4 中使用 fitSize 或 fitExtent 修改投影是最简单的 - 尽管您需要将点转换为 geojson。您还可以手动计算平移和缩放值来更新投影(请参阅 Mike Bostock 的 this answer,其中解释了这种常见的 d3v3 方法)。

或者,您可以通过调用缩放函数来修改绘制的路径 - this question昨天问的有一个很好的例子(在 d3v4 中)。或者,您可以手动计算并应用缩放,然后更新缩放以指示当前比例并进行平移。我将使用修改上面提到的 d3v3 投影的常用方法(使用 Mike 的答案)并将其应用于路径上的变换 - 而不是修改投影。 尽管不难看出如何更改我的答案以修改投影。

<小时/>

首先,您需要确定点的 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 * scale 相同,并且允许可变的边距量。 dx/w 返回的值是我们需要在 svg 容器的宽度上拉伸(stretch)差异的比例值的 1 倍。

(这样写可能更有意义:var scale = 0.9 * Math.min(w/dx,h/dy); - 我们希望通过最低比例值并将其乘以某个百分比以给出边距。但另一种表示形式在在线示例中普遍存在)

现在我们有了一个比例,我们只需要确定一个翻译。为此,我们找出需要将 xy 变量中保存的值重新定位多远,以便这些值居中:

var translate = [w/2 - scale * x, h/2-scale*y];

现在您可以设置 map 的初始比例和平移:

g.attr("transform", "translate("+translate+")scale("+scale+")");

但是,您可能希望在页面加载时更新缩放参数以反射(reflect)初始缩放和平移:

zoom.translate(translate);
zoom.scale(scale);

这样,当您放大或缩小初始 View 时,变化是相对于您的初始缩放而言的。

现在您所要做的就是在添加积分时包含上述代码。请注意,如果您想返回到初始位置,则此技术可能需要进行一些修改。

关于javascript - d3 美国 map 缩放加载至标记状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47750168/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com