Il est également possible d'insérer la syntaxe de la barre de poignée AngularJS directement dans les éléments générés par d3 :
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' }";
});
Veuillez noter les points suivants : le scope est en fait l'objet angular scope transmis par la directive à la fonction de rendu. Définir le style d'un élément avec une expression "{{...}}" ne fonctionnera pas. J'utilise donc l'attribut "ng-style" ici.
Cependant, il y a une autre astuce : vous devez dire à Angular de regarder les éléments DOM générés dynamiquement et d'établir la liaison des données, je connais maintenant deux façons de le faire :
//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']);
l'autre voie est la suivante :
//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);
Vous pouvez maintenant modifier les membres de votre portée et ils seront directement mis à jour dans vos éléments d3, dans ce cas les cercles svg. Dans le contrôleur angulaire (qui est instancié avant le déclenchement de la directive qui dessine les objets d3).
$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);
Veuillez noter l'appel $digest, qui indique à angular de digérer la portée modifiée ; cela changera les valeurs des éléments du cercle svg. Pour tout ce qui concerne les animations et autres, d3 n'est plus responsable et il faut l'implémenter manuellement ou utiliser un autre modèle.