即使数据没有改变,如何刷新D3树?

时间:2015-12-04 15:51:50

标签: javascript angularjs d3.js

我遇到了D3树的问题 - (仅在Safari中)当在一棵树的顶部新建一个在模态窗口中打开然后关闭所有节点变成黑色(它们最初是图像)。

作为一种解决方法,我认为只要模态窗口关闭就完全重绘树。但我不能让D3认为数据(实际上并没有改变)是新的,我试图克隆数据对象以使其退出()以前的数据。但它不起作用它只是在现有节点之上绘制相同的节点。

更新 - 正如评论中所建议的那样 - 我试图重现我在Plunker中遇到的问题。尝试在Safari中几次打开模态窗口 - 节点中的初始树图片将变为黑色。

var app = angular.module('plunker', ['mgcrea.ngStrap']);

app.controller('MainCtrl', function ($scope, $modal) {

});

app.directive('tree', tree);

function tree() {
    return {
        restrict: 'E',
        scope: true,
        replace: false,

        link: function (scope, element, attrs) {
            var treeData = [{
                "name": "Top Level",
                "parent": "null",
                "value": 10,
                "type": "black",
                "level": "red",
                "icon": "http://placekitten.com/g/48/48",
                "children": [{
                    "name": "Level 2: A",
                    "parent": "Top Level",
                    "value": 5,
                    "type": "grey",
                    "level": "red",
                    "icon": "http://placekitten.com/g/48/48",
                    "children": [{
                        "name": "Son of A",
                        "parent": "Level 2: A",
                        "value": 5,
                        "type": "steelblue",
                        "icon": "http://placekitten.com/g/48/48",
                        "level": "orange"
                    }, {
                        "name": "Daughter of A",
                        "parent": "Level 2: A",
                        "value": 18,
                        "type": "steelblue",
                        "icon": "http://placekitten.com/g/48/48",
                        "level": "red"
                    }]
                }, {
                    "name": "Level 2: B",
                    "parent": "Top Level",
                    "value": 10,
                    "type": "grey",
                    "icon": "http://placekitten.com/g/48/48",
                    "level": "green"
                }]
            }];

            // ************** 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 svg = d3.select(element[0]).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 + ")";
                    });

                var defs = node.append('defs').attr('id', 'imgdefs');

                var roundedCircle = defs.append("pattern")
                    .attr("id", "grump_avatar")
                    // .append("svg:image")
                    // .attr("xlink:href", 'http://placekitten.com/g/48/48')
                    .attr("width", 48)
                    .attr("height", 48)
                // .attr("x", 0)
                // .attr("y", 0);

                roundedCircle.append("image")
                    .attr("xlink:href", function (d) {
                        return d.icon;
                    })
                    // .attr("x", "-12px")
                    // .attr("y", "-12px")
                    .attr("width", "48px")
                    .attr("height", "48px");

                nodeEnter.append("circle")
                    .attr("cx", 48 / 2)
                    .attr("cy", (48 - 40) / 2)
                    .attr("r", 48 / 2)
                    .style('fill-opacity', 1)
                    .attr("fill", "url(#grump_avatar)");

                // 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")
                    .style("stroke", function (d) {
                        return d.target.level;
                    })
                    .attr("d", diagonal);

            }


        }
    }
}

1 个答案:

答案 0 :(得分:0)

现在我已经得到了这样的解决方案 - 每次打开模态时我都会删除整个svg(d3.select("svg").remove();)元素,然后调用另一个函数从头开始绘制树。