可变半径的连接节点与箭头 [英] linking nodes of variable radius with arrows
问题描述
我有一些不同半径的圆圈/节点,我必须用具有箭头端的路径连接它们。
I have some circles/nodes of different radius and I have to connect them with paths having arrow ends.
这是标记的代码:
svg.append("svg:defs").selectAll("marker")
.data(["default"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 5)
.attr("refY", -1.5)
.attr("markerWidth", 10)
.attr("markerHeight", 10)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M1,-5L10,0L0,5");
我已将圆的半径存储在数组中。
这是屏幕截图:
I have stored the radius of circles in an array. Here's the screen shot:
箭头实际上是在圆圈内。
The arrow is actually "inside" the circles. How do I get the arrows to be at the surface of the circles?
推荐答案
这真的很有趣;我刚刚解决了这个问题昨天。
This is really funny; I just solved this problem yesterday.
我做的是结束在节点的边缘,而不是在中心的路径。
我的case更复杂,因为我使用贝塞尔曲线,而不是直线,但这可能会帮助你:
What I did is to end the path at the edge of the node, not at the centre. My case is more complicated because I use Bezier curves, not straight lines, but this might help you:
svg.append("svg:defs").selectAll("marker")
.data(["default"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -3 6 6")
.attr("refX", 5.0)
.attr("refY", 0.0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-2.0L5,0L0,2.0");
links
.attr("fill", "none")
.attr("d", function(d) {
var tightness = -3.0;
if(d.type == "straight")
tightness = 1000;
// Places the control point for the Bezier on the bisection of the
// segment between the source and target points, at a distance
// equal to half the distance between the points.
var dx = d.target.x - d.source.x;
var dy = d.target.y - d.source.y;
var dr = Math.sqrt(dx * dx + dy * dy);
var qx = d.source.x + dx/2.0 - dy/tightness;
var qy = d.source.y + dy/2.0 + dx/tightness;
// Calculates the segment from the control point Q to the target
// to use it as a direction to wich it will move "node_size" back
// from the end point, to finish the edge aprox at the edge of the
// node. Note there will be an angular error due to the segment not
// having the same direction as the curve at that point.
var dqx = d.target.x - qx;
var dqy = d.target.y - qy;
var qr = Math.sqrt(dqx * dqx + dqy * dqy);
var offset = 1.1 * node_size(d.target);
var tx = d.target.x - dqx/qr* offset;
var ty = d.target.y - dqy/qr* offset;
return "M" + d.source.x + "," + d.source.y + "Q"+ qx + "," + qy
+ " " + tx + "," + ty; // to "node_size" pixels before
//+ " " + d.target.x + "," + d.target.y; // til target
});
顺便说一下,你必须对源箭头执行相同的操作(我只有目标)
By the way; you'll have to do the same for the 'source' arrow head (I only have it at the target)
这篇关于可变半径的连接节点与箭头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!