最近项目组接到了许多对图表有特殊要求的需求,比如今天说的这个呈现光纤的中断时长分布的需求:
光纤的中断大部分落在30分钟之内,但偶尔遇到特殊情况时,会出现中断一两天甚至更长的时间,如果把这些时长分布放在一个刻度均匀的数轴上,势必造成大部分的指标(此处为柱状图)特别短的问题,因此,希望建立一个刻度一开始均匀分布,比如10min、20min,到60min之后立刻升为2hour、1day这样的需求。
一开始拿到这个任务,我的第一反应,是查找Echarts的配置项手册,希望通过在yAxis上做手脚来解决问题。然鹅事情总是没有想象的顺利,echart对y轴对配置只能指定几种type:‘category’、‘value’和‘log’,虽然配置为log对数轴也可以解决较大值对较小值对影响的问题,但当值较小时也无法通过长度区分开,不够完美。
庆幸的是,在echarts的GitHub官网上,pissang大大给出了一个思路:
深受启发!为什么一定要依赖Echarts本身给予解决方案呢?完全可以自己构造一个新的分布呀!
不多说,开始码:
第一步:利用yAixs.axisLabel.formatter伪造一个不均匀坐标轴
先给大家看看具体的代码:
//利用formatter将y轴上本来为70(min),80(min)的点强制改为2hour和1day
formatter:function(value) {
let item='';
if(value==70){
item='2hour'
}else if(value===80){
item='1Day'
}else{
item=value+' min'
}
return item
}
第二步:将数据映射到一个特定的分布
这句话的意思,其实就是自己构造一个函数,将原始数据里较大的数值转换成一个小数值
我是这样做的:
//模拟数据,其中的200、150是应该落在2hour和1day之间,所以映射后的数据应该落在70min到80min之间
let data = [10, 15, 4, 20, 200, 150, 19,70,1441];
function formatData(arr){ //自己构造一个用来映射data到均匀数轴上的方法
for(let i=0;i<arr.length;i++){
if(arr[i]>60&&arr[i]<=120){
let percent1=(arr[i]-60)/120;
arr[i]=percent1*10+60;
}else if(arr[i]>120&&arr[i]<1440){
let percent2 =(arr[i]-120)/1440;
console.log(percent2);
arr[i]=percent2*10+70;
}
}
return arr;
}
上面这个formatData,其实就是对data数组里超过60的数据进行改造,如果这个数据超过了60min且小于120min(2hour),就按照这个数据在60到120段应该有的比例,映射到60到70段里,而超过2hour且小于1day的数据,则同样按这个方法,计算映射到70到80段里
这样一来,任务已经基本完成啦!
第三步:将数据反映射为原来的值
但是现在在图表里,我们拿到的是映射后的数据,如果此时的tooltip是开放的,那么用户在tooltip里读到的数据就不是原来的200min,150min这种的了,而变成了一个70min到80min之间的较小数据。怎么办?只能在每个需要展示数据的地方,严防死守,将这几条特殊的数据反计算回去咯!
tooltip:{
formatter:function(params) { //由于在tooltip里需要展示原始的数据,所以要把映射后的数据反计算回去
let str=params.name+':'+params.value;
if(params.value>=60&¶ms.value<70){
let percent = (params.value-60)/10
let value = Math.round(percent*120+60);//注意此处的percent已经是个浮点数了,所以得到value之前要用四舍五入取整才行
str=params.name+' : '+value;
}else if(params.value>70&¶ms.value<80){
let percent = (params.value-70)/10;
let value =Math.round(percent*1440+120);
str=params.name+' : '+value;
}
return '<div style="width:70px;height:50px;display:flex;align-items:center">\
<span style="background-color:#D53A35;width:15px;height:15px;display:inline-block;border-radius:50%"></span>\
<span>'+str+'</span>\
</div>'
}
}
嗯,现在就可以了,接下来上一个效果图炫耀一下:
一切看上去都是那么的完美,其实这种方法当然还是瑕疵的,你能看出来吗:)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。