Search code examples
jqueryjquery-ui-tabsc3

c3.js chart not working properly when used inside jquery tab


I am trying to generate c3 chart inside jquery tabs. when i render the page, the c3 chart in the first tab appears to be just fine. However the c3 chart inside the 2nd tab seems to be larger than the first. The dimension of the div block used for the charts in both tabs are identical. Not sure why the charts in 2nd tab is larger than the first tab. Please help me to resolve this issue. I am listing code below

content of tabs.css

#tabs_wrapper {
#width: 500px;
}

#tabs_container {
border-bottom: 1px solid #ccc;
}

#tabs {
list-style: none;
padding: 5px 0 4px 0;
margin: 0 0 0 10px;
font: 0.75em arial;
}

#tabs li {
display: inline;
}

#tabs li a {
border: 1px solid #ccc;
padding: 4px 6px;
text-decoration: none;
background-color: #eeeeee;
border-bottom: none;
outline: none;
border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
font-weight: bold;
font-size: 0.9em;
}

#tabs li a:hover {
background-color: #dddddd;
padding: 4px 6px;
}

#tabs li.active a {
border-bottom: 1px solid #fff;
background-color: #fff;
padding: 4px 6px 5px 6px;
border-bottom: none;
}

#tabs li.active a:hover {
background-color: #eeeeee;
padding: 4px 6px 5px 6px;
border-bottom: none;
}

#tabs li a.icon_accept {
#background-image: url(accept.png);
background-position: 5px;
background-repeat: no-repeat;
padding-left: 24px;
}

#tabs li a.icon_accept:hover {
padding-left: 24px;
}

#tabs_content_container {
border: 1px solid #ccc;
border-top: none;
padding: 10px;
#width: 400px;
}

.tab_content {
display: none;
}

content of html is given below

<html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="c3.css"/>
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css"/>
<link rel="stylesheet" type="text/css" href="tabs.css"/>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.js"></script

</head>

<body>

<div id="barChartWrapperId" style="float:left;#clear:left;#display:none;margin-left:12%;#margin:0 auto;">
<div id="tabs_container">
    <ul id='tabs'>
        <li class="active"><a href='#tab1'>Activity for today</a></li>
        <li><a href='#tab2'>Activity for current week</a></li>
        <li><a href='#tab3'>Activity for current month</a></li>
    </ul>
</div>

<div id="tabs_content_container" style="height:300px;">
    <div id='tab1' class="tab_content" style="display: block;">          
        <div style="margin:0 auto;text-align:center;">
            <div style="width:340px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for today</div>
                <div style="clear:both;"></div>
                <div id="importChart" style="width:340px;"></div>
            </div>

            <div style="width:530px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for today</div>
                <div style="clear:both;"></div>
                <div id="exportChart" style="width:530px;"></div>
            </div>
        </div>

    </div>
    <div id='tab2' class="tab_content" style="height:300px;">
        <div style="margin:0 auto;text-align:center;">
            <div style="width:340px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for this week</div>
                <div style="clear:both;"></div>
                <div id="weeklyImportChart" style="width:340px;"></div>
            </div>
            <div style="width:530px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for this week</div>
                <div style="clear:both;"></div>
                <div id="weeklyExportChart" style="width:530px;"></div>
            </div>
        </div>
    </div>

    <div id='tab3' class="tab_content" style="height:300px;">
        <div style="margin:0 auto;text-align:center;">
            <div style="width:340px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for this month</div>
                <div style="clear:both;"></div>
                <div id="monthlyImportChartC3" style="width:340px;"></div>
            </div>

            <div style="width:530px;#float:left;display:inline-block;">
                <div style="font-family:Arial;font-size:0.7em;">counts for this month</div>
                <div style="clear:both;"></div>
                <div id="monthlyExportChartC3" style="width:530px;"></div>
            </div>
        </div>
    </div>
</div>

<script>
var barDailyRcvdC3 = [757];
var barDailyCreatedC3 = [748];
var barDailyErrorC3 = [9];

var barDailyExRcvdC3 = [8966];
var barDailyExToDC3 = [7390];
var barDailyExToSC3 = [567];
var barDailyExToIC3 = [178];
var barDailyExToQC3 = [91];
var barDailyExToNC3 = [544];
var barDailyExToEC3 = [196];

var chart = c3.generate({
    bindto: '#importChart',
    data: {
    columns: [
    ['imprcvd',].concat(barDailyRcvdC3),
    ['impc',].concat(barDailyCreatedC3),
    ['impe',].concat(barDailyErrorC3)
  ],
  type:'bar',
    labels: true
  },
  legend : {
    position:'right'
  },
  axis : {
    y: {
      label: 'Counts'
    }
  },
  bar:{
    width: {
      ratio: 0.5 // this makes bar width 50% of length between ticks
    }
  }
});

var chart = c3.generate({
bindto: '#exportChart',
data: {
  columns: [
    ['exprcvd',].concat(barDailyExRcvdC3),
                            ['expd',].concat(barDailyExToDC3),
                            ['exps',].concat(barDailyExToSC3),
                            ['expi',].concat(barDailyExToIC3),
                            ['expq',].concat(barDailyExToQC3),
                            ['expn',].concat(barDailyExToNC3),
                            ['expe',].concat(barDailyExToEC3)
  ],
              type:'bar',
              labels: true
            },
            legend : {
                            position:'right'
            },
            axis : {
                            y: {
        label: 'Counts'
   }
            },
            bar:{
                            width: {
                                            ratio: 0.6 // this makes bar width 50% of length between ticks
                            }
            }
});


var barWeeklyRcvdC3 = [4244];
var barWeeklyCreatedC3 = [4218];
var barWeeklyErrorC3 = [29];

var barWeeklyExRcvdC3 = [18218];
var barWeeklyExToDC3 = [14795];
var barWeeklyExToSC3 = [1106];
var barWeeklyExToIC3 = [401];
var barWeeklyExToQC3 = [158];
var barWeeklyExToNC3 = [1029];
var barWeeklyExToEC3 = [733];



var chart = c3.generate({
bindto: '#weeklyImportChart',
data: {
  columns: [
    ['imprcvd',].concat(barWeeklyRcvdC3),
                            ['impc',].concat(barWeeklyCreatedC3),
                            ['impe',].concat(barWeeklyErrorC3)
  ],
              type:'bar',
              labels: true
            },
            legend : {
                            position:'right'
            },
            axis : {
                            y: {
        label: 'Counts'
   }
            },
            bar:{
                            width: {
                                            ratio: 0.5 // this makes bar width 50% of length between ticks
                            }
            }
   });


var chart = c3.generate({
bindto: '#weeklyExportChart',
data: {
  columns: [
    ['exprcvd',].concat(barWeeklyExRcvdC3),
                            ['expd',].concat(barWeeklyExToDC3),
                            ['exps',].concat(barWeeklyExToSC3),
                            ['expi',].concat(barWeeklyExToIC3),
                            ['expq',].concat(barWeeklyExToQC3),
                            ['expn',].concat(barWeeklyExToNC3),
                            ['expe',].concat(barWeeklyExToEC3)
  ],
              type:'bar',
              labels: true
            },
            legend : {
                            position:'right'
            },
            axis : {
                            y: {
        label: 'Counts'
   }
            },
            bar:{
                            width: {
                                            ratio: 0.6 // this makes bar width 50% of length between ticks
                            }
            }
});


</script>

<script>

$(document).ready( function() {

    //  When user clicks on tab, this code will be executed
    $("#tabs li").click(function() {

    //  First remove class "active" from currently active tab
    $("#tabs li").removeClass('active');

    //  Now add class "active" to the selected/clicked tab
    $(this).addClass("active");

    //  Hide all tab content
    $(".tab_content").hide();

    //  Here we get the href value of the selected tab
    var selected_tab = $(this).find("a").attr("href");

    //  Show the selected tab content
    $(selected_tab).fadeIn();

    //  At the end, we add return false so that the click on the link is not executed
    return false;

    });

});

</script>
</body>
</html>

Solution

  • The container will not have a rendered width / height when it is display: none.

    The easiest way to correct the problem you are having would be to set the width explicitly when you initialize the chart, like so

    ...
    var chart = c3.generate({
        bindto: '#weeklyImportChart',
        size: {
            width: 340
        },
        data: {
        ...
    

    and

    ...
    var chart = c3.generate({
        bindto: '#weeklyExportChart',
        size: {
            width: 530
        },
        data: {
        ...
    

    Alternatively, you could also initialize / reinitialize the chart after the tab is fully visible.