d3树左右上下反转

本文基于Adoins前辈D3 纵向组织结构树文章实现个性化改变。

  1. 左侧树
image.png
<!DOCTYPE html>
<html>
  <head>
    <title>左侧树</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="960" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:10, right:0};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
            
        //创建一个树状图
        var tree = d3.tree()
            .size([width-400,height-200])
            .separation(function(a,b){
                return (a.parent==b.parent?1:2)/a.depth;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器
        var Bézier_curve_generator = d3.linkHorizontal()
            .x(function(d) { return d.y; })
            .y(function(d) { return d.x; });
            
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                var start = {x:d.source.x,y:d.source.y};
                var end = {x:d.target.x,y:d.target.y};
                return Bézier_curve_generator({source:start,target:end});
            })
            .attr("fill","none")
            .attr("stroke","yellow")
            .attr("stroke-width",1);
            
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = d.x;
                var cy= d.y;
                return "translate("+cy+","+cx+")";
            });
        //绘制节点
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
            
        //文字
        gs.append("text")
            .attr("x",function(d){
                return d.children?-40:8;
            })
            .attr("y",-5)
            .attr("dy",10)
            .text(function(d){
                return d.data.name;
            });
            
    </script>
  </body>
</html>
  1. 纵向树


    image.png
<!DOCTYPE html>
<html>
  <head>
    <title>垂直树</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="960" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:30, right:0};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
            
        //创建一个树状图
        var tree = d3.tree()
            .size([width-400,height-200])
            .separation(function(a,b){
                return (a.parent==b.parent?1:2)/a.depth;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器 // 水平:d3.linkHorizontal() 垂直:d3.linkVertical()
        var Bézier_curve_generator = d3.linkVertical()
            .x(function(d) { return d.x; }) // 水平:d.y 垂直:d.x
            .y(function(d) { return d.y; });// 水平:d.x 垂直:d.y
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                var start = {x:d.source.x,y:d.source.y};
                var end = {x:d.target.x,y:d.target.y};
                return Bézier_curve_generator({source:start,target:end});
            })
            .attr("fill","none")
            .attr("stroke","yellow")
            .attr("stroke-width",1);
            
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = d.y; // 水平:d.x 垂直:d.y
                var cy= d.x;  // 水平:d.y 垂直:d.x
                return "translate(" + cy + "," + cx + ")";
            });
        //绘制节点
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
            
        //文字
        gs.append("text")
            .attr("x", function(d){
                return d.children ? -15 : 0;
            })
            .attr("y", function(d) {
                return d.children ? -10 : 15;
            })
            .attr("dy",0)
            .text(function(d){
                return d.data.name;
            })
            .style('writing-mode', function(d) {
                return d.children ? 'horizontal-tb' : 'tb-rl';
            });
            
    </script>
  </body>
</html>
  1. 纵向树2


    image.png
<!DOCTYPE html>
<html>
  <head>
    <title>垂直直线树</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="1280" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:10, right:40};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
        console.log(hierarchyData); 
        //创建一个树状图
        var tree = d3.tree()
            .size([width-80,height-200])
            .separation(function(a,b){
                return a.parent == b.parent ? 1 : 2;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器 // 水平:d3.linkHorizontal() 垂直:d3.linkVertical()
        var Bézier_curve_generator = d3.linkVertical()
            .x(function(d) { return d.x; }) // 水平:d.y 垂直:d.x
            .y(function(d) { return d.y; });// 水平:d.x 垂直:d.y
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        var boxWidth = 66, boxHeight = 40;
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                let sourceX = d.source.x,
                    sourceY = d.source.y + boxHeight,
                    targetX = d.target.x,
                    targetY = d.target.y;

                return "M" + sourceX + "," + sourceY +
                    "V" + ((targetY - sourceY) / 2 + sourceY) +
                    "H" + targetX +
                    "V" + targetY;
                /*
                var start = {x:d.source.x,y:d.source.y};
                var end = {x:d.target.x,y:d.target.y};
                return Bézier_curve_generator({source:start,target:end});
                */
            })
            .attr("fill","none")
            .attr("stroke","red")
            .attr("stroke-width",1);
              
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = d.y; // 水平:d.x 垂直:d.y
                var cy= d.x;  // 水平:d.y 垂直:d.x
                return "translate(" + cy + "," + cx + ")";
            });
        //绘制节点
        /*
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
        */
        gs.append("rect")
            .attr('y', 0)
            .attr('x', function (d) {
               boxWidth = d.data.name.length * 22;
               return d.depth < 2 ? -(boxWidth / 2) : -(boxHeight / 2)
            })
            .attr('width', function (d) {
               boxWidth = d.data.name.length * 22;
               return d.depth < 2 ? boxWidth : boxHeight;
            })
            .attr('height', function (d) {
               boxWidth = d.data.name.length * 22;
               return d.depth < 2 ? boxHeight : boxWidth;
            })
            // 矩形背景色以及边框颜色宽度
            .attr('fill', '#fff')
            .attr('stroke', 'steelblue')
            .attr('strokeWidth', '1px')
            .on('click', function (evt) {
               console.log(evt); // 显示所点击节点数据
            });
            
        //文字
        gs.append("text")
            .attr('y', function (d) {
                return d.depth < 2 ? boxHeight / 2 + 5 : 5;
            })
            .attr('style', function (d) {
                return d.depth < 2 ? '' : "writing-mode: tb;letter-spacing:0px";
            })
            .attr("text-anchor", function (d) {
                return d.depth < 2 ? 'middle' : "start";
            })
            .text(function(d){
                return d.data.name;
            });
            
    </script>
  </body>
</html>
  1. 左右反转


    image.png
<!DOCTYPE html>
<html>
  <head>
    <title>右侧树</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="960" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:10, right:0};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
            
        //创建一个树状图
        var treeWidth = width-400; // *****记录一下树的总宽度,做为左侧树反转为右侧树时使用
        var tree = d3.tree()
            .size([treeWidth,height-200])
            .separation(function(a,b){
                return (a.parent==b.parent?1:2)/a.depth;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器
        var Bézier_curve_generator = d3.linkHorizontal()
            .x(function(d) { return d.y; })
            .y(function(d) { return d.x; });
            
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                var start = {x:d.source.x,y:treeWidth - d.source.y};// *****使用treeWidth减去当前y,实现反转
                var end = {x:d.target.x,y:treeWidth - d.target.y};  // *****使用treeWidth减去当前y,实现反转
                return Bézier_curve_generator({source:start,target:end});
            })
            .attr("fill","none")
            .attr("stroke","yellow")
            .attr("stroke-width",1);
            
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = d.x;
                var cy= treeWidth - d.y;  // *****使用treeWidth减去当前y,实现反转
                return "translate("+cy+","+cx+")";
            });
        //绘制节点
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
            
        //文字
        gs.append("text")
            .attr("x",function(d){
                var left = -20 * d.data.name.length;
                return d.children ? 10 : left;
            })
            .attr("y",-5)
            .attr("dy",10)
            .text(function(d){
                return d.data.name;
            });
            
    </script>
  </body>
</html>
  1. 纵向反转


    image.png
<!DOCTYPE html>
<html>
  <head>
    <title>垂直树(上)</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="960" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:120, right:0};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
            
        //创建一个树状图
        var treeHeight = height-200; //*******记录一下树的高度,上反转使用
        var tree = d3.tree()
            .size([width-400,treeHeight])
            .separation(function(a,b){
                return (a.parent==b.parent?1:2)/a.depth;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器 // 水平:d3.linkHorizontal() 垂直:d3.linkVertical()
        var Bézier_curve_generator = d3.linkVertical()
            .x(function(d) { return d.x; }) // 水平:d.y 垂直:d.x
            .y(function(d) { return d.y; });// 水平:d.x 垂直:d.y
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                var start = {x:d.source.x,y:treeHeight - d.source.y};
                var end = {x:d.target.x,y:treeHeight - d.target.y};
                return Bézier_curve_generator({source:start,target:end});
            })
            .attr("fill","none")
            .attr("stroke","yellow")
            .attr("stroke-width",1);
            
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = treeHeight - d.y; // 水平:d.x 垂直:d.y
                var cy= d.x;  // 水平:d.y 垂直:d.x
                return "translate(" + cy + "," + cx + ")";
            });
        //绘制节点
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
            
        //文字
        gs.append("text")
            .attr("x", function(d){
                return d.children ? -15 : 0;
            })
            .attr("y", function(d) {
                return d.children ? 20 : -20 * d.data.name.length - 5;
            })
            .attr("dy",0)
            .text(function(d){
                return d.data.name;
            })
            .style('writing-mode', function(d) {
                return d.children ? 'horizontal-tb' : 'tb-rl';
            });
            
    </script>
  </body>
</html>
  1. 纵向2
image.png
<!DOCTYPE html>
<html>
  <head>
    <title>垂直直线树(上)</title>
    
    <script type="text/javascript" src="http://d3js.org/d3.v5.min.js">
    </script>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="1280" height="600"></svg>
    <script>
        //定义边界
        var marge = {top:50, bottom:0, left:120, right:40};
    
        var svg = d3.select("svg");
        var width = svg.attr("width");
        var height = svg.attr("height");
        
        var g = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        
        var scale = svg.append("g")
            .attr("transform","translate("+marge.top+","+marge.left+")");
        //数据
        var dataset = {
            name:"中国",
            children:[
                {
                    name:"浙江",
                    children:[
                        {name:"杭州" ,value:100},
                        {name:"宁波",value:100},
                        {name:"温州",value:100},
                        {name:"绍兴",value:100}
                    ]
                },
                {
                    name:"广西",
                    children:[
                        {
                            name:"桂林",
                            children:[
                                {name:"秀峰区",value:100},
                                {name:"叠彩区",value:100},
                                {name:"象山区",value:100},
                                {name:"七星区",value:100}
                            ]
                        },
                        {name:"南宁",value:100},
                        {name:"柳州",value:100},
                        {name:"防城港",value:100}
                    ]
                },
                {
                    name:"黑龙江",
                    children:[
                        {name:"哈尔滨",value:100},
                        {name:"齐齐哈尔",value:100},
                        {name:"牡丹江",value:100},
                        {name:"大庆",value:100}
                    ]
                },
                {
                    name:"新疆" , 
                    children:
                    [
                        {name:"乌鲁木齐"},
                        {name:"克拉玛依"},
                        {name:"吐鲁番"},
                        {name:"哈密"}
                    ]
                }
            ]
        };
        
        //创建一个hierarchy layout
        var hierarchyData = d3.hierarchy(dataset)
            .sum(function(d){
                return d.value;
            });
        console.log(hierarchyData); 
        //创建一个树状图
        var treeHeight = height-200; //*******记录一下树的高度,上反转使用
        var tree = d3.tree()
            .size([width-80,treeHeight])
            .separation(function(a,b){
                return a.parent == b.parent ? 1 : 2;
            })
        
        //初始化树状图,也就是传入数据,并得到绘制树基本数据
        var treeData = tree(hierarchyData);
        console.log(treeData);
        //得到节点
        var nodes = treeData.descendants();
        var links = treeData.links();
        
        //输出节点和边
        console.log(nodes);
        console.log(links);
        
        //创建一个贝塞尔生成曲线生成器 // 水平:d3.linkHorizontal() 垂直:d3.linkVertical()
        var Bézier_curve_generator = d3.linkVertical()
            .x(function(d) { return d.x; }) // 水平:d.y 垂直:d.x
            .y(function(d) { return d.y; });// 水平:d.x 垂直:d.y
        //有了节点和边集的数据后,我们就可以开始绘制了,
        //绘制边
        var boxWidth = 66, boxHeight = 40;
        g.append("g")
            .selectAll("path")
            .data(links)
            .enter()
            .append("path")
            .attr("d",function(d){
                let sourceX = d.source.x,
                    sourceY = treeHeight - d.source.y + boxHeight,
                    targetX = d.target.x,
                    targetY = treeHeight - d.target.y;

                return "M" + sourceX + "," + sourceY +
                    "V" + ((targetY - sourceY) / 2 + sourceY) +
                    "H" + targetX +
                    "V" + targetY;
                /*
                var start = {x:d.source.x,y:d.source.y};
                var end = {x:d.target.x,y:d.target.y};
                return Bézier_curve_generator({source:start,target:end});
                */
            })
            .attr("fill","none")
            .attr("stroke","red")
            .attr("stroke-width",1);
              
        //绘制节点和文字
        //老规矩,先创建用以绘制每个节点和对应文字的分组<g>
        var gs = g.append("g")
            .selectAll("g")
            .data(nodes)
            .enter()
            .append("g")
            .attr("transform",function(d){
                var cx = treeHeight - d.y; // 水平:d.x 垂直:d.y
                var cy= d.x;  // 水平:d.y 垂直:d.x
                return "translate(" + cy + "," + cx + ")";
            });
        //绘制节点
        /*
        gs.append("circle")
            .attr("r",6)
            .attr("fill","white")
            .attr("stroke","blue")
            .attr("stroke-width",1);
        */
        gs.append("rect")
            .attr('y', 0)
            .attr('x', function (d) {
               return d.depth < 2 ? -(boxWidth / 2) : -(boxHeight / 2)
            })
            .attr('width', function (d) {
               return d.depth < 2 ? boxWidth : boxHeight;
            })
            .attr('height', function (d) {
               return d.depth < 2 ? boxHeight : boxWidth;
            })
            // 矩形背景色以及边框颜色宽度
            .attr('fill', '#fff')
            .attr('stroke', 'steelblue')
            .attr('strokeWidth', '1px')
            .on('click', function (evt) {
               console.log(evt); // 显示所点击节点数据
            });
            
        //文字
        gs.append("text")
            .attr('y', function (d) {
                return d.depth < 2 ? boxHeight / 2 + 5 : 5;
            })
            .attr('style', function (d) {
                return d.depth < 2 ? '' : "writing-mode: tb;letter-spacing:0px";
            })
            .attr("text-anchor", function (d) {
                return d.depth < 2 ? 'middle' : "start";
            })
            .text(function(d){
                return d.data.name;
            });
            
    </script>
  </body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,639评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,093评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,079评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,329评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,343评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,047评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,645评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,565评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,201评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,338评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,014评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,701评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,194评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,685评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,345评论 2 358

推荐阅读更多精彩内容

  • 本文基于专注于D3的吕之华前辈分享的树状图画法来写纵向组织结构树图 第十五章中树状图的样式为: 我们可以进行拓展,...
    Adoins阅读 12,026评论 2 9
  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,623评论 1 180
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,567评论 0 11
  • 彩排完,天已黑
    刘凯书法阅读 4,220评论 1 3
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 125,252评论 2 7