D3 zoomable pack chart更新

时间:2015-12-15 20:13:23

标签: d3.js

我正在处理此example中的代码。我在角度指令中使用它。

function _directivePackChart() {
    return {
        restrict: 'EA',
        link: function (scope, elem, attrs) {
        var w = 600,
            h = 500,
            r = 500,
            x = d3.scale.linear().range([0, r]),
            y = d3.scale.linear().range([0, r]),
            node,
            root;

        var pack = d3.layout.pack()
            .size([r, r])
            .value(function (d) { return d.size; })

        var vis = d3.select("svg")
            .append("svg:g")
            .attr("transform", "translate(" + (w - r) / 2 + "," + (h - r) / 2 + ")");

        var data = scope.ChartData;
        function drawChart() {
            node = root = data;

            var nodes = pack.nodes(root);

            vis.selectAll("circle")
                .data(nodes, function (d) { return d.path;})
              .enter().append("svg:circle")
                .attr("class", function (d) { return d.children ? "parent" : "child"; })
                .attr("cx", function (d) { return d.x; })
                .attr("cy", function (d) { return d.y; })
                .attr("r", function (d) { return d.r; })
                .on("click", function (d) { return zoom(node == d ? root : d); });

            vis.selectAll("text")
                .data(nodes, function (d) { return d.path;})
              .enter().append("svg:text")
                .attr("class", function (d) { return d.children ? "parent" : "child"; })
                .attr("x", function (d) { return d.x; })
                .attr("y", function (d) { return d.y; })
                .attr("dy", ".35em")
                .attr("text-anchor", "middle")
                .style("opacity", function (d) { return d.r > 20 ? 1 : 0; })
                .text(function (d) { return d.name; });
        };
        drawChart();
        d3.select(window).on("click", function () { zoom(root); });
        scope.$watchCollection('ChartDataUpdateCounter', function (newValue, oldValue) {
            drawChart();
        });

        function zoom(d, i) {
            var k = r / d.r / 2;
            x.domain([d.x - d.r, d.x + d.r]);
            y.domain([d.y - d.r, d.y + d.r]);

            var t = vis.transition()
                .duration(d3.event.altKey ? 7500 : 750);

            t.selectAll("circle")
                .attr("cx", function (d) { return x(d.x); })
                .attr("cy", function (d) { return y(d.y); })
                .attr("r", function (d) { return k * d.r; });

            t.selectAll("text")
                .attr("x", function (d) { return x(d.x); })
                .attr("y", function (d) { return y(d.y); })
                .style("opacity", function (d) { return k * d.r > 20 ? 1 : 0; });

            node = d;
            d3.event.stopPropagation();
        }
    }
};
}

我遇到的问题是在drawchart方法中,我有enter()方法。我该如何转换此代码以便它也处理更新?请注意,绘图是从手表触发的。这是一个向下钻取用例,随着用户向下钻取,更多节点将添加到所选节点。

发生向下钻取时,我删除所选节点上的size属性并添加子节点。当我重新计算节点时,我怀疑父节点是否有更新的cx,cy,r属性。但由于没有定义更新,它仍然使用其旧属性,看起来很奇怪。

我是D3&的新手SVG。

1 个答案:

答案 0 :(得分:0)

我结果很简单。我不得不像这样打破这条线

 var circle = vis.selectAll("circle")
                    .data(nodes, function (d) { return d.path; });

                circle.enter().append("svg:circle")
                circle.exit().remove();

                circle.attr("class", function (d) { return d.children ? "parent" : "child"; })
                    .attr("cx", function (d) { return d.x; })
                    .attr("cy", function (d) { return d.y; })
                    .attr("r", function (d) { return d.r; })
                    .on("click", function (d) {
                        return zoom(node == d ? root : d);
                    });