d3js树状图tree
使用ds.js画出树状图,样式可自定义。以下是效果图

介绍下过程:
- 使用d3.js
- 初始化d3和画布大小,tree = d3.layout.cluster().size([h, w])
- 导入数据,使用d3默认处理数据: root = tree.nodes(data)
- 处理数据(包括坐标的处理)
- 展示数据
html代码如下,需要引用d3.js即可
<html>
<head>
<title></title>
</head>
<body>
<js href="/Public/plugins/d3js/d3.min.js" />
<style type="text/css">
#body{
height: 500px;
width: 500px;
}
/*d3js*/
.node circle {
cursor: pointer;
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font-size: 11px;
cursor: pointer;
}
path.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
</style>
<div id="body" class="body">
<div id="footer">
<button onclick="updateinfo()">Click me</button>
</div>
</div>
<script type="text/javascript">
updateinfo();
function updateinfo(){
var json ={"r":{"name":"flare","children":[{"name":"animate","children":[{"name":"Easing"},{"name":"FunctionSequence"},{"name":"ISchedulable"},{"name":"Parallel"},{"name":"Parallel2"},{"name":"Parallel4"},{"name":"Parallel6"},{"name":"Pause"}]}]},"l":{"name":"flare","children":[{"name":"query","children":[{"name":"AggregateExpression","pos":"l"},{"name":"And","pos":"l"},{"name":"Arithmetic","pos":"l"},{"name":"fasdfasdf","pos":"l"},{"name":"Arithmasdfasetic","pos":"l"},{"name":"dfasdfa","pos":"l"}],"pos":"l"}]}};
var d3js = function(json){
var objRight = json['r'] ? json['r'] : {};
var objLeft = json['l'] ? json['l'] : {};
d3jsTree('#body',objRight,objLeft);
}
d3js(json);
}
// d3js tree
function d3jsTree(aim,objRight,objLeft){
// $(aim+' svg').remove();
var m = [20, 120, 20, 120],
w = 1280 - m[1] - m[3],
h = 600 - m[0] - m[2], //靠左
i = 0;
var tree = d3.layout.cluster().size([h, w]);
var diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x]; });
var vis = d3.select(aim).append("svg:svg")
.attr("width", 1200)
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + h + "," + m[0] + ")"); // translate(靠左,靠上)
update(objRight,objLeft);
function init_nodes(left){
left.x0 = h / 2;
left.y0 = 0;
var nodes_dic = [];
var left_nodes = tree.nodes(left);
return left_nodes;
}
function update(source,l) {
var duration = d3.event && d3.event.altKey ? 5000 : 500;
// Compute the new tree layout.
var nodes = init_nodes(source);
var left_nodes = init_nodes(l);
// if( l !=)
var len = nodes.length;
for( var i in left_nodes ){
nodes[len++] = left_nodes[i];
}
// Normalize for fixed-depth.
nodes.forEach(function(d) {
tmp = 1;
if( d.pos == 'l' ){ tmp = -1;}
d.y = tmp * d.depth * 200; // 线条长度,也是作于方向
// d.x = d.l * 63;
});
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", function(d) { alert(d.name); }); // 点击事件
// .on("click", function(d) { ajax_get_server(d.name);console.log(d);toggle(d); update(d,l); });
nodeEnter.append("svg:circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("svg:text")
.attr("x", function(d) { return d.children || d._children ? -10 : 10; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeUpdate.select("text").style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = vis.selectAll("path.link")
.data(tree.links(nodes), function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter()
.insert("svg:path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
})
.transition()
.duration(duration)
.attr("d", diagonal);
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit()
.transition()
.duration(duration)
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children.
function toggle(d) {
if (d.children) {
d._children = d.children; // 闭合子节点
d.children = null;
} else {
d.children = d._children; // 开启子节点
d._children = null;
}
}
}
</script>
</body>
</html>