链路路径在重新调用相同的树函数 - D3树时消失

时间:2017-09-25 08:17:08

标签: javascript d3.js tree

我能够在应用程序的初始加载时使用json数据绘制树结构。

现在我的要求是,点击按钮我应该能够为每个工作正常的节点添加更多的text / css。 我实际上使用的是最初用于绘制树的相同功能,能够在按钮触发器上交换数据。

当我这样做时,单击第一级节点(扩展到第二级),第一级路径从g标签中消失,所选节点更改位置并位于第二级数据中。

厌倦了所有可能的方式,任何人都可以帮助解决这个问题。

提前致谢

以下是使用的树函数

//To draw tree structure for the selected data
    drawTree: function() {
        var driverTree = this;
        var id = "#" + this.getView().byId("chartArea").sId;
        // ************** Generate the tree diagram  *****************
        var treeData = driverTree.treeModel.oData;
        var radius = 40;
        var width = $(id).width();
        var height = window.innerHeight;
        var maxLabel = 1500;
        var i = 0,
            duration = 450,
            root;

        var tree = d3.layout.tree()
            .size([height, width])
            .separation(function(a, b) {
                return (a.parent == b.parent ? 1 : 2);
            });
        var margin = {
            top: 20,
            right: 120,
            bottom: 20,
            left: 120
        }
        var slider = d3.scale.linear()
            .domain([1, 100])
            .range([1, 100])
            .clamp(true);
        var canvasWidth = radius * 2 + margin.left + margin.right,
            canvasHeight = radius * 2 + margin.top + margin.bottom;
        var color = d3.scale.category10();
        var diagonal = d3.svg.diagonal()
            .projection(function(d) {
                return [d.y, d.x];
            });

        var pie = d3.layout.pie()
            .value(function(d) {
                if (isNaN(parseFloat(d.value)))
                    return 0;
                else
                    return parseFloat(d.value);
            })
            .sort(null);
        // arc object
        var arc = d3.svg.arc()
            .outerRadius(40)
            .innerRadius(20);
        //var id = "#" + chartArea.sId;
        d3.select(id).select("svg").remove();
        driverTree.zoomListener = d3.behavior.zoom()
            .scaleExtent([0.1, 3])
            .on("zoom", function(d) {
                zoomed(d);
            });
        var svgGroup = d3.select(id).append("svg")
            .attr("width", width)
            .attr("height", height)
            .attr("class", "tooltip")
            .call(driverTree.zoomListener);

        function zoomed(d) {
            if (driverTree.hoizMode)
                svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")rotate(90,50,50)");
            else
                svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }
        var svg = svgGroup.append("g")
            .attr("transform", "translate(" + width + "," + (height / 2) / 2 + ") rotate(90,50,50)");

        root = treeData;
        root.x0 = height / 2;
        root.y0 = 0;

        var div = d3.select("body").append("div").attr("class", "tooltip").style("opacity", "0");

        function collapse(d) {
            if (d.children) {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }
        }
        root.children.forEach(collapse);
        //update(root);
        //d3.select(self.frameElement).style("height", "800px");
        var circumference_r = 35;

        function update(source) {

            var levelWidth = [1];
            var childCount = function(level, n) {

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

                    levelWidth[level + 1] += n.children.length;
                    n.children.forEach(function(d) {
                        childCount(level + 1, d);
                    });
                }
            };
            childCount(0, root);
            var newHeight = d3.max(levelWidth) * 263.6; // 25 pixels per line  
            tree = tree.size([newHeight, window.innerHeight]);
            // 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;
            });

            // Update the nodes…
            var node = svg.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")
                .attr("id", function(d) {
                    return "id" + d.title;
                })
                .attr("class", "node")
                .attr("transform", function(d) {
                    if (driverTree.hoizMode)
                        return "translate(" + source.y0 + "," + source.x0 + ") rotate(-90)";
                    else
                        return "translate(" + source.y0 + "," + source.x0 + ") rotate(0)";
                })
                .on("mouseover", function(d) {
                    mouseover(d);
                })
                .on("mousemove", function(d) {
                    mousemove(d);
                })
                .on("mouseout", function(d) {
                    mouseout(d);
                });
            if (driverTree.editTree) {
                nodeEnter.append("rect")
                    .attr("id", "hideButton")
                    .attr("width", function(d) {
                        if (d.id != "NODE1") return "40px";
                    })
                    .attr("transform", function(d) {
                        if (d.id != "NODE1") return "translate(-40,-70)";
                    })
                    .attr("rx", "5")
                    .attr("ry", "5")
                    .attr("height", function(d) {
                        if (d.id != "NODE1") return "25px";
                    })
                    .style("stroke", "#999faa")
                    .style("stroke-width", "2px")
                    .style("fill", function(d) {
                        if (d.isHidden) return "#000f2b";
                        else return "#8E94A1";
                    })
                    .on("click", function(d) {
                        d.isHidden = !d.isHidden;
                        if (d.isHidden) return this.style.fill = "#000f2b";
                        else return this.style.fill = "#8E94A1";
                    });

                nodeEnter.append("text")
                    .attr("id", "hideText")
                    .attr("transform", "translate(-31,-54)")
                    .style("fill", "#eee")
                    .text(function(d) {
                        if (d.id != "NODE1") return "Hide";
                    })
                    .on("click", function(d) {
                        d.isHidden = !d.isHidden;
                        if (d.isHidden) return d3.select(this.parentNode).select("rect").style("fill", "#000f2b");
                        else return d3.select(this.parentNode).select("rect").style("fill", "#8E94A1");
                    });
            }
            nodeEnter.append("circle")
                .attr("r", "40")
                .on("click", click);
            nodeEnter.append("text")
                .attr("id", function(d) {
                    return "ct" + d.title;
                })
                .attr("x", "-8")
                .attr("y", "4")
                .text(function(d) {
                    return brevoVDT.util.Formatter.amountToMillions(d.value);
                })
                .on("click", click);
            nodeEnter.append("text")
                .attr("transform", "translate(55,-10)")
                .text(function(d) {
                    return "Org Value - " + brevoVDT.util.Formatter.amountToMillions(d.value_org);
                })
            nodeEnter.append("text")
                .attr("id", function(d) {
                    return "cv" + d.title;
                })
                .attr("transform", "translate(55,5)")
                .text(function(d) {
                    return "Currenet Value - " + brevoVDT.util.Formatter.amountToMillions(d.value);
                })
            nodeEnter.append("text")
                .attr("id", function(d) {
                    return "dv" + d.title;
                })
                .attr("transform", "translate(55,20)")
                .text(function(d) {
                    return "Difference  " + brevoVDT.util.Formatter.amountToMillions(parseFloat(d.value_org) - parseFloat(d.value));
                })
                .style("fill", function(d) {
                    var value = parseFloat(d.value_org) - parseFloat(d.value);
                    if (value > 0) return "green";
                    else if (value < 0) return "red";
                    else return "black";
                })
                /*nodeEnter.append("text")
                    .attr("transform", "translate(-50,58)")
                    .attr("text-anchor", "start")
                    .text(function(d) {
                        return d.title;
                    })*/
            nodeEnter.append("rect")
                .attr("width", "130px")
                .attr("transform", "translate(48,-25)")
                .attr("height", "50px")
                .attr("rx", "15")
                .attr("ry", "15")
                .style("fill", "rgba(238, 238, 238, 0)")
                .style("opacity", "0.9")
                .style("stroke",
                    function(d) {
                        if (d.children == null && d._children == null)
                            return "black";
                        else
                            return "orange";
                    })
                .style("stroke-width", "2");
            nodeEnter.append("g").attr("class", "slicers");
            nodeEnter.append("g").attr("class", "lines");
            var pieNodes = nodeEnter.select(".slicers").selectAll("path")
                .data(function(d, i) {
                    if (d.id == "NODE1") var value = 0;
                    else var value = d.parent.value;
                    value = value == 0 ? 1 : value;
                    return pie([d, {
                        value: value
                    }]);
                })
                .enter()
                .append("svg:path")
                .attr("class", "slice")
                .attr("fill", function(d, i) {
                    return color(i);
                })
                .each(function(d) {
                    d;
                })
                .attr('d', arc)

            //toolbar
            function mouseover(d) {
                div.transition()
                    .duration(500)
                    .style("opacity", 0.9)
                    .style("display", "block");
            }

            function mousemove(d) {
                var name = d.name.length > 13 ? d.name.slice("0", "13") : d.name;
                div.html("<b>" + d.title + "</b><table>" +
                    "<tr><td>" + name + ":</td><td>" + parseFloat(d.value).toFixed(1) + "</td></tr></table>")

                .style("left", (d3.event.pageX + 50) + "px")
                    .style("top", (d3.event.pageY + 0) + "px");
            }

            function mouseout(d) {
                div.transition()
                    .duration(500)
                    .style("display", "none");

            }
            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                .duration(duration)
                .attr("transform", function(d) {
                    if (driverTree.hoizMode)
                        return "translate(" + d.y + "," + d.x + ") rotate(-90)";
                    else
                        return "translate(" + d.y + "," + d.x + ") rotate(0)";
                });
            nodeUpdate.select("circle");
            nodeUpdate.select("text");
            nodeUpdate.select("rect");
            nodeUpdate.select("foreignObject");
            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                .duration(duration)
                .attr("transform", function(d) {
                    if (driverTree.hoizMode)
                        return "translate(" + source.y + "," + source.x + ") rotate(-90)";
                    else
                        return "translate(" + source.y + "," + source.x + ") rotate(0)";
                })
                .remove();
            nodeExit.select("circle");
            nodeExit.select("text");
            nodeExit.select("rect");
            nodeExit.select("foreignObject");
            // Update the links…
            var link = svg.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("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 + 100
                    };
                    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;
            });
        }
        // Function to center node when clicked/dropped so node doesn't get lost when collapsing/moving with large amount of children.
        function centerNode(source) {
            var scale = driverTree.zoomListener.scale();
            var x = -source.y0;
            var y = -source.x0;
            if (driverTree.hoizMode) {
                d3.select("g").transition()
                    .duration(1)
                    .attr("transform", "translate(" + width + "," + (height / 2) / 2 + ")scale(" + scale + ")rotate(90,50,50)");
                driverTree.zoomListener.translate([width, (height / 2) / 2]);
            } else {
                d3.select("g").transition()
                    .duration(1)
                    .attr("transform", "translate(" + height / 2 + "," + -width / 2 + ")scale(" + scale + ")");
                driverTree.zoomListener.translate([height / 2, -width / 2]);
            }
            driverTree.zoomListener.scale(scale);

        }

        // Toggle children on click.
        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
            centerNode(d)
        }

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

        update(root);
        centerNode(root);

以下是我的编辑功能代码

// To make the tree editable
    handleEdit: function(evt) {
        var that = this;
        this.editTree = !this.editTree;
        this.treeModel.oData.x = 0;
        this.treeModel.oData.y = 0;
        this.treeModel.oData.x0 = 0;
        this.treeModel.oData.y0 = 0;
        this.treeModel.oData.children.forEach(function(d){
            d.x = 0; d.y = 0; d.x0 = 0; d.y0 = 0;
            var children = (d._children == undefined ? d.children : d._children );
            children.forEach(function(a){
                a.x = 0; a.y = 0; a.x0 = 0; a.y0 = 0;
            });
        });
        this.drawTree();

    },

0 个答案:

没有答案