LoginSignup
4
2

More than 5 years have passed since last update.

C3.jsのline-chartをiOSで使ったら重かった(解決済み)

Last updated at Posted at 2017-11-23

C3.jsというチャート描画ライブラリのline-chartについての記事です。

C3.jsとは

C3.jsはjavascriptでチャートを作成できるライブラリです。色々なチャートを描画することが出来るので大変便利です。今回はこの中のline-chartについてです。

現象

C3.jsのline-chartをつかって300point位のデータを20本並べたline-chartを描くWebPageを作成していました。再現プログラムを切り出したので、下のサンプルプログラムのデータは乱数で生成しています。
c3-graph.jpg

MacのSafariやChromeでは問題なく動いていたのですが、同じページをiOSの端末からアクセスすると異常に動作が遅く、たまに落ちてしまう現象が発生しました。
最初はデータの転送量が多くて中々反応していないのかと考えたり、iOSのjavascriptで扱うにはデータが多すぎるのかと考えていたのですが、どうも違ったようです。

c3-sample.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js" charset="utf-8"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.min.js"></script>
  </head>

  <body>
    <div id="chart"></div>
  </body>

  <script>
    const chartObj = {
      bindto: '#chart',
      size: { width: 1280, height: 600 },
      point: { show: false },
      tooltip: { show: false },
      data: {
        columns: [],
      },
    };
    for(let i = 0; i < 20; i++) {
      chartObj.data.columns[i] = ['data' + i];
      for(let j = 0; j < 300; j++) {
        let d = Math.random() * 100;
        if(j == 0) {
          chartObj.data.columns[i].push(d);
        } else {
          d = chartObj.data.columns[i][j] + (d / 10 - 5);
          if(d < 0) d = 0;
          if(d > 100) d = 100;
          chartObj.data.columns[i].push(d);
        }
      }
    }
    c3.generate(chartObj);
  </script>
</html>

問題点

Safariのinspectorで中身を見てみたところ、c3.jsのチャートはsvgで描画されているようですので更にその中を見ていくと
<g class="c3-chart-lines">の下に
<g class="c3-chart-line c3-target c3-target-data0">から順に20本のlineがあります。
更にその中を見てみると
<g class=" c3-shapes c3-shapes-data0 c3-lines c3-lines-data0">があり、こちらがline-chartの線を引いているデータです。
ここまでは全く問題ありません。
この次に出てくるのが
<g class=" c3-shapes c3-shapes-data0 c3-circles c3-circles-data0" style="cursor: pointer;">
なのですが、中身は
<circle class="c3-shape c3-shape-0 c3-circle c3-circle-0" r="2.5" cx="13" cy="467.5179823348915" style="fill: rgb(31, 119, 180); opacity: 0;">がline-chartのポイントの分全て存在しています。
20x300=6000個のcircleを描画しているので重たいようでした。
勿論そんなにline-chartにpointを表示させると画面がbusyなので消す設定にしているのですが、point: { show: false },がどこに効いているかというとopacity: 0;の部分みたいです。

解決策

結局のところ、画像などに比べてデータの量としては問題になる大きさではないのでcircleを描画させなければいいと考えて、下記のstyleをcssに追加しました。

.c3-circles {
  display: none;
}

これでグラフのスクロールや描画がサクサクと動くようになりました。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2