svg – 获取箭头指向D3中节点的外边缘

前端之家收集整理的这篇文章主要介绍了svg – 获取箭头指向D3中节点的外边缘前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是D3的新手,我正在尝试创建一个互动的网络可视化.我复制了大部分的 this示例,但是我已经通过使用SVG“行”而不是“路径”将曲线更改为直线,而且我也根据它们所代表的数据对节点进行了缩放.问题是我的箭头(用SVG标记创建)在线的末端.由于一些节点很大,箭头隐藏在它们之后.我想让我的箭头显示在他们指向的节点的外边缘.

以下是我创建标记链接的方式:

svg.append("svg:defs").selectAll("marker")
    .data(["prereq","coreq"])
    .enter().append("svg:marker")
    .attr("id",String)
    .attr("viewBox","0 -5 10 10")
    .attr("refX",15)
    .attr("markerWidth",6)
    .attr("markerHeight",6)
    .attr("orient","auto")
    .append("svg:path")
    .attr("d","M0,-5L10,0L0,5");

var link = svg.selectAll(".link")
    .data(force.links())
    .enter().append("line")
    .attr("class","link")
    .attr("marker-end",function(d) { return "url(#" + d.type + ")"; });

我注意到,“refX”属性指定箭头应该显示的行的末尾有多远.我如何使它取决于它指向的节点的半径?如果我不能这样做,我可以改变线路的端点本身吗?我想我会在这个功能中做到这一点,当一切都移动时,它会重置线的端点:

function tick() {
        link
            .attr("x1",function(d) { return d.source.x; })
            .attr("y1",function(d) { return d.source.y; })
            .attr("x2",function(d) { return d.target.x; })
            .attr("y2",function(d) { return d.target.y; });

        circle.attr("transform",function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        });

        text.attr("transform"," + d.y + ")";
        });
    }

哪种方法更有意义,我该如何实现?

解决方法

感谢Lars Kotthoff,我按照其他问题的建议工作,首先我从使用线路切换到路径.我不认为我实际上不必这样做,但是它使得我更容易地遵循我正在看的其他例子,因为他们使用路径.

然后,我向我的节点添加了一个“radius”字段.当我设置radius属性时,我只是将其添加为实际字段而不是立即返回值:

var circle = svg.append("svg:g").selectAll("circle")
                    .data(force.nodes())
                    .enter().append("svg:circle")
                    .attr("r",function(d) {
                        if (d.logic != null) {
                            d.radius = 5;
                        } else {
                            d.radius = node_scale(d.classSize);
                        }
                        return d.radius;

然后我编辑了我的tick()函数来考虑这个半径.这需要一点简单的几何…

function tick(e) {

        path.attr("d",function(d) {
            // Total difference in x and y from source to target
            diffX = d.target.x - d.source.x;
            diffY = d.target.y - d.source.y;

            // Length of path from center of source node to center of target node
            pathLength = Math.sqrt((diffX * diffX) + (diffY * diffY));

            // x and y distances from center to outside edge of target node
            offsetX = (diffX * d.target.radius) / pathLength;
            offsetY = (diffY * d.target.radius) / pathLength;

            return "M" + d.source.x + "," + d.source.y + "L" + (d.target.x - offsetX) + "," + (d.target.y - offsetY);
        });

基本上,由路径形成的三角形,总共x个变化(diffX),它的总y变化(diffY)是与目标节点内的路径段(即节点半径)形成的三角形相似的三角形,目标节点(offsetX)内的x变化,目标节点(offsetY)内的y变化.这意味着目标节点半径与总路径长度的比值等于offsetX与diffX的比值以及offsetY与diffY的比值.

我还将refX值更改为10的箭头.我不知道为什么这是必要的,但现在似乎工作!

原文链接:https://www.f2er.com/js/155313.html

猜你在找的JavaScript相关文章