Flot graph does not render when parent container is hidden
Asked Answered
S

5

11

I was having an issue where a flot graph would not render in a tabbed interface because the placeholder divs were children of divs with 'display: none'. The axes would be displayed, but no graph content.

I wrote the javascript function below as a wrapper for the plot function in order to solve this issue. It might be useful for others doing something similar.

function safePlot(placeholderDiv, data, options){

    // Move the graph place holder to the hidden loader
    // div to render
    var parentContainer = placeholderDiv.parent();
    $('#graphLoaderDiv').append(placeholderDiv);

    // Render the graph
    $.plot(placeholderDiv, data, options);

    // Move the graph back to it's original parent
    // container
    parentContainer.append(placeholderDiv);
}

Here is the CSS for the graph loader div which can be placed anywhere on the page.

#graphLoaderDiv{
    visibility: hidden;
    position: absolute;
    top: 0px;
    left: 0px;
    width: 500px;
    height: 150px;
}
Samadhi answered 25/3, 2011 at 1:50 Comment(0)
A
8

Perhaps this is better solution. It can be used as a drop in replacement for $.plot():

var fplot = function(e,data,options){
  var jqParent, jqHidden;
  if (e.offsetWidth <=0 || e.offetHeight <=0){
    // lets attempt to compensate for an ancestor with display:none
    jqParent = $(e).parent();
    jqHidden = $("<div style='visibility:hidden'></div>");
    $('body').append(jqHidden);
    jqHidden.append(e);
  }

  var plot=$.plot(e,data,options);

  // if we moved it above, lets put it back
  if (jqParent){
     jqParent.append(e);
     jqHidden.remove();
  }

  return plot;
};

Then just take your call to $.plot() and change it to fplot()

Agatha answered 7/11, 2012 at 17:43 Comment(0)
S
2

The only thing that works without any CSS trick is to load the plot 1 second after like this:

$('#myTab a[href="#tabname"]').on("click", function() {
    setTimeout(function() {
       $.plot($(divChartArea), data, options);       
    }, 1000);
});

or for older jquery

$('#myTab a[href="#tabname"]').click (function() {
      setTimeout(function() {
         $.plot($(divChartArea), data, options);       
      }, 1000);
    });

The above example is applied to Bootstrap tags for Click funtion. But should work for any hidden div or object.

Working example: http://topg.org/server-desteria-factions-levels-classes-tokens-id388539 Just click the "Players" tab and you'll see the above example in action.

Spiritual answered 27/9, 2014 at 2:40 Comment(0)
A
1

This one is a FAQ:

Your #graphLoaderDiv must have a width and height, and unfortunately, invisible divs do not have them. Instead, make it visible, but set its left to -10000px. Then once you are ready to show it, just set it's left to 0px (or whatever).

Advisory answered 25/3, 2011 at 15:36 Comment(3)
Divs with visibility:hidden do actually have dimensions, it is divs with display:none which do not.Samadhi
if its a child of a display:none div, then it wouldn't would it?Advisory
Right, children of a display:none div won't have dimensions available for Flot to use for rendering the graph, in IE for sure. That is the problem this invisible loading div is used to solve because it is placed at a top level outside outside of any container divs.Samadhi
A
0

OK, I understand better now what you're actually saying... I still think your answer is too complicated though. I just tried this out using a tabbed interface where the graph is in a hidden tab when it's loaded. It seems to work fine for me.

http://jsfiddle.net/ryleyb/dB8UZ/

I didn't have the visibility:hidden bit in there, but it didn't seem necessary...

You could also have visibility:hidden set and then change the tabs code to something like this:

$('#tabs').tabs({
  show: function(e,ui){
    if (ui.index != 2) { return; }
    $('#graphLoaderDiv').css('visibility','visible');
  }
});

But given the information provided, none of that seems particularly necessary.

Advisory answered 26/3, 2011 at 23:11 Comment(2)
This was mainly an issue I saw in IE and made a general solution for. If you try your example in IE8, you'll probably see the same issue. First you'd have to use excanvas.js to even get it rendering in IE though.Samadhi
Seems to work fine in IE7/9 for me once I add excanvas: jsfiddle.net/dB8UZ/1Advisory
A
0

I know this is a bit old but you can also try using the Resize plugin for Flot.

http://benalman.com/projects/jquery-resize-plugin/

It is not perfect because you'll sometimes get a flash of the non-sized graph which may be shrunk. Also some formatting and positioning may be off depending on the type of graph that you are using.

Anticlockwise answered 6/4, 2016 at 23:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.