tree 订阅
Tree
信息
操作系统
未知
开发语言
开源协议
未知
Tree
Tree Structure that you can easily create by entering the values in text box and add in tree formate. It just uses the simple js file and small html file thats it. You can easily add and remove the nodes. The expanding and collapsing fecilties are provided in this tree structure.. You please look at it.
收起全文
精华内容
下载资源
问答
  • import open3d as o3d pcd = o3d.io.read_point_cloud("bunny.pcd") pcd.paint_uniform_color([0.5, 0.5, 0.5])#把所有点渲染为灰色(灰兔子) pcd_tree = o3d.geometry.KDTreeFlann(pcd)#建立KD树索引
  • Trie Tree和Radix Tree

    千次阅读 2019-06-13 22:38:28
    前言 在实际应用场景中,很多时候我们会用到字典集的查找。通过一个键值key,去拿到它对应的值...本节笔者将要谈论的是对于基数统计来说,使用上更为适用的1种数据结构Trie Tree以及它的衍生优化版Radix Tree。 ...

    前言


    在实际应用场景中,很多时候我们会用到字典集的查找。通过一个键值key,去拿到它对应的值对象。这种方法确实很高效,很快,但是这里有个问题,当字典集储存的键值很多的情况时,毫无疑问,这里会消耗掉大量的内存空间。这个在我们做基数计数的统计应用时,这个空间会膨胀地特别厉害。本节笔者将要谈论的是对于基数统计来说,使用上更为适用的1种数据结构Trie Tree以及它的衍生优化版Radix Tree。

    Trie Tree


    我们先来看第一种树结构Trie Tree,名叫字典树。Trie Tree的原理是将每个key拆分成每个单位长度字符,然后对应到每个分支上,分支所在的节点对应为从根节点到当前节点的拼接出的key的值。它的结构图如下所示。

    在这里插入图片描述

    上图中每个节点存储的值为一个数值,当然这不是绝对的,我们可以假想这可以是key值所对应的任何值对象。只是计数统计在平时使用中更为常见一些。那么问题来了,相比较于字典集的存储方式,Trie Tree将key以树型结构构造,有什么用意呢?一个最大的帮助是公共的前缀被共享了,这样可以避免被重复地存储了。而在普通的字典集结构中,这种重复key前缀都是独立被包含在每个key内的。假设当字典集中所存储的key都带有大量重复的前缀时,Trie Tree将会消耗比普通字典结构更少的空间。

    如上述所描述的,通过共享公共前缀的方式空间省了不少,但是它的查询效率如何呢?按照树的查询方式,一个查询key长度m,首先我们会将key拆分成m个字符,然后对应每个长度,从根节点依次向下,总共会进行到m次查找。因此我们可以得出,它的查询时间复杂度为O(m),随着查询key长度的增加,它所消耗的时间将会线性增长。

    往深层面来看查询时间的问题,其实本质上这是树的深度引起的问题,对于长key而言,它的key对应的节点构造的深度过深。那么如果说我们将这“棵”树构造得更紧凑一些,会如何呢?于是我们有了另外一个衍生版本树:Radix Tree(基数树)。

    Radix Tree


    Radix Tree名为基数树,它的计数统计原理和Trie Tree极为相似,一个最大的区别点在于它不是按照每个字符长度做节点拆分,而是可以以1个或多个字符叠加作为一个分支。这就避免了长字符key会分出深度很深的节点。Radix Tree的结构构造如下图所示:

    在这里插入图片描述
    从上图我们可以看到,上面每个分支可以是局部部分字符串。以简单的字符查找为例,Radix Tree的搜索查找过程如下:

    在这里插入图片描述

    针对Radix Tree的构造规则,它的节点插入和删除行为相比较于Trie Tree来说,略有不同。

    • 对于节点插入而言,当有新的key进来,需要拆分原有公共前缀分支。
    • 对于节点删除而言,当删除一个现有key后,发现其父节点只有另外一个子节点key,则此子节点可以和父节点合并为一个新的节点,以此减少树的比较深度。

    Radix Tree的insert过程如下图所示:
    在这里插入图片描述

    Trie Tree、Radix Tree的局限性


    的确Trie Tree、Radix Tree在某些应用场景可以帮助我们节省内存使用空间,但是它们也有其使用的局限性。比如这类树结构无法适用于所有的数据类型,目前来看主要适用于能够用string字符等可作为表达式查询key的场景。

    引用


    [1].https://en.wikipedia.org/wiki/Radix_tree
    [2].https://en.wikipedia.org/wiki/Trie

    展开全文
  • tree.jstree.jstree.js

    2009-11-11 22:48:25
    tree.jstree.jstree.jstree.jstree.jstree.jstree.jstree.jstree.js
  • B-Tree和B+Tree

    千次阅读 2019-08-12 10:49:48
    目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构,在本文的下一节会结合存储器原理及计算机存取原理讨论为什么B-Tree和B+Tree在被如此广泛用于索引,这一节先单纯从数据结构角度描述它们。...

    目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构,在本文的下一节会结合存储器原理及计算机存取原理讨论为什么B-Tree和B+Tree在被如此广泛用于索引,这一节先单纯从数据结构角度描述它们。

    B-Tree

    为了描述B-Tree,首先定义一条数据记录为一个二元组[key, data],key为记录的键值,对于不同数据记录,key是互不相同的;data为数据记录除key外的数据。那么B-Tree是满足下列条件的数据结构:

    d为大于1的一个正整数,称为B-Tree的度。

    h为一个正整数,称为B-Tree的高度。

    每个非叶子节点由n-1个key和n个指针组成,其中d<=n<=2d。

    每个叶子节点最少包含一个key和两个指针,最多包含2d-1个key和2d个指针,叶节点的指针均为null 。

    所有叶节点具有相同的深度,等于树高h。

    key和指针互相间隔,节点两端是指针。

    一个节点中的key从左到右非递减排列。

    所有节点组成树结构。

    每个指针要么为null,要么指向另外一个节点。

    如果某个指针在节点node最左边且不为null,则其指向节点的所有key小于v(key1),其中v(key1)为node的第一个key的值。

    如果某个指针在节点node最右边且不为null,则其指向节点的所有key大于v(keym),其中v(keym)为node的最后一个key的值。

    如果某个指针在节点node的左右相邻key分别是keyi和keyi+1且不为null,则其指向节点的所有key小于v(keyi+1)且大于v(keyi)。

    图2是一个d=2的B-Tree示意图。

    图2

    由于B-Tree的特性,在B-Tree中按key检索数据的算法非常直观:首先从根节点进行二分查找,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或找到null指针,前者查找成功,后者查找失败。B-Tree上查找算法的伪代码如下:

    BTree_Search(node, key) {
        if(node == null) return null;
        foreach(node.key)
        {
            if(node.key[i] == key) return node.data[i];
                if(node.key[i] > key) return BTree_Search(point[i]->node);
        }
        return BTree_Search(point[i+1]->node);
    }
    data = BTree_Search(root, my_key);
    

    关于B-Tree有一系列有趣的性质,例如一个度为d的B-Tree,设其索引N个key,则其树高h的上限为logd((N+1)/2),检索一个key,其查找节点个数的渐进复杂度为O(logdN)。从这点可以看出,B-Tree是一个非常有效率的索引数据结构。

    另外,由于插入删除新的数据记录会破坏B-Tree的性质,因此在插入删除时,需要对树进行一个分裂、合并、转移等操作以保持B-Tree性质,本文不打算完整讨论B-Tree这些内容,因为已经有许多资料详细说明了B-Tree的数学性质及插入删除算法,有兴趣的朋友可以在本文末的参考文献一栏找到相应的资料进行阅读。

    B+Tree

    B-Tree有许多变种,其中最常见的是B+Tree,例如MySQL就普遍使用B+Tree实现其索引结构。

    与B-Tree相比,B+Tree有以下不同点:

    每个节点的指针上限为2d而不是2d+1。

    内节点不存储data,只存储key;叶子节点不存储指针。

    图3是一个简单的B+Tree示意。

    图3

    由于并不是所有节点都具有相同的域,因此B+Tree中叶节点和内节点一般大小不同。这点与B-Tree不同,虽然B-Tree中不同节点存放的key和指针可能数量不一致,但是每个节点的域和上限是一致的,所以在实现中B-Tree往往对每个节点申请同等大小的空间。

    一般来说,B+Tree比B-Tree更适合实现外存储索引结构,具体原因与外存储器原理及计算机存取原理有关,将在下面讨论。

    带有顺序访问指针的B+Tree

    一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针。

    图4

    如图4所示,在B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+Tree。做这个优化的目的是为了提高区间访问的性能,例如图4中如果要查询key为从18到49的所有数据记录,当找到18后,只需顺着节点和指针顺序遍历就可以一次性访问到所有数据节点,极大提到了区间查询效率。

    这一节对B-Tree和B+Tree进行了一个简单的介绍,下一节结合存储器存取原理介绍为什么目前B+Tree是数据库系统实现索引的首选数据结构。

    展开全文
  • LayUI—tree树形结构的使用

    万次阅读 多人点赞 2019-09-01 21:46:46
    树形结构在实际开发中很长用到,...官网地址:https://www.layui.com/v1/doc/modules/tree.html 先看一下显示的效果图。 点击节点右面会显示对应部门的详情信息,可以修改。可以自定义按钮添加部门,也可以直接...

    树形结构在实际开发中很长用到,比如部门管理,权限菜单等。因为用树形结构来展示会显的很清晰明了。最近写了一个个人博客小项目中用到了LayUI的树形结构,之后写了一个小案例整理一下。

    官网地址:https://www.layui.com/v1/doc/modules/tree.html

    先看一下显示的效果图。

    点击节点右面会显示对应部门的详情信息,可以修改。可以自定义按钮添加部门,也可以直接用自带的方法对部门进行新增,修改和删除。可以获取选中的节点,根据项目需求(有的需要选中保存)。

    先需要引入LayUI的样式文件JS和CSS。

    案例对应的实体类Dept。

    @Entity
    public class Dept {
        private Integer id;
        private String name;    //部门名称
        private String deptName;    //部门负责人
        private String phone;   //电话号
        private String number;  //编号
        private double idx;     //排序
        @JsonIgnore
        private Dept parent;
        @JsonIgnore
        private List<Dept> children = new ArrayList<>();
    
        @Id
        @GeneratedValue
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDeptName() {
            return deptName;
        }
    
        public void setDeptName(String deptName) {
            this.deptName = deptName;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public double getIdx() {
            return idx;
        }
    
        public void setIdx(double idx) {
            this.idx = idx;
        }
    
        @ManyToOne
        @CreatedBy
        public Dept getParent() {
            return parent;
        }
    
        public void setParent(Dept parent) {
            this.parent = parent;
        }
    
        @OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
        @OrderBy(value="idx")
        public List<Dept> getChildren() {
            return children;
        }
    
        public void setChildren(List<Dept> children) {
            this.children = children;
        }
    
        public Dept(Integer id, String name, String deptName, String phone, String number, double idx, Dept parent, List<Dept> children) {
            this.id = id;
            this.name = name;
            this.deptName = deptName;
            this.phone = phone;
            this.number = number;
            this.idx = idx;
            this.parent = parent;
            this.children = children;
        }
    
        public Dept(Integer id) {
            this.id = id;
        }
    
        public Dept() {
        }
    }

    显示LayUI树形菜单,只需要一个标签容器即可。

    <div id="dept_tree">
    </div>

    在案例中还有一些其他样式,比如右边的详情信息,新增按钮等。完整代码如下。

    <style type="text/css">
        #dept_main, #dept_particulars{
            width: 48.5%;
            display: inline-block;
            vertical-align: top;
            padding: 20px;
            background: white;
            box-sizing: border-box;
        }
        #dept_tree{
            margin-top: 20px;
        }
    </style>
    
    <div id="dept_main" style="margin-right: 2%;">
        <fieldset class="layui-elem-field layui-field-title">
            <legend>所有部门</legend>
        </fieldset>
        <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>添加部门</button>
        <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>
        <div id="dept_tree">
    
        </div>
    </div>
    <div id="dept_particulars">
        <fieldset class="layui-elem-field layui-field-title">
            <legend>部门详情</legend>
        </fieldset>
        <div id="dept_home">
            <div class="layui-tree-emptyText">无数据</div>
        </div>
    </div>

    JS请求数据渲染页面代码,data为请求数据源,当时直接放入的请求链接,好像不行,所以之后才写了一个方法去请求数据源。

    layui.use(['tree', 'util'], function() {
        var tree = layui.tree;
        var util = layui.util;
        tree.render({
            elem: '#dept_tree',
            data: getData(),
            id: 'treeId',
            showCheckbox: true,     //是否显示复选框
            onlyIconControl: true
        });
    });
    
    function getData(){
        var data = [];
        $.ajax({
            url: "dept/treeload",    //后台数据请求地址
            type: "post",
            async:false,
            success: function(resut){
                data = resut;
            }
        });
        return data;
    }

     tree 组件提供的有以下基础参数,可根据需要进行相应的设置。

    参数选项说明类型示例值
    elem指向容器选择器String/Object-
    data数据源Array-
    id设定实例唯一索引,用于基础方法传参使用。String-
    showCheckbox是否显示复选框Booleanfalse
    edit是否开启节点的操作图标。默认 false。
    • 若为 true,则默认显示“改删”图标
    • 若为 数组,则可自由配置操作图标的显示状态和顺序,目前支持的操作图标有:addupdatedel,如: 
      edit: ['add', 'update', 'del']
    Boolean/Array['update', 'del']
    accordion是否开启手风琴模式,默认 falseBooleanfalse
    onlyIconControl是否仅允许节点左侧图标控制展开收缩。默认 false(即点击节点本身也可控制)。若为 true,则只能通过节点左侧图标来展开收缩Booleanfalse
    isJump是否允许点击节点时弹出新窗口跳转。默认 false,若开启,需在节点数据中设定 link 参数(值为 url 格式)Booleanfalse
    showLine是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。Booleantrue
    text自定义各类默认文本,目前支持以下设定:

    text: {

         defaultNodeName: '未命名' //节点默认名称

         ,none: '无数据' //数据为空时的提示文本

    }

    Object-

    因为tree指定了json数据的键名称,所以后台传递过来的数据对应的键名不一样时需要做一下处理,或者实体类中的属性名就和tree的JSON数据的键名称一样。

    键名:

    属性选项说明类型示例值
    title节点标题String未命名
    id节点唯一索引,用于对指定节点进行各类操作String/Number任意唯一的字符或数字
    children子节点。支持设定选项同父节点Array[{title: '子节点1', id: '111'}]
    href点击节点弹出新窗口对应的 url。需开启 isJump 参数String任意 URL
    spread节点是否初始展开,默认 falseBooleantrue
    checked节点是否初始为选中状态(如果开启复选框的话),默认 falseBooleantrue
    disabled节点是否为禁用状态。默认 falseBooleanfalse

    后台请求数据的方法。

    @RequestMapping(value = "/treeload")
    @ResponseBody
    public Object treeload(){
        Sort sort = Sort.by("idx");
        List<Dept> dpet = deptService.findByParentIsNull(sort);    //查找所有菜单
        List<HashMap<String, Object>> result = new ArrayList<>();    //定义一个map处理json键名问题
        return fun(dpet, result);
    }
    
    private Object fun(List<Dept> dpet, List<HashMap<String, Object>> result) {
        for(Dept d : dpet){
            HashMap<String, Object> map = new HashMap<>();
            map.put("id", d.getId());
            map.put("title", d.getName());
            map.put("spread", true);      //设置是否展开
            List<HashMap<String, Object>> result1 = new ArrayList<>();
            List<Dept> children = d.getChildren();    //下级菜单
            //这里可以根据自己需求判断节点默认选中
            /*if(m.getParent() != null || m.getChildren().size() == 0){
                map.put("checked", true);    //设置为选中状态
            }*/
            map.put("children", fun(children, result1));
            result.add(map);
        }
        return result;
    }

    因为这里新建的实体类字段名和tree指定了json数据的键名称不一样,所以这里用了一个fun递归方法处理的。中间可以根据项目需求,根据条件判断是否需要选中该节点。

    返回的JSON数据格式

    [
    	{
    		"children": [		//子节点
    			{
    				"children": [
    					{
    						"children": [],
    						"id": 30,
    						"title": "测试",
    						"spread": true
    					}, {
    						"children": [],
    						"id": 31,
    						"title": "开发",
    						"spread": true
    					}, {
    						"children": [
    							{
    								"children": [],
    								"id": 36,
    								"title": "测试节点",
    								"spread": true
    							}
    						],
    						"id": 32,
    						"title": "测试",
    						"spread": true
    					}
    				],
    				"id": 2,
    				"title": "技术部",
    				"spread": true
    			}, {
    				"children": [],
    				"id": 19,
    				"title": "财务部",
    				"spread": true
    			}
    		],
    		"id": 1,	//节点id
    		"title": "某某公司",	//节点名称
    		"spread": true
    	}, {
    		"children": [],
    		"id": 33,
    		"title": "测试",
    		"spread": true
    	}
    ]

    设置节点点击回调方法(在加载数据方法tree.render中添加以下代码)。

    click: function (obj) {
        var id = obj.data.id;
        $("#dept_home").load("dept/show?id="+id);
    }

    把请求过来的详情页面load到右边的div中显示。后台请求方法

    @RequestMapping(value = "/show")
    public void show(DeptForm form, ModelMap map) throws InstantiationException, IllegalAccessException {
        Dept model = new Dept();
        Integer id = form.getId();
        Integer parentId = 0;
        if(id!=null) {
            model = deptService.findById(id);
            parentId = model.getParent()==null?0:model.getParent().getId();
        }
        map.put("parentId", parentId);
        map.put("model", model);
    }

    DeptForm类为一个接收类,其中字段和实体类中一样。根据请求传递过来的id,查询这条数据的详细信息,之后把查询的当前部门详情数据及父级节点id(用于下拉树TreeSelect)传递给详情页面。

    show.html详情页面代码。

    <meta charset="UTF-8" />
    <style type="text/css">
        .myData .layui-form-item{
            margin: 20px 100px 10px 45px;
        }
        .myData .layui-form-label{
            width: 85px;
        }
        .layui-input-block {
            margin-left: 120px;
        }
    </style>
    <form class="layui-form myData" action="save" method="post" lay-filter="stuform">
        <input type="hidden" name="id" data-th-value="${model.id}" />
    
        <div class="layui-form-item">
            <label class="layui-form-label">上级部门:</label>
            <div class="layui-input-block">
                <input type="text" name="parentId" id="tree" lay-filter="tree" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">部门名称:</label>
            <div class="layui-input-block">
                <input type="text" name="name" lay-verify="required" th:value="${model.name}" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">部门负责人:</label>
            <div class="layui-input-block">
                <input type="text" name="deptName" th:value="${model.deptName}" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">电话:</label>
            <div class="layui-input-block">
                <input type="text" name="phone" th:value="${model.phone}" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">编号:</label>
            <div class="layui-input-block">
                <input type="text" name="number" th:value="${model.number}" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">排序:</label>
            <div class="layui-input-block">
                <input type="text" name="idx" value="0" th:value="${model.idx}" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label"></label>
            <div class="layui-input-block">
                <button lay-submit class="layui-btn layui-btn-radius layui-btn-normal" lay-filter="btnSub">
                    <i class="layui-icon">&#xe642;</i>修改并保存
                </button>
            </div>
        </div>
    </form>
    
    <script th:inline="javascript">
        layui.use(["treeSelect", "form", "tree"], function () {
            var form = layui.form;
            var tree = layui.tree;
            form.render('select');
            var treeSelect = layui.treeSelect;
            treeSelect.render({
                // 选择器
                elem: '#tree',
                // 数据
                data: 'dept/treeSelect?id='+[[${model.id==null ? 0 : model.id}]],
                // 异步加载方式:get/post,默认get
                type: 'post',
                // 占位符
                placeholder: '上级菜单',
                // 是否开启搜索功能:true/false,默认false
                search: true,
                // 一些可定制的样式
                style: {
                    folder: {
                        enable: true
                    },
                    line: {
                        enable: true
                    }
                },
                // 加载完成后的回调函数
                success: function (d) {
                    // 选中节点,根据id筛选
                    treeSelect.checkNode('tree', [[${model.parent == null? parentId: model.parent.id}]]);
                    treeSelect.refresh('tree');
                }
            });
    
            form.on('submit(btnSub)', function (data) {
                $.post('dept/save', data.field, function (result) {
                    if (result.success) {
                        tree.reload('treeId', {data: getData()});
                    }
                    layer.msg(result.msg, {offset: 'rb'});
                });
                return false;
            });
        });
    </script>
    

    上级部门使用的是LayUI下拉树显示的,下拉树数据请求方法。关于下拉树的使用,可以访问LayUI下拉树TreeSelect的使用

    @RequestMapping(value="/treeSelect")
    @ResponseBody
    public Object treeSelect(Integer id) {
        Sort sort = Sort.by("idx");
        Specification<Dept> spec = buildSpec1();
        List<Dept> list = deptService.findAll(spec,sort);
        return buildTree(list, id);
    }
    
    private Object buildTree(List<Dept> list, Integer id) {
        List<HashMap<String, Object>> result=new ArrayList<>();
        for (Dept dept : list) {
            if(dept.getId() != id) {
                HashMap<String, Object> node=new HashMap<>();
                node.put("id", dept.getId());
                node.put("name",dept.getName());
                node.put("open", false);
                node.put("checked", false);
                if(dept.getChildren().size() != 0) {
                    node.put("children",buildTree(dept.getChildren(), id));
                }
                result.add(node);
            }
        }
    
        return result;
    }
    
    public Specification<Dept> buildSpec1() {
        Specification<Dept> specification = new Specification<Dept>() {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                HashSet<Predicate> rules=new HashSet<>();
                Predicate parent = cb.isNull(root.get("parent"));
                rules.add(parent);
                return cb.and(rules.toArray(new Predicate[rules.size()]));
            }
    
        };
        return specification;
    }

    显示的效果。

    上面修改并保存后台方法(因为修改和新增共用的一个方法,用id区分的)。

    @Override
    public Object save(DeptForm form) {
        try {
            Dept model = new Dept();
            Integer id = form.getId();
            if(id != null) {
                model = deptService.findById(id);
            }
            //父级菜单id
            Integer parentId = form.getParentId();
            if(parentId == null) {
                model.setParent(null);
            }else {
                model.setParent(new Dept(parentId));
            }
            BeanUtils.copyProperties(form, model,"id", "parent");
            deptService.save(model);
            return new AjaxResult("数据保存成功!");
        } catch (Exception e) {
            return new AjaxResult(false,"数据保存失败");
        }
    }

    设置节点操作(在加载数据方法tree.render中添加以下代码)。

    edit: ['add', 'update', 'del'], //操作节点的图标
    operate: function(obj){
        var type = obj.type; //得到操作类型:add、edit、del
        var data = obj.data; //得到当前节点的数据
        var elem = obj.elem; //得到当前节点元素
    
        var id = data.id;
        var name = data.title;
        if(type === 'add'){ //增加节点
            $.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
                tree.reload('treeId', {data: getData()});
            })
            //返回 key 值
            return ;
        } else if(type === 'update'){ //修改节点
            $.post("dept/update", {id: id, name: name}, function () {
                tree.reload('treeId', {data: getData()});
            })
        } else if(type === 'del'){ //删除节点
            $.post("dept/delete", {id: id}, function () {
                tree.reload('treeId', {data: getData()});
            });
        };
    }

    其中operate为操作节点回调方法。

    obj.type为操作类型,add为新增,update为修改,edl为删除。obj.data为操作节点后的数据。

    新增节点后,向后台发送请求添加节点,save方法和上面修改方法一样,id为新建节点的父级节点id。

    修改节点,同样,向后台发送修改请求,并传递对象的id,和修改后的数据作为参数。后台响应方法。

    @RequestMapping(value = "/update")
    @ResponseBody
    public Object update(DeptForm form) {
        try {
            Dept model = deptService.findById(form.getId());
            model.setName(form.getName());
            deptService.save(model);
            return new AjaxResult("数据保存成功!");
        } catch (Exception e) {
            return new AjaxResult(false,"数据保存失败");
        }
    }

    删除节点同理,传递删除节点的id。删除请求方法。

    @RequestMapping(value="/delete")
    @ResponseBody
    public Object delete(Integer id) {
    	try {
    		deptService.deleteById(id);
    		return new AjaxResult("数据删除成功");
    	} catch (Exception e) {
    		return new AjaxResult(false,"数据删除失败");
    	}
    }

    使用按钮操作树形菜单。

    现在页面中定义两个按钮,给按钮添加lay-demo=""属性,并设置属性值,JS通过这个属性值,绑定点击事件。

    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>添加部门</button>
    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>

    绑定添加部门和获取选中节点按钮的点击事件的JS代码。

    util.event('lay-demo', {
        addDept: function(othis){
            $.get('dept/edit', function(data) {
                layer.open({
                    type: 1,
                    title: '新增',
                    area: ['530px'],
                    content: data,
                    btn: ['提交', '退出'],
                    yes: function () {
                    },
                    success: function (layero, index) {
                        layui.use('form', function () {
                            var form = layui.form;
                            layero.addClass('layui-form');
                            var submitBtn = layero.find('.layui-layer-btn0');
                            submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
                            layero.keydown(function (e) {
                                if (e.keyCode == 13) {
                                    submitBtn.click();
                                }
                            });
    
                            form.on('submit(formVerify)', function (data) {
                                $.post('dept/save', data.field, function (result) {
                                    if (result.success) {
                                        layer.close(index);
                                        tree.reload('treeId', {data: getData()});
                                    }
                                    layer.msg(result.msg, {offset: 'rb'});
                                });
                                return false;
                            });
                        });
                    }
                })
            })
        },
        gain: function () {
            var checkData = tree.getChecked('treeId');
            var str = JSON.stringify(checkData);
            $.post('dept/checkedGain', {data: str}, function () {
            });
            layer.alert(JSON.stringify(checkData), {shade:0});
        }
    });

    添加部门按钮点击事件,先发送请求到后台,跳转到eidt新增页面,edit.html新增页面代码,和上面的show.html显示部门详情页面差不多。上级部门同样使用的LayUI下拉树显示的,下拉树数据请求方法,和上面的详情页面下拉树请求方法一致。LayUI下拉树TreeSelect的使用。新增后的保存方法也和上面的保存方法一致。

    后台请求方法代码,跳转到edit页面。

    @RequestMapping(value = "/edit")
    public void edit(){
        
    }

    edit.html页面完整代码如下。

    <meta charset="UTF-8" />
    <style type="text/css">
        .myData .layui-form-item{
            margin: 20px 100px 10px 45px;
        }
        .myData .layui-form-label{
            width: 85px;
        }
        .layui-input-block {
            margin-left: 120px;
        }
    </style>
    <form class="layui-form myData" action="save" method="post" lay-filter="stuform">
    
        <div class="layui-form-item">
            <label class="layui-form-label">上级部门:</label>
            <div class="layui-input-block">
                <input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">部门名称:</label>
            <div class="layui-input-block">
                <input type="text" name="name" lay-verify="required" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">部门负责人:</label>
            <div class="layui-input-block">
                <input type="text" name="deptName" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">电话:</label>
            <div class="layui-input-block">
                <input type="text" name="phone" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">编号:</label>
            <div class="layui-input-block">
                <input type="text" name="number" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item" >
            <label class="layui-form-label">排序:</label>
            <div class="layui-input-block">
                <input type="text" name="idx" value="0" class="layui-input" />
            </div>
        </div>
    </form>
    
    <script th:inline="javascript">
        layui.use(["treeSelect", "form"], function () {
            var form = layui.form;
            form.render('select');
            var treeSelect = layui.treeSelect;
            treeSelect.render({
                // 选择器
                elem: '#tree2',
                // 数据
                data: 'dept/treeSelect',
                // 异步加载方式:get/post,默认get
                type: 'post',
                // 占位符
                placeholder: '上级菜单',
                // 是否开启搜索功能:true/false,默认false
                search: true,
                // 一些可定制的样式
                style: {
                    folder: {
                        enable: true
                    },
                    line: {
                        enable: true
                    }
                },
                // 加载完成后的回调函数
                success: function (d) {
                }
            });
        });
    </script>
    

    页面效果。

    获取选中节点按钮点击事件。如果项目需要保存数据时,就需要获取到选中节点的数据了。这里可以获取到选中节点的数据,之后当参数传递到后台。传递到后台是一个JSON数据的字符串,需要转换一下,这里给推荐大家两个很好用的JSON转换工具net.sf.json.JSONObjectAlibaba Fastjson。这里用的是Alibaba Fastjson,需要引入以下依赖。

    <dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>fastjson</artifactId>
    	<version>1.2.47</version>
    </dependency>

    这里用于输出,新建了一个和tree的json数据的键名称一样的工具类DeptTree,代码如下。

    import java.util.ArrayList;
    import java.util.List;
    
    public class DeptTree {
        private Integer id;
        private String title;
        private boolean checked;
        private boolean spread;
        private List<DeptTree> children = new ArrayList<>();
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public List<DeptTree> getChildren() {
            return children;
        }
    
        public void setChildren(List<DeptTree> children) {
            this.children = children;
        }
    
        public boolean isChecked() {
            return checked;
        }
    
        public void setChecked(boolean checked) {
            this.checked = checked;
        }
    
        public boolean isSpread() {
            return spread;
        }
    
        public void setSpread(boolean spread) {
            this.spread = spread;
        }
    }

    后台接收到传递过来的JSON数据字符串,转换后输出方法。

    @RequestMapping(value = "/checkedGain")
    @ResponseBody
    public void checkedGain(String data){
        List<DeptTree> array2 = JSONArray.parseArray(data, DeptTree.class);
        treeData(array2);
    }
    
    //递归输出选中数据
    private void treeData(List<DeptTree> array2) {
        for (DeptTree tree: array2){
            System.out.println(tree.getTitle()+"==="+tree.getId());
            if(tree.getChildren() != null){
                treeData(tree.getChildren());
            }
        }
    }

    选中节点,点击获取选中节点数据。

    后台对应方法接收到数据,转换后输出结果。

    数据拿到了,之后保存方法就简单了。

    后台方法代码基本都在上面了,页面全部代码。

    <style type="text/css">
        #dept_main, #dept_particulars{
            width: 48.5%;
            display: inline-block;
            vertical-align: top;
            padding: 20px;
            background: white;
            box-sizing: border-box;
        }
        #dept_tree{
            margin-top: 20px;
        }
    </style>
    
    <div id="dept_main" style="margin-right: 2%;">
        <fieldset class="layui-elem-field layui-field-title">
            <legend>所有部门</legend>
        </fieldset>
        <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>添加部门</button>
        <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>
        <div id="dept_tree">
    
        </div>
    </div>
    <div id="dept_particulars">
        <fieldset class="layui-elem-field layui-field-title">
            <legend>部门详情</legend>
        </fieldset>
        <div id="dept_home">
            <div class="layui-tree-emptyText">无数据</div>
        </div>
    </div>
    
    <script type="text/javascript">
        layui.use(['tree', 'util', 'layer'], function() {
            var tree = layui.tree;
            var util = layui.util;
            var layer = layui.layer;
            tree.render({
                elem: '#dept_tree',
                data: getData(),
                id: 'treeId',
                showCheckbox: true,     //时候显示复选框
                onlyIconControl: true,
                edit: ['add', 'update', 'del'], //操作节点的图标
                click: function (obj) {
                    var id = obj.data.id;
                    $("#dept_home").load("dept/show?id="+id);
                },
                operate: function(obj){
                    var type = obj.type; //得到操作类型:add、edit、del
                    var data = obj.data; //得到当前节点的数据
                    var elem = obj.elem; //得到当前节点元素
    
                    var id = data.id;
                    var name = data.title;
                    if(type === 'add'){ //增加节点
                        $.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
                            tree.reload('treeId', {data: getData()});
                        })
                        //返回 key 值
                        return ;
                    } else if(type === 'update'){ //修改节点
                        $.post("dept/update", {id: id, name: name}, function () {
                            tree.reload('treeId', {data: getData()});
                        })
                    } else if(type === 'del'){ //删除节点
                        $.post("dept/delete", {id: id}, function () {
                            tree.reload('treeId', {data: getData()});
                        });
                    };
                }
            });
    
            util.event('lay-demo', {
                addDept: function(othis){
                    $.get('dept/edit', function(data) {
                        layer.open({
                            type: 1,
                            title: '新增',
                            area: ['530px'],
                            content: data,
                            btn: ['提交', '退出'],
                            yes: function () {
                            },
                            success: function (layero, index) {
                                layui.use('form', function () {
                                    var form = layui.form;
                                    layero.addClass('layui-form');
                                    var submitBtn = layero.find('.layui-layer-btn0');
                                    submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
                                    layero.keydown(function (e) {
                                        if (e.keyCode == 13) {
                                            submitBtn.click();
                                        }
                                    });
    
                                    form.on('submit(formVerify)', function (data) {
                                        $.post('dept/save', data.field, function (result) {
                                            if (result.success) {
                                                layer.close(index);
                                                tree.reload('treeId', {data: getData()});
                                            }
                                            layer.msg(result.msg, {offset: 'rb'});
                                        });
                                        return false;
                                    });
                                });
                            }
                        })
                    })
                },
                gain: function () {
                    var checkData = tree.getChecked('treeId');
                    var str = JSON.stringify(checkData);
                    $.post('dept/checkedGain', {data: str}, function () {
                    });
                    layer.alert(JSON.stringify(checkData), {shade:0});
                }
            });
        });
    
        function getData(){
            var data = [];
            $.ajax({
                url: "dept/treeload",    //后台数据请求地址
                type: "post",
                async:false,
                success: function(resut){
                    data = resut;
                }
            });
            return data;
        }
        
    </script>

    如果对你有帮助,点赞关注一下呗^_^,留下你的足迹。

    展开全文
  • jsTree实例,jsTree实例

    热门讨论 2010-09-06 15:11:45
    jsTree实例,jsTree实例,jsTree实例
  • win tree命令 tree导出目录 tree显示树形结构 windows下,如何使用tree命令导出目录,如何使用tree命令显示文件目录的树形结构?tree命令如何使用呢?下面就为大家分享一下,如何使用tree命令显示一级文件、如何...
     
    

    win tree命令 tree导出目录 tree显示树形结构


    工具/原料

    • windows操作系统
    • tree命令、tree命令使用知识
    • tree命令需要使用的文件目录


    方法/步骤

    1. 1

      登录windows操作系统

      打开电脑,登录windows操作系统。

      win tree命令 tree导出目录 tree显示树形结构

    2. 2

      找到命令行程序

      在电脑操作系统的开始菜单中,搜索cmd或者直接使用WIN+R快捷键组合,直接打开命令行运行程序。

      win tree命令 tree导出目录 tree显示树形结构

    3. 3

      打开命令行程序

      点击确定或者使用回车键,即可打开cmd、命令行运行程序。

      win tree命令 tree导出目录 tree显示树形结构

    4. 4

      进入文件目录

      找到需要生成树形结构的文件目录,如果不是在C盘,需要先进入对应大盘符(如进入D盘,使用D:+回车键,d可以不分大小写),再使用cd +目录路径的方式,进入对应的目录。

      win tree命令 tree导出目录 tree显示树形结构

    5. 5

      查看文件目录

      使用dir命令,可以查看当前目录的文件列表,此时如果想查看某一个目录下的文件或文件名,是无法看到的。

      win tree命令 tree导出目录 tree显示树形结构

    6. 6

      使用tree命令生成树形结构

      分别使用以下命令:tree、tree /f 命令,就可以看到屏幕的效果了,还可以使用tree /a等命令,来生成想要的文件目录。

      win tree命令 tree导出目录 tree显示树形结构

      win tree命令 tree导出目录 tree显示树形结构

    7. 7

      导出生成的文件目录

      使用tree /f > tree.txt命令,就可以把生成的文件目录树形结构写入到tree.txt文件中了,tree.txt这个文件名称是可以修改的。打开对应的文件目录,就可以看到多了一个tree.txt的文件,其中tree文件里面的内容,和屏幕输出的内容是一致的,以后就可以使用tree命令来生成文件目录的树形结构了。

      win tree命令 tree导出目录 tree显示树形结构

      win tree命令 tree导出目录 tree显示树形结构

      win tree命令 tree导出目录 tree显示树形结构

    8. 8

      举手之劳,希望以上分享能帮助到大家。如果您觉得本经验有帮助,请点击本文正下方或本文右上角的“投票”或“分享”或“关注”给我支持和鼓励,为了方便下次查看,您可以点击“收藏”,还可以分享给好友。

    展开全文
  • TreeDataGridView

    热门讨论 2011-09-20 16:19:41
    TreeDataGridView 在DataGridView上加上Tree结构,有子结点,点开就可以下拉下一个样式! 含使用调用窗体! 只提供一个设计方法,完全自主开发!!
  • DeviceTree

    热门讨论 2009-12-15 13:16:57
    DeviceTree主要是显示分层驱动的加载层次关系 包含各个平台的DeviceTree工具,支持最新win7
  • tree命令安装包

    2014-08-23 12:40:40
    tree命令安装包,最小化安装系统,安装此软件包即可使用tree命令查看文件树。
  • JSTree

    万次阅读 2016-05-09 17:45:12
    JSTree是一个JQuery插件,当前最新版本v3.3.1(2016-05-05MIT),使用JSTree可以很方便的通过简单的配置快速实现复杂的树形结构,支持模糊查询、动态加载。
  • easyUI 附加tree节点到tree

    千次阅读 2012-08-13 10:50:59
    这个教程向你展示如何附加节点到tree,我们将创建一个食品tree包含水果和蔬菜节点,然后添加一些其他水果到已存在的水果节点. 创建 foods(食品) tree 首先,我们创建食品树,代码就像这样. 注意:tree...
  • Symmetric Tree

    千次阅读 2018-06-05 23:33:33
    Symmetric Tree Description Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). Example 1: For example, this binary tree [1,2,2,3,4,4,3] is symmetric: ...
  • B-tree, AVL tree, RB tree

    千次阅读 2014-07-04 13:04:01
    http://stackoverflow.com/questions/1589556/when-to-choose-rb-tree-b-tree-or-avl-tree/1589587#1589587 http://stackoverflow.com/questions/647537/b-tree-faster-than-avl-or-redblack-tree/1195288#1
  • Merkle Tree学习

    万次阅读 2019-05-17 21:07:20
    Merkle Tree概念    Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树。Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值。非叶节点是其对应子节点串联字符串的hash。[1]  1....
  • Merkle Tree(HashTree)

    千次阅读 2015-06-26 17:12:24
    Merkle Tree是基于数据HASH构建的一个树,Merkle Tree的叶子节点的value是数据集合的单元数据或者单元数据hash,Merke Tree非叶子节点value是其所有子节点value的HASH值。 Merkle tree可以用来进行大数据的比对,...
  • easyUI Tree

    千次阅读 2012-08-03 17:23:10
    覆盖默认值 $.fn.tree.defaults. tree显示一个树结构分层数据在web页面中,它提供用户, expand(展开), collapse(折叠), drag(拖动) ,editing (编辑)和异步加载功能. 相关依赖 draggabledroppable ...
  • 问题:程序"tree"尚未安装。sudo apt install tree 显示无法安装软件包tree。 解决步骤: 先输入sudo apt-get update 运行结束后再输入:sudo apt-get install tree 大功告成!
  • jsTree例子

    千次下载 热门讨论 2012-04-09 16:23:57
    使用jsTree的插件小例子,这个例子描述了html_data,json_data,xml_data插件
  • LayUi tree 树形组件tree.reload实例重载解决方案,我这里研究了2种方案,希望对你有帮助。
  • Antd Tree组件Tree props#属性 checkStrictly

    千次阅读 2019-08-02 18:47:46
    Antd 3.20.7 版本 Tree组件Tree props#属性 checkStrictly值为true,则点击选中树
  • jsTree中文文档

    热门讨论 2015-03-14 19:50:43
    jsTree中文文档
  • Chromium网页Layer Tree同步为Pending Layer Tree的过程分析

    万次阅读 热门讨论 2016-05-09 01:02:36
    CC Layer Tree绘制完成后,会同步到一个新的CC Pending Layer Tree去。同步过程由Compositor线程执行,并且Main线程处于等待状态。所谓同步,就是将CC Layer Tree的内容拷贝到CC Pending Layer Tree去。同步完毕,...
  • B-tree与二叉树的关系 B-tree与二叉树都是树形算法,他们之间的区别在于二叉树的每个节点只能存储一个值,二B-tree可以存储M个值(其中M为用户设定的节点所包含键值对的数量)  二叉树(每个节点只有一个键值对)...
  • Windows下cmd中Tree命令的使用

    万次阅读 2021-07-09 12:29:02
    经常会见到项目组织的树形结构: ├── images │ └── scottsdale │ ├── IMG_1786-2.jpg │ ├── IMG_1787-2.jpg │ └── IMG_1788-2.jpg ...使用的是tree命令 打开cmd,跳转到某一磁盘,
  • 网页分块的光栅化操作完成后,CC Pending Layer Tree就会激活为CC Active Layer Tree。CC Active Layer Tree代表用户当前在屏幕上看到的网页内容,它可以快速响应用户输入,例如滚动和缩放。本文接下来就分析CC ...
  • iview下拉菜单树的iview-select-tree的使用以及iview-select-tree的实现的源代码公众号前言单选效果多选效果validate验证效果iview-select-tree的集成的npm的地址集成iview-select-tree 公众号 大家可以直接微信...
  • AngularJS的tree控件

    2016-02-26 14:25:53
    Angularjs,自己整理个tree的控件,非常好用
  • 一、安装tree-node-cli,全局安装(基于node,安装前安装node.js) #安装tree-node-cli模块包 npm install -g tree-node-cli 二、使用命令 $ tree --help Usage: tree [options] Options: -V, --version ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,035,721
精华内容 414,288
关键字:

tree