D3 JS-是否可以在树节点之间绘制直线? [英] D3 js - is it possible to draw straight lines between tree nodes?

查看:82
本文介绍了D3 JS-是否可以在树节点之间绘制直线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个水平树形图,如下图所示.我想要节点之间的直线.节点之间的曲线在d3 js中是默认设置.我在Google上看到了一些答案,但是没有找到满意的结果.那么有可能在d3 js中的节点之间绘制直线吗?如果是,那我该怎么办?

I have created a horizontal tree diagram as shown in below image. I want straight lines between nodes. The curved lines between nodes are default in d3 js. I saw some answers on google for this but did not found any satisfactory result. So is it possible to draw straight lines between nodes in d3 js? If yes then how can I do that?

在此处输入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    <script src="https://d3js.org/d3.v3.min.js"></script>
   

    <style>
        .node circle {
            fill: #ff9900;
            stroke: #ff9900;
            stroke-width: 1px;
        }
        
        .node text {
            font: 16px sans-serif;
        }
        
        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 2px;
        }
    </style>
</head>

<body>

    <script language="javascript">
        var treeData = [{
            "name": "1",
            "parent": "null",
            "children": [{
                "name": "2",
                "parent": "Persons",
                "children": [{
                    "name": "3",
                    "parent": "Country of residence"
                }, {
                    "name": "4",
                    "parent": "Country of residence"
                }, {
                    "name": "5",
                    "parent": "Country of residence"
                }, {
                    "name": "6",
                    "parent": "Country of residence"
                }]
            }]
        }];

        // ************** Generate the tree diagram  *****************
        var margin = {
                top: 20,
                right: 120,
                bottom: 20,
                left: 120
            },
            width = 960 - margin.right - margin.left,
            height = 500 - margin.top - margin.bottom;

        var i = 0;

        var tree = d3.layout.tree().size([height, width]);

        var diagonal = d3.svg.diagonal()
            .projection(function(d) {
                return [d.y, d.x];
            });

        var line = d3.svg.line()
            .x(function(d) {
                return d.lx;
            })
            .y(function(d) {
                return d.ly;
            });

        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];

        update(root);

        function update(source) {

            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function(d) {
                d.y = d.depth * 180;
            });

            // Declare the nodes…
            var node = svg.selectAll("g.node")
                .data(nodes, function(d) {
                    return d.id || (d.id = ++i);
                });

            // Enter the nodes.
            var nodeEnter = node.enter().append("g")
                .attr("class", "node")
                .attr("transform", function(d) {
                    return "translate(" + d.y + "," + d.x + ")";
                });

            nodeEnter.append("circle")
                .attr("r", 40)
                .style("fill", "#ff9900");



            // append icon inside circle
            nodeEnter.append("image")
                .attr("xlink:href", "http://localhost/d3/user2.jpg")
                .attr("x", "-18px")
                .attr("y", "-18px")
                .attr("width", "35px")
                .attr("height", "35px");


            nodeEnter.append("text")
                .attr("x", function(d) {
                    return d.children || d._children ? -40 : -50;
                })
                .attr("y", function(d) {
                    return d.children || d._children ? 55 : 55;
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function(d) {
                    return d.children || d._children ? "start" : "start";
                })
                .text(function(d) {
                    return d.name;
                })
                .style("fill-opacity", 1);

            // Declare the links…
            var link = svg.selectAll("path.link")
                .data(links, function(d) {
                    return d.target.id;
                });

            // Enter the links.
            link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("d", diagonal);


        }
    </script>
</body>
</body>

</html>

推荐答案

定义行:

        var line = d3.svg.line()
            .x(function(d) {
                return d.y; // because tree is horizontal
            })
            .y(function(d) {
                return d.x; // because tree is horizontal
            });

将链接功能更改为此,因为d3.svg.line()将点数组作为参数

Change your links function to this because d3.svg.line() takes array of points as argument

希望这会有所帮助

        // Enter the links.
        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", function(d) {
                return line([d.source, d.target]);
            });

<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    <script src="https://d3js.org/d3.v3.min.js"></script>
   

    <style>
        .node circle {
            fill: #ff9900;
            stroke: #ff9900;
            stroke-width: 1px;
        }
        
        .node text {
            font: 16px sans-serif;
        }
        
        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 2px;
        }
    </style>
</head>

<body>

    <script language="javascript">
        var treeData = [{
            "name": "1",
            "parent": "null",
            "children": [{
                "name": "2",
                "parent": "Persons",
                "children": [{
                    "name": "3",
                    "parent": "Country of residence"
                }, {
                    "name": "4",
                    "parent": "Country of residence"
                }, {
                    "name": "5",
                    "parent": "Country of residence"
                }, {
                    "name": "6",
                    "parent": "Country of residence"
                }]
            }]
        }];

        // ************** Generate the tree diagram  *****************
        var margin = {
                top: 20,
                right: 120,
                bottom: 20,
                left: 120
            },
            width = 960 - margin.right - margin.left,
            height = 500 - margin.top - margin.bottom;

        var i = 0;

        var tree = d3.layout.tree().size([height, width]);

        var diagonal = d3.svg.diagonal()
            .projection(function(d) {
                return [d.y, d.x];
            });

        var line = d3.svg.line()
            .x(function(d) {
                return d.y;
            })
            .y(function(d) {
                return 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];

        update(root);

        function update(source) {

            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function(d) {
                d.y = d.depth * 180;
            });

            // Declare the nodes…
            var node = svg.selectAll("g.node")
                .data(nodes, function(d) {
                    return d.id || (d.id = ++i);
                });

            // Enter the nodes.
            var nodeEnter = node.enter().append("g")
                .attr("class", "node")
                .attr("transform", function(d) {
                    return "translate(" + d.y + "," + d.x + ")";
                });

            nodeEnter.append("circle")
                .attr("r", 40)
                .style("fill", "#ff9900");



            // append icon inside circle
            nodeEnter.append("image")
                .attr("xlink:href", "http://localhost/d3/user2.jpg")
                .attr("x", "-18px")
                .attr("y", "-18px")
                .attr("width", "35px")
                .attr("height", "35px");


            nodeEnter.append("text")
                .attr("x", function(d) {
                    return d.children || d._children ? -40 : -50;
                })
                .attr("y", function(d) {
                    return d.children || d._children ? 55 : 55;
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function(d) {
                    return d.children || d._children ? "start" : "start";
                })
                .text(function(d) {
                    return d.name;
                })
                .style("fill-opacity", 1);

            // Declare the links…
            var link = svg.selectAll("path.link")
                .data(links, function(d) {
                    return d.target.id;
                });

            // Enter the links.
            link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("d", function(d) { return line([d.source, d.target])});


        }
    </script>
</body>
</body>

</html>

这篇关于D3 JS-是否可以在树节点之间绘制直线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆