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

背景:脑洞大开的产品看到如下图这种多个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代表什么一目了然,实际开发时可以进行遍历后存放在数组中,如果觉得对你有帮助请点个赞再走啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容