【问题标题】:How to append the arrow marker dynamically in force layout d3.js如何在强制布局 d3.js 中动态附加箭头标记
【发布时间】:2015-03-24 05:35:38
【问题描述】:

如何在 d3.js 的强制布局中动态附加箭头标记,如下图所示

  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");

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    http://bl.ocks.org/mbostock/1153292 有一个例子

    您需要做的是创建svg:defs 并将svg:marker 元素放在defs 中。然后使用marker-endmarker-midmarker-start 属性之一附加标记

    // 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://stackoverflow.com/a/15758791/1617269

    因此改编自该问题中已接受的答案,您可以拥有一个像这样的生成器函数,它生成中间有一个节点的线条或基于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 你能用你的代码更新你的问题吗?
    • 如图所示,我将获得曲线和直线链接。在曲线链接中它的工作正常但不是直线。
    • @fekkyDEV 是的,我认为 marker-mid 可能有很多错误,因为我认为它可能需要路径在中间有一个节点,否则它不会绘制。我认为您需要更改直线生成器以在中间生成一个节点。我将通过指向另一个解决此问题的 stackoverflow 帖子的链接来更新我的答案。
    • 在这篇文章stackoverflow.com/a/15758791/1617269 中,他们提到使用策略线,但我怎样才能将它弯曲成曲线?
    • @fekkyDEV 查看我的编辑,了解如何生成中间有节点的线路径。这似乎适用于 chrome v41
    猜你喜欢
    • 2012-06-22
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2017-11-17
    • 2016-05-05
    相关资源
    最近更新 更多