如何解决如何在D3中创建连接节点的曲线
我想在D3中创建一个图形,该图形包含通过曲线相互连接的节点。线的弯曲应根据线的起点和终点相距多远而有所不同。
例如(A)是较长的连接,因此弯曲程度小于(C)。
哪个D3函数最适合用于此计算以及如何将其作为SVG路径输出
一个代码示例(例如在observablehq.com上)对我有很大帮助。
解决方法
这是obserbavlehq.com中的代码示例 https://observablehq.com/@garciaguillermoa/circles-and-links
我会尝试解释一下,让我知道是否有我不清楚的地方:
让我们从圆开始,我们使用d3.pie()
来定位该圆,通过上面定义的数据,它将返回一些弧,但是由于我们想用圆而不是圆,我们使用arc.centroid
获取我们圈子的坐标
我们用于计算位置的扇形布局中的间距是必需的值,如果您想要更多的圆,则需要减小该值,这是相关代码:
pie = d3
.pie()
.sort(null)
.value((d) => {
return d.value;
});
arc = d3.arc().outerRadius(300).innerRadius(50);
data = [
{ id: 0,value: 10 },{ id: 1,{ id: 2,{ id: 3,{ id: 4,{ id: 5,{ id: 6,{ id: 7,{ id: 8,{ id: 9,];
const circles = [];
for(let item of pieData) {
const [x,y] = arc.centroid(item);
circles.push({x,y});
}
现在我们可以绘制圆圈了:
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height);
const mainGroup = svg
.append("g")
.attr("id","main")
.attr("transform","translate(" + width / 2 + "," + height / 2 + ")");
// Insert lines and circles groups,lines first so they are behind circles
const linesGroup = mainGroup.append("g").attr("id","lines");
const circlesGroup = mainGroup.append("g").attr("id","circles");
circlesGroup
.selectAll("circle")
.data(circles,(_,index) => index)
.join((enter) => {
enter
.append("circle")
.attr("id",index) => {
return `circle-${index}`;
})
.attr("r",20)
.attr("cx",(d) => {
return d.x;
})
.attr("cy",(d) => {
return d.y;
})
.style("stroke-width","2px")
.style("stroke","#000")
.style("fill","#963cff");
});
现在我们需要声明链接,我们可以使用一个数组来指定链接,该数组指定源和目的地的ID(从和到)。我们使用它搜索每个圆,获取其坐标(链接的源和目的地),然后创建链接,为了创建它们,我们可以使用路径和d3方法quadraticCurveTo
,此功能需要四个参数,前两个是定义曲线的“控制点”,我们使用0,0是它的中心,即Viz的中心(因为在父组中使用了平移,所以它是中心)。
lines = [
{
from: 1,to: 3,},{
from: 8,to: 4,];
for (let line of lines) {
const fromCircle = circles[line.from];
const toCircle = circles[line.to];
const fromP = { x: fromCircle.x,y: fromCircle.y };
const toP = { x: toCircle.x,y: toCircle.y };
const path = d3.path();
path.moveTo(fromP.x,fromP.y);
path.quadraticCurveTo(0,toP.x,toP.y);
linesGroup
.append("path")
.style("fill","none")
.style("stroke-width","2px")
.style("stroke-dasharray","10 10")
.style("stroke","#000")
.attr("d",path);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。