Координаты НАН на D3.Яш В4 макетов
Попытка использовать D3.Яш раскладов на картах на вход JSON вида:
var data = {
"name": "Top",
"frequency": 0,
"children": [
{
"name": "Per",
"frequency": 1287
},
{
"name": "Tu",
"frequency": 133,
"children": [
{
"name": "Mel",
"frequency": 50
}
]
}
]
}
Я застрял на получении X и y позиций, и я думал, что это из-за моего отсутствия знаний использования .сумма или .значение () для захвата частотного поля. Я хотел проверить свое предположение, поэтому я попробовал компоновку дерева, просто чтобы увидеть пространственно организованные данные:
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 ответа:
Вы устанавливаете ширину и высоту SVG в процентах:
var svg = d3.select("body").append("svg") .attr("height", "100%") .attr("width", "100%");
Итак, когда вы используете геттер, вы получаете строку
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
sd3.tree().size()
.Есть несколько решений, самое простое-это просто передачачисел в размер макета. Однако, как вы используете
Итак, мое решение здесь (опять же, не единственное возможное) - это использование"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()
, который вернет a число:
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>
Короткий ответ: вы определяете размер svg относительно размера окна (100% ширины и высоты страницы). С вашим текущим кодом это приводит к тому, что целое число none передается в
d3.tree.size()
, вызывая NaN. как указывает Херардо, это может легко преобразовываться из процента в значение пикселя, однако использование фиксированных значений ширины и высоты не является ужасной идеей при попытке получить небольшие примеры, подобные этому.Если вы измените ширину и высоту на фиксированные значения, то ваш код работает. Я бы предложил делать это до тех пор, пока вам не станет более комфортно с D3 и тем, что вы пытаетесь достичь с помощью этого кода выше.