我有一些不同半径的圆/节点,我必须用箭头末端的路径连接它们.
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");
我已将圆的半径存储在数组中.
这是屏幕截图:
箭头实际上是“圈内”.如何让箭头位于圆圈表面?
解决方法
这是一个老问题,但如果您希望箭头位于节点的边缘而不是在它们的顶部或下方,这是我的解决方案.我的方法也是绘制连接节点的路径,使得端点位于节点的边缘而不是节点的中心.从Mobile Patent Suits示例(
http://bl.ocks.org/mbostock/1153292)开始,我将linkArc方法替换为:
function linkArc(d) { var sourceX = d.source.x; var sourceY = d.source.y; var targetX = d.target.x; var targetY = d.target.y; var theta = Math.atan((targetX - sourceX) / (targetY - sourceY)); var phi = Math.atan((targetY - sourceY) / (targetX - sourceX)); var sinTheta = d.source.r * Math.sin(theta); var cosTheta = d.source.r * Math.cos(theta); var sinPhi = d.target.r * Math.sin(phi); var cosPhi = d.target.r * Math.cos(phi); // Set the position of the link's end point at the source node // such that it is on the edge closest to the target node if (d.target.y > d.source.y) { sourceX = sourceX + sinTheta; sourceY = sourceY + cosTheta; } else { sourceX = sourceX - sinTheta; sourceY = sourceY - cosTheta; } // Set the position of the link's end point at the target node // such that it is on the edge closest to the source node if (d.source.x > d.target.x) { targetX = targetX + cosPhi; targetY = targetY + sinPhi; } else { targetX = targetX - cosPhi; targetY = targetY - sinPhi; } // Draw an arc between the two calculated points var dx = targetX - sourceX,dy = targetY - sourceY,dr = Math.sqrt(dx * dx + dy * dy); return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY; }
请注意,此代码要求“r”或radius属性位于节点数据中.为了将箭头的点放在正确的位置,我更改了refX和refY属性,以便箭头的点位于节点的边缘:
svg.append("defs").selectAll("marker") .data(["suit","licensing","resolved"]) .enter().append("marker") .attr("id",function(d) { return d; }) .attr("viewBox",10) .attr("refY",0) .attr("markerWidth",6) .attr("markerHeight",6) .attr("orient","auto") .append("path") .attr("d","M0,5");