如果在隐藏的 div 中呈现,图表会消失

charts disappear if rendered in hidden divs

我有两个图表(使用 charts.js 创建),我想通过单击按钮在它们之间切换。

最初我将它们分别放在不同的 div 中,如下所示:

<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>

如果我删除 'hidden' class,图表将不会显示。

这是一个 JSFiddle:http://jsfiddle.net/2rzkpzy9/12/

有没有办法绕过这个或其他方法来交替处理它们?

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 {
    display: none;
}
<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>

我没有使用过 Chart.js,但快速浏览 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 以了解此行为的示例:

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>

要修复,您可以显式设置宽度和高度(不确定 Chart.js 是否为此提供了配置),或者您可以渲染图表然后 然后 隐藏元素 - 不是很优雅,因为你可能会得到闪光。第二个选项的另一个版本是使用 position: absolute; top: -1000px 之类的东西将 "hidden" div 移到屏幕外,而不是用 display: none.

隐藏

查看您的 fiddle,已更新为在此处使用第二个选项:http://jsfiddle.net/2rzkpzy9/13/ - 似乎有效:

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>

不要隐藏非活动选项卡,而是将其高度设置为 0px 并且 overflow:hidden

您的 css 可能如下所示:

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

你可以试试这个

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>