【问题标题】:Can I append a literal SVG element with d3?我可以用 d3 附加文字 SVG 元素吗?
【发布时间】:2016-10-13 23:00:36
【问题描述】:

我想用 d3 附加一个文字 SVG 元素。

所以不要写

svg.selectAll("circle")            
    .data(data)                    
    .enter()                       
    .append("circle")    // etc etc

我想做:

svg.selectAll("circle")            
    .data(data)                    
    .enter()                       
    .append('<circle cx="158.9344262295082" cy="200" r="16" fill="red"></circle>')   

这样我就可以在其他地方创建一个复杂的模板(例如使用车把),然后用数据编译它并附加它。

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    您可以这样做,但不能通过 selection.append() 函数。相反,您需要使用 selection.html() 函数。

    这将使它很难在数据连接的上下文中使用,但并非不可能。这可能是您能做的最好的事情,其中​​涉及向 DOM 添加一个额外的 svg 组,这可能不是一件坏事:

    var svg = d3.selectAll("svg");
    svg.selectAll("circle")            
           .data([50, 100, 150])                    
           .enter()                       
           .append("g")
           .attr("transform", function(d) { return "translate(" + [d, d] + ")"; })
           .html('<circle r="16" fill="red"></circle>');   
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <svg width="500" height="500"></svg>

    我想这个答案更进一步,您实际上可以将您希望直接渲染的结果嵌入到您的 data 对象中。所以你添加了一些看起来像这样的代码:

    .html(function(d) { return d.templatedHTML; });

    此时请停下来问自己一个问题:“我用 D3 做什么?”。 D3被描述为

    数据驱动文档

    如果您使用的是车把之类的东西,那么您就是在拿走 D3 设计的核心职责之一(从一些数据构建一些 DOM)并将其交给其他库。

    我并不是说你不应该这样做(因为你确实提到了复杂的模板),但只是问自己这个问题,以确保这是你希望走的路。

    【讨论】:

    • 感谢您提供简洁彻底的答案。我同意我应该三思而后行——也许这只是 d3 中非常实用的风格带来的认知摩擦,我(还)不习惯这种风格。
    • @simone 没问题 - 如果您认为答案很好,请随时点赞;) D3 需要一点学习,但是当您学会使用它时,它是一个非常强大的库。
    【解决方案2】:

    不,你不能。不相信我?查看他们的文档HERE

    您必须做的是调用.append(),然后多次调用.attr(attr_name, attr_value) 来设置每个属性的值。 D3 不像 jQuery 那样工作。

    【讨论】:

      【解决方案3】:

      D3 不提供此功能,并且没有多大意义(当您考虑根据数据操作元素时)。

      但是,附带说明一下,您可以实现自己的函数来附加文字 SVG 元素。

      这是Chris Viau创建的函数,命名为appendSVG

      d3.selection.prototype.appendSVG = 
          d3.selection.enter.prototype.appendSVG = function(SVGString) {
              return this.select(function() {
                  return this.appendChild(document.importNode(new DOMParser()
                      .parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + SVGString + 
                  '</svg>', 'application/xml').documentElement.firstChild, true));
              });
          };
      

      扩展原型后,就可以使用了:

      selection.appendSVG("<some literal SVG element>");  
      

      这是一个演示。首先,我们设置数据:

      var data = [{x:30,y:50},{x:420,y:100},{x:160,y:150},{x:260,y:30}];
      

      然后,我们以通常的方式附加我们的文字 SVG 元素:

      var myLiteral = svg.selectAll(".literal")
          .data(data)
          .enter()
          .appendSVG("<literal SVG here>");
      

      最后我们使用translate设置位置:

      .attr("transform", function(d){ 
          return "translate(" + d.x + "," + d.y + ")";
      });
      

      检查sn-p:

      d3.selection.prototype.appendSVG = d3.selection.enter.prototype.appendSVG = function(SVGString) {return this.select(function() { return this.appendChild(document.importNode(new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + SVGString + '</svg>', 'application/xml').documentElement.firstChild, true));});};
      
      var svg = d3.select("body").append("svg").attr("width", 500).attr("height", 300);
      
      var data = [{x:30,y:50},{x:420,y:100},{x:160,y:150},{x:260,y:30}];
      		
      var myLiteral = svg.selectAll(".literal")
        .data(data)
        .enter()
        .appendSVG("<path d='M 22.889471,25.607172 C 22.589713,24.605127 24.092318,24.708731 24.554936,25.108955 C 25.808602,26.193538 25.053398,28.14136 23.885905,28.938102 C 21.797533,30.363287 19.018523,29.16303 17.893076,27.101823 C 16.241437,24.076919 17.936475,20.36976 20.896603,18.945312 C 24.841988,17.046747 29.504523,19.25402 31.216796,23.116087 C 33.371517,27.976105 30.644503,33.605344 25.878773,35.599962 C 20.106834,38.015712 13.505062,34.765112 11.231216,29.094691 C 8.551568,22.412295 12.327973,14.834577 18.903736,12.283452 C 26.495714,9.3380778 35.051552,13.641683 37.878656,21.12322 C 41.09099,29.624218 36.259254,39.159651 27.87164,42.261821 C 18.462006,45.741988 7.9459296,40.381466 4.5693566,31.087558 C 0.82072068,20.769559 6.7105029,9.2720694 16.910868,5.6215926' style='fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1'/>")
        .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")"});
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-03
        • 2016-01-19
        • 1970-01-01
        相关资源
        最近更新 更多