Tuesday, July 16, 2013

Getting JqPlot to work inside a JQuery UI Tab

Jqplot is a very simple jquery-based plotting library for displaying simple plotting charts on html page, however, having a jqplot <div> in a jquery ui container such as tab and not having it displayed as default (e.g. having the jqplot as the second tab page instead of the default first tab page), the jqplot <div> will not display any plot. For example the following code will not work for the jqplot:

<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery-ui/themes/base/jquery.ui.all.css">
<link rel="stylesheet" type="text/css" href="jquery-ui/demos.css">
<link rel="stylesheet" type="text/css" href="jqplot/jquery.jqplot.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="jqplot/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pointLabels.min.js"></script>
<script src="jquery-ui/ui/jquery.ui.core.js"></script>
<script src="jquery-ui/ui/jquery.ui.widget.js"></script>
<script src="jquery-ui/ui/jquery.ui.tabs.js"></script>
<script type="text/javascript">
$(function(){
$( "#tabs" ).tabs();

    var s1 = [1, 2, 3];
    // Can specify a custom tick Array.
    // Ticks should match up one for each y value (category) in the series.
    var ticks = ["Val1", "Val2", "Val3"];
     
    var plot1 = $.jqplot('chart1', [s1], {
        // The "seriesDefaults" option is an options object that will
        // be applied to all series in the chart.
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {fillToZero: true}
        },
        // Custom labels for the series are specified with the "label"
        // option on the series option.  Here a series option object
        // is specified for each series.
        series:[
            {label:'Search Query'}
        ],
        // Show the legend and put it outside the grid, but inside the
        // plot container, shrinking the grid to accomodate the legend.
        // A value of "outside" would not shrink the grid and allow
        // the legend to overflow the container.
        legend: {
            show: true,
            placement: 'outsideGrid'
        },
        axes: {
            // Use a category axis on the x axis and use our custom ticks.
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            },
            // Pad the y axis just a little so bars can get close to, but
            // not touch, the grid boundaries.  1.2 is the default padding.
            yaxis: {
                pad: 1.05,
                tickOptions: {formatString: '%d'}
            }
        }
    });
var s2 = [["Val1":1], ["Val2":2], ["Val3":3]];
         
    var plot2 = $.jqplot('pie', [s2], {
        grid: {
            drawBorder: false, 
            drawGridlines: false,
            background: '#ffffff',
            shadow:false
        },
        axesDefaults: {
             
        },
        seriesDefaults:{
            renderer:$.jqplot.PieRenderer,
            rendererOptions: {
                showDataLabels: true
            }
        },
        legend: {
            show: true,
            rendererOptions: {
                numberRows: 1
            },
            location: 's'
        }
    }); 
$('#tabs').bind('tabsshow', function(event, ui) {
 if (ui.index === 1 && plot1._drawCount === 0) {
plot1.replot();
 }
 else if (ui.index === 2 && plot2._drawCount === 0) {
plot2.replot();
 }
});

});
</script>
</head>
<body>
<div id="tabs" style="min-height:500px">
<ul>
<li><a href="#tabs-1">Tabular Data</a></li>
<li><a href="#tabs-2">Histogram</a></li>
<li><a href="#tabs-3">Pie Chart</a></li>
</ul>
       <div id="tabs-1">
First Tab Page
</div>
<div id="tabs-2">
<div id="chart1" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
<div id="tabs-3">
<div id="pie" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
</div>
</body>
</html>

The solution is to call the jqplot element's replot() method when a tab page is selected by adding the highlighted section shown below:

<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery-ui/themes/base/jquery.ui.all.css">
<link rel="stylesheet" type="text/css" href="jquery-ui/demos.css">
<link rel="stylesheet" type="text/css" href="jqplot/jquery.jqplot.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="jqplot/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pointLabels.min.js"></script>
<script src="jquery-ui/ui/jquery.ui.core.js"></script>
<script src="jquery-ui/ui/jquery.ui.widget.js"></script>
<script src="jquery-ui/ui/jquery.ui.tabs.js"></script>
<script type="text/javascript">
$(function(){
$( "#tabs" ).tabs();

    var s1 = [1, 2, 3];
    // Can specify a custom tick Array.
    // Ticks should match up one for each y value (category) in the series.
    var ticks = ["Val1", "Val2", "Val3"];
     
    var plot1 = $.jqplot('chart1', [s1], {
        // The "seriesDefaults" option is an options object that will
        // be applied to all series in the chart.
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {fillToZero: true}
        },
        // Custom labels for the series are specified with the "label"
        // option on the series option.  Here a series option object
        // is specified for each series.
        series:[
            {label:'Search Query'}
        ],
        // Show the legend and put it outside the grid, but inside the
        // plot container, shrinking the grid to accomodate the legend.
        // A value of "outside" would not shrink the grid and allow
        // the legend to overflow the container.
        legend: {
            show: true,
            placement: 'outsideGrid'
        },
        axes: {
            // Use a category axis on the x axis and use our custom ticks.
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            },
            // Pad the y axis just a little so bars can get close to, but
            // not touch, the grid boundaries.  1.2 is the default padding.
            yaxis: {
                pad: 1.05,
                tickOptions: {formatString: '%d'}
            }
        }
    });
var s2 = [["Val1":1], ["Val2":2], ["Val3":3]];
         
    var plot2 = $.jqplot('pie', [s2], {
        grid: {
            drawBorder: false, 
            drawGridlines: false,
            background: '#ffffff',
            shadow:false
        },
        axesDefaults: {
             
        },
        seriesDefaults:{
            renderer:$.jqplot.PieRenderer,
            rendererOptions: {
                showDataLabels: true
            }
        },
        legend: {
            show: true,
            rendererOptions: {
                numberRows: 1
            },
            location: 's'
        }
    }); 
$('#tabs').bind('tabsshow', function(event, ui) {
  if (ui.index === 1 && plot1._drawCount === 0) {
plot1.replot();
  }
  else if (ui.index === 2 && plot2._drawCount === 0) {
plot2.replot();
  }
});

});
</script>
</head>
<body>
<div id="tabs" style="min-height:500px">
<ul>
<li><a href="#tabs-1">Tabular Data</a></li>
<li><a href="#tabs-2">Histogram</a></li>
<li><a href="#tabs-3">Pie Chart</a></li>
</ul>
       <div id="tabs-1">
First Tab Page
</div>
<div id="tabs-2">
<div id="chart1" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
<div id="tabs-3">
<div id="pie" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
</div>
</body>
</html>

No comments:

Post a Comment