我是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的箭头.我不知道为什么这是必要的,但现在似乎工作!