【问题标题】:AngularJS directive not updating D3 circle pack chartAngularJS 指令不更新 D3 圆包图
【发布时间】:2012-12-22 01:38:30
【问题描述】:

我一直在遵循walk through of how to hook up Angular and D3 together 的指令,并且我已经获得了要显示的 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
  }
 };
});

【问题讨论】:

  • 如果你 console.log 数据,它更新了吗?我对 d3 不熟悉,但如果是这种情况,请查看 apply 方法:link
  • 你能提供一个not working 的例子和plnkr.co吗?

标签: javascript angularjs d3.js circle-pack


【解决方案1】:

由于您使用 '=' 在隔离范围内设置了到 val 的双向数据绑定,然后您正在 $watch()ing val,因此我假设表单数据已正确传播到指令。

所以这很可能是 D3 问题(在 $watch 函数内),而不是 Angular 问题。 (我只熟悉 Angular,但 D3 看起来很有趣。)

不过,您的表单中确实有 ng-model='val',对吗?

【讨论】:

    【解决方案2】:

    您好,我将粘贴我正在使用的那种“模板”。考虑数据的观察者。您需要比较这些值,这是在将 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,
    
                        }
                    }
                };
            }
        ])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      相关资源
      最近更新 更多