【发布时间】:2018-11-16 19:07:37
【问题描述】:
我正在尝试使用 d3 geo 将链接图形树附加到旋转的地球。我已经改编了看到 here (sans drag and drop) 和 here 的旋转地球演示,并设法附加了我发现 here 的节点/链接的强制定向布局。
This 是我迄今为止所拥有的。力图出现在南极附近,为跳跃链接道歉我认为这只是一个 css 问题,因为它在我的模拟中正确显示(我现在已经离开了样式表)。
由于我希望节点固定在特定的纬度/经度,我想完全摆脱力模拟。然而,在保留节点和链接的同时删除它的所有尝试都会导致它们完全消失。我还在努力修复它们的位置并将节点覆盖地图图形(您可以看到节点在陆地后面)
总而言之,我想:
- 移除强制布局但保留节点/链接
- 在旋转期间修复特定纬度/经度的节点
- 在地理地图特征之上覆盖节点/链接
我们将非常感谢您就这些方面的任何一点提供帮助。
HTML
<!doctype html>
<html lang="en">
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<div id="vis"></div>
</body>
</html>
脚本
(function (){
var config = {
"projection": "Orthographic",
"clip": true, "friction": 1,
"linkStrength": 1,
"linkDistance": 20,
"charge": 50,
"gravity": 1,
"theta": .8 };
var width = window.innerWidth,
height = window.innerHeight - 5,
fill = d3.scale.category20(),
feature,
origin = [0, -90],
velocity = [0.01, 0],
t0 = Date.now(),
nodes = [{x: width/2, y: height/2}],
links = [];
var projection = d3.geo.orthographic()
.scale(height/2)
.translate([(width/2)-125, height/2])
.clipAngle(config.clip ? 90 : null)
var path = d3.geo.path()
.projection(projection);
var force = d3.layout.force()
.linkDistance(config.linkDistance)
.linkStrength(config.linkStrength)
.gravity(config.gravity)
.size([width, height])
.charge(-config.charge);
var svg = d3.select("#vis").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.drag()
.origin(function() { var r = projection.rotate(); return {x: 2 * r[0], y: -2 * r[1]}; })
.on("drag", function() { force.start(); var r = [d3.event.x / 2, -d3.event.y / 2, projection.rotate()[2]]; t0 = Date.now(); origin = r; projection.rotate(r); }))
for(x=0;x<20;x++){
source = nodes[~~(Math.random() * nodes.length)]
target = {x: source.x + Math.random(), y: source.y + Math.random(), group: Math.random()}
links.push({source: source, target: target})
nodes.push(target)
}
var node = svg.selectAll("path.node")
.data(nodes)
.enter().append("path").attr("class", "node")
.style("fill", function(d) { return fill(d.group); })
.style("stroke", function(d) { return d3.rgb(fill(d.group)).darker(); })
.call(force.drag);
console.log(node)
var link = svg.selectAll("path.link")
.data(links)
.enter().append("path").attr("class", "link")
force
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
var url = "https://raw.githubusercontent.com/d3/d3.github.com/master/world-110m.v1.json";
d3.json(url, function(error, topo) {
if (error) throw error;
var land = topojson.feature(topo, topo.objects.land);
svg.append("path")
.datum(land)
.attr("class", "land")
.attr("d", path)
d3.timer(function() {
force.start();
var dt = Date.now() - t0;
projection.rotate([velocity[0] * dt + origin[0], velocity[1] * dt + origin[1]]);
svg.selectAll("path")
.filter(function(d) {
return d.type == "FeatureCollection";})
.attr("d", path);
});
});
function tick() {
node.attr("d", function(d) { var p = path({"type":"Feature","geometry":{"type":"Point","coordinates":[d.x, d.y]}}); return p ? p : 'M 0 0' });
link.attr("d", function(d) { var p = path({"type":"Feature","geometry":{"type":"LineString","coordinates":[[d.source.x, d.source.y],[d.target.x, d.target.y]]}}); return p ? p : 'M 0 0' });
}
function clip(d) {
return path(circle.clip(d));
}
})();
【问题讨论】:
-
移至 D3 v4/5。然后,使用
forceX和forceY设置位置。完成。 -
我假设您已经知道要显示的节点的纬度和经度?
-
是的,为了在示例中方便,我现在只是随机放置它们
标签: javascript d3.js svg topojson