2016-12-20 12 views
0

私は、d3の力向グラフを描くためにangularjs指示文を作成しました。このグラフは、新しいノードとリンクで定期的に更新されます。2つの配列が更新されたときのanglejsコールウォッチ

最近、私は、グラフが更新されると、2倍の時間がかかる再描画されていることに気付きました。その部分は、最初にノード配列を更新し、次にエッジ配列を更新し、それぞれが再描画をトリガーする必要があるためです。私は両方が更新された後に呼び出されるようにしたいと思います。

私はOR関係のために時計に対処する方法についての質問をたくさん見てきましたが、は、私は、具体的にのみANDのリンクが更新された両方のノードの後に​​起こることを再描画します。ここで

は私の現在のディレクティブではありません:

graphs.directive('myGraph', [function() { 

    function renderGraph(scope, elem) { 

     drawGraph(scope.data, scope.data.params || {}, elem); 

     scope.$watchCollection('data', function (newData) { 
      drawGraph(newData, scope.data.params || {}, elem); 
     }); 
    } 

    function drawGraph(data, params, elem) { 

     const rawSvg = elem.find(".svg")[0]; 

     forceDirectedGraph.create(data.nodes, data.links, data.nodeTypes, rawSvg, params); 
    } 

    return { 
     scope: { 
      data: '=' 
     }, 
     templateUrl: 'graph.html', 
     link: renderGraph 
    } 
}]); 

そして、ここでは、私は、グラフを更新する方法である:

//initialization code: 
$scope.graph = { links:[], nodes:[], params:{ /*stuff*/} } 

//graph update code: 
$http.get(url).then(function(response) { 
    links = []; 
    nodes = []; 

    //process and format links and nodes for d3 from request 

    $scope.graph.links = links; 
    $scope.graph.nodes = nodes; 

}); 

答えて

2

いくつかのオプションが頭に浮かぶ、偉大それらのどれも - 私は思いますが、 #1に向かって傾ける。彼らはあなたの特定のためにどのように理想的なことを確認していないが必要です。

オプション1

shouldRedraw呼ばdataオブジェクトに新しいプロパティを追加します。 $ http.get successコールバックの先頭にfalseを設定します。データの更新が完了したら、trueに設定します。設定した場合、$ウォッチでは、唯一の再描画:

//initialization code: 
$scope.graph = { links:[], nodes:[], shouldRedraw:true, params:{ /*stuff*/} } 

//graph update code: 
$http.get(url).then(function(response) { 
    $scope.graph.shouldRedraw = false; 

    links = []; 
    nodes = []; 

    //process and format links and nodes for d3 from request 

    $scope.graph.links = links; 
    $scope.graph.nodes = nodes; 
    $scope.graph.shouldRedraw = true; 
}); 

// the watch 
scope.$watchCollection('data', function (newData) { 
    if (newData.shouldRedraw === true) { 
     drawGraph(newData, scope.data.params || {}, elem); 
    } 
}); 

オプション2

は別々のスコープ入力としてlinksnodesparams値を受け入れるためにあなたのmyGraphディレクティブを更新します。そして$はlinksnodesの変数を見ます。フラグがisStagedForRedrawの場合、デフォルトはfalseになります。いずれに設定されるフラグをトリガし、第二の設定を解除さ再描画フラグをトリガする、第一links又はnodesに更新される:3

持ち

var isStagedForRedraw = false; 

scope.$watchGroup(['links', 'nodes'], function (newValues, oldValues, scope) { 
    if (isStagedForRedraw) { 
     drawGraph({links:scope.links, nodes:scope.nodes}, scope.data.params || {}, elem); 
     isStagedForRedraw = false; 
    } else { 
     isStagedForRedraw = true; 
    } 
}); 

オプションディレクティブはdataオブジェクトを追跡しますが、data.linksおよびdata.nodes値のJSONified値も保持します。時計では、新しい値data.linksdata.nodesをJSON化します。両方が変更された場合は、追跡されたJSONified値を再描画して更新します。 1つだけ変更された場合は、何もしないでください。

+0

ありがとうございます!これまでの結果:オプション2は、最初にページをリフレッシュしたときにグラフを表示するのが好きではなく、その後のナビゲーションで表示されます。 オプション1は私がこれまで行っていることです。しかし、ページから離れてナビゲートすると、それでも2倍の描画が行われます(ただし、他の場合(ページは開いたままで、要求と初期ページの読み込みからグラフが更新されます)。進捗。 – adeady

+0

これは、(1)グラフオブジェクトを最初に初期化するときに 'shouldRedraw'をtrueにデフォルト設定し、(2)時計を作成する前に明示的にグラフを描画しているためです。 2回描画しないようにするには、デフォルトの 'shouldRedraw'をfalseに設定するだけです: ' $ scope.graph = {links:[]、nodes:[]、shouldRedraw:false、params:{/ * stuff * /}} ; – GPicazo

+0

スコープオブジェクトを作成するときに 'draw'をプリエンプティブにfalseに設定しました。そうしなければ100%右側になります。 楽しいために時計の外でdrawGraphステートメントを取り出しました。私は前にそれが必要だったと思うが、今はない。どうもありがとう! – adeady

関連する問題