Я делаю карту treemap с d3.js. Мое дерево имеет гораздо больше листовых узлов, чем я мог бы визуализировать, поэтому я хочу обрезать дерево, чтобы поддерживать процент листовых узлов для каждой ветви, но уменьшать общее количество листьев до небольшого размера n
.Почему `treemap.nodes` не видит обновления для моего объекта?
Я успешно реализовал цикл for, который упорядочивает дочерние объекты моего объекта data
желаемым образом, но когда я вызываю treemap.nodes(data)
, я получаю список с исходным числом узлов как возвращаемое значение, а не сокращенный список узлов с меньшим количеством листьев.
Вот минимальный пример, который воспроизводит проблему.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<script type="text/javascript">
var w = 1280 - 80,
h = 800 - 180;
// Declare treemap
var treemap = d3.layout.treemap()
.round(false)
.size([w, h])
.sticky(true)
.value(function(d) { return d.size; });
// Load data
d3.json("demo.json", function(data) {
// Trim data
var categories = treemap.nodes(data)
.filter(function(d) { return d.depth==1; });
n = 10; //This is the maximum number of leaves I want to have
var total_value = treemap.nodes(data)[0].value;
for(var vertex of categories)
{
var num_children = vertex.children.length;
var percentage_screen = num_children/total_value;
var max_leaves = Math.max(1, Math.floor(n * percentage_screen));
vertex.children = vertex.children.slice(0,max_leaves)
}
// Here I try to get a list of the leaves
var nodes = treemap.nodes(data)
.filter(function(d) { return !d.children; });
// This print statement prints 20, the original number of leaves
console.log(nodes.length);
// But if I recursively count the number of leaves, I get the new smaller number, 10
console.log(recursive_node_counter(data));
});
function recursive_node_counter(d){
if('children' in d){
var num_child = 0;
for(child of d.children){
num_child += recursive_node_counter(child);
}
return num_child;
} else {
return 1
}
};
</script>
</body>
</html>
Использование вместе с этим JSON: demo.json
{"name": "root", "children":
[{"name": "branch_A", "children":
[{"name": "A_leaf", "size": 1},
{"name": "A_leaf", "size": 1},
{"name": "A_leaf", "size": 1},
{"name": "A_leaf", "size": 1},
{"name": "A_leaf", "size": 1},
{"name": "A_leaf", "size": 1}]},
{"name": "branch_B", "children":
[{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1},
{"name": "B_leaf", "size": 1}]},
{"name": "branch_C", "children":
[{"name": "C_leaf", "size": 1},
{"name": "C_leaf", "size": 1},
{"name": "C_leaf", "size": 1},
{"name": "C_leaf", "size": 1}]}]}
Почему treemap.nodes(data)
не видит изменения в переменной data
?
Вы не делаете любые изменения в переменной 'data'. Если вы измените его перед выполнением объединения данных, эти изменения будут отражены в древовидной структуре. –
@cool, если я не вношу никаких изменений в переменную данных, почему второй оператор печати печатает 10? – Cecilia
Предполагая, что закрытие всегда плохое в javascript. Макет имеет побочные эффекты для массива данных, так что одного достаточно, чтобы заставить меня очень неудобно пытаться туннелировать данные через макет. –