Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NVD3 Charts not rendering correctly in hidden tab

I am building a page which contains many charts, which are displayed one at a time depending on which tab you are looking at.

The chart in the initially active tab renders correctly. However when I click to another tab, the chart is not rendered properly.

Presumably this is because the hidden field does not have dimensions until it is made visible. In fact if I resize the window the chart will correct it's proportions, and render so that it fills the available width.

I can fix this problem by explicitly defining the chart size via css, but this defeats the responsive aspect of the charts.

Can anyone tell me how to trigger the same NVD3 event which gets activated when the window resizes? That way I can bind it to the selection of a new tab, and hopefully remedy the rendering issue.

like image 745
metaColin Avatar asked Feb 04 '14 21:02

metaColin


3 Answers

I had the same issue (charts on multiple tabs), and this is the only thing that I could get to work.

$(function () {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
        window.dispatchEvent(new Event('resize'));
    });
});

I have a feeling, however, that all of the charts are being re-rendered, regardless of whether they are on the active tab (visible) or in the non-selected tabs (hidden).

Does anyone know how to ensure ONLY the active chart gets resized / redrawn?

like image 123
Nicholas Hamilton Avatar answered Sep 18 '22 09:09

Nicholas Hamilton


I figured out how to trigger the resize event I needed. In my case the tabs are driven by bootstrap. So I simply modified my bootstrap show tab event to trigger a page resize event as well. It's a little indirect, but it gets the job done:

jQuery('#myTab a').click(function (e) {
    e.preventDefault()
    jQuery(this).tab('show')
    jQuery(window).trigger('resize'); // Added this line to force NVD3 to redraw the chart
})
like image 20
metaColin Avatar answered Sep 18 '22 09:09

metaColin


Just add this JavaScript:

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  window.dispatchEvent(new Event('resize'));
})

hidden.bs.tab is the event that fires after a new tab is shown as per the Bootstrap docs. This code fires a resize event after each tab change.

like image 8
nostromo Avatar answered Sep 19 '22 09:09

nostromo