2012-06-21 3 views
42

Sto provando a creare la mia prima app con AngularJS. Sembra pulito, ma c'è molta astrazione, e sono curioso di sapere se qualcuno ha consigli sul modo più idiomatico di usare la metodologia angolare per aggiornare i visual creati con d3js.D3 all'interno di un'app AngularJS

Grazie, BP

risposta

34

Al fine di rendere angolari e altri framework bel gioco è quello di avvolgere le "altre" strutture che utilizzano direttive.

http://docs.angularjs.org/guide/directive

La cosa che si vuole fare è quello di raccontare angolare quando i dati sono stati aggiornati dalle "altre" quadri. Se l'angolare non ha bisogno di sapere, allora il tuo compito è più semplice.

Ecco un esempio che funziona con SVG, la sua impressionante

http://sullerandras.github.com/SVG-Sequence-Diagram/

Ecco un esempio che avvolge TinyMCE

http://jsfiddle.net/programmieraffe/kjsEV/

44

Si prega di controllare anche l'articolo di Brian Ford (Stagista di AngularJS) dove descrive l'integrazione di AngluarJS con D3 in dettaglio.

http://briantford.com/blog/angular-d3.html

+0

Questo è molto utile, grazie per la condivisione :) – gouravtiwari21

+1

Qui si trova un altro articolo come integrare D3 in angolare http://goo.gl/KYBFnX e un progetto GitHub Seed http://goo.gl/CS97f2 –

3

Esiste anche la possibilità di inserire i AngularJS gestiscono sintassi bar direttamente nella d3 elementi generato:

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

prega di notare le seguenti cose: lo scopo è in effetti la portata angolare oggetto passato dalla direttiva alla funzione di rendering. Impostare lo stile di un elemento su un'espressione "{{...}}" non funzionerà quindi sto usando l'attributo "ng-style" qui.

Tuttavia c'è un altro trucco: Dovete dire angolare di guardare ai elementi DOM generate dinamicamente e vincolante filo il backup dei dati, ora so di due modi per farlo:

//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'altra modo è questo:

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

Ora è possibile modificare i vostri membri portata e saranno direttamente aggiornato per gli elementi D3, in questo caso i cerchi SVG. Nel controller angolare (che viene istanziato prima che la direttiva firmi che disegna gli oggetti 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); 

Si prega di notare la chiamata $ digest, che dice all'angolo di digerire l'ambito modificato; questo cambierà i valori sugli elementi del cerchio svg. Per qualcosa come le animazioni e simili, d3 non è più responsabile e si dovrebbe implementare manualmente o utilizzare un modello diverso.

0

Puoi anche seguire questo tutorial/screencast per vedere come usare D3 con angolare. E 'un po' diverso, perché utilizza una libreria wrapper d3 chiamato risciò, che fornisce alcune cose specifiche graficamente, ma l'approccio è esattamente la stessa:

http://tagtree.tv/d3-with-rickshaw-and-angular

0

Se usiamo d3 all'interno di una direttiva per generare elementi con altre direttive Angular (come penso che troverete è un requisito abbastanza comune) è possibile chiamare $compile alla fine della fase UPDATE del processo di rendering con il metodo call(). Ti piace questa (supponendo che stiamo rendendo un mucchio di cerchi):

mySvg.selectAll("circle") 
       .data(scope.nodes) 
       .enter() 
       .append("circle") 
       .attr("someDirective") 
       .call(function(){ 
        $compile(this[0].parentNode)(scope); 
       });