我正在尝试绘制不平衡树,如下所示
以下是代码:
var array = [ 'F', 'G', 'I', 'H', 'B', 'A', 'D', 'C', 'E' ];
var clusterLayout = d3.cluster().size([ 400, 200 ]);
var rootdata = addNode(array, null);
var root = d3.hierarchy(rootdata);
clusterLayout(root);
update(root);
function addNode(array, root) {
var rootdata = {};
array.forEach(function(d) {
if (jQuery.isEmptyObject(rootdata)) {
rootdata = {
name : d,
children : []
};
} else {
var next = rootdata;
var previous = null;
while (next != null) {
previous = next;
if (next.name > d) {
next = next.children[0];
} else {
if (next.children == null)
next = null;
else
next = next.children[1];
}
}
if (previous.children == null) {
previous.children=[];
}
if (previous.name > d) {
previous.children[0] = {
name : d,
children : []
};
} else {
if (previous.children[0] == null)
previous.children[0] = {};
previous.children[1] = {
name : d,
children : []
};
}
}
});
return rootdata;
}
function update(root) {
var circles = d3.select('svg g.nodes').selectAll('circle.node').data(
root.descendants());
circles.enter().append('circle').classed('node', true).attr("fill", "white").attr(
'cx', function(d) {
return d.x;
}).attr('cy', function(d) {
return d.y;
}).attr('r', 20);
circles.enter().append("text").attr("dx", function(d) {
return d.x;
}).attr("dy", function(d) {
return d.y;
}).text(function(d) {
return d.data.name
}).attr("fill", "black").attr("font-size", "15px").attr("font-family",
"sans-serif").attr("text-anchor", "middle");
// Links
d3.select('svg g.links').selectAll('line.link').data(root.links()).enter().append(
'line').classed('link', true).attr('x1', function(d) {
return d.source.x;
}).attr("stroke", "black").attr('y1', function(d) {
return d.source.y;
}).attr('x2', function(d) {
return d.target.x;
}).attr('y2', function(d) {
return d.target.y;
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.js"></script>
<link rel="stylesheet" href="simple_tree.css">
</head>
<body>
<svg width="1000" height="1000">
<g transform="translate(80,80)">
<g class="links"></g>
<g class="nodes"></g>
</g>
</svg>
<script type="application/javascript" src="/simple_tree.js"></script>
<div id="tree-container"></div>
</body>
</html>
呈现为
问题是因为代码片段下方的 addNode方法中添加了emtpy节点。我无法添加子项[0] = null,这是错误的。但我不能添加子1右节点而不在0处添加子数组。我该怎样解决这个问题?
if (previous.children[0] == null)
previous.children[0] = {};
答案 0 :(得分:0)
如下所示,但无法移除最后一个空节点。
var array = [ 'F', 'G', 'I', 'H', 'B', 'A', 'D', 'C', 'E' ];
var clusterLayout = d3.cluster().size([ 400, 200 ]);
var rootdata = addNode(array, null);
var root = d3.hierarchy(rootdata);
clusterLayout(root);
update(root);
function addNode(array, root) {
var rootdata = {};
array.forEach(function(d) {
if (jQuery.isEmptyObject(rootdata)) {
rootdata = {
name : d,
children : []
};
} else {
var next = rootdata;
var previous = null;
while (!jQuery.isEmptyObject(next) && next != null) {
previous = next;
if (next.name > d) {
next = next.children[0];
} else {
if (next.children == null)
next = null;
else
next = next.children[1];
}
}
if (previous.name > d) {
previous.children[0] = {
name : d,
children : []
};
} else {
if (previous.children[0] == null) {
previous.children[0] = {};
previous.children[1] = {
name : d,
children : []
};
} else if (jQuery.isEmptyObject(previous.children[0])) {
previous.children[0] = {
name : d,
children : []
};
} else {
previous.children[1] = {
name : d,
children : []
};
}
}
}
});
return rootdata;
}
function update(root) {
var circles = d3.select('svg g.nodes').selectAll('circle.node').data(
root.descendants());
circles.enter().append('circle').classed('node', true).attr("fill", "white").attr(
'cx', function(d) {
return d.x;
}).attr('cy', function(d) {
return d.y;
}).attr('r', 20);
circles.enter().append("text").attr("dx", function(d) {
return d.x;
}).attr("dy", function(d) {
return d.y;
}).text(function(d) {
return d.data.name
}).attr("fill", "black").attr("font-size", "15px").attr("font-family",
"sans-serif").attr("text-anchor", "middle");
// Links
d3.select('svg g.links').selectAll('line.link').data(root.links()).enter().append(
'line').classed('link', true).attr('x1', function(d) {
return d.source.x;
}).attr("stroke", "black").attr('y1', function(d) {
return d.source.y;
}).attr('x2', function(d) {
return d.target.x;
}).attr('y2', function(d) {
return d.target.y;
});
}