2017-04-19 17 views
1

$ scopeにバインドされたcrossfilters関数を使用するdc.jsチャートを作成するファクトリがあります。タグはそうcrossfilter.js with dc.jsコールバックグループのチャートの更新

<mypie id="mypie" chart-dimesion="mypie.dimension" chart-group="mypie.group"...etc 

のようなものですので、Plnkr Example

$scope.updateMyPie = function(data) { 
    var cf = crossfilter(data) 
    $scope.mypie.dimension = cf.dimension(function(d) { return d.key }) 
    $scope.mypie.group = 
    $scope.mypie.dimension.group().reduceSum(function(d){ return d.value }); 
} 

チャートの工場は、このアプローチは、フィルタリング、初期データの読み込み、結合およびチャートのレンダリングなどのために正常に動作角度ディレクティブでDOMを介してすべてのグラフのプロパティを取ります....しかしこれは一つの例外です。新しいデータリクエストを発生させるボタンのクリックイベントのようなものがあり、それをコールバックとして使用してデータをうまく処理しますが、グラフを更新しません。もし私がdc.redrawAll()やrenderAll()などをインクルードしたとしても、私はredraw()、redrawAll()の埋め込みを試みた。データが正しく戻ってきていることを確認して、タグを完全に破棄して再作成して追加した。 DOMなどにDC/D3チャートを作成するこの工場スタイルの実装を使用する際に問題があると私は想定していますが、スコープ内のグループおよび/または次元を更新しても機能するはずです。チャートオブジェクトがdim/groupsへの変更を受け取っていないかのようですか?私は、$ scope.etcによって参照CFグループの値は、使用して変更されていることを確認することができ、最初の呼び出しと2回目の呼び出しの両方で、次の

var print_filter = function(filter) { 
    var f = eval(filter); 
    if (typeof (f.top) != "undefined") { 
     f = f.top(Infinity); 
    } 
    if (typeof (f.dimension) != "undefined") { 
     f = f.dimension(function (d) { 
      return ""; 
     }).top(Infinity); 
    } 

    console.log(filter + "(" + f.length + ") = " + JSON.stringify(f).replace("[", "[\n\t").replace(/}\,/g, "},\n\t").replace("]", "\n]")); 
}; 

UPDATE:追加plnkr、より良いとのように、=を説明しようと私はディレクティブと要素を使って達成しようとしているサービスベースのアプローチと比較して、DCチャートを構築するための「伝統的な」方法の一種を持っています。すべて私はplnkrで表示しようとしたものを除いて動作します...新しいデータ(ajax)を要求すると、最初の更新はうまくいきます。私は数多くの方法を試しましたが、本質的に$ scope dim/groupを更新することは正しく機能するはずですか?私はそれが2つの方法バインディングだと信じているので、これらの "2つのスコープ"は参照を共有する必要がありますか?しかし、私がscope。$ parent.my.dimensionなどを使用しても、それには影響しません。

答えて

1

グラフは、依然として古いクロスフィルタ、ディメンション、およびグループにバインドされています。一般に、新しいデータを読み込んだりデータを置き換えたりするときは、クロスフィルタ、ディメンション、またはグループを破棄しないでください。 crossfilter.removeおよびcrossfilter.addメソッドを使用してデータを追加または削除します。

ここではあなたの例を変更する方法は次のとおりです。あなたはあなたのコントローラを作成する場合は、将来的にそれらのいずれかのより多くを作成したり、破壊しないアップフロント、

はあなたCrossfilterを作成寸法、およびグループ:

myapp.controller('mycontroller', ['$scope', 'dataCaller', function($scope, dataCaller){ 
     $scope.pageTitle = "Updating DC.js and Crossfilter"; 

     $scope.currentData1 = "data1.json"; 
     $scope.currentData2 = "data1.json"; 

     $scope.my = {}; 
     $scope.my.cf = crossfilter(); 
     $scope.my.dimension = $scope.my.cf.dimension(function(d){ return d.key; }) 
     $scope.my.group = $scope.my.dimension.group().reduceSum(function(d){ return d.value; }) 

それからちょうどCrossfilterでデータを切り替えるために、あなたの更新機能を変更する:あなたはdc.jsフィルターあなたがこれを行うとき、Tを維持したい場合は

$scope.factoryBuildPieExample = function(data) { 
    $scope.my.cf.remove() 
    $scope.my.cf.add(data.response.data) 
    dc.redrawAll(); 
    } 

彼の質問/回答は方法について説明します。ここではUpdating dc.js data and reapplying original filters

は作業Plunkerです:http://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p=preview

+0

すごいです!エタンにもう一度感謝します。これは実際に私が散布図について昨日尋ねたフィルター問題の根底にあったものでした。ヘルプマンを感謝しなさい! – Justin

+0

Ethan、私は更新機能の中でこれを実装した後、データを渡しています。それを慰め、すべてがあり、次にcf.remove、次にcf.addと私は応答配列の最初のオブジェクトを取得しています?何か案は? – Justin

+0

私は、チャート自体のレンダレットクリックから呼び出す必要があることを言及する必要があります。チャート上の選択は(理想的には)保持され、コールバックにはフィルタリングを疑似するためのパラメータが含まれています。 – Justin

関連する問題