简体   繁体   English

AngularJS指令不更新D3圆包图

[英]AngularJS directive not updating D3 circle pack chart

I've been following the walk through of how to hook up Angular and D3 together with a directive and I have gotten the D3 graph to display. 我一直在遵循如何将Angular和D3与指令连接在一起的演练,并获得了要显示的D3图形。 However when I change the data in the form the graph isn't updating. 但是,当我更改表格形式的数据时,图形不会更新。 Any ideas why this might be happening? 任何想法为什么会发生这种情况?

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
  }
 };
});

Since you set up two-way databinding to val in your isolate scope using '=', and then you are $watch()ing val , I assume the form data is being properly propagated to the directive. 由于您在隔离范围内使用'='设置了与val的双向数据绑定,然后使用$ watch()ing val ,因此我假设表单数据已正确传播到该指令。

So this is likely a D3 issue (inside the $watch function), and not an Angular issue. 因此,这很可能是D3问题(在$ watch函数内部),而不是Angular问题。 (I'm only familiar with Angular, but D3 looks interesting.) (我只熟悉Angular,但D3看起来很有趣。)

You do have ng-model='val' somewhere in your form though, correct? 您的表单中是否确实有ng-model='val' ,对吗?

Hello I will paste the kind of 'template' I am using. 您好,我将粘贴我正在使用的“模板”类型。 Take into account the watcher for data. 考虑到观察者的数据。 You need to compare the values, this is accomplished when setting true as a parameter. 您需要比较这些值,这是在将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,

                    }
                }
            };
        }
    ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM