web-dev-qa-db-ja.com

AngularJSアプリ内のD3

私はAngularJSで最初のアプリを作成しようとしています。きれいに見えますが、多くの抽象化があり、d3jsで作成されたビジュアルを更新するためのangular方法論を使用する最も慣用的な方法に関するアドバイスがあれば、興味があります。

ありがとう、bp

42
BHP

angularと他のフレームワークをプレイするために、ニースはディレクティブを使用して「他の」フレームワークをラップします。

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

あなたがしたいことは、「他の」フレームワークによってデータが更新されたときにangularを伝えることです。angularあなたのタスクはより簡単です。

SVGで動作する例は次のとおりです。

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

TinyMCEをラップする例を次に示します

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

34
Dan Doyon

また、AngularJSハンドルバー構文を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' }";
                                });

次のことに注意してください:スコープは、ディレクティブからレンダリング関数に渡されるangularスコープオブジェクトです。要素のスタイルを「{{...} } "式は機能しないため、ここでは" ng-style "属性を使用しています。

ただし、もう1つのトリックがあります。動的に生成されたDOM要素を調べてデータバインディングを結び付けるには、Angularと伝える必要があります。これを行う2つの方法を知っています。

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

他の方法はこれです:

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

スコープメンバーを変更すると、d3要素(この場合はsvgサークル)に直接更新されます。 angularコントローラ(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);

$ digest呼び出しに注意してください。これは、angularに変更されたスコープをダイジェストします。これにより、svg circle要素の値が変更されます。アニメーションなどの場合、d3はもはや手動で実装するか、別のパターンを使用する必要があります。

3
hans

ディレクティブ内でd3を使用して他のAngularディレクティブを持つ要素を生成することは非常に一般的な要件であると思います)UPDATEの最後に_$compile_を呼び出すことができますcall()メソッドを使用したレンダリングプロセスのフェーズこのように(一連の円をレンダリングする場合):

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

このチュートリアル/スクリーンキャストに従って、DangularでD3を使用する方法を確認することもできます。これは、少し異なるものです。これは、特定のグラフを作成する人力車と呼ばれるd3のラッパーライブラリを使用しているためです。ただし、アプローチはまったく同じです。

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

0
hendrikswan