图1背景:脑洞大开的产品看到如下图这种多个tooltip联动的统计图,为了在客户面前装逼就把这个功能加到了本次需求里面,经过查看源码发现使用echarts绘制的,虽然本人也经常用echarts但是这种图实在没画过,查看相关API也没找到实现办法,网上关于这部分的问题也非常少,最后终于实现,记录如下:
代码暂时没有优化但是功能全部实现了,可以直接拷贝下面的代码到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代表什么一目了然,实际开发时可以进行遍历后存放在数组中,如果觉得对你有帮助请点个赞再走啦
网友评论