javascript – 使用箭头链接可变半径的节点

前端之家收集整理的这篇文章主要介绍了javascript – 使用箭头链接可变半径的节点前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一些不同半径的圆/节点,我必须用箭头末端的路径连接它们.

这是标记代码

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");

我已将圆的半径存储在数组中.
这是屏幕截图:

箭头实际上是“圈内”.如何让箭头位于圆圈表面?

解决方法

这是一个老问题,但如果您希望箭头位于节点的边缘而不是在它们的顶部或下方,这是我的解决方案.我的方法也是绘制连接节点的路径,使得端点位于节点的边缘而不是节点的中心.从Mobile Patent Suits示例( http://bl.ocks.org/mbostock/1153292)开始,我将linkArc方法替换为:
function linkArc(d) {
    var sourceX = d.source.x;
    var sourceY = d.source.y;
    var targetX = d.target.x;
    var targetY = d.target.y;

    var theta = Math.atan((targetX - sourceX) / (targetY - sourceY));
    var phi = Math.atan((targetY - sourceY) / (targetX - sourceX));

    var sinTheta = d.source.r * Math.sin(theta);
    var cosTheta = d.source.r * Math.cos(theta);
    var sinPhi = d.target.r * Math.sin(phi);
    var cosPhi = d.target.r * Math.cos(phi);

    // Set the position of the link's end point at the source node
    // such that it is on the edge closest to the target node
    if (d.target.y > d.source.y) {
        sourceX = sourceX + sinTheta;
        sourceY = sourceY + cosTheta;
    }
    else {
        sourceX = sourceX - sinTheta;
        sourceY = sourceY - cosTheta;
    }

    // Set the position of the link's end point at the target node
    // such that it is on the edge closest to the source node
    if (d.source.x > d.target.x) {
        targetX = targetX + cosPhi;
        targetY = targetY + sinPhi;    
    }
    else {
        targetX = targetX - cosPhi;
        targetY = targetY - sinPhi;   
    }

    // Draw an arc between the two calculated points
    var dx = targetX - sourceX,dy = targetY - sourceY,dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY;
}

请注意,此代码要求“r”或radius属性位于节点数据中.为了将箭头的点放在正确的位置,我更改了refX和refY属性,以便箭头的点位于节点的边缘:

svg.append("defs").selectAll("marker")
    .data(["suit","licensing","resolved"])
  .enter().append("marker")
    .attr("id",function(d) { return d; })
    .attr("viewBox",10)
    .attr("refY",0)
    .attr("markerWidth",6)
    .attr("markerHeight",6)
    .attr("orient","auto")
  .append("path")
    .attr("d","M0,5");

猜你在找的JavaScript相关文章