D3 绘制 树图(tree) 笔记

绘制一个树形图分为四部

  1. 选中页面设置的svg绘制区域的宽高 添加g元素 设置位置
  2. 生成树状布局,设置尺寸
  3. 对角线生成器
  4. 请求数据
    • 获取节点数组和连线数组

    • 绘制连线

    • 绘制节点

    • 给节点添加圆圈设置半径

    • 给节点添加文本 设置文本样式 位置

 

本地连接json会出现跨域问题 需要用http-server启动本地服务器

  1. 打开cmd,安装:npm install http-server -g  
  2. cd到项目目录 或者 进入项目所在文件夹 shift+右键 “在此处打开命令窗口”  打开cmd 
  3. 输入  hs -o  相当于http-server - open  默认端口为8080 

具体原因自己恶补js基础

下面直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./js/d3.min.js" charset="utf-8"></script>
    <style>
        /* 圆圈 */
        .node circle{
            fill: #fff;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
        /* 文字 */
        .node  text{
            font-size: 15px;
            color: black;
        }
        /* path */
        .link{
            fill: none;
            stroke: black;
            stroke-width: 1.5px;
        }
    </style>
</head>
<body>
    <script>
        var width = 700;
        var height = 700;
        //1选中页面设置的svg绘制区域的宽高 添加g元素 设置位置
        var svg = d3.select('body')
                .append('svg')
                .attr('width',width)
                .attr('height',height)
                .append('g')
                .attr('transform','translate(50,0)')
        //2 生成树状布局,设置尺寸
        var tree = d3.layout.tree()
                    .size([width,height-200])
        
        //3对角线生成器
        var diagonal = d3.svg.diagonal()
                    .projection(d=>[d.y,d.x])
        //4 请求数据
        d3.json("./json/flare.json", function(error, root) {
            //1 获取节点数组和连线数组
            var  nodes = tree.nodes(root)//获取所有节点信息
            var  links = tree.links(nodes)//获取节点的连线信息集合

            //2 生成连线
            var link = svg.selectAll('.link')
                    .data(links)
                    .enter()
                    .append('path')
                    .attr('class','link')
                    .attr('d',diagonal)

            // 3 生成节点
            var node = svg.selectAll('.node')
                    .data(nodes)
                    .enter()
                    .append('g')
                    .attr('class','node')
                    .attr('transform',function(d){
                        return "translate(" + d.y + "," + d.x + ")";
                    });

            // 4 给节点添加圆圈设置半径 
                node.append('circle')
                    .attr('r',4.5);
                    

            // 5 给节点添加文本 设置文本样式 位置
                node.append("text")
                    .attr("dx", function(d) { return d.children ? -15 : 15; })//定义文本显示x轴偏移量
                    .attr("dy", 10)//定义文本显示y轴偏移量
                    .style("text-anchor", function(d) { return d.children ? "end" : "start"; })//文字对齐显示
                    .attr('class','text')
                    .text(function(d) { return d.name; });
            });
    </script>
</body>
</html>

JSON数据:


{
    "name":"中国",
    "children":
    [
        { 
          "name":"浙江" , 
            "children":
            [
                    {"name":"杭州" },
                    {"name":"宁波" },
                    {"name":"温州" },
                    {"name":"绍兴" }
            ] 
          },
          
        { 
            "name":"广西" , 
            "children":
            [
                {
                "name":"桂林",
                "children":
                [
                    {"name":"秀峰区"},
                    {"name":"叠彩区"},
                    {"name":"象山区"},
                    {"name":"七星区"}
                ]
                },
                {"name":"南宁"},
                {"name":"柳州"},
                {"name":"防城港"}
            ] 
        },
        
        { 
            "name":"黑龙江",
            "children":
            [
                {"name":"哈尔滨"},
                {"name":"齐齐哈尔"},
                {"name":"牡丹江"},
                {"name":"大庆"}
            ] 
        },
        
        { 
            "name":"新疆" , 
            "children":
            [
                {"name":"乌鲁木齐"},
                {"name":"克拉玛依"},
                {"name":"吐鲁番"},
                {"name":"哈密"}
            ]
        }
    ]
    }

在D3知识的海洋里一步一步的摸索,有没有大佬发下相关的好一点的教程,网上现在好多都是v3版的。感激不尽啊。

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要用到d3.js库中的布局功能,具体来说是树状布局(tree layout)。具体的代码实现可以参考以下示例: ``` var margin = {top: 20, right: 120, bottom: 20, left: 120}, width = 960 - margin.right - margin.left, height = 800 - margin.top - margin.bottom; 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 + ")"); var root = { "name": "A", "children": [ { "name": "B", "children": [ { "name": "C" }, { "name": "D" } ] }, { "name": "E", "children": [ { "name": "F" }, { "name": "G" } ] } ] }; var nodes = tree.nodes(root), links = tree.links(nodes); var link = svg.selectAll(".link") .data(links) .enter().append("path") .attr("class", "link") .attr("d", diagonal); var node = svg.selectAll(".node") .data(nodes) .enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) node.append("circle") .attr("r", 4.5); node.append("text") .attr("dx", function(d) { return d.children ? -8 : 8; }) .attr("dy", 3) .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) .text(function(d) { return d.name; }); ``` 这个示例其实就是一个非常简单的树状结构,但是可以看到节点和节点之间是通过直线相连接的。具体来说,需要用到d3.layout.tree()这个函数进行树状布局,再用到d3.svg.diagonal()这个函数来定义连接线的路径,最后通过d3.selectAll()以及.data()等函数将节点和线条加入进去即可。需要注意的是,在节点连接线这一部分的代码当中,attr函数中的参数d以及diagonal函数中的参数d都表示一个节点在树状结构中的位置,需要根据实际情况加以理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值