gpt4 book ai didi

javascript - 在 D3 中交替或防止重叠路径

转载 作者:行者123 更新时间:2023-11-29 15:34:57 26 4
gpt4 key购买 nike

我正在创建一个圆弧图,希望能找到一种方法来防止圆弧重叠。有一个 working bl.ock here 的例子.

Arc diagram

在这种情况下,较暗的线是重叠线,其中多个节点共享相同的边。我想防止这种情况发生,也许可以通过两次通过:第一次将弧线交替移动到节点上方而不是节点下方,给出一种螺旋外观;如果上方/下方已经存在弧线,则第二个会绘制稍大的弧线以帮助区分链接。

var width   = 1000,
height = 500,
margin = 20,
pad = margin / 2,
radius = 6,
yfixed = pad + radius;

var color = d3.scale.category10();

// Main
//-----------------------------------------------------

function arcDiagram(graph) {
var radius = d3.scale.sqrt()
.domain([0, 20])
.range([0, 15]);

var svg = d3.select("#chart").append("svg")
.attr("id", "arc")
.attr("width", width)
.attr("height", height);

// create plot within svg
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + pad + ", " + pad + ")");

// fix graph links to map to objects
graph.links.forEach(function(d,i) {
d.source = isNaN(d.source) ? d.source : graph.nodes[d.source];
d.target = isNaN(d.target) ? d.target : graph.nodes[d.target];
});

linearLayout(graph.nodes);
drawLinks(graph.links);
drawNodes(graph.nodes);
}

// layout nodes linearly
function linearLayout(nodes) {
nodes.sort(function(a,b) {
return a.uniq - b.uniq;
})

var xscale = d3.scale.linear()
.domain([0, nodes.length - 1])
.range([radius, width - margin - radius]);

nodes.forEach(function(d, i) {
d.x = xscale(i);
d.y = yfixed;
});
}

function drawNodes(nodes) {

var gnodes = d3.select("#plot").selectAll("g.node")
.data(nodes)
.enter().append('g');

var nodes = gnodes.append("circle")
.attr("class", "node")
.attr("id", function(d, i) { return d.name; })
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; })
.attr("r", 5)
.style("stroke", function(d, i) { return color(d.gender); });

nodes.append("text")
.attr("dx", function(d) { return 20; })
.attr("cy", ".35em")
.text(function(d) { return d.name; })

}

function drawLinks(links) {
var radians = d3.scale.linear()
.range([Math.PI / 2, 3 * Math.PI / 2]);

var arc = d3.svg.line.radial()
.interpolate("basis")
.tension(0)
.angle(function(d) { return radians(d); });

d3.select("#plot").selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("transform", function(d,i) {
var xshift = d.source.x + (d.target.x - d.source.x) / 2;
var yshift = yfixed;
return "translate(" + xshift + ", " + yshift + ")";
})
.attr("d", function(d,i) {
var xdist = Math.abs(d.source.x - d.target.x);
arc.radius(xdist / 2);
var points = d3.range(0, Math.ceil(xdist / 3));
radians.domain([0, points.length - 1]);
return arc(points);
});
}

关于我如何开始解决问题的任何指示?

最佳答案

这是一个bl.ock以供引用。它以灰色显示您的原始路径,以红色显示建议的路径。

首先存储给定路径出现次数的计数:

graph.links.forEach(function(d,i) {
var pathCount = 0;
for (var j = 0; j < i; j++) {
var otherPath = graph.links[j];
if (otherPath.source === d.source && otherPath.target === d.target) {
pathCount++;
}
}

d.pathCount = pathCount;
});

然后一旦你有了这些数据,我会使用椭圆而不是径向线,因为看起来径向线只能为圆绘制曲线:

d3.select("#plot").selectAll(".ellipse-link")
.data(links)
.enter().append("ellipse")
.attr("fill", "transparent")
.attr("stroke", "gray")
.attr("stroke-width", 1)
.attr("cx", function(d) {
return (d.target.x - d.source.x) / 2 + radius;
})
.attr("cy", pad)
.attr("rx", function(d) {
return Math.abs(d.target.x - d.source.x) / 2;
})
.attr("ry", function(d) {
return 150 + d.pathCount * 20;
})
.attr("transform", function(d,i) {
var xshift = d.source.x - radius;
var yshift = yfixed;
return "translate(" + xshift + ", " + yshift + ")";
});

请注意,改变上面ry 的值会改变不同曲线的高度。

最后,您必须使用剪切路径来限制实际显示的每个椭圆的区域,以便它们仅显示在节点下方。 (这不是在 bl.ock 中完成的)

关于javascript - 在 D3 中交替或防止重叠路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30356723/

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