D3.js v4 布局上的 NaN 坐标
NaN coordinates on D3.js v4 layouts
尝试在 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>
在控制台中登录 root 我看到 x 和 y 字段仍然是 NaN。您看到我的代码中的错误了吗?
您将 SVG 的宽度和高度设置为百分比:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
因此,当您使用 getter 时,您检索字符串 100%
:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(svg.attr("width"))
<script src="https://d3js.org/d3.v4.min.js"></script>
当然,对这样的字符串使用一元加号可以得到 NaN
:
console.log(+"100%")
并且您将那些 NaN
传递给 d3.tree().size()
。
有几种解决方案,最简单的一种就是将 numbers 传递给布局大小。但是,当您使用 "100%"
时,我们可以假设您不知道 SVG 的大小。
所以,我这里的解决方案(同样,不是唯一可能的)是使用 d3.style
来获取 像素 的属性,而不是百分比(但仍然是一个字符串)...
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(d3.style(svg.node(), "width"))
<script src="https://d3js.org/d3.v4.min.js"></script>
... 然后使用 parseInt()
(或任何其他方法)摆脱 px
:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(parseInt(d3.style(svg.node(), "width")))
<script src="https://d3js.org/d3.v4.min.js"></script>
最后,如果你不想处理字符串,只需使用getBoundingClientRect()
,这将return一个数字:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(svg.node().getBoundingClientRect().width);
<script src="https://d3js.org/d3.v4.min.js"></script>
简短的回答是您正在根据 window 大小(页面宽度和高度的 100%)调整 svg 的大小。使用您当前的代码,这会导致 none 整数被传递给 d3.tree.size()
,从而导致 NaN。正如 Gerardo 指出的那样,这可以很容易地从百分比转换为像素值,但是,在尝试让这样的小示例起作用时,使用固定值宽度和高度并不是一个糟糕的主意。
如果您将宽度和高度更改为固定值,则您的代码可以正常工作。我建议您这样做,直到您熟悉 D3 以及您尝试使用上面的代码实现的目标。
尝试在 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>
在控制台中登录 root 我看到 x 和 y 字段仍然是 NaN。您看到我的代码中的错误了吗?
您将 SVG 的宽度和高度设置为百分比:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
因此,当您使用 getter 时,您检索字符串 100%
:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(svg.attr("width"))
<script src="https://d3js.org/d3.v4.min.js"></script>
当然,对这样的字符串使用一元加号可以得到 NaN
:
console.log(+"100%")
并且您将那些 NaN
传递给 d3.tree().size()
。
有几种解决方案,最简单的一种就是将 numbers 传递给布局大小。但是,当您使用 "100%"
时,我们可以假设您不知道 SVG 的大小。
所以,我这里的解决方案(同样,不是唯一可能的)是使用 d3.style
来获取 像素 的属性,而不是百分比(但仍然是一个字符串)...
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(d3.style(svg.node(), "width"))
<script src="https://d3js.org/d3.v4.min.js"></script>
... 然后使用 parseInt()
(或任何其他方法)摆脱 px
:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(parseInt(d3.style(svg.node(), "width")))
<script src="https://d3js.org/d3.v4.min.js"></script>
最后,如果你不想处理字符串,只需使用getBoundingClientRect()
,这将return一个数字:
var svg = d3.select("body").append("svg")
.attr("height", "100%")
.attr("width", "100%");
console.log(svg.node().getBoundingClientRect().width);
<script src="https://d3js.org/d3.v4.min.js"></script>
简短的回答是您正在根据 window 大小(页面宽度和高度的 100%)调整 svg 的大小。使用您当前的代码,这会导致 none 整数被传递给 d3.tree.size()
,从而导致 NaN。正如 Gerardo 指出的那样,这可以很容易地从百分比转换为像素值,但是,在尝试让这样的小示例起作用时,使用固定值宽度和高度并不是一个糟糕的主意。
如果您将宽度和高度更改为固定值,则您的代码可以正常工作。我建议您这样做,直到您熟悉 D3 以及您尝试使用上面的代码实现的目标。