[Chartjs]-Charts disappear if rendered in hidden divs

5๐Ÿ‘

โœ…

I havenโ€™t used Chart.js, but a quick glance at the code suggests that itโ€™s querying the DOM to get height and width for the render. If the containing div is hidden, that query probably returns 0. So the hidden chart probably has 0x0 size. See https://jsfiddle.net/2rzkpzy9 for an example of this behavior:

var width = document.getElementById('myChart').offsetWidth;

document.getElementById('info').innerHTML = width.toString();
.hidden {
    display: none;
}
<div class="hidden">
    <canvas id="myChart" width="400" height="400"></canvas>
</div>

<div id="info"></div>

To fix, you might be able to set the width and height explicitly (not sure if Chart.js offers a config for this), or you can render the chart and then hide the element โ€“ not very elegant, since you might get a flash. Another version of the second option is to use something like position: absolute; top: -1000px to move the โ€œhiddenโ€ div off-screen instead of hiding with display: none.

See your fiddle, updated to use the second option here: http://jsfiddle.net/2rzkpzy9/13/ โ€“ seems to work:

var data1 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "rgba(220,220,220,0.2)",
            strokeColor: "rgba(220,220,220,1)",
            pointColor: "rgba(220,220,220,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: [65, 59, 80, 81, 56, 55, 40]
        }]
};
var data2 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "#FD6260",
            strokeColor: "#FD6260",
            pointColor: "#FD6260",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: [65, 59, 80, 81, 56, 55, 40]
        }]
};

var options = {
    scaleShowGridLines : false,
    scaleShowHorizontalLines: false,
    scaleShowVerticalLines: false,
 }

var cxt = document.getElementById("myChart1").getContext("2d");
var chart = new Chart(cxt).Bar(data1,options);

var cxt2 = document.getElementById("myChart2").getContext("2d");
var chart2 = new Chart(cxt2).Bar(data2,options);
        
swap= function() {
     console.log(document.getElementById("one").className);
     document.getElementById("one").className = "hidden";
     document.getElementById("two").className = '';
    console.log(document.getElementById("one").className);
}
.hidden {
    position: fixed;
    top: -1000px;
}
<script src="http://www.chartjs.org/assets/Chart.js"></script>
<div id="one">
    <canvas id="myChart1" width="400" height="400"></canvas>
</div>
<div id="two" class="hidden">
    <canvas id="myChart2" width="400" height="400"></canvas>
</div>
<button type="button" class="btn" onClick="swap()">Swap!</button>
<div id="info"></div>

5๐Ÿ‘

instead of hiding the inactive tab set its height to 0px and overflow:hidden

your css may look like this:

#one, #two
{
height:auto;
overflow:inherit;
}
#one.hidden, #two.hidden
{
height:0;
overflow:hidden;
}

0๐Ÿ‘

You can try this

swap= function() {
 console.log(document.getElementById("one").className);
 if(document.getElementById("one").className == "hidden"){
 document.getElementById("one").className = '';
 document.getElementById("two").className = 'hidden';
 }else{
 document.getElementById("one").className = 'hidden';
 document.getElementById("two").className = '';
 }

console.log(document.getElementById("one").className);

}

var data1 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "rgba(220,220,220,0.2)",
            strokeColor: "rgba(220,220,220,1)",
            pointColor: "rgba(220,220,220,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: [65, 59, 80, 81, 56, 55, 40]
        }]
};
var data2 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "#FD6260",
            strokeColor: "#FD6260",
            pointColor: "#FD6260",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: [65, 59, 80, 81, 56, 55, 40]
        }]
};

var options = {
    scaleShowGridLines : false,
    scaleShowHorizontalLines: false,
    scaleShowVerticalLines: false,
 }

var cxt = document.getElementById("myChart1").getContext("2d");
var chart = new Chart(cxt).Bar(data1,options);

var cxt2 = document.getElementById("myChart2").getContext("2d");
var chart2 = new Chart(cxt2).Bar(data2,options);
        
swap= function() {
     console.log(document.getElementById("one").className);
     if(document.getElementById("one").className == "hidden"){
     document.getElementById("one").className = '';
     document.getElementById("two").className = 'hidden';
     }else{
     document.getElementById("one").className = 'hidden';
     document.getElementById("two").className = '';
     }
     
    console.log(document.getElementById("one").className);
}
.hidden {
    position: fixed;
    top: -1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<div id="one">
    <canvas id="myChart1" width="400" height="400"></canvas>
</div>
<div id="two" class="hidden">
    <canvas id="myChart2" width="400" height="400"></canvas>
</div>
<button type="button" class="btn" onClick="swap()">Swap!</button>
<div id="info"></div>

Leave a comment