echarts 在同一个canvas绘制多图并实现tooltip

2019-07-30  本文已影响0人  易冷zzz

背景:脑洞大开的产品看到如下图这种多个tooltip联动的统计图,为了在客户面前装逼就把这个功能加到了本次需求里面,经过查看源码发现使用echarts绘制的,虽然本人也经常用echarts但是这种图实在没画过,查看相关API也没找到实现办法,网上关于这部分的问题也非常少,最后终于实现,记录如下:

图1

代码暂时没有优化但是功能全部实现了,可以直接拷贝下面的代码到html文件运行即可,先占个位置:
增加了最值标记,均值标线等,效果如下:


image.png
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="main" style="width: 100%; height: 1750px;"></div>
        <script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts-en.common.js"></script>
        <script type="text/javascript">
            // 基于准备好的dom,初始化echarts实例
            var myChart = echarts.init(document.getElementById('main'));
            // 指定图表的配置项和数据
            var datas = [{"data":[[0,19],[5000,0],[10000,3],[15000,0],[20000,6],[25000,0],[30000,1],[35000,0],[40000,0],[45000,0],[50000,0],[55000,4],[60000,9],[65000,0],[70000,5],[75000,1],[80000,2],[85000,0],[90000,0],[95000,0],[100000,0],[105000,0],[110000,0],[115000,0],[120000,0],[125000,1],[130000,0],[135000,1],[140000,8],[145000,1],[150000,0],[155000,0],[160000,0],[165000,0],[170000,0],[175000,0],[180000,1],[185000,1],[190000,3],[195000,0]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,372],[5000,404],[10000,425],[15000,413],[20000,414],[25000,415],[30000,416],[35000,417],[40000,415],[45000,404],[50000,405],[55000,456],[60000,486],[65000,473],[70000,471],[75000,501],[80000,455],[85000,457],[90000,457],[95000,458],[100000,458],[105000,459],[110000,460],[115000,459],[120000,460],[125000,461],[130000,462],[135000,463],[140000,464],[145000,476],[150000,472],[155000,473],[160000,474],[165000,474],[170000,462],[175000,464],[180000,473],[185000,469],[190000,470],[195000,471]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,0],[5000,0],[10000,0],[15000,0],[20000,0],[25000,0],[30000,0],[35000,0],[40000,0],[45000,0],[50000,0],[55000,0],[60000,0],[65000,0],[70000,0],[75000,0],[80000,0],[85000,0],[90000,0],[95000,0],[100000,0],[105000,0],[110000,0],[115000,0],[120000,0],[125000,0],[130000,0],[135000,0],[140000,0],[145000,0],[150000,0],[155000,0],[160000,0],[165000,0],[170000,0],[175000,0],[180000,0],[185000,0],[190000,0],[195000,0]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,0],[5000,0],[10000,0],[15000,0],[20000,0],[25000,0],[30000,0],[35000,0],[40000,0],[45000,0],[50000,0],[55000,0],[60000,0],[65000,0],[70000,0],[75000,0],[80000,0],[85000,0],[90000,0],[95000,0],[100000,0],[105000,0],[110000,0],[115000,0],[120000,0],[125000,0],[130000,0],[135000,0],[140000,0],[145000,0],[150000,0],[155000,0],[160000,0],[165000,0],[170000,0],[175000,0],[180000,0],[185000,0],[190000,0],[195000,0]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,8.0],[5000,2.0],[10000,9.0],[15000,3.0],[20000,17.0],[25000,2.0],[30000,4.0],[35000,0.0],[40000,4.0],[45000,7.0],[50000,5.0],[55000,2.0],[60000,49.0],[65000,3.0],[70000,2.0],[75000,7.0],[80000,11.0],[85000,4.0],[90000,3.0],[95000,1.0],[100000,2.0],[105000,2.0],[110000,16.0],[115000,2.0],[120000,3.0],[125000,8.0],[130000,3.0],[135000,3.0],[140000,0.0],[145000,2.0],[150000,2.0],[155000,1.0],[160000,18.0],[165000,3.0],[170000,18.0],[175000,3.0],[180000,4.0],[185000,1.0],[190000,54.0],[195000,2.0]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,38.0],[5000,38.0],[10000,38.0],[15000,38.0],[20000,38.0],[25000,38.0],[30000,38.0],[35000,38.0],[40000,38.0],[45000,38.0],[50000,38.0],[55000,38.0],[60000,38.0],[65000,38.0],[70000,38.0],[75000,38.0],[80000,38.0],[85000,38.0],[90000,38.0],[95000,39.0],[100000,39.0],[105000,39.0],[110000,39.0],[115000,39.0],[120000,39.0],[125000,39.0],[130000,39.0],[135000,39.0],[140000,39.0],[145000,39.0],[150000,39.0],[155000,39.0],[160000,39.0],[165000,39.0],[170000,39.0],[175000,39.0],[180000,39.0],[185000,39.0],[190000,39.0],[195000,39.0]],"data2":[],"xMax":195000,"xMin":0},{"data":[[0,24],[5000,26],[10000,33],[15000,0],[20000,0],[25000,0],[30000,0],[35000,0],[40000,0],[45000,0],[50000,0],[55000,33],[60000,0],[65000,30],[70000,60],[75000,51],[80000,0],[85000,60],[90000,40],[95000,60],[100000,0],[105000,0],[110000,0],[115000,0],[120000,0],[125000,0],[130000,0],[135000,0],[140000,0],[145000,0],[150000,0],[155000,0],[160000,0],[165000,60],[170000,40],[175000,36],[180000,60],[185000,0],[190000,0],[195000,60]],"data2":[],"xMax":195000,"xMin":0}];
            var dataList = [];
            var valueList0 = [];
            var valueList1 = [];
            var valueList2 = [];
            var valueList3 = [];
            var valueList4 = [];
            var valueList5 = [];
            var valueList6 = [];
            datas.map(function(obj, index) {
                if(index === 0) {
                    dataList = obj.data.map(function(item) {
                        return Math.floor(item[0] / 1000);
                    });
                    valueList0 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 1) {
                    valueList1 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 2) {
                    valueList2 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 3) {
                    valueList3 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 4) {
                    valueList4 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 5) {
                    valueList5 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
                if(index === 6) {
                    valueList6 = obj.data.map(function(item) {
                        return item[1];
                    });
                }
            })
            var markLine = {
                data : [
                    {type : 'average', name: '平均值'},//平均线
                    { xAxis: '20' },//x='20'的垂直线   因为x轴默认类型为category,所以取值必须为字符串,若为数字则定位到第20个点
                    { yAxis: 50 },//y=50的水平线
                ]
            };
            var option = {
                axisPointer: {
                    link: [{
                        xAxisIndex: 'all',
                    }],
                },
                tooltip: {
                    trigger: 'axis',
                    formatter: function(params, b, c){
                        let dataArr = [];
                        let newDataArr = [];
                        let formatterStr = ''
                        params.map(function (item, index) {
                            dataArr[item.seriesIndex] = item;
                        })
                        //console.log(dataArr);
                        dataArr.map(function (item, index) {
                            newDataArr.push({seriesName: item.seriesName, name: item.name, value: item.value})
                        })
                        console.log(newDataArr)
                        newDataArr.map(function (item, index) {
                            formatterStr += item.seriesName + ':(' + item.name + ',' + item.value + ')<br />'
                        })
                        return formatterStr
                    }
                },
                xAxis: [{
                    type : 'category',
                    //x轴类目名称列表
                    data: dataList,
                    //x 轴所在的 grid 的索引,默认0表示位于第一个 grid
                    gridIndex: 0,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 1,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 2,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 3,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 4,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 5,
                    name: '时间(s)'
                }, {
                    data: dataList,
                    gridIndex: 6,
                    name: '时间(s)'
                }],
                yAxis: [{
                    type : 'value',
                    //展示网格线
                    splitLine: {
                        show: true
                    },
                    //y 轴所在的 grid 的索引,默认0表示位于第一个 grid
                    gridIndex: 0,
                    name: '占用(%)'
                }, {
                    type : 'value',
                    splitLine: {
                        show: true
                    },
                    gridIndex: 1,
                    name: '占用(MB)'
                }, {
                    splitLine: {
                        show: true
                    },
                    gridIndex: 2,
                    name: '消耗(kb)'
                }, {
                    splitLine: {
                        show: true
                    },
                    gridIndex: 3,
                    name: '消耗(kb)'
                }, {
                    splitLine: {
                        show: true
                    },
                    gridIndex: 4,
                    name: '占用(%)'
                }, {
                    splitLine: {
                        show: true
                    },
                    gridIndex: 5,
                    name: '温度(℃)'
                }, {
                    splitLine: {
                        show: true
                    },
                    gridIndex: 6,
                    name: '均值(fps)'
                }],
                //配置grid组件在视图中位置, 每个占据整个canvas的10%
                grid: [{
                    top: '4%',
                    bottom: '86%',
                }, {
                    top: '18%',
                    bottom: '72%'
                }, {
                    top: '32%',
                    bottom: '58%'
                }, {
                    top: '46%',
                    bottom: '44%'
                }, {
                    top: '60%',
                    bottom: '30%'
                }, {
                    top: '74%',
                    bottom: '16%'
                }, {
                    top: '88%',
                    bottom: '2%'
                }],
                dataZoom: [
                    //内置型缩放组件,即拖拽、滚轮缩放
                    {   
                        type: 'inside',
                        start: 0,
                        end: 100,
                        xAxisIndex: [0, 1, 2, 3, 4, 5, 6],//dataZoom 组件控制的x轴索引
                    },
                    //滑动型缩放组件,即底部缩放条缩放
                    {
                        type: 'slider',
                        start: 0,
                        end: 100,
                        xAxisIndex: [0, 1, 2, 3, 4, 5, 6],
                    },
                ],
                series: [{
                    type: 'line',
                    name: 'CPU占用',
                    data: valueList0,//y轴类目数据
                    xAxisIndex: 0,//使用x轴的索引
                    yAxisIndex: 0,//使用y轴的索引
                    //图表标注
                    markPoint: markPoint('CPU占用'),
                    //图表标线
                    markLine : markLine
                }, {
                    type: 'line',
                    name: '内存占用',
                    data: valueList1,
                    xAxisIndex: 1,
                    yAxisIndex: 1,
                    markPoint: markPoint('内存占用'),
                    markLine : markLine
                }, {
                    type: 'line',
                    name: '下行流量消耗',
                    data: valueList2,
                    xAxisIndex: 2,
                    yAxisIndex: 2,
                    markPoint: markPoint('下行流量消耗'),
                    markLine : markLine
                }, {
                    type: 'line',
                    name: '上行流量消耗',
                    data: valueList3,
                    xAxisIndex: 3,
                    yAxisIndex: 3,
                    markPoint:  markPoint('上行流量消耗'),
                    markLine : markLine
                }, {
                    type: 'line',
                    name: 'GPU占用',
                    data: valueList4,
                    xAxisIndex: 4,
                    yAxisIndex: 4,
                    markPoint:  markPoint('GPU占用'),
                    markLine : markLine
                }, {
                    type: 'line',
                    name: '电池温度',
                    data: valueList5,
                    xAxisIndex: 5,
                    yAxisIndex: 5,
                    markPoint:  markPoint('电池温度'),
                    markLine : markLine
                }, {
                    type: 'line',
                    data: valueList6,
                    name: '帧率',
                    xAxisIndex: 6,
                    yAxisIndex: 6,
                    markPoint:  markPoint('帧率'),
                    markLine : markLine
                }]
            };
            myChart.setOption(option);
            
            function markPoint (seriesName) {
                return {
                    itemStyle:{  
                        normal:{
                            label:{
                                show: true,  
                                color:"gray",
                                formatter: function (param) { 
                                    console.log(param)
                                    if (param.data.type == "max") {
                                        return seriesName + "最大值" + param.value
                                    }else if(param.data.type == "min"){
                                        return seriesName + "最小值" + param.value
                                    }
                                }  
                            }  
                         }
                    },
                    data: [
                        {type: 'max', name: '最大'},
                        {type: 'min', name: '最小'}
                    ]
                }
            }
        </script>
    </body>

</html>

以上,虽然代码比较多但是都是重复性的代码片段,没有进行代码优化是因为这样看起来更直观,每个API代表什么一目了然,实际开发时可以进行遍历后存放在数组中,如果觉得对你有帮助请点个赞再走啦

上一篇 下一篇

猜你喜欢

热点阅读