1

I am trying to draw a simple bar chart inside an angular app with d3.js.

To do this, I start by basically wrapping d3 in a directive:

  angular.module('myApp', []).directive(barChart', function($parse) {
    return {
         restrict: 'E',
         replace: false,
         scope: {data: '=chartData'},
         link: function (scope, element, attrs) {
           var chart = d3.select(element[0]);
            chart.append("div").attr("class", "chart")
             .selectAll('div')
             .data(scope.data).enter().append("div")
             .transition().ease("elastic")
             .style("width", function(d) { return d + "%"; })
             .text(function(d) { return d + "%"; });
         } 
      };
  });

I then get the data through an API call wrapped in a directive using promises. Here is the syntax I use is the following:

function myCtrl ($scope) {
    $scope.myData = [];

    myPromise.
    .then(function(data) {
      $scope.myData = _.values(data);
      console.log($scope.myData);
    });
}

The data is loaded just fine as it gets printed properly in the console. However, the chart is not updated. My d3 code is fine as the following works as well:

function myCtrl ($scope) {
    $scope.myData = [34.5, 34.25, 34.5, 36.152, 40.33];;
}

What am I doing wrong? Should I force a new digest cycle or use $scope.$apply?

Many thanks

1 Answer 1

1

I don't think d3 watches for changes in your data. Try wrapping your directive code in a watcher to update your chart.

angular.module('myApp', []).directive(barChart', function($parse) {
    return {
         restrict: 'E',
         replace: false,
         scope: {data: '=chartData'},
         link: function (scope, element, attrs) {
           var chart = d3.select(element[0]);
           chart.append("div");
           scope.$watch("data", function(d){
                 chart.find("div:first").attr("class", "chart")
                  .selectAll('div')
                  .data(d).enter().append("div")
                  .transition().ease("elastic")
                  .style("width", function(d) { return d + "%"; })
                  .text(function(d) { return d + "%"; });
           });
         } 
      };
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.