增加我的D3树布局的节点之间的差距

 逍遥微博2011_213 发布于 2023-02-07 20:44

如图所示,我试图增加树布局两侧的最后节点之间的间隙,因为它们是重叠的

在D3中有什么办法吗?

在此输入图像描述

带有节点的treelayout

            {
            "name": "",
            "type": "network",
            "children": [{
                "name": "",
                "type": "lb",
                "children": [{
                        "name": "",
                        "type": "mm",
                        "id": "app",
                        "connServer": "s",
                        "size": 3938
                    }]
            },
            {
                "name": "",
                "type": "vm",
                "children": [{
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "appServer",
                        "id": "app1",
                        "connServer": "db1",
                        "size": 3938
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "webServer",
                        "id": "web1",
                        "connServer": "app1",
                        "size": 3534
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "dataServer",
                        "id": "db1",
                        "connServer": "app1",
                        "size": 7074
                    }]
                }]
            },
            {
                "name": "",
                "type": "vm",
                "children": [{
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "webServer",
                        "id": "web2",
                        "connServer": "app1",
                        "size": 721
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "dataServer",
                        "id": "db2",
                        "connServer": "db1",
                        "size": 721
                    }]
                }]
            },
            {
                "name": "",
                "type": "vm",
                "children": [{
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "appServer",
                        "id": "app2",
                        "connServer": "db3",
                        "size": 721
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "webServer",
                        "id": "web3",
                        "connServer": "app2",
                        "size": 721
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "dataServer",
                        "id": "db3",
                        "connServer": "app2",
                        "size": 721
                    }]
                }]
            },
            {
                "name": "",
                "type": "vm",
                "children": [{
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "appServer",
                        "id": "app3",
                        "connServer": "db4",
                        "size": 721
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "webServer",
                        "id": "web4",
                        "connServer": "app3",
                        "size": 721
                    }]
                },
                {
                    "name": "",
                    "type": "container",
                    "children": [{
                        "name": "",
                        "type": "dataServer",
                        "id": "db4",
                        "connServer": "app3",
                        "size": 721
                    }]
                }]
            },{
                "name": "",
                "type": "sto",
                "children": [{
                        "name": "",
                        "type": "mm",
                        "id": "app",
                        "connServer": "s",
                        "size": 3938
                    }]
            }]
        }

这是代码,我用于构建树的布局,当我使用separate()时,树的布局的子节点没有在空间中对齐,它们坚持到自己的位置,没有单独的方法,collpased子节点将被包裹在一起/在空格中对齐/****/var tooltipMap = d3.map();

    // Get JSON data
    treeJSON = d3.json("network.json", function(error, treeData) {
        // Calculate total nodes, max label length
        var totalNodes = 0;
        var maxLabelLength = 15;
        // variables for drag/drop
        var selectedNode = null;
        var draggingNode = null;
        // panning variables
        var panSpeed = 200;
        var panBoundary = 20; // Within 20px from edges will pan when
        // dragging.
        // Misc. variables
        var i = 0;
        var duration = 750;
        var root;

        // size of the diagram
        var docWidth = $(document).width();
        var viewerWidth = docWidth / (1.361);
        var docHeight = $(document).height();
        var halfHeight = docHeight / 2;
        var quarterHeight = docHeight / 4;
        viewerHeight = halfHeight + quarterHeight;
        var tree = d3.layout.tree().size([ viewerHeight, viewerWidth ]);
        /*
         * var tree = d3.layout.tree().separation(function(a, b) { return ((a.parent ==
         * root) && (b.parent == root)) ? 3 : 1; }).size([ viewerHeight, viewerWidth -
         * 160 ]);
         */
        // define a d3 diagonal projection for use by the node paths
        // later on.
        var diagonal = d3.svg.diagonal().projection(function(d) {
            return [ d.x, -d.y ];
        });

        // A recursive helper function for performing some setup by
        // walking through all nodes

        function visit(parent, visitFn, childrenFn) {
            if (!parent)
                return;

            visitFn(parent);

            var children = childrenFn(parent);
            if (children) {
                var count = children.length;
                for ( var i = 0; i < count; i++) {
                    visit(children[i], visitFn, childrenFn);
                }
            }
        }

        // Call visit function to establish maxLabelLength
        visit(treeData, function(d) {
            totalNodes++;
            maxLabelLength = Math.max(d.name.length, maxLabelLength);

        }, function(d) {
            return d.children && d.children.length > 0 ? d.children : d.children;
        });

        function getConServers(element, event, status) {
            var conServerNode;
            var targetElement = event.target;
            var targetId = targetElement.id;
            if (targetId != null) {
                var server = tooltipMap.get(targetElement.id);
                if (server != null) {
                    var connectedServer = server.get("connId");
                    var outerTarget = d3.select("#" + "outer" + targetId);
                    var outerCon = d3.select("#" + "outer" + connectedServer);
                    if (status == "enter") {

                        outerTarget.style("stroke", "#48C127");
                        outerTarget.style("stroke-width", 3);
                        outerCon.style("stroke", "#F07A0B");
                        outerCon.style("stroke-width", 3);

                    } else if (status == "exit") {

                        outerTarget.style("stroke", "#fff");
                        outerCon.style("stroke", "#fff");
                        outerTarget.style("stroke-width", 1);
                        outerCon.style("stroke-width", 1);

                    }
                }
            }

        }

        // sort the tree according to the node names

        function sortTree() {
            tree.sort(function(a, b) {
                return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
            });
        }
        // Sort the tree initially incase the JSON isn't in a sorted
        // order.
        sortTree();

        // TODO: Pan function, can be better implemented.

        function pan(domNode, direction) {
            var speed = panSpeed;
            if (panTimer) {
                clearTimeout(panTimer);
                translateCoords = d3.transform(svgGroup.attr("transform"));
                if (direction == 'left' || direction == 'right') {
                    translateX = direction == 'left' ? translateCoords.translate[0] + speed : translateCoords.translate[0]
                            - speed;
                    translateY = translateCoords.translate[1];
                } else if (direction == 'up' || direction == 'down') {
                    translateX = translateCoords.translate[0];
                    translateY = direction == 'up' ? translateCoords.translate[1] + speed : translateCoords.translate[1]
                            - speed;
                }
                scaleX = translateCoords.scale[0];
                scaleY = translateCoords.scale[1];
                scale = zoomListener.scale();
                svgGroup.transition().attr("transform",
                        "translate(" + translateX + "," + translateY + ")scale(" + scale + ")");
                d3.select(domNode).select('g.node').attr("transform", "translate(" + translateX + "," + translateY + ")");
                zoomListener.scale(zoomListener.scale());
                zoomListener.translate([ translateX, translateY ]);
                panTimer = setTimeout(function() {
                    pan(domNode, speed, direction);
                }, 50);
            }
        }

        // Define the zoom function for the zoomable tree

        function zoom() {
            svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }

        // define the zoomListener which calls the zoom function on the
        // "zoom" event constrained within the scaleExtents
        var zoomListener = d3.behavior.zoom().scaleExtent([ 0.1, 3 ]).on("zoom", zoom);

        function initiateDrag(d, domNode) {
            draggingNode = d;
            d3.select(domNode).select('.ghostCircle').attr('pointer-events', 'none');
            d3.selectAll('.ghostCircle').attr('class', 'ghostCircle show');
            d3.select(domNode).attr('class', 'node activeDrag');

            svgGroup.selectAll("g.node").sort(function(a, b) { // select
                // the
                // parent
                // and
                // sort
                // the
                // path's
                if (a.id != draggingNode.id)
                    return 1; // a is not the hovered element,
                // send "a" to the back
                else
                    return -1; // a is the hovered element,
                // bring "a" to the front
            });
            // if nodes has children, remove the links and nodes
            if (nodes.length > 1) {
                // remove link paths
                links = tree.links(nodes);
                nodePaths = svgGroup.selectAll("path.link").data(links, function(d) {
                    return d.target.id;
                }).remove();
                // remove child nodes
                nodesExit = svgGroup.selectAll("g.node").data(nodes, function(d) {
                    return d.id;
                }).filter(function(d, i) {
                    if (d.id == draggingNode.id) {
                        return false;
                    }
                    return true;
                }).remove();
            }

            // remove parent link
            parentLink = tree.links(tree.nodes(draggingNode.parent));
            svgGroup.selectAll('path.link').filter(function(d, i) {
                if (d.target.id == draggingNode.id) {
                    return true;
                }
                return false;
            }).remove();

            dragStarted = null;
        }

        // define the baseSvg, attaching a class for styling and the
        // zoomListener
        var baseSvg = d3.select("#tree-container").append("svg").attr("width", viewerWidth).attr("height", viewerHeight)
                .attr("class", "overlay").attr("id", "treesvg").call(zoomListener);

        // Define the drag listeners for drag/drop behaviour of nodes.
        dragListener = d3.behavior.drag().on("dragstart", function(d) {
            if (d == root) {
                return;
            }
            dragStarted = true;
            nodes = tree.nodes(d);
            d3.event.sourceEvent.stopPropagation();
            // it's important that we suppress the mouseover
            // event on the node being dragged. Otherwise it
            // will absorb the mouseover event and the
            // underlying node will not detect it
            // d3.select(this).attr('pointer-events',
            // 'none');
        }).on("drag", function(d) {
            if (d == root) {
                return;
            }
            if (dragStarted) {
                domNode = this;
                initiateDrag(d, domNode);
            }

            // get coords of mouseEvent relative to svg
            // container to allow for panning
            relCoords = d3.mouse($('svg').get(0));
            if (relCoords[0] < panBoundary) {
                panTimer = true;
                pan(this, 'left');
            } else if (relCoords[0] > ($('svg').width() - panBoundary)) {

                panTimer = true;
                pan(this, 'right');
            } else if (relCoords[1] < panBoundary) {
                panTimer = true;
                pan(this, 'up');
            } else if (relCoords[1] > ($('svg').height() - panBoundary)) {
                panTimer = true;
                pan(this, 'down');
            } else {
                try {
                    clearTimeout(panTimer);
                } catch (e) {

                }
            }

            d.x0 += d3.event.dy;
            d.y0 += d3.event.dx;
            var node = d3.select(this);
            node.attr("transform", "translate(" + d.y0 + "," + d.x0 + ")");
            updateTempConnector();
        }).on("dragend", function(d) {
            if (d == root) {
                return;
            }
            domNode = this;
            if (selectedNode) {
                // now remove the element from the
                // parent, and insert it into the new
                // elements children
                var index = draggingNode.parent.children.indexOf(draggingNode);
                if (index > -1) {
                    draggingNode.parent.children.splice(index, 1);
                }
                if (typeof selectedNode.children !== 'undefined' || typeof selectedNode._children !== 'undefined') {
                    if (typeof selectedNode.children !== 'undefined') {
                        selectedNode.children.push(draggingNode);
                    } else {
                        selectedNode._children.push(draggingNode);
                    }
                } else {
                    selectedNode.children = [];
                    selectedNode.children.push(draggingNode);
                }
                // Make sure that the node being added
                // to is expanded so user can see added
                // node is correctly moved
                expand(selectedNode);
                sortTree();
                endDrag();
            } else {
                endDrag();
            }
        });

        function endDrag() {
            selectedNode = null;
            d3.selectAll('.ghostCircle').attr('class', 'ghostCircle');
            d3.select(domNode).attr('class', 'node');
            // now restore the mouseover event or we won't be able to
            // drag a 2nd time
            d3.select(domNode).select('.ghostCircle').attr('pointer-events', '');
            updateTempConnector();
            if (draggingNode !== null) {
                update(root);
                centerNode(draggingNode);
                draggingNode = null;
            }
        }

        // Helper functions for collapsing and expanding nodes.

        function collapse(d) {
            if (d.children) {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }
        }

        function expand(d) {
            if (d._children) {
                d.children = d._children;
                d.children.forEach(expand);
                d._children = null;
            }
        }

        var overCircle = function(d) {
            selectedNode = d;
            updateTempConnector();
        };
        var outCircle = function(d) {
            selectedNode = null;
            updateTempConnector();
        };

        // Function to update the temporary connector indicating
        // dragging affiliation
        var updateTempConnector = function() {
            var data = [];
            if (draggingNode !== null && selectedNode !== null) {
                // have to flip the source coordinates since we did this
                // for the existing connectors on the original tree
                data = [ {
                    source : {
                        x : selectedNode.y0,
                        y : selectedNode.x0
                    },
                    target : {
                        x : draggingNode.y0,
                        y : draggingNode.x0
                    }
                } ];
            }
            var link = svgGroup.selectAll(".templink").data(data);

            link.enter().append("path").attr("class", "templink").attr("d", d3.svg.diagonal()).attr('pointer-events',
                    'none');

            link.attr("d", d3.svg.diagonal());

            link.exit().remove();
        };

        // Function to center node when clicked/dropped so node doesn't
        // get lost when collapsing/moving with large amount of
        // children.

        function centerNode(source) {
            scale = zoomListener.scale();
            x = -source.y0;
            y = -source.x0;
            x = x * scale + viewerWidth / 2;
            y = y * scale + viewerHeight / 2;
            var mySvg = d3.select("#tree-container");
            mySvg.select('g').transition().duration(duration).attr("transform",
                    "translate(" + (x - 230) + "," + (y + 411) + ")scale(" + scale + ")");
            zoomListener.scale(scale);
            zoomListener.translate([ x, y ]);

            var shootX, shootY;

            // shootX=x+270;
            // shootY=y+350;

            shootX = "850.242468772961", shootY = "450.75";
            getShootImage(shootX, shootY);
        }

        /**
         * This function is used to add shooting image and text into the frame.
         * 
         * @param shootImgX
         * @param shootTextX
         * @return
         */
        function getShootImage(shootImgX, shootImgY) {
            d3.select("#shootCircle").remove();
            var imgUrl = "image/target-icon.png";
            baseSvg.append("image").attr("id", "shootCircle").attr("xlink:href", imgUrl).attr("x", shootImgX).attr("y",
                    shootImgY).attr("width", 50).attr("height", 50).style("fill", "red").classed("shoot", true);

            baseSvg.append("text").text("Shooting Gun").attr("x", shootImgX).attr("y", shootImgY + 50).attr("width", 50)
                    .attr("height", 50).style("font-weight", "bold");

            var loadButton = document.createElement("input");
            loadButton.setAttribute("type", "button");
            loadButton.setAttribute("value", "Add Load");
            loadButton.setAttribute("class", "btn btn-cust-info");
            loadButton.setAttribute("id", "addload");
            loadButton.setAttribute("x", shootImgX);
            loadButton.setAttribute("y", shootImgY);
            loadButton.setAttribute("width", 500);
            loadButton.setAttribute("height", 500);
            loadButton.style.align = "left";
        }

        // Toggle children function

        function toggleChildren(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else if (d._children) {
                d.children = d._children;
                d._children = null;
            }
            return d;
        }

        // Toggle children on click.

        function click(d) {
            if (d3.event.defaultPrevented)
                return; // click suppressed
            d = toggleChildren(d);
            update(d);
            centerNode(d);
        }

        function update(source) {
            // Compute the new height, function counts total children of
            // root node and sets tree height accordingly.
            // This prevents the layout looking squashed when new nodes
            // are made visible or looking sparse when nodes are removed
            // This makes the layout more consistent.
            var levelWidth = [ 1 ];
            var childCount = function(level, n) {

                if (n.children && n.children.length > 0) {
                    if (levelWidth.length <= level + 1)
                        levelWidth.push(10);

                    levelWidth[level + 1] += n.children.length;
                    n.children.forEach(function(d) {
                        childCount(level + 1, d);
                    });
                }
            };
            childCount(0, root);
            var newHeight = d3.max(levelWidth) * 25; // 25 pixels per
            // line
            tree = tree.size([ newHeight, viewerWidth ]);

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

            // Set widths between levels based on maxLabelLength.
            nodes.forEach(function(d) {
                d.y = (d.depth * (maxLabelLength * 7)); // maxLabelLength
                // * 10px
                // alternatively to keep a fixed scale one can set a
                // fixed depth per level
                // Normalize for fixed-depth by commenting out below
                // line
                // d.y = (d.depth * 500); //500px per level.

                /** My code -starts here * */
                if (nodes[i] != null && nodes[i] != 'undefined') {
                    if (nodes[i].type == "appServer") {
                        var toolMap = d3.map();
                        toolMap.set("connId", d.connServer);
                        toolMap.set("id", d.id);
                        toolMap.set("type", "Web server");
                        tooltipMap.set(d.id, toolMap);
                    } else if (nodes[i].type == "webServer") {
                        var toolMap = d3.map();
                        toolMap.set("connId", d.connServer);
                        toolMap.set("id", d.id);
                        toolMap.set("type", "Web server");
                        tooltipMap.set(d.id, toolMap);
                    } else if (nodes[i].type == "dataServer") {
                        var toolMap = d3.map();
                        toolMap.set("connId", d.connServer);
                        toolMap.set("id", d.id);
                        toolMap.set("type", "Web server");
                        tooltipMap.set(d.id, toolMap);
                    }
                }
                /** My code ends here */

            });

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

            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter().append("g").call(dragListener).attr("class", "node").attr("transform",
                    function(d) {
                        return "translate(" + source.y0 + "," + source.x0 + ")";
                    }).on('click', click);

            // Adding the outer circle to highlight the connected servers
            nodeEnter.append("circle").attr({
                r : 15
            }).attr("id", function(d, i) {
                if (nodes[i].type == "appServer") {
                    return "outer" + nodes[i].id;
                } else if (nodes[i].type == "webServer") {
                    return "outer" + nodes[i].id;
                } else if (nodes[i].type == "dataServer") {
                    return "outer" + nodes[i].id;
                }
            }).style("fill", "transparent").style("stroke-width", function(d, i) {
                if (nodes[i].type == "appServer") {
                    return "1";
                } else if (nodes[i].type == "webServer") {
                    return "1";
                } else if (nodes[i].type == "dataServer") {
                    return "1";
                } else {
                    return "0";
                }
            }).style("stroke", "#fff");

            nodeEnter.append("circle").attr("r", 5).attr("id", function(d, i) {
                if (nodes[i].type == "appServer") {
                    return nodes[i].id;
                } else if (nodes[i].type == "webServer") {
                    return nodes[i].id;
                } else if (nodes[i].type == "dataServer") {
                    return nodes[i].id;
                }
            }).style("filter", function(d, i) {
                if (nodes[i].type == "vm") {
                    return "url(#virtualMac)";
                } else if (nodes[i].type == "container") {
                    return "url(#container)";
                } else if (nodes[i].type == "appServer") {
                    return "url(#appserver)";
                } else if (nodes[i].type == "webServer") {
                    return "url(#webserver)";
                } else if (nodes[i].type == "sto") {
                    return "url(#storage)";
                } else if (nodes[i].type == "dataServer") {
                    return "url(#dbserver)";
                } else if (nodes[i].type == "network") {
                    return "url(#network)";
                } else if (nodes[i].type == "lb") {
                    return "url(#loadbalancer)";
                }
            }).style("fill", function(d) {
                return d._children ? "lightsteelblue" : "#fff";
            }).on("mouseover", function(d) {
                getConServers(this, d3.event, "enter");
            }).on("mouseout", function(d) {
                getConServers(this, d3.event, "exit");
            });

            nodeEnter.append("text").attr("x", function(d) {
                return d.children || d._children ? -10 : 10;
            }).attr("dy", ".35em").attr('class', 'nodeText').attr("text-anchor", function(d) {
                return d.children || d._children ? "end" : "start";
            }).text(function(d) {
                return d.name;
            }).style("fill-opacity", 0);

            // phantom node to give us mouseover in a radius around it
            nodeEnter.append("circle").attr('class', 'ghostCircle').attr("r", 30).attr("opacity", 0.2) // change
            // this
            // to zero to
            // hide the
            // target area
            .style("fill", "red").attr('pointer-events', 'mouseover').on("mouseover", function(node) {
                overCircle(node);
            }).on("mouseout", function(node) {
                outCircle(node);
            });

            // Update the text to reflect whether node has children or
            // not.
            node.select('text').attr("x", function(d) {
                return d.children || d._children ? -10 : 10;
            }).attr("text-anchor", function(d) {
                return d.children || d._children ? "end" : "start";
            }).text(function(d) {
                return d.name;
            });

            // Change the circle fill depending on whether it has
            // children and is collapsed
            node.select("circle.nodeCircle").attr("r", 4.5).style("fill", function(d) {
                return d._children ? "lightsteelblue" : "#fff";
            });

            // Transition nodes to their new position.
            var nodeUpdate = node.transition().duration(duration).attr("transform", function(d) {
                return "translate(" + (d.x - 8) + "," + -d.y + ")";
            });

            // Fade the text in
            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", 0);

            nodeExit.select("text").style("fill-opacity", 0);

            // Update the links…
            var link = svgGroup.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("stroke-dasharray", function(d) {
                return (d.source.parent) ? "6,6" : "1,0";
            }).attr("d", function(d) {
                var o = {
                    x : source.x0,
                    y : source.y0
                };
                return diagonal({
                    source : o,
                    target : o
                });
            });

            // 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;
            });
        }

        // Append a group which holds all nodes and which the zoom
        // Listener can act upon.

        var svgGroup = baseSvg.append("g");

        // Define the root
        root = treeData;
        root.x0 = viewerHeight / 2;
        root.y0 = 0;

        // Layout the tree initially and center on the root node.
        update(root);
        centerNode(root);
        addLoadSLAButtons();

    });

    function addLoadSLAButtons() {
        var slaDiv = document.createElement("div");
        slaDiv.setAttribute("id", "slaDiv");
        slaDiv.style.position = "relative";
        slaDiv.style.left = "35px";
        slaDiv.style.top = "-250px";
        slaDiv.style.width = "100px";

        var slaButton = document.createElement("input");
        slaButton.setAttribute("type", "button");
        slaButton.setAttribute("value", "View/Modify ServiceContract");
        slaButton.setAttribute("class", "btn btn-info");
        slaButton.setAttribute("id", "addSla");
        slaButton.style.position = "absolute";
        slaButton.setAttribute("onclick", "");// this will be modified once we
        // receive clarification on the
        // functionality.

        document.getElementById("tree-container").appendChild(slaDiv);
        document.getElementById("slaDiv").appendChild(slaButton);

        var relDiv = document.createElement("div");
        relDiv.setAttribute("id", "relDiv");
        relDiv.style.position = "relative";
        relDiv.style.left = "35px";
        relDiv.style.top = "-190px";
        relDiv.style.width = "100px";

        var loadButton = document.createElement("input");
        loadButton.setAttribute("type", "button");
        loadButton.setAttribute("value", "Add Load");
        loadButton.setAttribute("class", "btn btn-cust-info");
        loadButton.setAttribute("id", "addload");
        loadButton.style.position = "absolute";
        loadButton.style.align = "left";

        loadButton.setAttribute("onclick", ""); // reLoadPage()

        document.getElementById("tree-container").appendChild(relDiv);
        document.getElementById("relDiv").appendChild(loadButton);

    }

VividD.. 7

更好的方法是使用separation()方法.请查看文档以获取详细信息,原则上使用该方法定义节点之间的最小距离,但在您的情况下,您需要限制仅对某些节点进行gapos,这就是为什么在separator()内部存在条件)

var tree = d3.layout.tree()
    .separation(function(a, b) { return ((a.parent == root) && (b.parent == root)) ? 3 : 1; })
    .size([height, width - 160]);

在下面的图片是没有代码行的树,调用分离():(我将节点AA和ZZ添加到我之前的示例,还有BB和CC,但这些节点至少在这种情况下显示OK)

在此输入图像描述

......和这一行一起:

在此输入图像描述

直播jsfiddles:

在这里和这里

只是为了笑,我进一步修改了从"?3:1;})"到"?5:.6;})"的行,我得到了:

在此输入图像描述

1 个回答
  • 更好的方法是使用separation()方法.请查看文档以获取详细信息,原则上使用该方法定义节点之间的最小距离,但在您的情况下,您需要限制仅对某些节点进行gapos,这就是为什么在separator()内部存在条件)

    var tree = d3.layout.tree()
        .separation(function(a, b) { return ((a.parent == root) && (b.parent == root)) ? 3 : 1; })
        .size([height, width - 160]);
    

    在下面的图片是没有代码行的树,调用分离():(我将节点AA和ZZ添加到我之前的示例,还有BB和CC,但这些节点至少在这种情况下显示OK)

    在此输入图像描述

    ......和这一行一起:

    在此输入图像描述

    直播jsfiddles:

    在这里和这里

    只是为了笑,我进一步修改了从"?3:1;})"到"?5:.6;})"的行,我得到了:

    在此输入图像描述

    2023-02-07 20:47 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有