【问题标题】:d3 Force: Calculating position of text on links where links between nodes are arcsd3 Force:在节点之间的链接是弧的链接上计算文本的位置
【发布时间】:2017-03-15 20:53:46
【问题描述】:

将链接应用到文本的一种方法是对文本元素使用 force.links() 数组,并将文本置于链接的中点。

我有一些带有双向链接的节点,我将它们渲染为在它们的中点弯曲的路径,以确保两个节点之间有两条链接。

对于这些双向链接,我想移动文本,使其正确位于弯曲路径上。

为此,我尝试计算以链接中心点为中心的圆与垂直于链接且也通过其中心的直线的交点。我认为原则上这是有道理的,而且似乎工作了一半,但是我不确定如何定义通过计算要应用于哪个标签的交点返回的坐标,以及如何阻止它们在弯曲链接之间跳转时我移动节点(参见 jsfiddle - https://jsfiddle.net/sL3au5fz/6/)。

计算圆弧路径上文字坐标的函数如下:

function calcLinkTextCoords(d,coord, calling) {
    var x_coord, y_coord;        
    //find centre point of coords
    var cp = [(d.target.x + d.source.x)/2, (d.target.y + d.source.y)/2];       
    // find perpendicular gradient of line running through coords
    var pg = -1 / ((d.target.y - d.source.y)/(d.target.x - d.source.x));
    // define radius of circle (distance from centre point text will appear)
    var radius = Math.sqrt(Math.pow(d.target.x - d.source.x,2) + Math.pow(d.target.y - d.source.y,2)) / 5 ;       
    // find x coord where circle with radius 20 centred on d midpoint meets perpendicular line to d.
    if (d.target.y < d.source.y) {
        x_coord = cp[0] + (radius / Math.sqrt(1 + Math.pow(pg,2)));
    } else {
        x_coord = cp[0] - (radius / Math.sqrt(1 + Math.pow(pg,2)));
    };
    // find y coord where x coord is x_text and y coord falls on perpendicular line to d running through midpoint of d
    var y_coord = pg * (x_coord - cp[0]) + cp[1];
    return (coord == "x" ? x_coord : y_coord);
};

任何解决上述问题或提出其他方法来实现此目的的帮助将不胜感激。

顺便说一句,我曾尝试使用 textPath 将我的文本与我的链接对齐,但我发现该方法在显示 30-40 个以上的节点和链接时并不高效。

更新:修改了上述功能,现在可以按预期工作。在这里更新小提琴:https://jsfiddle.net/o82c2s4x/6/

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    你可以计算弦到x和y轴的投影,并添加到源节点坐标:

    function calcLinkTextCoords(d,coord) {
    
            //find chord length
            var  dx = (d.target.x - d.source.x);
            var dy = (d.target.y - d.source.y);
            var chord = Math.sqrt(dx*dx + dy*dy);
    
            //Saggita
            // since radius is equal to chord
            var sag = chord - Math.sqrt(chord*chord - Math.pow(chord/2,2));
    
             //Find the angles
            var t1 = Math.atan2(sag, chord/2);
            var t2 = Math.atan2(dy,dx);
            var teta = t1+t2;
    
            var h = Math.sqrt(sag*sag + Math.pow(chord/2,2));
    
            return ({x: d.source.x + h*Math.cos(teta),y: d.source.y + h*Math.sin(teta)});
    
        };
    

    这是更新后的JsFiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-01
      • 2023-03-20
      • 2017-07-23
      相关资源
      最近更新 更多