如何在力导向图中使用d3.js动态添加箭头标记

4
如何在d3.js的力导向图中动态添加箭头标记,如下图所示:enter image description here (注:本翻译仅供参考,具体情况还需根据上下文和实际情况进行调整。)
  d3.select('svg.svgparentTag').selectAll("marker").data(["BLACK", "BLUE"]).enter().append("svg:marker")
        .attr("id", String)
        .attr("viewBox", "0 -5 10 10")
        .attr("markerWidth", 6)
        .attr("markerHeight", 6)
        .attr("orient", "auto")
        .append("svg:path")
        .attr("class", function(d) { return "marker_only " + d.type; })
        .attr("d", "M0,-5L10,0L0,5"); //marker 

 var path = d3.select('.pitch').selectAll("path")
            .data(force.links())
            .enter().append('g').classed('g_path', true).append("svg:path").attr("class", "link");


 path.filter(function(d) {
            return d.arrow == true;
        }).attr("marker-mid", function(d) { return "url(#BLUE)"}).attr("stroke-linecap", "round");
1个回答

7
这是一个有关 IT 技术的例子,请访问http://bl.ocks.org/mbostock/1153292以查看示例。
您需要创建svg:defs并在其中放置svg:marker元素。然后,使用属性marker-endmarker-midmarker-start中的任意一个将标记附加到元素上。请注意,不要删除原有的 HTML 标签。
// Per-type markers, as they don't inherit styles.
svg.append("defs").append("marker")
    .attr("id", "marker")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
  .append("path")
    .attr("d", "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path")
    .data(force.links())
  .enter().append("path")
    .attr("marker-end", "url(#marker)"; });

如果您需要直线的中间标记,但路径中没有节点,则可能会遇到标记未在中间绘制的问题。请看talkol的答案,了解如何解决这个问题:https://dev59.com/NWUo5IYBdhLWcg3w2CWJ#15758791 所以,根据该问题的被接受的答案进行调整,您可以编写一个类似于以下生成器函数,该函数会基于d.type生成具有中间节点或弧的线条。在jsfiddle上查看它。
function tick() {
  path.attr("d", function(d) {
    var dx = d.target.x - d.source.x,
        dy = d.target.y - d.source.y,
        dr = Math.sqrt(dx * dx + dy * dy)/4,
        mLx = d.source.x + dx/2,
        mLy = d.source.y + dy/2,
        mAx = d.source.x + dx,
        mAy = d.source.y + dy;
      if (d.type === "line") {
       return [
          "M",d.source.x,d.source.y,
           "L",mLx,mLy,
           "L",d.target.x,d.target.y,
           "Z"
          ].join(" ");
      }
    return [
      "M",d.source.x,d.source.y,
      "A",dr,dr,0,0,1,mAx,mAy,
      "A",dr,dr,0,0,1,d.target.x,d.target.y
    ].join(" ");
  });

@fekkyDEV,你能否更新你的问题并附上你的代码? - cyon
在图像中,我会得到曲线链接和直线链接。在曲线链接中它运行良好,但在直线链接中不起作用。 - ferozcoder
@fekkyDEV 是的,我认为 marker-mid 在这方面可能会有一些错误,因为我认为它可能需要路径在中间有一个节点,否则它不会绘制。我认为你需要更改直线生成器以产生一个中间节点。我将更新我的答案,并附上解决此问题的另一个stackoverflow帖子的链接。 - cyon
在这篇文章中https://dev59.com/NWUo5IYBdhLWcg3w2CWJ#15758791,他们提到使用折线,但我如何将其弯曲成曲线? - ferozcoder
@fekkyDEV,看一下我的编辑,你可以了解如何生成具有中间节点的线路路径。这似乎在Chrome v41上有效。 - cyon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接