d3.js树状图的zoom事件和节点不重叠
效果图如下:
话不多说,直接上代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>zoom树形图</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
html,body{
background-color: #ddd;
}
.month_svg{
height: 400px;
width: 500px;
margin: 50px auto;
background-color: white
}
.month_svg .axis path, .month_svg .axis line {
stroke: black;
fill: none;
}
.node {
cursor: pointer;
}
.overlay{
background-color:#EEE;
}
.node.active{
fill:#f00;
stroke: #f00;
}
.node.active circle{
fill: #f00;
stroke: #f00;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font-size:14px;
font-family:sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
.templink {
fill: none;
stroke: red;
stroke-width: 3px;
}
</style>
</head>
<body>
<div id="tree-container" class="month_svg">
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
//节点数据
var treeData = {
user_name: "人员",
radius: "4",
lineColor: "#999999",
strokeColor: "#999999",
fillColor: "#999999",
employee_id: "",
children: [
{
user_name: "张三",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "张四",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "张六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "张七",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
]
},
{
user_name: "张五",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "张八",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "张九",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李七",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十一",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十二",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十三",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
]
},
]
},
{
user_name: "李四",
lineColor: "#999999",
strokeColor: "#999999",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "李五",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "李六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李七",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十一",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十二",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十三",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李七",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十一",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十二",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十三",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
]
},
{
user_name: "李六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
children: [
{
user_name: "李八",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李九",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李六",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李七",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十一",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十二",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
{
user_name: "李十三",
lineColor: "#999999",
strokeColor: "#1E9FFF",
fillColor: "#1E9FFF",
employee_id: "",
radius: 4,
},
]
},
]
},
]
};
creatTree();
function creatTree(){ //直方图
$("#tree-container").html('');
var boxWidth = $("#tree-container").width();
var boxHeight = $("#tree-container").height();
var margin = {top: 30, right: 120, bottom: 30, left: 120},
width = boxWidth - margin.right - margin.left,
height = boxHeight - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree() //创建树图布局
.nodeSize([20, 100]); //为树设置 size ,您正在设置固定的大小,节点可能会发生重叠。如果你想要 nodeSize 工作,你不能有固定的树大小 。如果您声明一个 nodeSize ,则不要声明 size 。
var zoom = d3.behavior.zoom() //创建zoom行为
.scaleExtent([0.1, 10]) //设置缩放范围
.on("zoom", zoomed); //zoom事件发生时调用zoomed函数
var diagonal = d3.svg.diagonal() //新建一个对角线生成器。
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("#tree-container").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.call(zoom)
.append("g")
.attr("id","g_main")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
var root = treeData;
console.log(root);
updates(root);
function zoomed() { //改变svg的位置,缩放量
svg.attr("transform","translate("+d3.event.translate+")scale("+d3.event.scale+")");
}
function updates(source) { //创建节点
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 120; });
// Declare the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("id",function(d){
return "node"+d.employee_id;
})
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";
});
nodeEnter.append("circle")
.attr("r", function(d) {
return d.radius;
})
.style("fill", function(d) {
return d.fillColor;
})
.style("stroke", function(d) {
return d.strokeColor;
});
nodeEnter.append("text")
.attr("x", function(d) {
return d.children || d._children ? (15) * -1 : + 15
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start";
})
.text(function(d) {
//console.log(d.user_name);
return d.user_name;
})
.style("fill-opacity", 1);
// Declare the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter the links.
link.enter().insert("path", "g")
.attr("class", "link")
.style("stroke", function(d) { return d.target.lineColor; })
.attr("d", diagonal);
}
}
</script>
</body>
</html>