D3 Nothing Displaying

2019-01-26 16:40发布

Trying to display some simple bar charts using D3 but nothing is being displayed.

<style>
    .chart div {
      font: 10px sans-serif;
      background-color: steelblue;
      text-align: right;
      padding: 3px;
      margin: 1px;
      color: white;
    }
</style>


<script src="d3.v3.js"></script>
<script>

    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]);
    }

</script>

When using chrome's inspect I see the newly created elements and the svg is highlighted but not the inner div's Thank you.

1条回答
疯言疯语
2楼-- · 2019-01-26 17:18

In a nutshell: you cannot append a HTML element to a SVG. The reason is simple: <div>, <p>, <h1>, <h2>, <td>, <li> and so on are not valid SVG elements.

This has been asked and answered many, many times. However, I'd like to answer this question because of a specific part of it (which is normally not asked):

When using chrome's inspect I see the newly created elements.

Yes, the elements are there. But this doesn't mean it's going to work.

Let's show this in the following snippet, in which I'm appending <div>s to the SVG. look at the console.log, it shows the SVG structure:

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>

You can see that the divs are in the DOM. However, there is nothing on the screen...

The fact that you see the element in the DOM means nothing, because you can append anything!

For instance, let's append an element named 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>

You can see <charlesDarwin> in the DOM. However, it's obvious that nothing will show up in the SVG.

PS: Regarding your chart:

  1. Get rid of that for loop. You don't need that when using D3;
  2. Set the class without the dot;
  3. Append the divs to the body, as discussed above.

This is the working code:

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;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

查看更多
登录 后发表回答