2017-07-11 13 views
1

私は統計的な計算を行い、後で結果のデータをD3.jsで表示するアプリケーションに取り組んでいます。重度の計算とUIをブロックせずにデータを表示

ほとんどの場合、実際の計算をWebWorkerに渡すことで、UIをブロックすることを避けることができます。

計算が完了した後、データポイントはとソートとなり、d3.jsで表示されます。ワーカー自身がDOMとやりとりすることはできないが、WebWorker内のDOM要素で作業するのは厄介です(though possible)。それでも私は本当にそれを避けたいと思います。

データポイントが約100万個あり、これをソートしてd3で表示するとします。 jsがこのタスクを実行するときに、UIがフリーズしないようにするにはどうすればよいですか?

一部に作品のアイデアは、延長:

D3コードは次のようになります。

d3.select ... 
.sort ... 
.enter ... 
.attr ... 
.attr ... 
.style ... 

これは、すべてを一度に実行されます。 render queueにあなたができるものの間でこのような何かでレンダリングする機会を与えるために:データのD3操作の最初の部分は、コールバックキューにプッシュされます

let prom = new Promise((re, rj) => { 
      setTimeout(function() { 
       let val = d3.select ... 
          .sort ... 
          .enter ... 
       re(val);    
       }, 0); 
     }); 

prom.then(val => { 
    val = val.attr ... 
      .attr ... 
      .style ... 
}); 

を、レンダリングキューはする機会を持っています次にd3コードの次の部分が実行されます(複数の約束が可能なより複雑なモデル)。それでもこのは問題を解決しません。一度にすべてを実行するよりも若干良いかもしれませんが、単一のパーツ自体が長すぎる場合、UIはフリーズします。

誰でもこの問題の良い解決策を知っていますか?

+1

結果を20,000の50バッチにバッチ処理できますか? – Archer

+0

@Archer既にそれについて考えました。これは通常は良いアイデアですが、状況によってはそれが許されません。私はすべての(1 Mio)データポイントを並べ替えて1つのチャートに表示したい場合があります。 – User12547645

+1

WebWorkerでそれらを(バッチで)返す前にソートできないので、その特定の問題を解決できますか? – Archer

答えて

1

問題は、すべてのバーを表すためにDom要素を追加する必要があるSVGを使用していることです。重い処理を行うWebワーカーを使用していても、何千ものDom要素を追加したり、画像を計算したり、絵を描くことでメインスレッドがロックされます。

代わりにキャンバスを使用すると、多量のDom要素の問題はなく、GPUでもっと機能します。 D3 V4はキャンバスをサポートしていますが、動作させるには再設計が必要です。また、徐々にレンダリングさせることもできます。トリッキーなビットは、リスナーをアタッチする個々の要素がないため、相互作用を追加することになります。

+0

ヒントありがとうございました。私はそれを試みます – User12547645

0

elliotが既に指摘しているように、D3は非常に多くの要素をDOMに追加するという問題があります。メインスレッドをブロックしないようにするには、提案のようにデータをチャンクで描画することが可能ですhere

私はまだ最初にソートする必要があります。

関連する問題