javascript - d3js:世界地图上的强制布局在缩放时重新计算
问题描述
我有一张世界地图,上面有圆圈。d3.forceSimulation
重叠的圆圈不会碰撞并形成气泡。
问题发生在缩放上。如果我放大地图,圆圈会停留在原始位置,而不是形成一个新的气泡或停留在确切的位置。我怎样才能做到这一点?我读到了 force.start() 但我不能在我的缩放功能中调用它..
var width = 1200,
height = 500;
var zoom = d3.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var projection = d3.geoMercator()
.center([120, -20]) //long and lat starting position
.scale(100) //starting zoom position
.rotate([10,0]); //where world split occurs
var worldmap = d3.select("#worldmap")
.attr("viewBox", "0 0 " + width + " " + height )
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 600 300")
.call(zoom);
var path = d3.geoPath()
.projection(projection);
var g = worldmap.append("g");
var simulation = d3.forceSimulation()
.force('x', d3.forceX().x(function(d) {return projection([d.LastLocation.lon, d.LastLocation.lat])[0]}))
.force('y', d3.forceY().y(function(d) {return projection([d.LastLocation.lon, d.LastLocation.lat])[1]}))
.force("charge", d3.forceManyBody().strength(0.5)) // Nodes are attracted one each other of value is > 0
.force("collide", d3.forceCollide().strength(.1).radius(2).iterations(2)) // Force that avoids circle overlapping
//Zoom functionality
function zoomed() {
const currentTransform = d3.event.transform;
g.attr("transform", currentTransform);
g.selectAll("circle")
.attr("r", 3 - (currentTransform.k / 4))
}
d3.select(".zoom-in").on("click", function() {
zoom.scaleBy(svg.transition().duration(750), 1.2);
});
d3.select(".zoom-out").on("click", function() {
zoom.scaleBy(svg.transition().duration(750), 0.8);
});
// load and display the world and locations
d3.json("https://gist.githubusercontent.com/d3noob/5193723/raw/world-110m2.json", function(error, topology) {
var world = g.selectAll("path")
.data(topojson.object(topology, topology.objects.countries).geometries)
.enter()
.append("path")
.attr("d", path)
;
var locations = g.selectAll("circle")
.data(devicesAll)
.enter()
.append("circle")
.attr("cx", function(d) {return projection([d.LastLocation.lon, d.LastLocation.lat])[0];})
.attr("cy", function(d) {return projection([d.LastLocation.lon, d.LastLocation.lat])[1];})
.attr("r", 2)
.style("fill", "black")
.style("opacity", 1)
.on("mouseover", function(d) {
var getUrl = window.location;
$('.notebooks.map .detailview, .modules.installations .detailview').css('display', 'block');
$('#insideCardTitle').html(d.UnitName);
$('#insideCardLastOnline').html(d.LastOnline);
$('#insideCardVrManV').html(d.InstalledPlatformVersion);
$('#inside-card').attr("href", getUrl .protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1] + '/notebooks/view/' + d.ID);
d3.selectAll("g > line").remove()
})
// Apply these forces to the nodes and update their positions.
// Once the force algorithm is happy with positions ('alpha' value is low enough), simulations will stop.
simulation
.nodes(devicesAll)
.on("tick", function(){
locations
.attr("cx", function(d){ return d.x; })
.attr("cy", function(d){ return d.y; })
});
解决方案
推荐阅读
- android - 如何在另一个布局下部分获取布局
- python - 将二进制转换为字符串,然后使用 python 再次返回
- react-admin - React Admin - 根据其他资源为过滤器输入
- javascript - 合并相同长度的json
- reactjs - axios post 方法只是没有响应任何东西
- playframework - 在模块中播放 WS 客户端
- ruby-on-rails - 将 Heroku 中的 Rails API 设置为 Procfile 的开发和影响?
- html - HTML 中的嵌入式 CSS - 根据不同的单词更改单词颜色
- android - linux mint - android studio 模拟器进程被杀死
- python - 复杂函数的双重积分