可变半径的连接节点与箭头 [英] linking nodes of variable radius with arrows

查看:111
本文介绍了可变半径的连接节点与箭头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些不同半径的圆圈/节点,我必须用具有箭头端的路径连接它们。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆