缩放D3力布局链接标记上的箭头

时间:2012-06-20 14:09:13

标签: javascript svg d3.js force-layout markers

我在d3强制导向图中有以下代码,我试图根据值(1-3)改变链接及其相关箭头的大小。行程重量确实随着值而变化,但箭头不会保持在正确的位置。当笔划重量从1变为3时,它往往会从最后移回。有关如何在更改笔划值时保持箭头(标记)正确对齐的任何想法?非常感谢!

      var link = vis.selectAll("line.link")
      .data(json.links)
    .enter().append("svg:line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); })
      .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; })
      .attr("marker-end", "url(#arrowGray)")
      .on("click", function(d) {
            link.style("stroke","#dddddd");
            node.style("stroke","#FFFFFF");
            d3.select(this).style("stroke","red");
            link.attr("marker-end", null);
            link.attr("marker-end", "url(#arrowGray)");
            d3.select(this).attr("marker-end", null);
            d3.select(this).attr("marker-end", "url(#arrowRed)");
            clickLink(d);
            });

    defs.append("svg:marker")
            .attr("id", "arrowGray")
            .attr("viewBox","0 0 10 10")
            .attr("refX","20")
            .attr("refY","5")
            .attr("markerUnits","strokeWidth")
            .attr("markerWidth","9")
            .attr("markerHeight","5")
            .attr("orient","auto")
            .append("svg:path")
            .attr("d","M 0 0 L 10 5 L 0 10 z")
            .attr("fill", "#BBBBBB");

2 个答案:

答案 0 :(得分:8)

问题

jsFiddle演示了相关问题。标记def的值与其所连接的元素的行程宽度有关(在这种情况下为链接线)。请参阅markerUnits spec。通过对strokeWidth属性使用markerUnits,不同大小箭头的坐标会略有不同。简而言之,一个尺寸箭头的适当值将无法正确转换为其他尺寸。

解决方案1:多个标记

正如评论中所提到的,一种解决方案是为每个strokeWidth创建一个不同的标记。只有当您事先知道需要什么尺寸时,这才有效。

解决方案2:修改行

另一种选择是修改线的终点。不是让行终止于节点的中心,而是在节点的外边缘终止它。这个jsFiddle证明了这一点。这减轻了移动箭头的需要,因为我们现在可以在线的末端绘制它。

此解决方案涉及一些数学计算,以确定x2的{​​{1}}和y2值应该是什么。因此,对于具有大量边缘的系统来说,它可能并不理想。

line

答案 1 :(得分:1)

您的refX可能太大了。尝试将其设置为1左右。