2013年10月14日月曜日

Multiple Dygraph in Twitter Bootstrap based Tab

This post is a response to "Multiple Dygraph is not working in Twitter bootstrap based Tab !"

Bootstrap の tab に dygraph.js でグラフを描画している時に、「タブを切り替えるとグラフが正しく描画されない」という問題があります。より正確に言えば、「初期状態で非表示の領域にグラフを描画すると問題がおきる」でしょうか。

参考:Issue 238 - dygraphs - Canvas & container div have zero height and width when parent is invisible.

対策としてはリンク先でも述べられている通り、グラフが格納された div 要素が表示されたら、 Dygraph インスタンスの .resize() メソッドを実行すれば表示はされます。ただし、高さと幅が初期値に固定されてしまいます。これを防ぐために、描画領域の要素から style プロパティを削除しています。

Demo

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="jquery-2.0.3.min.js"></script>
  <!-- Bootstrap -->
  <script src="tab.js"></script>
  <link href="bootstrap.min.css" rel="stylesheet" media="screen">
  <!-- Dygraphs -->
  <script src="dygraph-combined.js"></script>
  <!-- CSS for resizable graph -->
  <style>
    .dygraph-wrapper {
      position: relative;
      height: 300px;
    }
    .dygraph-target {
      position: absolute;
      top: 20px;
      left: 0px;
      bottom: 50px;
      right: 20px;
    }
  </style>
</head>

<body>

  <div class="container">
    <ul class="nav nav-tabs">
      <li class="active"><a href="#tab1">tab1</a></li>
      <li><a href="#tab2">tab2</a></li>
    </ul>
    <div class="tab-content">
      <div class="tab-pane active" id="tab1">
        <div class="dygraph-wrapper">
          <div class="dygraph-target"></div>
        </div>
      </div>
      <div class="tab-pane" id="tab2">
        <div class="dygraph-wrapper">
          <div class="dygraph-target"></div>
        </div>
      </div>
    </div>
  </div>

  <script>
    // list of dygraph object
    var graphs = [];
    $(document).ready(function() {
      $(".nav-tabs a").click(function(event) {
        event.preventDefault();
        $(this).tab('show');
        var target_id = $(this).attr("href");
        // clear the default style properties.
        $(target_id).find(".dygraph-target").removeAttr("style");
        graphs[target_id].resize();
      });
      $(".dygraph-target").each(function() {
        var random_data = [];
        for (i = 0; i < 10; i++) {
          random_data.push([
            new Date(2013, 9, i + 1),
            Math.random()
          ]);
        }
        g = new Dygraph($(this)[0], random_data);
        // append the dygraph object to the list
        graphs["#" + $(this).parents(".tab-pane").attr("id")] = g;
      });
    });
  </script>

</body>
</html>

0 件のコメント:

コメントを投稿