2017-03-17 9 views
0

私はいくつかのGoogle Chartsタイムラインを描画するアプリケーションを構築しようとしています。タイムラインを埋めるために使用されるデータはJSONファイルから取り出されます。かなり大きいものもあります。私のテストデータの中で最大のものは約30MBです。Google charts draw()performance

Google Chartsのドキュメントによると、chart.draw(table, options)は非同期です。しかし、それはそうではないようです。データを読み込んでチャートを描画すると、最後のチャートが描画プロセスを完了するまでロックされます。

// several times, call: 
google.charts.load('current', { 
    packages: ['timeline'], 
    callback: this.layoutTimelineFor_(
    container, 
    this.data[group], 
    group), 
    }); 

// ... 

layoutTimelineFor_: function(container, timeline, group) { 
    return() => { 
    const chart = new google.visualization.Timeline(container); 
    const table = this.mapTimelineToDataTable_(timeline, group); 

    // ... 

    const options = { 
     backgroundColor: 'transparent', 
     height: document.documentDelement.clientHeight/2 - 50, 
     width: (container.parentElement || container) 
     .getBoundingClientRect().width, 
     forceIFrame: true, 
     timeline: { 
     singleColor: '#d5ddf6', 
     }, 
     tooltip: { 
     trigger: 'none', 
     }, 
     hAxis: { 
     minValue: 0, 
     }, 
    }; 

    if (this.duration > 0) { 
     options.hAxis.format = this.pickTimeFormat_(this.duration); 
     options.hAxis.maxValue = this.duration; 
     const p1 = performance.now(); 
     chart.draw(table, options); 
     const p2 = performance.now(); 
     console.log(`${group} chart.draw(table, options) took ${p2-p1}ms`); 
    } else { 
     this.chartQueue_.push({chart, table, options, group}); 
    } 
    } 
} 

// ... 

durationChanged: function() { 
    while (this.chartQueue_.length) { 
    const data = this.chartQueue_.shift(); 
    data.options.hAxis.format = this.pickTimeFormat_(this.duration); 
    data.options.hAxis.maxValue = this.duration; 
    const p1 = performance.now(); 
    data.chart.draw(data.table, data.options); 
    const p2 = performance.now(); 
    console.log(`${data.group} chart.draw(table, options) took ${p2-p1}ms`); 
    } 
} 

私の二タイマーの出力は、これらの線に沿って何かである:

label chart.draw(table, options) took 154.26999999999998ms 
shot chart.draw(table, options) took 141.98500000000013ms 
face chart.draw(table, options) took 1601.9849999999997ms 
person chart.draw(table, options) took 13932.140000000001ms 

これらの数値は、各タイムラインチャートのデータとして使用されるJSONの大きさにほぼ比例します。 (注:上記の数値は最大ではなく、〜20MBのテストデータから来ています)

私のアプリケーションを296msにロックするのは残念ですが、問題ありません。まあ、ほとんどのユーザーはおそらく1.9秒遅れに気づかないでしょう。 15.8秒は受け入れられません。そして、まだ、Google's guideは言う:

draw()方法は非同期です:つまり、それはすぐに戻りますが、それが返すことのインスタンスは、すぐに使用できない場合があります。

drawは、ドキュメントの主張と同じように、非同期で実行する方法がありますか?

+1

「〜20MB」のデータを尋ねるだけでは単純な統計図ではあまりにも正確ではないでしょうか?おそらく、タイムウィンドウを狭めるか、精度を1秒から2秒にカットすると、50%小さくなり、50%速くレンダリングされるはずです。どちらの場合でも、 'async'コールは依然としてブラウザの移植に大きく依存しています。 ChromeとFirefoxの両方が他の結果を表示します。 @WhiteHat、ありがとうございます。 – Xorifelse

+0

私は以前のバージョンのコードでこれを一度だけ呼び出すと思いました。しかし、単一のload()呼び出しに戻っても問題は解決されません。 –

+0

@ Xorifelseでは、データはページ上の他の場所に表示されているビデオに対応しています。最大のJSONファイルは、10fpsで動作するビデオに基づいて生成されました。上記の13932.14msの数字は、「{"id": "4574491"、 "注釈":{"人":[... 26661オブジェクト]}}の一般的な構造のファイルから来ています。 ' –

答えて

0

さらに調査した結果、チャートの実際ののみが非同期であるように見えます。描画が始まる前に、データは(同期的な)処理ステップを経て、問題が発生します。私のように大きなデータセットを持つタイムラインチャートの解決策はありません。

コアチャート(エリア、バー、バブル、キャンドル、柱、コンボ、ヒストグラム、ライン、パイ、散布、段差エリア)チャンクにこの処理ステップを壊すallowAsyncオプションas of version 41を持っているプロセス全体ができるように、 (それぞれのチャンクはできませんが)中断されます。残念ながら、タイムラインはコアチャートではなく、このオプションはありません。