介绍

树状图由两个部分组成节点node和连接线link组成,link是一个路径,而node是一个组由text和circle组成,D3能够帮助我们计算路径,计算节点的位置.

示例

https://tinuv.top/MyPages/tree/tree.html

初始化

    var width = 1000;
    var height = 1000;
    var padding = {left: 100, right: 100, top: 100, bottom: 100};


    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + padding.right + "," + padding.top + ")");

初始化定义宽度高度,padding值,要注意上面的变量虽然叫做svg,但实际上它只是svg里面填充的一个组,让它们可以组合里面的link和node.

定义树布局

var tree = d3.layout.tree()
        .size([width - padding.right - padding.left, height - padding.top - padding.bottom]);

这个是定义tree的布局,d3主要利用这个类来合理的计算node的位置和link的路径,所以需要配置这个tree,除此之外还有几项配置

    tree.sort = null;
    tree.children = function(d) { return d.children; } 
    tree.separation = function(a, b) { return a.parent == b.parent ? 1 : 2; }

上面的几项都是默认配置

请求数据并计算node和link

d3内置了好几个请求数据的方法,我使用的是json数据,所以使用d3.json()函数,里面有一个回调函数,参数error抛出异常,data是将json数组转化为js对象,主要使用两个函数来处理这些数据.

var nodes = tree.nodes(data);
var links = tree.links(nodes);

nodes和links都会生成一个数组

nodes数组里面元素的内容如下:

links数组元素的内容如下:

iZeFTf.png

填充图形

计算完之后就要填充图形了 填充link,link本质上是一个path路径,它通过d属性来定义一个路径,而d属性的内容就是通过对角线函数diagonal()生成的路径

        var link = svg.selectAll(".link")
            .data(links)
            .enter()
            .append("path")
            .attr("class", "link")
            .attr("d", diagonal);

填充node

node是一个组,因为既有图形又有文字

        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;
            });
🌹💗正文结束💗🌹