It is also possible to insert AngularJS descriptor syntax directly into d3-generated elements:
var containerDiv = d3.select(targetCSSSelectorForADiv); var svgG = containerDiv .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") svgG.selectAll(".tempclass").data(scope.circles).enter() .append("circle") .attr("class", "tempclass") .attr("cx", function (d, i) { return "{{circles[" + i + "].cx}}" }) .attr("cy", function (d, i) { return "{{circles[" + i + "].cy}}" }) .attr("r", function (d, i) { return "{{circles[" + i + "].radius}}" }) .attr("ng-style", function (d, i) { return "{fill: circles[" + i + "].circolor" + ", opacity: circles[" + i + "].opa" + ", 'stroke-width': 4*circles[" + i + "].opa" + ", stroke: 'red' }"; });
Note the following: the scope is an angular object object passed from the directive to the rendering function. Setting the element style to the expression "{...}} will not work, so I use the attribute" ng-style "here.
However, there is one more trick: you need to tell angular to look at the dynamically generated DOM elements and bind the data binding, now I know two ways to do this:
//the target div is the one with the angular ng-controller attribute //this you can call at the end of the d3 rendering call from within the render function angular.bootstrap(document.getElementById("d3ContainerDivID"), ['d3App']);
Another way:
//and this could be called from the directive that triggered the rendering or //some other place that could have the angular $compile service injected $compile(document.getElementById("d3ContainerDivID"))(scope);
Now you can change your scope members and they will be directly updated to your d3 elements, in this case svg circles. In the angular controller (which receives the instance before the directive that draws the d3 objects).
$scope.circles = []; for (var i = 0; i < 50; i++) { $scope.circles.push(new Circle()); } setInterval(function () { $scope.circles.forEach(function (d, i) { $scope.circles[i] = new Circle(); }); $scope.$digest(); }, 2000);
Notice the call to $ digest, which tells angular to digest the changed area; this will change the values ββfor the SVG circle elements. For something like animation, etc. Now d3 is no longer responding, and you will need to manually or use a different template.