bootstrap下多Tab echarts切换tab不显示

问题遇到的现象和发生背景

PHP语言:bootstrap框架 多Tabs中 每个tab中都有echarts; 当浏览器窗口发生变化后,切换Tab,切换到的tab下的图表不能正常显示,canvas中的width一直是0(拖拽改变浏览器大小后,才能恢复)

问题相关代码,请勿粘贴截图
            <div>
                <ul class="nav nav-tabs" id="myTab">
                    <li class="nav-item active">
                        <a href="#Cat1" class="nav-link active" data-toggle="tab">Cat1</a>
                    </li>
                    <li><a href="#RF" class="nav-link" data-toggle="tab">RF</a></li>
                    <li><a href="#APP" class="nav-link" data-toggle="tab">APP</a></li>
                    <li><a href="#WCN" class="nav-link" data-toggle="tab">WCN</a></li>
                    <li><a href="#GU" class="nav-link" data-toggle="tab">顾总</a></li>
                </ul>
            </div>

        <!-- 选项卡内容区域-tab内容栏 -->
        <div class="tab-content container-fluid">
            <div class="tab-pane fade in active show" id="Cat1">
                <div class="container ">
                    <!-- echarts 图表区域 -->
                    <div class="myTable-container" id="Cat1-container"></div>
                </div>
            </div>

            <div class="tab-pane fade in active" id="RF">
                <div class="container">
                    <!-- echarts 图表区域 -->
                    <div class="myTable-container" id="RF-container"></div>
                </div>
            </div>
        </div>





let mEcharts = [];
//图表容器初始化
let cat1 = echarts.init(document.getElementById("Cat1_container"));
let rf = echarts.init(document.getElementById('RF_container'));


//图表数据
let option1 = {
    title: {
        text: 'CAT1 SDK PASSRATE'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['FunctionTest', 'FTTest', 'AutomationTest']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true //left、right、bottom都设置为0的时候,纵坐标标线是否显示
    },
    toolbox: {
        feature: {

            dataView: {
                show: true,
                readOnly: false,
                optionToContent: function (opt) {
                    var axisData = opt.xAxis[0].data; //x轴作为条件,y轴需改成yAxis[0].data;
                    var series = opt.series;
                    var tdHeads = '<td  style="padding:0 10px">名称</td>';
                    series.forEach(function (item) {
                        tdHeads += '<td style="padding: 0 10px">' + item.name + '</td>';
                    });
                    var table = '<table border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;background-color:#F8F8FF"><tbody><tr>' + tdHeads + '</tr>';
                    var tdBodys = '';
                    for (var i = 0, l = axisData.length; i < l; i++) {
                        for (var j = 0; j < series.length; j++) {
                            if (typeof (series[j].data[i]) == 'object') {
                                tdBodys += '<td>' + series[j].data[i].value + '</td>';
                            } else {
                                tdBodys += '<td>' + series[j].data[i] + '</td>';
                            }
                        }
                        table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
                        tdBodys = '';
                    }
                    table += '</tbody></table>';
                    return table;
                }
            }, //展示原始数据
            magicType: {
                show: true,
                type: ['line', 'bar']
            }, //bar和线之间切换
            saveAsImage: {}, //图表保存成图片功能
        },
    },
    xAxis: {
        type: 'category',
        boundaryGap: false, //横坐标标线 与名称是否留白,不留白则对齐
        data: data_x,

        // x轴坐标文字倾斜率
        // axisLabel: {
        //     interval: 0,
        //     rotate: 60
        // }

    },
    yAxis: {
        type: 'value',
        name: 'PassRate%',
        nameLocation: 'center',
        nameGap: 40,

        // axisLabel: {
        //     formatter: '{value} %'
        // },

        min: 50,
        max: 100,

    },
    series: [{
        name: 'FunctionTest',
        type: 'line',
        // stack: 'Total', //第二条线在第一条线的基础上,数据叠加,所有不设置或者设置不同的名字
        data: data_y
    }, {
        name: 'FTTest',
        type: 'line',
        // stack: 'Total',
        data: [79, 96, 82.5, 94.6, 80.1]
    }, {
        name: 'AutomationTest',
        type: 'line',
        // stack: 'Total',
        data: [79.5, 89.3, 94.6, 87.3, 97.2]
    }]
};
let optionRF = {
    title: {
        text: 'RF PASSRATE'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['FunctionTest', 'FTTest', 'AutomationTest']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true //left、right、bottom都设置为0的时候,纵坐标标线是否显示
    },
    toolbox: {
        feature: {
            dataView: {
                show: true,
                readOnly: false,
                optionToContent: function (opt) {
                    var axisData = opt.xAxis[0].data; //x轴作为条件,y轴需改成yAxis[0].data;
                    var series = opt.series;
                    var tdHeads = '<td  style="padding:0 10px">名称</td>';
                    series.forEach(function (item) {
                        tdHeads += '<td style="padding: 0 10px">' + item.name + '</td>';
                    });
                    var table = '<table border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;background-color:#F8F8FF"><tbody><tr>' + tdHeads + '</tr>';
                    var tdBodys = '';
                    for (var i = 0, l = axisData.length; i < l; i++) {
                        for (var j = 0; j < series.length; j++) {
                            if (typeof (series[j].data[i]) == 'object') {
                                tdBodys += '<td>' + series[j].data[i].value + '</td>';
                            } else {
                                tdBodys += '<td>' + series[j].data[i] + '</td>';
                            }
                        }
                        table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
                        tdBodys = '';
                    }
                    table += '</tbody></table>';
                    return table;
                }
            }, //展示原始数据
            magicType: {
                show: true,
                type: ['line', 'bar']
            }, //图表显示切换
            saveAsImage: {} //图表保存成图片功能
        },
        dataView: {
            // show: true,
            // readOnly: false
        },
    },
    xAxis: {
        type: 'category',
        // boundaryGap: false, //横坐标标线 与名称是否留白,不留白则对齐
        data: ['RFxxx01', 'RFxxx02', 'RFxxx03', 'RFxxx04'],


    },
    yAxis: {
        type: 'value',
        name: 'PassRate%',
        nameLocation: 'center',
        nameGap: 40,
        min: 50,
        max: 100,

    },
    series: [{
        name: 'FunctionTest',
        type: 'bar',
        barMaxWidth: 30,
        emphasis: {
            focus: 'series'
        },
        data: [55, 98.7, 88, 89.5]
    }, {
        name: 'FTTest',
        type: 'bar',
        barMaxWidth: 30,
        emphasis: {
            focus: 'series'
        },
        data: [79, 96, 82.5, 94.6]
    }, {
        name: 'AutomationTest',
        type: 'bar',
        barMaxWidth: 30,
        emphasis: {
            focus: 'series'
        },
        data: [79.5, 89.3, 94.6, 87.3]
    }]
};


//配置图表数据
cat1.setOption(option1);
rf.setOption(optionRF);


//生成图表数组
mEcharts.push(cat1);
mEcharts.push(rf);


//图表resize自适应
$(window).resize(function() {
    for (var i = 0; i < mEcharts.length; i++) {
        mEcharts[i].resize();
    }
});

//解决tab切换不显示问题 在加载窗口后重新渲染
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    console.log(e);
    for (var i = 0; i < mEcharts.length; i++) {
        console.log(e);
        mEcharts[i].resize();
    }
});
运行结果及报错内容

当浏览器窗口发生变化后,切换Tab,切换到的tab下的图表不能正常显示,canvas中的width一直是0(拖拽改变浏览器大小后,才能恢复)

我的解答思路和尝试过的方法

使用了 //解决tab切换不显示问题 在加载窗口后重新渲染,但是似乎事件不能监听到,console无日志输出

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    console.log(e);
    for (var i = 0; i < mEcharts.length; i++) {
        console.log(e);
        mEcharts[i].resize();
    }
});
我想要达到的结果

改变浏览器大小后,切换tab,图表可以正常加载出来

首先看看js版本问题
然后看看是不是jquery和bootstrap两个js的引入顺序的问题


如果解决不了,试试下面解决方法:

1、全局定义一个echarts数组,用于存放echarts

var myCharts = new Array();

img

2、页面加载时定义方法重新渲染echarts

//data-toggle="pill还是data-toggle="tab" 根据前面所用标签页的不同来选择。我使用的是data-toggle="tab"。
//解决tab切换不显示问题 在加载窗口后重新渲染。
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    for(var i = 0; i < myCharts.length; i++) {
        myCharts[i].resize();
    }
});

img


3、将tab下的各个图表加入定义的数组中(这里是myCharts)
myCharts.push(myChart);

img

加个setTimeout试下

朋友你好,可以试试这个
//解决tab切换不显示问题 在加载窗口后重新渲染。
$('a[data-toggle="pill"]').on('shown.bs.tab', function(e) {
for(var i = 0; i < charts.length; i++) {
charts[i].resize();
}
}); //data-toggle="pill还是data-toggle="tab" 根据前面所用标签页的不同来选择

望采纳谢谢欧

会不会是因为切换到当前页面时,数据还没获取到,导致不能正常显示

tab切换echarts无法正常的原因:
在页面进行加载时,隐藏的图表找不到对应的div大小,所以默认给了一个大小。而这个默认宽度很小,所以导致echarts图表显示不完全。

解决办法大约有2种:
第一种:将div的宽高设置成固定值,比如style=”300px;height:300px”,这时候echarts有了明确的大小时候就可以正常显示出来了。(提示:这个方式有一个方法,有一个缺点,就是固定值的高宽无法自适应网页大小)
第二种:在点击第二个tab的时候才初始化echarts,也就是调用建立echarts的函数,而不要在加载网页的时候就初始化了,也就是
你这里
//图表容器初始化

let cat1 = echarts.init(document.getElementById("Cat1_container"));
let rf = echarts.init(document.getElementById('RF_container'));

这里只初始化一个

然后再
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
//你在这里做初始化

});

初始化的时候重新定义一下echarts的宽高



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link crossorigin="anonymous" integrity="sha384-9GKi7Mg3e8wxMnh60bnNnc9kuwGfarF0StF1UbfPt4F5GMVfxBgfh8/pW4iHavxG"
        href="https://lib.baomitu.com/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">

    <script crossorigin="anonymous" integrity="sha384-TlQc6091kl7Au04dPgLW7WK3iey+qO8dAi/LdwxaGBbszLxnizZ4xjPyNrEf+aQt"
        src="https://lib.baomitu.com/jquery/2.2.4/jquery.js"></script>
    <script crossorigin="anonymous" integrity="sha384-BqgdDRqoSM34U92AkJHjlNmbVsfEZStnqGg4pVMc/AMY0XbNFRu3cO5LfJXXXETD"
        src="https://lib.baomitu.com/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>

    <script crossorigin="anonymous" integrity="sha384-JlcI68PaXChZgu6b6NnpXs40VQAdMKzfi70CblD1PhVamAXhmhhdIcmrAR06/84E"
        src="https://lib.baomitu.com/echarts/3.8.5/echarts.js"></script>

    <style>
        #Cat1-container {
            width: 500px;
            height: 500px;

        }

        #RF-container {
            width: 500px;
            height: 500px;
        }
    </style>

</head>

<body>
    <div>
        <ul class="nav nav-tabs" id="myTab">
            <li class="nav-item active">
                <a href="#Cat1" class="nav-link active" data-toggle="tab">Cat1</a>
            </li>
            <li><a href="#RF" class="nav-link" data-toggle="tab">RF</a></li>
            <li><a href="#APP" class="nav-link" data-toggle="tab">APP</a></li>
            <li><a href="#WCN" class="nav-link" data-toggle="tab">WCN</a></li>
            <li><a href="#GU" class="nav-link" data-toggle="tab">顾总</a></li>
        </ul>
    </div>
    <!-- 选项卡内容区域-tab内容栏 -->
    <div class="tab-content container-fluid">
        <div class="tab-pane fade in active show" id="Cat1">
            <div class="container ">
                <!-- echarts 图表区域 -->
                <div class="myTable-container" id="Cat1-container"></div>
            </div>
        </div>

        <div class="tab-pane fade in active" id="RF">
            <div class="container">
                <!-- echarts 图表区域 -->
                <div class="myTable-container" id="RF-container"></div>
            </div>
        </div>
    </div>
    <script>
        window.onload = function () {
            let mEcharts = [];
            //图表容器初始化
            let cat1 = echarts.init(document.getElementById("Cat1-container"));
            let rf = echarts.init(document.getElementById('RF-container'));


            //图表数据
            let option1 = {
                title: {
                    text: 'CAT1 SDK PASSRATE'
                },
                tooltip: {
                    trigger: 'axis'
                },
                legend: {
                    data: ['FunctionTest', 'FTTest', 'AutomationTest']
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true //left、right、bottom都设置为0的时候,纵坐标标线是否显示
                },
                toolbox: {
                    feature: {

                        dataView: {
                            show: true,
                            readOnly: false,
                            optionToContent: function (opt) {
                                var axisData = opt.xAxis[0].data; //x轴作为条件,y轴需改成yAxis[0].data;
                                var series = opt.series;
                                var tdHeads = '<td  style="padding:0 10px">名称</td>';
                                series.forEach(function (item) {
                                    tdHeads += '<td style="padding: 0 10px">' + item.name + '</td>';
                                });
                                var table = '<table border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;background-color:#F8F8FF"><tbody><tr>' + tdHeads + '</tr>';
                                var tdBodys = '';
                                for (var i = 0, l = axisData.length; i < l; i++) {
                                    for (var j = 0; j < series.length; j++) {
                                        if (typeof (series[j].data[i]) == 'object') {
                                            tdBodys += '<td>' + series[j].data[i].value + '</td>';
                                        } else {
                                            tdBodys += '<td>' + series[j].data[i] + '</td>';
                                        }
                                    }
                                    table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
                                    tdBodys = '';
                                }
                                table += '</tbody></table>';
                                return table;
                            }
                        }, //展示原始数据
                        magicType: {
                            show: true,
                            type: ['line', 'bar']
                        }, //bar和线之间切换
                        saveAsImage: {}, //图表保存成图片功能
                    },
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false, //横坐标标线 与名称是否留白,不留白则对齐
                    data: [79, 96, 82.5, 94.6, 80.1],

                    // x轴坐标文字倾斜率
                    // axisLabel: {
                    //     interval: 0,
                    //     rotate: 60
                    // }

                },
                yAxis: {
                    type: 'value',
                    name: 'PassRate%',
                    nameLocation: 'center',
                    nameGap: 40,

                    // axisLabel: {
                    //     formatter: '{value} %'
                    // },

                    min: 50,
                    max: 100,

                },
                series: [{
                    name: 'FunctionTest',
                    type: 'line',
                    // stack: 'Total', //第二条线在第一条线的基础上,数据叠加,所有不设置或者设置不同的名字
                    data: [79, 96, 82.5, 94.6, 80.1]
                }, {
                    name: 'FTTest',
                    type: 'line',
                    // stack: 'Total',
                    data: [79, 96, 82.5, 94.6, 80.1]
                }, {
                    name: 'AutomationTest',
                    type: 'line',
                    // stack: 'Total',
                    data: [79.5, 89.3, 94.6, 87.3, 97.2]
                }]
            };
            let optionRF = {
                title: {
                    text: 'RF PASSRATE'
                },
                tooltip: {
                    trigger: 'axis'
                },
                legend: {
                    data: ['FunctionTest', 'FTTest', 'AutomationTest']
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true //left、right、bottom都设置为0的时候,纵坐标标线是否显示
                },
                toolbox: {
                    feature: {
                        dataView: {
                            show: true,
                            readOnly: false,
                            optionToContent: function (opt) {
                                var axisData = opt.xAxis[0].data; //x轴作为条件,y轴需改成yAxis[0].data;
                                var series = opt.series;
                                var tdHeads = '<td  style="padding:0 10px">名称</td>';
                                series.forEach(function (item) {
                                    tdHeads += '<td style="padding: 0 10px">' + item.name + '</td>';
                                });
                                var table = '<table border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;background-color:#F8F8FF"><tbody><tr>' + tdHeads + '</tr>';
                                var tdBodys = '';
                                for (var i = 0, l = axisData.length; i < l; i++) {
                                    for (var j = 0; j < series.length; j++) {
                                        if (typeof (series[j].data[i]) == 'object') {
                                            tdBodys += '<td>' + series[j].data[i].value + '</td>';
                                        } else {
                                            tdBodys += '<td>' + series[j].data[i] + '</td>';
                                        }
                                    }
                                    table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
                                    tdBodys = '';
                                }
                                table += '</tbody></table>';
                                return table;
                            }
                        }, //展示原始数据
                        magicType: {
                            show: true,
                            type: ['line', 'bar']
                        }, //图表显示切换
                        saveAsImage: {} //图表保存成图片功能
                    },
                    dataView: {
                        // show: true,
                        // readOnly: false
                    },
                },
                xAxis: {
                    type: 'category',
                    // boundaryGap: false, //横坐标标线 与名称是否留白,不留白则对齐
                    data: ['RFxxx01', 'RFxxx02', 'RFxxx03', 'RFxxx04'],


                },
                yAxis: {
                    type: 'value',
                    name: 'PassRate%',
                    nameLocation: 'center',
                    nameGap: 40,
                    min: 50,
                    max: 100,

                },
                series: [{
                    name: 'FunctionTest',
                    type: 'bar',
                    barMaxWidth: 30,
                    emphasis: {
                        focus: 'series'
                    },
                    data: [55, 98.7, 88, 89.5]
                }, {
                    name: 'FTTest',
                    type: 'bar',
                    barMaxWidth: 30,
                    emphasis: {
                        focus: 'series'
                    },
                    data: [79, 96, 82.5, 94.6]
                }, {
                    name: 'AutomationTest',
                    type: 'bar',
                    barMaxWidth: 30,
                    emphasis: {
                        focus: 'series'
                    },
                    data: [79.5, 89.3, 94.6, 87.3]
                }]
            };


            //配置图表数据
            cat1.setOption(option1);
            rf.setOption(optionRF);


            //生成图表数组
            mEcharts.push(cat1);
            mEcharts.push(rf);


            //图表resize自适应
            $(window).resize(function () {
                for (var i = 0; i < mEcharts.length; i++) {
                    mEcharts[i].resize();
                }
            });

            //解决tab切换不显示问题 在加载窗口后重新渲染
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                console.log(e);
                for (var i = 0; i < mEcharts.length; i++) {
                    console.log(e);
                    mEcharts[i].resize();
                }
            });
        }

    </script>
</body>

</html>

建议渲染图的时候是每次点击tab你去请求一次,二次点击不用请求直接用浏览器缓存加载渲染就可以。这样新请求的话每次都会正常显示

相信我,切换tab的时候要触发请求图表那个对象(init接收的那个对象)存在的时候就resize(),不存在的时候就init就可以了,不然还有一种就是tab没点击的时候不要初始化了,点击的时候才真的渲染页面,不然tab没显示就已经渲染了Echart图表不resize是不会有宽高度的即图表加载成功了也会看不见(这个时候你把浏览器F12看控制台等造成窗口大小变化就会触发window监控的resize方法,图表就resize成功了能看见了,所以要除了window的resize监控还要主动切换调用resize)