2012-12-22 62 views
2

我一直在用指令跟蹤walk through of how to hook up Angular and D3 together,並且我已經獲得了D3圖形顯示。但是,當我更改表格中的數據時,圖表沒有更新。任何想法,爲什麼這可能會發生?AngularJS指令不更新D3圓形包圖表

budgetApp.directive('d3Vis', function() { 

var r = 500, 
format = d3.format(",d"), 
fill = d3.scale.category20c(); 

var bubble = d3.layout.pack() 
.sort(null) 
.size([r, r]) 
.padding(1.5); 

return { 
    restrict: 'E', 
    scope: { 
    val: '=' 
}, 
link: function (scope, element, attrs) { 

    var vis = d3.select(element[0]).append("svg") 
    .attr("width", r) 
    .attr("height", r) 
    .attr("class", "bubble"); 

    scope.$watch('val', function (newVal, oldVal) { 

    // clear the elements inside of the directive 
    vis.selectAll('*').remove(); 

    // if 'val' is undefined, exit 
    if (!newVal) { 
     return; 
    } 

    var node = vis.selectAll("g.node") 
    .data(bubble.nodes(classes(newVal)) 
     .filter(function(d) { 
     return !d.children; 
     })) 
    .enter().append("g") 
    .attr("class", "node") 
    .attr("transform", function(d) { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }); 

    node.append("title") 
    .text(function(d) { 
     return d.className + ": " + format(d.value); 
    }); 

    node.append("circle") 
    .attr("r", function(d) { 
     return d.r; 
    }) 
    .style("fill", function(d) { 
     return fill(d.packageName); 
    }); 

    node.append("text") 
    .attr("text-anchor", "middle") 
    .attr("dy", ".3em") 
    .text(function(d) { 
     return d.className.substring(0, d.r/3); 
    }); 

    // Helper function, returns a flattened hierarchy containing all leaf nodes under the root. 
    function classes(root) { 
     var classes = []; 

     function recurse(name, node) { 
     if (node.children) node.children.forEach(function(child) { 
      recurse(node.name, child); 
     }); 
     else classes.push({ 
      packageName: name, 
      className: node.name, 
      value: node.size 
     }); 
     } 

     recurse(null, root); 
     return { 
     children: classes 
     }; 
    } 

    }); // end watch 
    } 
}; 
}); 
+0

如果你console.log數據,它有更新嗎?我不熟悉d3,但是如果是這種情況,請查看apply方法:[link](http://docs.angularjs.org/api/ng.$ro​​otScope.Scope#$apply) –

+1

你可以嗎在http://plnkr.co/上提供一個「不工作」的例子? – Olivier

回答

0

既然你雙向數據綁定在隔離範圍使用「=」設置爲val,然後你$腕錶()荷蘭國際集團val,我想表單數據被正確地傳播到指令。

所以這可能是一個D3問題(在$ watch函數中),而不是一個Angular問題。 (我只熟悉Angular,但D3看起來很有趣。)

你確實有ng-model='val'在你的表格中的某個地方,但是正確嗎?

0

你好,我會粘貼我使用的那種「模板」。考慮數據的觀察者。您需要比較這些值,這是在將true設置爲參數時完成的。

angular.module('myDirectives', []) 
    .directive('test', ['$window', 
     function ($window) { 
      return { 
       restrict: 'E', 
       scope: { 
        data: '=', 
        /* other attributes */ 
       }, 
       replace: false, 
       template: '<div id="mydirective"></div>', 
       link: function (scope, element, attrs) { 
        var svg = d3.select(element[0]) 
         .append('svg') 
         .style('width', '100%')      
        var margin = parseInt(attrs.margin) || 20; 

        // Browser onresize event 
        $window.onresize = function() { 
         scope.$apply(); 
        }; 
        // New data 
        scope.$watch('data', function (newVals, oldVals) { 
         return scope.render(newVals); 
        }, true); 


        scope.$watch(function() { 
         return angular.element($window)[0].innerWidth; 
        }, function() { 
         scope.render(scope.data); 
        }); 

        scope.render = function (data) { 
         // custom d3 code 
         svg.selectAll('*').remove(); 
         if (!data) return; 
         var width = d3.select(element[0]).node().offsetWidth - margin, 

        } 
       } 
      }; 
     } 
    ])