AngularJSを使用して最初のアプリを作成しようとしています。見た目はすっきりしていますが、抽象化がたくさんあります。角度の方法論を使用してd3jsで作成されたビジュアルを更新する最も慣用的な方法について誰かがアドバイスを持っているかどうか知りたいです。
ありがとう、bp
angular およびその他のフレームワークをうまく機能させるには、ディレクティブを使用して「その他の」フレームワークをラップします。
http://docs.angularjs.org/guide/directive
やりたいことは、「他の」フレームワークによってデータが更新されたときに角度を伝えることです。angular が知る必要がない場合、タスクはより簡単になります。
SVG で動作する例を次に示します。
http://sullerandras.github.com/SVG-Sequence-Diagram/
TinyMCE をラップする例を次に示します。
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' }";
});
次の点に注意してください: スコープは、ディレクティブからレンダリング関数に渡された実際の角度スコープ オブジェクトです。要素のスタイルを「{{...}}」式に設定しても機能しないため、ここでは「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);
変更されたスコープをダイジェストするように angular に指示する $digest 呼び出しに注意してください。これにより、svg circle 要素の値が変更されます。アニメーションなどについては、d3 はもはや責任を負いません。手動で実装するか、別のパターンを使用する必要があります。
このチュートリアル/スクリーンキャストに従って、D3 を angular で使用する方法を確認することもできます。人力車と呼ばれる d3 の周りにラッパー ライブラリを利用しているため、少し異なります。これは、グラフ固有のものを提供しますが、アプローチはまったく同じです。
ディレクティブ内で d3 を使用して他の Angular ディレクティブで要素を生成する場合 (これは非常に一般的な要件であることがわかると思います) $compile
、メソッドを使用してレンダリング プロセスの UPDATE フェーズの最後に呼び出すことができますcall()
。このように (たくさんの円をレンダリングしていると仮定して):
mySvg.selectAll("circle")
.data(scope.nodes)
.enter()
.append("circle")
.attr("someDirective")
.call(function(){
$compile(this[0].parentNode)(scope);
});