Ваш код был почти готов;единственное, чего не хватало, было то, что вам нужно было добавить поддельный корневой узел в вашу иерархию, указать аксессор для дочерних элементов и зафиксировать значение для конечных узлов, которые имели дополнительный уровень вложенности, который необходимо было удалить.
Значение конечного узла:
var nested_data = d3.nest()
[...]
.rollup(function(leaves) {
return {
value: leaves.length
}
})
.entries(data);
приводит к тому, что конечные узлы выглядят так:
{ value: { value: 5 } }
удаляет лишние value:
из вызова rollup
:
var nested_data = d3.nest()
[...]
.rollup(function(leaves) {
return leaves.length
})
.entries(data);
и теперь ваши конечные узлы выглядят так:
{ value: 5 }
Поддельный корневой узел
Убедитесь, что все ваши вложенные данные собраны в одной иерархии, добавив поддельный корень:
d3.hierarchy({ values: nested_data })
Метод доступа к дочернему узлу
Укажите метод доступа для дочерних элементов, так как в противном случае d3 будет искать x.children
и, если его там нет, будет предполагать, что узел является листом:
d3.hierarchy({ value: nested_data }, function(d) { return d.values })
Результат:
const margin = {
top: 40,
right: 10,
bottom: 10,
left: 10
};
var width = 960 - margin.left - margin.right;
var height = 960 - margin.top - margin.bottom;
var color = d3.scaleOrdinal().range(d3.schemeCategory20b);
var treemap = d3.treemap()
.size([width, height])
.padding(1)
.round(true);
var json_data = d3.json("https://raw.githubusercontent.com/vega/vega/master/docs/data/cars.json", function(error, data) {
if (error) throw error;
var nested_data = d3.nest()
.key(function(d) {
return d.Origin;
})
.key(function(d) {
return d.Cylinders;
})
.key(function(d) {
return d.Miles_per_Gallon;
})
.rollup(function(leaves) {
return leaves.length
})
.entries(data);
var root = d3.hierarchy({
values: nested_data
}, d => d.values)
.sum(function(d) {
return d.value;
})
treemap(root);
var nodes = d3.select('svg g')
.selectAll('g')
.data(root.descendants())
.enter()
.append('g')
.attr('transform', function(d) {
return 'translate(' + [d.x0, d.y0] + ')'
})
nodes
.append('rect')
.attr('width', function(d) {
return (d.x1 - d.x0) * 10;
})
.attr('height', function(d) {
return (d.y1 - d.y0) * 10;
})
.attr('fill', function(d) {
return color(d.data.key);
})
nodes
.append('text')
.text(function(d) {
return d.data.key;
})
});
body {
font: 10px sans-serif;
position: relative;
}
.node {
box-sizing: border-box;
line-height: 1em;
overflow: hidden;
position: absolute;
white-space: pre;
background: #ddd;
}
.node-label,
.node-value {
margin: 4px;
}
.node-value {
margin-top: -2px;
}
.node-value {
font-weight: bold;
}
<title>My treemap</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<svg width="1000" height="1000">
<g></g>
</svg>