最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Plotly chart height resize when using tabs - Stack Overflow

programmeradmin1浏览0评论

I'm using Plotly library to create charts of my data. The issue that I'm encountering with is that when I tried to separate them in different tabs it's not resizing as it's suppose to do (just with the height, width is OK) except for the chart of the first tab, which works OK.

In my index.html I have the following structure:

<script type="text/javascript" src="{{STATIC_URL}}myindex.js"></script>

<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#var1">Var 1</a></li>
  <li><a data-toggle="tab" href="#var2">Var 2</a></li>
</ul>

<div class="tab-content">
  <div id="var1" class="tab-pane fade in active">

    <div class="thumbnail parent_container" style="margin-top: 100px;">
      <div class="thumbnail text-center chart">
          <div id="chart1">
          </div>
      </div>
      ...
    </div>

  </div>

  <div id="var2" class="tab-pane fade">

    <div class="thumbnail parent_container" style="margin-top: 100px;">
      <div class="thumbnail text-center chart">
          <div id="chart2">
          </div>
      </div>
      ...
    </div>

  </div>
</div>

And myindex.js part that has to create the chart looks like this:

$( document ).ready(function()
{
  "use strict";  

  var WIDTH_IN_PERCENT_OF_PARENT = 96;
  var HEIGHT_IN_PERCENT_OF_PARENT = 80;

  var chart1 = d3.select('div#chart1')
    .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT)/2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + '%'
    });

  var chart2 = d3.select('div#chart2')
    .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT)/2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + '%'
    });

  var chart1_node = chart1.node();
  var chart2_node = chart2.node();

  var time_Array = [];
  var var1_value = [];
  var var2_value = [];

  var data_var1 = [{
    x: time_Array,
    y: var1_value,
    ...
  }];

  var data_var2 = [{
    x: time_Array,
    y: var2_value,
    ...
  }];

  var layout_var1 = {
    xaxis: {...},
    yaxis: {...}
  };

  var layout_var2 = {
    xaxis: {...},
    yaxis: {...}
  };

  Plotly.plot(chart1_node, data_var1, layout_var1);
  Plotly.plot(chart2_node, data_var2, layout_var2);

  ...
});

I'm sure that it's having some issue with the tabs because when I first putted it all together it worked as a charm. I think that since they are being created since the beginning $( document ).ready(function()...) it's not giving the right height to the second chart. (The chart of the first tab resizes just fine.)

Right now I'm having trouble to found a reliable solution, so thanks in advance.

EDIT 1:

Well, I got it working in jsfiddle plotly working with tabs, so now I have even more doubts why it's not working. I'm using DJango 1.9.2.

I'm using Plotly library to create charts of my data. The issue that I'm encountering with is that when I tried to separate them in different tabs it's not resizing as it's suppose to do (just with the height, width is OK) except for the chart of the first tab, which works OK.

In my index.html I have the following structure:

<script type="text/javascript" src="{{STATIC_URL}}myindex.js"></script>

<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#var1">Var 1</a></li>
  <li><a data-toggle="tab" href="#var2">Var 2</a></li>
</ul>

<div class="tab-content">
  <div id="var1" class="tab-pane fade in active">

    <div class="thumbnail parent_container" style="margin-top: 100px;">
      <div class="thumbnail text-center chart">
          <div id="chart1">
          </div>
      </div>
      ...
    </div>

  </div>

  <div id="var2" class="tab-pane fade">

    <div class="thumbnail parent_container" style="margin-top: 100px;">
      <div class="thumbnail text-center chart">
          <div id="chart2">
          </div>
      </div>
      ...
    </div>

  </div>
</div>

And myindex.js part that has to create the chart looks like this:

$( document ).ready(function()
{
  "use strict";  

  var WIDTH_IN_PERCENT_OF_PARENT = 96;
  var HEIGHT_IN_PERCENT_OF_PARENT = 80;

  var chart1 = d3.select('div#chart1')
    .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT)/2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + '%'
    });

  var chart2 = d3.select('div#chart2')
    .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT)/2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + '%'
    });

  var chart1_node = chart1.node();
  var chart2_node = chart2.node();

  var time_Array = [];
  var var1_value = [];
  var var2_value = [];

  var data_var1 = [{
    x: time_Array,
    y: var1_value,
    ...
  }];

  var data_var2 = [{
    x: time_Array,
    y: var2_value,
    ...
  }];

  var layout_var1 = {
    xaxis: {...},
    yaxis: {...}
  };

  var layout_var2 = {
    xaxis: {...},
    yaxis: {...}
  };

  Plotly.plot(chart1_node, data_var1, layout_var1);
  Plotly.plot(chart2_node, data_var2, layout_var2);

  ...
});

I'm sure that it's having some issue with the tabs because when I first putted it all together it worked as a charm. I think that since they are being created since the beginning $( document ).ready(function()...) it's not giving the right height to the second chart. (The chart of the first tab resizes just fine.)

Right now I'm having trouble to found a reliable solution, so thanks in advance.

EDIT 1:

Well, I got it working in jsfiddle plotly working with tabs, so now I have even more doubts why it's not working. I'm using DJango 1.9.2.

Share Improve this question edited Feb 9, 2016 at 22:12 rxmxn asked Feb 9, 2016 at 16:51 rxmxnrxmxn 4991 gold badge5 silver badges18 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

I use Plotly with Django and had a similar issue using Bootstrap tabs. When the page is loaded only currently active tab's plots autosized correctly. So my workaround was to use shown.bs.tab event to trigger rerendering of each corresponding graph. The Plotly.Plots.resize or Plotly.relayout(item, {autosize: true}) will do the trick

$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (event) {
    var doc = $(".tab-pane.active .plotly-graph-div");
    for (var i = 0; i < doc.length; i++) {
        Plotly.relayout(doc[i], {autosize: true});
    }
})

Works with the latest versions of Edge, Google Chrome and IE11

It's a year ago, but people may look for this - like I did.

(function() {
        var d3 = Plotly.d3;

        // .content is the class of the parent element.
        // So I take the size from there
        var contentInnerWidth = $('.content').innerWidth();
        var contentInnerHeight = $('.content').innerHeight();

        /* I am selecting the parent element and it has a child 
           element with the class .tab.content, where I append a new 
           div with an id (to call it from the tab-menu), it gets the 
           necessary classes and the width and height of its parent 
           element */
        var gd3 = d3.select('.content').selectAll('div.tab-content')
            .append('div')
            .attr('id', 'durationDateArea')
            .attr('class', 'tab-pane fade')
            .style({
                width: contentInnerWidth + 'px',
                height: contentInnerHeight + 'px'
            });

        // Building a graph
        var gd = gd3.node();

        Plotly.plot(gd, [{
            type: 'bar',
            x: [1, 2, 3, 4],
            y: [5, 10, 2, 8],
            marker: {
                color: '#C8A2C8',
                line: {
                    width: 2.5
                }
            }
        }], {
            title: 'Auto-Resize',
            font: {
                size: 16
            }
        });

        // I encountered some problems with the autoresize of Plotly
        // This is my fix for it
        $(window).resize(function() {

            // Getting the height of the window
            var windowheight = $(window).height();

            // Apply window height to .content
            $(".content").css({
                "height": windowheight + "px"
            });

            // Getting the width of .content
            var contentInnerWidth = $('.content').innerWidth();

            // Apply width and height to two divs that are created by 
            // Plotly. Fixed some issueswith hidden overfull elements.
            $(".js-plotly-plot").css({
                "width": contentInnerWidth + "px",
                "height": windowheight + "px"
            });
            $(".plotly").css({
                "width": contentInnerWidth + "px",
                "height": windowheight + "px"
            });

            // Applying width and height to a new variable for Plotly
            var update = {
                width: contentInnerWidth,
                height: windowheight
            };
            // Using Plotly's relayout-function with graph-name and 
            // the variable with the new height and width
            Plotly.relayout(gd, update);
        });

The structure of the html file is:

<div class="content">
    <ul class="nav nav-tabs" role="tablist">
        <!-- Navigation Tab Items. All Tabs have to be in here. -->
        <li class="nav-item active">
            <a class="nav-link" data-toggle="tab" href="#durationDateLine">
                <i class="fa fa-line-chart" aria-hidden="true"></i> Line Chart
            </a>
        </li>
        <li class="nav-item">
            <a class="nav-link" data-toggle="tab" href="#durationDateArea">
                <i class="fa fa-area-chart" aria-hidden="true"></i> Area Chart
            </a>
        </li>

    </ul>
    <!-- Element where the charts will be shown and the JS-file may append the divs to. -->
    <div class="tab-content">
        <div id="durationDateLine" class="tab-pane fade in active"></div>
    </div>
</div>
发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>