【问题标题】:D3 tutorial doesn't work on local machineD3 教程在本地机器上不起作用
【发布时间】:2018-05-24 08:58:10
【问题描述】:

我正在尝试自学 D3,我正在使用评价很高的 Curran Kelleher 的 D3 简介 (GitHub Page)

我目前正忙于从 CSV 文件中读取/解析数据。他的代码和预期输出在这里 (D3 Example Code)。

编辑:: 在此处复制/粘贴我的代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 tutorial 10</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body").append("svg")
        .attr("width",  250)
        .attr("height", 250);

      var xScale = d3.scaleLinear().range([0, 250]);
      var yScale = d3.scaleLinear().range([0, 250]);

      function render(data){

        xScale.domain(d3.extent(data, function (d){ return d.sepal_length; }));
        yScale.domain(d3.extent(data, function (d){ return d.petal_length; }));

        var circles = svg.selectAll("circle").data(data);
        circles.enter().append("circle").attr("r", 10);
        circles
          .attr("cx", function (d){ return xScale(d.sepal_length); })
          .attr("cy", function (d){ return yScale(d.petal_length); });

        circles.exit().remove();
      }

      function type(d){
        d.sepal_length = +d.sepal_length;
        d.sepal_width  = +d.sepal_width;
        d.petal_length = +d.petal_length;
        d.petal_width  = +d.petal_width;
        return d;
      }

      d3.csv("iris.csv", type, render);
</script>
</body>
</html>

我在我的 d3.html 页面中复制并粘贴了完全相同的代码,但这是我在 Chrome 浏览器窗口中得到的输出。关于我哪里出错的任何想法?

【问题讨论】:

标签: javascript d3.js


【解决方案1】:

enter.append() 的魔力

对于调试 D3 dataviz 的任何人,这里有一个非常重要的信息:圆圈已附加。您可以在原点 (0,0) 看到它们。

这一事实消除了一系列其他问题,例如未加载 CSV、未引用库、缺少 Web 服务器等...

元素在原点堆积是不同问题的征兆。通常,罪魁祸首是某处的NaN。但这里的问题更微妙:

问题是您使用的是 D3 v4,而您应该使用 D3 v3,这是该代码作者使用的版本。

这些行适用于 v3,但不适用于 v4:

var circles = svg.selectAll("circle").data(data);
circles.enter().append("circle").attr("r", 10);
circles.attr("cx", function(d) {
        return xScale(d.sepal_length);
    })
    .attr("cy", function(d) {
        return yScale(d.petal_length);
    });

让我们评论一下这里发生了什么。这是“更新”选择:

var circles = svg.selectAll("circle").data(data);

这是“进入”选择:

circles.enter().append("circle").attr("r", 10);

现在,请注意:您将位置设置为 “更新” 选项,而不是“输入”选项:

circles.attr("cx", function(d) {
        return xScale(d.sepal_length);
    })
    .attr("cy", function(d) {
        return yScale(d.petal_length);
    });

这在 D3 v4 中不起作用。据Mike Bostock,D3创作者:

D3 2.0 引入了一项更改来解决这种重复:追加到输入选择现在会将输入元素复制到更新选择中。因此,在附加到 enter 选择之后应用于更新选择的任何操作都将适用于输入和更新元素,并且可以消除重复代码 [...] D3 4.0 消除了 enter.append 的魔力。事实上,D3 4.0 完全消除了输入选择和普通选择之间的区别:现在只有一类选择。

这就是 “enter.append() 的魔法”,它在 v2 和 v3 中有效,但在 v4 中不再有效。

解决方案:

只需使用 D3 v3。

或者,如果您想保留 v4,只需合并选择:

var circles = svg.selectAll("circle").data(data);
circles.enter().append("circle").attr("r", 10).merge(circles)
    .attr("cx", function(d) {
        return xScale(d.sepal_length);
    })
    .attr("cy", function(d) {
        return yScale(d.petal_length);
    });

circles.exit().remove();

下面是使用 v4 的代码:https://bl.ocks.org/anonymous/6f7a7e1bbc682097932d49b0a13221fc/dda68f134c57dc68b7469d10206280ea1a8d610a

【讨论】:

  • 是的,那是我的问题。现在我的解决方案与示例和预期输出相匹配。谢谢!
【解决方案2】:

我看到@Gerardo 已经回答了。但是,当我学习 D3.js 时,我发现在版本 4 中编码非常有用,即使教程是在版本 3 中,并尝试重新编码这些教程以使其工作。

这个非常简单。唯一显着的变化是命名法:d3.scale.linear() 变为 d3.scaleLinear()。分配数据属性也更简单(输入数据后,您可以立即添加圆圈的属性,无需重新选择圆圈)。

v4 代码如下。我还删除了一行——circles.exit().remove();——因为它与本教程无关!

<script>
  var svg = d3.select("body").append("svg")
    .attr("width",  250)
    .attr("height", 250);

  var xScale = d3.scaleLinear().range([0, 250]);
  var yScale = d3.scaleLinear().range([0, 250]);

  function render(data) {

    xScale.domain(d3.extent(data, function(d) { return d.sepal_length; }));
    yScale.domain(d3.extent(data, function(d) { return d.petal_length; }));

    var circles = svg.selectAll("circle")
      .data(data)
      .enter().append("circle")
        .attr("r", 10)
        .attr("cx", function (d) { return xScale(d.sepal_length); })
        .attr("cy", function (d) { return yScale(d.petal_length); });
  }

  function type(d) {
    d.sepal_length = +d.sepal_length;
    d.sepal_width  = +d.sepal_width;
    d.petal_length = +d.petal_length;
    d.petal_width  = +d.petal_width;
    return d;
  }

   d3.csv("iris.csv", type, render);

 </script>

它产生this output。尝试从头开始学习 v4 编码。最终会为您节省时间!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2015-02-25
    • 2011-02-15
    • 2015-03-19
    • 2018-01-02
    相关资源
    最近更新 更多