【问题标题】:Elements appended to SVG with D3 are not appearing使用 D3 附加到 SVG 的元素未出现
【发布时间】:2017-03-10 08:54:06
【问题描述】:

我正在尝试使用 D3 显示一些简单的条形图,其中每个条形都是 div,但没有显示任何内容。

var chartData =  [4, 8, 15, 16, 23, 42];
var body = d3.select('body');
    	
var svg = body.append('svg')
   .attr("width",800)
   .attr("height",500);
    				
var div = svg.append('div').attr('class', '.chart');
    	
for (var i = 0; i < chartData.length; i++) {
   div.append('div')
    	.attr("height", 20)
    	.attr("width", chartData[i]*10)
    	.html(chartData[i]);
}
.chart div {
	font: 10px sans-serif;
  background-color: steelblue;
	text-align: right;
	padding: 3px;
  margin: 1px;
	color: white;
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"&gt;&lt;/script&gt;

当使用检查 SVG 时,我看到新创建的元素并且 svg 被突出显示,但内部的 divs 没有。

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    简而言之:您不能将 HTML 元素附加到 SVG。原因很简单:&lt;div&gt;&lt;p&gt;&lt;h1&gt;&lt;h2&gt;&lt;td&gt;&lt;li&gt; 等都是无效的 SVG 元素。

    这个问题已经被问过很多次了。但是,我想回答这个问题是因为它的特定部分(通常不会被问到):

    当使用 chrome 的检查时,我看到了新创建的元素。

    是的,元素就在那里。但这并不意味着它会起作用。

    让我们在下面的 sn-p 中展示这一点,其中我将 &lt;div&gt;s 附加到 SVG。看看console.log,它显示了 SVG 结构:

    var svg = d3.select("svg");
    
    var data = d3.range(5);
    
    var divs = svg.selectAll("foo")
    	.data(data)
    	.enter()
    	.append("div")
    	.html("Where are you?")
    	
    var mySVG = (new XMLSerializer()).serializeToString(svg.node());
    console.log(mySVG)
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>

    您可以看到 div 位于 DOM 中。但是,屏幕上什么都没有……

    您在 DOM 中看到元素这一事实没有任何意义,因为您可以附加 anything

    例如,让我们附加一个名为 CharlesDarwin 的元素:

    var svg = d3.select("svg");
    
    var data = d3.range(5);
    
    var divs = svg.selectAll("foo")
    	.data(data)
    	.enter()
    	.append("CharlesDarwin")
    	.html("I'm a strange tag!")
    	
    var mySVG = (new XMLSerializer()).serializeToString(svg.node());
    console.log(mySVG)
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>

    你可以在 DOM 中看到&lt;charlesDarwin&gt;。但是,很明显 SVG 中不会显示任何内容。

    PS:关于你的图表:

    1. 摆脱那个 for 循环。使用 D3 时不需要它;
    2. 设置类没有点;
    3. 如上所述,将 div 附加到正文。

    这是工作代码:

    var chartData = [4, 8, 15, 16, 23, 42];
    
    var body = d3.select('body');
    
    var div = body.selectAll("foo")
      .data(chartData)
      .enter()
      .append('div')
      .attr('class', 'chart')
      .style("width", d => d * 10 + "px")
      .html(d => d);
    .chart {
      font: 10px sans-serif;
      background-color: steelblue;
      text-align: right;
      padding: 3px;
      margin: 1px;
      color: white;
    }
    &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 很好的答案,但您还没有真正解释为什么它不起作用。原因是 &lt;div&gt; 不是有效的 SVG 元素。所以在&lt;svg&gt; 内没有效果。
    • 确实,@PaulLeBeau,你是对的!正如我已经解释过的,在之前的几十次中,类似的问题被问过,我忘了在这一次中重复解释。已编辑。
    • 谢谢杰拉尔多。为透彻的解释。我从你的回复中学到了一些新东西。谢谢。
    • 我已将您的代码复制并粘贴到 index.html、app.js 和 app.css 中,但我仍然什么也没看到。我很困惑如何让它发挥作用。
    • 我什么也看不到 - 这是你的设置吗?
    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多