D3更新图例旧数据未删除

时间:2015-05-22 13:54:52

标签: angularjs d3.js

我是javascript中的新手,我跟着example创建了一个饼图。我希望它更新选择列表中的更改。当馅饼工作时,传奇列表就会增长。

我尝试了exit()。remove()和selectAll(“g”)。remove()我在调试中看到“g”元素已被删除,但变量图例在每次更新中都在不断增长而不是删除旧版本数据。任何人都可以找出为什么代码与馅饼一起工作而传说不起作用?

非常感谢!

这是我的代码

    var app=angular.module("app",[]);

    // controller gets average json data and reform by host, produces executions
    app.controller("pieCtrl",function($scope,$http){
        $http.get("average.json").success(function(data){
            //executions- key:hostName, value:[listExecutions]
            var executions={};
            data.forEach(function(d){
                if(!(d.hostName in executions)){
                    executions[d.hostName]={
                        hostName:d.hostName,
                        listExecutions:[]
                    }
                }
                executions[d.hostName].listExecutions.push(d);
            });

            //listHostnames for <select> [["host1"],["host2"]]
            $scope.ListHostnames=[];
            Object.keys(executions).forEach(function(hostName) {
                $scope.ListHostnames.push(executions[hostName]);
            });
            //default value, bound to <select>
            $scope.selectedHostname = $scope.ListHostnames[2];
        }).error(function(err){
            throw err;
        });
    });

    app.directive("pie",function() {
        function link(scope,element,attr) {
            var wpie = 300;
            var hpie = 300;
            var outerRadius = wpie / 2;
            var innerRadius = outerRadius*0.5;
            var color = d3.scale.category10();
            var legendRectSize = 18;
            var legendSpacing = 4;

            scope.$watch('data', update);

            var pie = d3.layout.pie()
                    .value(function(d) {
                        return d.executionNum;
                    })
                    .sort(null);//prevent values from being sorted;

            var arc = d3.svg.arc()
                    .outerRadius(outerRadius)
                    .innerRadius(innerRadius);
          
            //svg must be outside update(), otherwise multiple charts will be created instead of updating one chart
            var svg = d3.select("#chart").append("svg")
                    .attr("width", wpie*2)
                    .attr("height", hpie*1.5)
                    .append("g")
                    .attr("transform", "translate(" + wpie / 2 + "," + hpie / 2 + ")");

            //tooltip
            var tooltip = d3.select('pie')
                    .append('div')
                    .attr('class', 'tooltip');
            tooltip.append('div')
                    .attr('class', 'date');
            tooltip.append('div')
                    .attr('class', 'num');

            function update(){
                //clear what is left
                svg.selectAll('path').remove();

                //input data
                if (!scope.$parent.selectedHostname){ return }
                var data = scope.$parent.selectedHostname.listExecutions;
                //bind data
                var arcs = svg.selectAll("path")
                        .data(pie(data));
                //append path for shapes
                arcs.enter().append("path")
                        .attr("d", arc)
                        .attr("fill", function(d) {
                            return color((d.data.day));
                        })
                        .each(function(d){this._current=d;});// animation

                //mouseover tooltip to show contents
                arcs.on('mouseover', function(d) {
                    var num=(d.enabled)? d.data.executionNum :0;
                    tooltip.select('.date').html('Date: '+d.data.day+' / '+d.data.month);
                    tooltip.select('.num').html('Number of executions: '+num);
                    tooltip.style('display', 'block');
                });
                arcs.on('mouseout', function() {
                    tooltip.style('display', 'none');
                });

                //add labels
                arcs.enter().append("text")
                        .attr("transform", function(d) {
                            return "translate(" + arc.centroid(d) + ")";
                        })
                        .attr("dy", ".35em")
                        .style("text-anchor", "middle")
                        .text(function(d) {
                            return d.data.executionNum;
                        })
                        .attr("fill","black");

                svg.selectAll(".legend").remove();
                svg.selectAll("g").remove();
                svg.selectAll("g.legend").remove();

                var legend = svg.selectAll('.legend')
                        .data(color.domain());

                legend.exit().remove();
              
                legend.enter()
                        .append('g')
                        .attr('class', 'legend')
                        .attr('transform', function(d, i) {
                            var height = legendRectSize + legendSpacing;
                            var offset =  height * color.domain().length / 2;
                            var horz = 10 * legendRectSize;
                            var vert = i * height - offset;
                            return 'translate(' + horz + ',' + vert + ')';
                        });

                legend.append('circle')
                        .attr('cx', legendRectSize)
                        .attr('cy', legendRectSize)
                        .attr('r',8)
                        .style('fill', color)
                        .style('stroke', color)
                        .attr('class', 'legend');

                legend.append('text')
                        .attr('x', legendRectSize + 4*legendSpacing)
                        .attr('y', legendRectSize +4)
                        .text(function(d) { return d; })
                        .attr('class', 'legend');
                legend.exit().remove();

            }
        }

        return{
            link: link,
            restrict: 'E',
            scope: { data : '='}

        };

    })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>dynamic pie</title>
</head>
<body ng-app="app" ng-controller="pieCtrl">
<h1> Dynamic pie chart </h1>
<div id="list">
<select ng-model="selectedHostname" ng-options="hostName as hostName.hostName for hostName in ListHostnames"></select>
</div>
<div id="chart">
<pie data="selectedHostname"></pie>
</div>

</body>
</html>

我正在使用角度控制器来查询数据,而d3代码在pie指令中。调用update函数来刷新图表。原始数据是一个json文件。 [{"durationSec":515,"month":2,"day":15.0,"executionNum":8,"hostName":"monitoring02"},{"durationSec":515,"month":2,"day":17.0,"executionNum":3,"hostName":"monitoring02"},{"durationSec":521,"month":2,"day":16.0,"executionNum":5,"hostName":"monitoring02"},{"durationSec":515,"month":2,"day":18.0,"executionNum":6,"hostName":"monitoring02"},{"durationSec":739,"month":2,"day":18.0,"executionNum":7,"hostName":"apple-pc"},{"durationSec":1140,"month":2,"day":19.0,"executionNum":7,"hostName":"apple-pc"},{"durationSec":1117,"month":2,"day":20.0,"executionNum":6,"hostName":"apple-pc"},{"durationSec":1125,"month":2,"day":21.0,"executionNum":3,"hostName":"monitoring01"},{"durationSec":1169,"month":2,"day":22.0,"executionNum":5,"hostName":"monitoring01"}]

0 个答案:

没有答案