html树图制作,d3.js制作树结构图

一、运行效果

e8b9ef61aeb07cfe9f17917cea9b8fb2.gif说明:使用鼠标滚轮放大缩小,点解节点可以收缩打开子节点,按住鼠标左键拖动可移动整体图形。

二、实现过程

1、编写html和css结构

.node {

ursor: pointer;

}

.node circle {

fill: #fff;

stroke: steelblue;

stroke-width: 1.5px;

}

.node text {

font: 10px sans-serif;

}

.link {

fill: none;

stroke: #ccc;

stroke-width: 1.5px;

}

.tree{

width: 800px;

height: 800px;

margin: 0 auto;

background: #E0E0E0;

}

.tree svg{

width: 100%;

height: 100%;

}

2、创建tree布局var margin = [20, 120, 20, 120],

width = document.getElementById("tree").offsetWidth,

height = document.getElementById("tree").offsetHeight;

var i = 0,

duration = 750,

root;

var tree = d3.layout.tree() //创建d3树布局,并定义画布大小

.size([height, width]);

var diagonal = d3.svg.diagonal()

.projection(function(d) { return [d.y, d.x]; });

var zoom = d3.behavior.zoom().scaleExtent([0.1, 100]).on("zoom", zoomed);//添加放大缩小事件

var svg = d3.select("body").select("#tree").append("svg")

.call(zoom)//给svg绑定zoom事件

.append("g")

.attr("transform", "translate(" + margin[3] + "," + margin[0] + ")")

.call(zoom)//给g绑定zoom事件

.append("g");

function zoomed() { //根据操作更改svg的大小位置

svg.attr("transform",

"translate(" + zoom.translate() + ")" +

"scale(" + zoom.scale() + ")"

);

}

3、在书布局中创建tree的每个节点,并绑定点击收缩展开子节点事件root = json[0];

root.x0 = height / 2;

root.y0 = 0;

root.children.forEach(collapse);

update(root);  //根据数据,创建节点以及连线

function collapse(d) {

if (d.children) {

d._children = d.children;

d._children.forEach(collapse);

d.children = null;

}

}

function update(source) {

var nodes = tree.nodes(root).reverse(),

links = tree.links(nodes);

nodes.forEach(function(d) { d.y = d.depth * 180; });

var node = svg.selectAll("g.node")

.data(nodes, function(d) { return d.id || (d.id = ++i); });

var nodeEnter = node.enter().append("g")

.attr("class", "node")

.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })

.on("click", click);

nodeEnter.append("circle")

.attr("r", 1e-6)

.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

nodeEnter.append("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);

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);

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);

var link = svg.selectAll("path.link")

.data(links, function(d) { return d.target.id; });

link.enter().insert("path", "g")

.attr("class", "link")

.attr("d", function(d) {

var o = {x: source.x0, y: source.y0};

return diagonal({source: o, target: o});

});

link.transition()

.duration(duration)

.attr("d", diagonal);

link.exit().transition()

.duration(duration)

.attr("d", function(d) {

var o = {x: source.x, y: source.y};

return diagonal({source: o, target: o});

})

.remove();

nodes.forEach(function(d) {

d.x0 = d.x;

d.y0 = d.y;

});

}

function click(d) {

if (d.children) {

d._children = d.children;

d.children = null;

} else {

d.children = d._children;

d._children = null;

}

update(d);

}

注意,其中的json数据格式为:var json = [

{

"name": "张三",

"parent": "null",

"children": [

{

"name": "李四",

"parent": "张三",

"children": [

{

"name": "王五",

"parent": "李四",

"children": [

{"name": "程六","parent": "王五" },

{"name": "王八","parent": "王五" },

{"name": "王七","parent": "王五" },

{

"name": "王九",

"parent": "王五",

"children":[

{"name": "王十","parent": "王五" },

{"name": "王十一","parent": "王五" },

{"name": "王十二","parent": "王五" },

{"name": "王十三","parent": "王五" },

{"name": "王十四","parent": "王五" },

{

"name": "程五",

"parent": "王五",

"children":[

{"name": "程六","parent": "程五" },

{"name": "程七","parent": "程五" },

{"name": "程八","parent": "程五" },

{"name": "小张","parent": "小红" },

{"name": "小王","parent": "小红" },

{"name": "小程","parent": "小红" },

{"name": "小陈","parent": "小红" },

{"name": "小明","parent": "小红" },

{"name": "小张","parent": "小红" }

]

}

]

}

]

},

{

"name": "马一",

"parent": "李四",

"children":[

{"name": "马二","parent": "马一" },

{"name": "马三","parent": "马一" },

{"name": "马四","parent": "马一" },

{"name": "马五","parent": "马一" },

{"name": "马六","parent": "马一" },

{"name": "马七","parent": "马一" },

{"name": "小明","parent": "小红" },

{"name": "小张","parent": "小红" }

]

}

]

},

{

"name": "小红",

"parent": "张三",

"children":[

{"name": "小明","parent": "小红" },

{"name": "小张","parent": "小红" },

{"name": "小王","parent": "小红" },

{"name": "小程","parent": "小红" },

{"name": "小陈","parent": "小红" },

{"name": "小明","parent": "小红" },

{"name": "小张","parent": "小红" }

]

}

]

}

];

三、项目结构图

7783db1e889adea7bffaadb1d9f69916.png

四、补充说明

这里使用的是v3版本的d3.js,每个版本的d3.js都有些许不同,引入库时需要注意这点。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
权限树状图通常用于展示系统中的权限结构,让用户更好地了解和管理权限。下面是使用 HTML、CSS 和 JavaScript 编写一个简单的权限树状图的示例代码: HTML 代码: ``` <div class="tree"> <ul> <li> <span class="node">权限 1</span> <ul> <li> <span class="node">子权限 1.1</span> </li> <li> <span class="node">子权限 1.2</span> </li> <li> <span class="node">子权限 1.3</span> </li> </ul> </li> <li> <span class="node">权限 2</span> <ul> <li> <span class="node">子权限 2.1</span> </li> <li> <span class="node">子权限 2.2</span> </li> </ul> </li> </ul> </div> ``` CSS 代码: ``` .tree ul { margin: 0; padding: 0; list-style-type: none; } .tree .node { cursor: pointer; } .tree li { margin: 0; padding: 0 1em; line-height: 2em; color: #333; position: relative; } .tree li:before, .tree li:after { content: ''; left: -0.5em; position: absolute; right: auto; } .tree li:before { border-left: 1px solid #999; bottom: 50%; height: 50%; top: 0; } .tree li:after { border-top: 1px solid #999; height: 2em; top: 25px; } .tree li:last-child:before { height: 25px; } .tree ul ul:before { content: ''; height: 2em; left: -0.5em; position: absolute; top: 25px; width: 1em; } .tree li li:after { border-top: 1px solid #999; height: 2em; top: 25px; } .tree li li:last-child:before { height: 25px; } .tree .node { background-color: #fff; border: 1px solid #999; border-radius: 5px; display: inline-block; padding: 0.2em 0.5em; } .tree .node:hover { background-color: #eee; } ``` JavaScript 代码: ``` // 获取所有的权限节点 var nodes = document.querySelectorAll('.tree .node'); // 遍历所有的节点,为其添加点击事件 nodes.forEach(function(node) { node.addEventListener('click', function() { var parent = this.parentNode; var children = parent.querySelectorAll(':scope > ul'); children.forEach(function(child) { child.classList.toggle('hidden'); }); }); }); ``` 这段代码主要实现了以下功能: 1. 使用 HTML 和 CSS 构建了一个基本的权限树状图。 2. 使用 JavaScript 获取所有的权限节点,并为其添加点击事件。 3. 点击节点时,展开或收起该节点下的子节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值