众所周知,这个插件使用的svg技术,而IE8(包括IE8)之前的浏览器是不支持svg的

接下来看代码吧

从后台获取到带id和父id的目录数据[json格式]

var module = requestUrl('/Home/ModuleList', null);
module = eval("(" + module + ")");

 再将json拼成需要的svg格式

//svg图数据
    var treeData = null;
 //如果左侧菜单目录不为空
    if (module.total != 0) {
        var json = "[";
        //循环第一层
        for (var i = 0; i < module.total; i++) {
            //根节点
            var root = module.rows[i].PARENTID;
            //如果为第一层
            if (module.rows[i].LEVEL == '1') {
                json += "{";
                json += "'name': '" + module.rows[i].MODULE + "(" + module.rows[i].MODULEID +")',";
                json += "'parent':'信息管理系统(0)','value': 10,'children': [";
                //当前的模块ID
                var moduleId = module.rows[i].MODULEID;
                var parentId = null;
                for (var j = 0; j < module.total; j++) {

                    //如果为第二层
                    if (module.rows[j].LEVEL == '2') {
                        //获取第二层父ID
                        parentId = module.rows[j].PARENTID;
                        var moduleId_children = module.rows[j].MODULEID;
                        //如果第二层父ID等于第一层模块ID
                        if (moduleId == parentId) {
                            json += "{";
                            json += "'name':'" + module.rows[j].MODULE + "(" + module.rows[j].MODULEID+")',";
                            json += "'parent': '" + module.rows[i].MODULE + "','value': 10,'children': [";

                            for (var k = 0; k < module.total; k++) {
                                if (module.rows[k].LEVEL == '3') {
                                    parentId = null;
                                    parentId = module.rows[k].PARENTID;
                                    if (moduleId_children == parentId) {
                                        json += "{";
                                        json += "'name': '" + module.rows[k].MODULE + "(" + module.rows[k].MODULEID +")','value': 5";
                                        json += "},";
                                    }
                                }
                            }
                            json += "]},";
                        }
                    }
                }
                json += "]},";
            }
        }

        json += "]";
        //svg数据[json]
        treeData = [{
            "name": "信息管理系统(0)",
            "parent": "root",
            "value": 10,
            "children": eval("(" + json + ")")
        }];

  接下来是绘制svg图的代码:

// ************** Generate the tree diagram  *****************
    //定义树图的全局属性(宽高)
    var margin = { top: 10, right: 120, bottom: 20, left: 400 },
        width = 1200 - margin.right - margin.left,
        height = 600 - margin.top - margin.bottom;

    var i = 0,
        duration = 750,//过渡延迟时间
        root;

    var tree = d3.layout.tree()//创建一个树布局
        .size([height, width]);

    var diagonal = d3.svg.diagonal()
        .projection(function (d) { return [d.y, d.x]; });//创建新的斜线生成器

    //声明与定义画布属性
    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0];//treeData为上边定义的节点属性
    root.x0 = height / 2;
    root.y0 = 0;

    update(root);

    d3.select(self.frameElement).style("height", "750px");

    function update(source) {

        // Compute the new tree layout.计算新树图的布局
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        // Normalize for fixed-depth.设置y坐标点,每层占180px
        nodes.forEach(function (d) { d.y = d.depth * 180; });

        // Update the nodes…每个node对应一个group
        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });//data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

        // Enter any new nodes at the parent's previous position.新增节点数据集,设置位置
        var nodeEnter = node.enter().append("g")  //在 svg 中添加一个g,g是 svg 中的一个属性,是 group 的意思,它表示一组什么东西,如一组 lines , rects ,circles 其实坐标轴就是由这些东西构成的。
            .attr("class", "node") //attr设置html属性,style设置css属性
            .attr("transform", function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
            .on("click", click);

        //添加连接点---此处设置的是圆圈过渡时候的效果(颜色)
        // nodeEnter.append("circle")
        //   .attr("r", 1e-6);//d 代表数据,也就是与某元素绑定的数据。

        nodeEnter.append("path")
            .style("stroke-width", "2px")
            .style("stroke", "#EB5409")
            .style("fill", "white")
            .attr("d", d3.svg.symbol()
                .size(function (d) {
                    if
                    (d.value <= 9) { return "400"; } else if
                    (d.value >= 9) { return "400"; }
                })
                .type(function (d) {
                    if
                    (d.value <= 9) { return "triangle-up"; } else if
                    (d.value >= 9) { return "circle"; }
                }))
            .attr('class', function (d) {
                if (d.value <= 9) {
                    return 'bling';
                } else {
                    return 'fill_normal';
                }
            });

        //添加标签
        nodeEnter.append("text")
            .attr("x", function (d) { return d.children || d._children ? -13 : 13; })
            .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.将节点过渡到一个新的位置-----主要是针对节点过渡过程中的过渡效果
        //node就是保留的数据集,为原来数据的图形添加过渡动画。首先是整个组的位置
        var nodeUpdate = node.transition()  //开始一个动画过渡
            .duration(duration)  //过渡延迟时间,此处主要设置的是圆圈节点随斜线的过渡延迟
            .attr("r", 10)
            .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; });
        //更新连接点的填充色
        // nodeUpdate.select("circle")
        // .attr("r", 10)
        // .attr('class',function(d){
        //   if(d.value <= 9){
        //     return 'bling';
        //   }else{
        //     return 'fill_normal';
        //   }
        // });
        nodeUpdate.select("path")
            .style("stroke-width", "2px")
            .style("stroke", "#EB5409")
            .style("fill", "white")
            .attr("d", d3.svg.symbol()
                .size(function (d) {
                    if
                    (d.value <= 9) { return "400"; } else if
                    (d.value >= 9) { return "400"; }
                })
                .type(function (d) {
                    if
                    (d.value <= 9) { return "triangle-up"; } else if
                    (d.value >= 9) { return "circle"; }
                }))
            .attr('class', function (d) {
                if (d.value <= 9) {
                    return 'bling';
                } else {
                    return 'fill_normal';
                }
            });

        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 = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        // Enter any new links at the parent's previous position.
        //添加新的连线
        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 });  //diagonal - 生成一个二维贝塞尔连接器, 用于节点连接图.
            })
            .style("stroke", function (d) {
                //d包含当前的属性console.log(d)
                return '#ccc';
            });

        // 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 on click.切换子节点事件
    function click(d) {
        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
        update(d);
    }

    // 定义菜单选项
    var userMenuData = [
        [
            {
                text: "添加",
                func: function () {
                    // id为节点id
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    showDialog(id);
                }
            },
            {
                text: "修改",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    showEditDialog(id);
                }
            },
            {
                text: "禁用",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));

                }
            },
            {
                text: "删除",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    deleteAppModule(id);
                }
            }
        ]
    ];
    // 事件监听方式添加事件绑定
    $("g").smartMenu(userMenuData, {
        name: "chatRightControl",
        container: "g.node"
    });

  效果如下图:

使用d3.v3插件绘制出svg图的更多相关文章

  1. D3.js (v3)+react框架 基础部分之认识选择集和如何绘制一个矢量图

    首先需要下载安装d3.js  :  yarn add d3 然后在组建中引入 :  import * as d3 from 'd3' 然后定义一个方法,在componentDidMount()这个钩子 ...

  2. 【D3.V3.js系列教程】--(十五)SVG基本图形绘制

    [D3.V3.js系列教程]--(十五)SVG基本图形绘制 1.path <!DOCTYPE html> <html> <head> <meta charse ...

  3. D3.js系列——布局:打包图和地图

    一.打包图 打包图( Pack ),用于表示包含与被包含的关系,也可表示各对象的权重,通常用一圆套一圆来表示前者,用圆的大小来表示后者. 1.布局(数据转换) var pack = d3.layout ...

  4. java+数据库+D3.js 实时查询人物关系图

    先看下 效果 某个用户,邀请了自己的朋友 ,自己的朋友邀请了其他朋友,1 展示邀请关系,2 点击头像显示邀请人和被邀请人的关系.(网上这种资料很少, 另外很多都是从JSON文件取 数据, 这里是从数据 ...

  5. D3.JS V4 绘制中国地图

    参考:http://bl.ocks.org/almccon/fe445f1d6b177fd0946800a48aa59c71 http://blog.csdn.net/lzhlzz/article/d ...

  6. 使用ABAP绘制可伸缩矢量图

    Jerry去年的文章 动手使用ABAP Channel开发一些小工具,提升日常工作效率 里曾经介绍过一些用ABAP实现的可供娱乐的小程序,比如用古老的HPGL接口在SAPGUI里绘图: 关于如何用SA ...

  7. 使用 HTML5 Canvas 绘制出惊艳的水滴效果

    HTML5 在不久前正式成为推荐标准,标志着全新的 Web 时代已经来临.在众多 HTML5 特性中,Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在 HTML 上进行图形操作 ...

  8. Origin9.1如何绘制风向玫瑰图(Binned Data)?

    Origin9.1如何绘制风向玫瑰图(Binned Data)? 时间:2014/5/14 21:02:44 点击: 2624 核心提示:今天为大家介绍下如何使用Origin9.1绘制如下图所示的风向 ...

  9. Origin9.1如何使用原始数据(Raw Data)绘制风向玫瑰图

    核心提示:今天为大家简单介绍下如何使用原始数据绘制风向玫瑰图.本例以Origin 9.1进行演示.1.本例所用数据截图如下,列A为风向,列B为风速.2.选中两列数据,进入Plot下的Specializ ...

随机推荐

  1. Sublime text 3 快捷键的使用

    快捷键的便捷使用: ctr+shift+n:打开新的sublime text ctr+shift+w:关闭sublime text ctr+o:打开 某个文件 ctrl+n:新建一个文本 ctrl+w ...

  2. 我的c++学习(6)默认参数和内联函数

    默认参数 一般情况下,函数调用时实参个数应与形参相同,但为了更方便地使用函数,C++也允许定义具有默认参数的函数,这种函数调用时实参个数可以与形参不相同.“默认参数”指在定义或声明函数时为形参指定默认 ...

  3. 洛谷P1263 || 巴蜀2311 宫廷守卫

    题目描述 从前有一个王国,这个王国的城堡是一个矩形,被分为M×N个方格.一些方格是墙,而另一些是空地.这个王国的国王在城堡里设了一些陷阱,每个陷阱占据一块空地. 一天,国王决定在城堡里布置守卫,他希望 ...

  4. 前台js分页,自己手写逻辑

    js代码如下: //设置分页 var pageSize = 10; //设置一次显示多少页 var pageLimit = 5; $(function(){ //查询所有内容 $.post(ctx + ...

  5. redis 常用操作命令

    操作相关的命令连接 quit:关闭连接(connection)auth:简单密码认证 持久化 save:将数据同步保存到磁盘bgsave:将数据异步保存到磁盘lastsave:返回上次成功将数据保存到 ...

  6. XSLT 调用外部程序

    通常可以通过xslt把一个xml转成html cd.xml <?xml version="1.0" encoding="UTF-8"?> <? ...

  7. JavaSwing JScrollPane的使用

    JavaSwing JScrollPane的使用: 参考:http://duyz.blog.ifeng.com/article/340649.html package com.srie.test; i ...

  8. Spring Boot Document Part II(上)

    Part II. Getting started 这一章内容适合刚接触Spring Boot或者"Spring"家族的初学者!随着安装指导说明,你会发现对Spring boot有一 ...

  9. [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现

    根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...

  10. CSS深入理解学习笔记之z-index

    1.z-index基础 z-index含义:指定了元素及其子元素的"z顺序",而"z顺序"可以决定元素的覆盖顺序.z-index值越大越在上面. z-index ...