如何更新角度指令中的d3.js图形?

时间:2015-11-20 19:34:22

标签: angularjs d3.js

对于个人项目,我尝试动态更新用于构建具有与well known d3.js example相同功能的图表的数据。但是,在更新数据后,我无法找到删除和重新绘制上一个图表的方法。

我的代码是针对包含d3.js图的angular指令。该指令的摘要如下:

angular.module('stockchartFccApp')
.directive('linearChart', ['$window', '$timeout', 'd3Service', function ($window, $timeout, d3Service) {
    return {
        restrict: 'EA',
        replace:true,
        scope: {chartData: '='},
        template:"<svg width='850' height='1200'></svg>",
        link: function(scope, elem, attrs) {

            d3Service.d3().then(function(d3) {
                scope.svg = null;
                scope.container = null;

                scope.render = function(data){

                    var margin = {top: 20, right: 20, bottom: 30, left: 40},
                     width = 480 - margin.left - margin.right,
                     height = 360 - margin.top - margin.bottom,
                     padding = 20,
                     p = [20, 50, 30, 50]; 

                    var matrix_data = dataBuilding(tickers, daterange);

                    var svg = d3.select(elem[0])
                        .append("svg")
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .append("g")
                        .attr("transform",
                        "translate(" + margin.left + "," + margin.top + ")");

                    var n = matrix_data[0].length;

                    var color_range = d3.scale
                        .category10();

                    var stack = d3.layout.stack();
                    var layers = stack(matrix_data);
                    var yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); });
                    var yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });

                    var x = d3.scale
                        .ordinal()
                        .domain(d3.range(max_m))
                        .rangeRoundBands([0, width - margin.right - margin.left]);




                    var y = d3.scale
                        .linear()
                        .domain([0, yStackMax])
                        .range([height, 0]);


                    var valgroup = svg.selectAll("g.valgroup")
                        .data(layers)
                        .enter()
                        .append("svg:g")
                        .attr("class", "valgroup")
                        .style("fill", function(d, i) {
                            return color_range(i);
                        })
                        .style("stroke", function(d, i) { return d3.rgb(color_range(i)).darker(); });          

                    var rect = valgroup.selectAll("rect")
                        .data(function(d){return d;})
                        .enter()
                        .append("svg:rect")
                        .attr("x", function(d) { return x(d.x); })
                        .attr("y", height)
                        .attr("width", x.rangeBand())
                        .attr("height", 0)

                    rect.transition()
                        .delay(function(d, i) { return i * 10; })
                        .attr("y", function(d) { return y(d.y0 + d.y); })
                        .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); });


                    d3.selectAll("input")
                        .on("change", change);


                    var timeout = setTimeout(function() {
                        d3.select("input[value=\"grouped\"]")
                        .property("checked", true)
                        .each(change);
                    }, 2000);

                    function change() {
                        clearTimeout(timeout);
                        if (this.value === "grouped") transitionGrouped();
                        else transitionStacked();
                    };

                    function rescale(yrange) {
                        //code
                    };

                    function transitionGrouped() {
                        //code
                    };

                    function transitionStacked() {
                        //code

                    };
                }

                scope.$watch('chartData', function(newVal, oldVal){
                    scope.render(newVal);
                }, true);


            });
        }
      }
   }
 ]);

代码排除了图例和其他功能,与示例或相关内容完全相似。

使用我当前的代码,我的旧图表变为非活动状态,并且它与新的活动图表重叠。我尝试过类似下面的内容:

svg.selectAll("*").remove();

删除上一张图表但未成功。

简而言之,我的问题是:代码中的方式和位置可以摆脱每个旧图表,以便始终使用新数据?

我正在处理的整个代码和练习可以在我的github存储库evaristoc找到。

提前致谢,

0 个答案:

没有答案