NaN坐标在D3.js v4布局上

时间:2018-02-01 00:58:18

标签: d3.js layout hierarchical-data

尝试在表单的JSON输入上使用D3.js布局树形图:

var data = {
  "name": "Top",
  "frequency": 0,
  "children": [
  {
    "name": "Per",
    "frequency": 1287
  },
  {
    "name": "Tu",
    "frequency": 133,
    "children": [
    {
      "name": "Mel",
      "frequency": 50
    }
    ]
  }
  ]
}

我被困在获得x和y位置,我认为这是因为我缺乏使用.sum()或.value()捕获频率字段的知识。我想验证我的假设,所以我尝试了树的布局,只是为了看到空间组织的数据:

var svg = d3.select(".chart").append("svg")
  .attr("height", "100%")
  .attr("width", "100%");

var root = d3.hierarchy(data);

var treeLayout = d3.tree().size([+svg.attr("width"), +svg.attr("height")]);

treeLayout(root);

var nodes = root.descendants();

svg.selectAll("circle").data(nodes)
      .enter().append("circle")
        .attr("r", function(d, i) {
          return 4;
        })
        .attr("cx", function(d, i) {
          return d.x;
        })
        .attr("cy", function(d, i) {
          return d.y;
        });

HTML:

<style type="text/css">
  div.chart {
    height: 5000px;
  }
</style>
<div class="chart">
</div>

在控制台中记录根我发现x和y字段仍然是NaN。你在我的代码中看到了错误吗?

2 个答案:

答案 0 :(得分:2)

您将SVG的宽度和高度设置为百分比:

var svg = d3.select("body").append("svg")
    .attr("height", "100%")
    .attr("width", "100%");

因此,当您使用getter时,您将检索字符串100%

&#13;
&#13;
var svg = d3.select("body").append("svg")
  .attr("height", "100%")
  .attr("width", "100%");

console.log(svg.attr("width"))
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

当然,使用带有这种字符串的一元加号可以得到NaN

&#13;
&#13;
console.log(+"100%")
&#13;
&#13;
&#13;

您已将这些NaN传递给d3.tree().size()

有几种解决方案,最简单的方法就是将数字传递给布局大小。但是,当您使用"100%"时,我们可以假设您不知道SVG的大小。

所以,我的解决方案(再次,不是唯一可能的解决方案)是使用d3.style来获取像素中的属性,而不是百分比(但仍然是字符串)。

&#13;
&#13;
var svg = d3.select("body").append("svg")
  .attr("height", "100%")
  .attr("width", "100%");

console.log(d3.style(svg.node(), "width"))
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

...然后使用parseInt()(或任何其他方法)摆脱px

&#13;
&#13;
var svg = d3.select("body").append("svg")
  .attr("height", "100%")
  .attr("width", "100%");

console.log(parseInt(d3.style(svg.node(), "width")))
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

最后,如果您不想处理字符串,只需使用getBoundingClientRect(),这将返回一个数字:

&#13;
&#13;
var svg = d3.select("body").append("svg")
  .attr("height", "100%")
  .attr("width", "100%");

console.log(svg.node().getBoundingClientRect().width);
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

简短的回答是你是在调整你的svg相对于窗口大小(页面的宽度和高度的100%)。使用当前代码,这会导致将一个非整数传递给d3.tree.size(),从而导致NaN&#39}。正如Gerardo所指出的,这可以很容易地从百分比转换为像素值,但是,当试图让这样的小例子起作用时,使用固定值宽度和高度并不是一个糟糕的主意。

如果将宽度和高度更改为固定值,则代码可以正常工作。我建议你这样做,直到你对D3更加满意,以及你用上面的代码尝试实现的目标。