我需要在圆上的点之间手动绘制一些链接,并在所述圆的中心聚集点。我有源,目标点的x,y对,但我不希望它们之间有简单的直线;我想要一条曲线(类似于树形图中的链接)。我可以使用linkHorizontal
或linkVertical
,但它们的切线是恒定的;我想使用linkRadial
并将切线作为该特定弧点处的径向线(我也有这个点)。
我不理解linkRadial
API;它想要一个角度和一个半径,而不是一个x或y点。如何将我的两个x,y对(以及径向线角度)转换为预期的角度和半径?
答案 0 :(得分:3)
由于您的数据数组中包含x
和y
位置("我有x和y对的源点和目标点" ),您必须将它们转换为angle
和radius
。让我们看看如何做到这一点。
首先,让我们看一个固定坐标的例子。例如,假设您拥有此数据数组,其中x
和y
位置为:
var data = [{
source: {y: 150,x: 75
},
target: {y: 300,x: 0
}
}, {
source: {y: 150,x: 75
},
target: {y: 0,x: 0
}
}, {
source: {y: 150,x: 75
},
target: {y: 150,x: 150
}
}, ];
使用此链接生成器...
var link = d3.linkHorizontal()
.x(function(d) {
return d.y;
})
.y(function(d) {
return d.x;
});
...你将有一个这样的图表:
var data = [{
source: {
y: 150,
x: 75
},
target: {
y: 300,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 0,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 150,
x: 150
}
}, ];
var svg = d3.select("svg");
var link = d3.linkHorizontal()
.x(function(d) {
return d.y;
})
.y(function(d) {
return d.x;
});
svg.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("fill", "none")
.attr("stroke", "blue")
.attr("d", link);

<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>
&#13;
我们如何将其转换为可与d3.linkRadial()
一起使用的数据集?
一个选项是迭代每个对象,使用基本三角函数填充angle
和radius
属性:
var radialData = data.map(function(d) {
return {
source: {
x: 0,
y: 0
},
target: {
x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
}
};
});
然后,使用此链接生成器:
var linkRadial = d3.linkRadial()
.angle(function(d) {
console.log(d)
return d.x;
})
.radius(function(d) {
return d.y;
});
我们有这个:
var data = [{
source: {
y: 150,
x: 75
},
target: {
y: 300,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 0,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 150,
x: 150
}
}, ];
var svg = d3.select("svg");
var radialData = data.map(function(d) {
return {
source: {
x: 0,
y: 0
},
target: {
x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
}
};
});
var g = svg.append("g")
.attr("transform", "translate(150,75)")
var linkRadial = d3.linkRadial()
.angle(function(d) {
return d.x;
})
.radius(function(d) {
return d.y;
});
g.selectAll(null)
.data(radialData)
.enter()
.append("path")
.attr("fill", "none")
.attr("stroke", "red")
.attr("d", linkRadial);
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>
&#13;
现在两个发电机组合在一起,进行比较:
var data = [{
source: {
y: 150,
x: 75
},
target: {
y: 300,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 0,
x: 0
}
}, {
source: {
y: 150,
x: 75
},
target: {
y: 150,
x: 150
}
}, ];
var svg = d3.select("svg");
var link = d3.linkHorizontal()
.x(function(d) {
return d.y;
})
.y(function(d) {
return d.x;
});
svg.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("fill", "none")
.attr("stroke", "blue")
.attr("d", link);
var radialData = data.map(function(d) {
return {
source: {
x: 0,
y: 0
},
target: {
x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
}
};
});
var g = svg.append("g")
.attr("transform", "translate(150,75)")
var linkRadial = d3.linkRadial()
.angle(function(d) {
return d.x;
})
.radius(function(d) {
return d.y;
});
g.selectAll(null)
.data(radialData)
.enter()
.append("path")
.attr("fill", "none")
.attr("stroke", "red")
.attr("d", linkRadial);
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>
&#13;