Echart双Y轴刻度对齐
Hz 4/12/2023 Echart
# 前情回顾
推荐这篇优秀的文章:
EchartJS 双Y轴 0刻度对齐处理
文章中介绍了Echart双轴出现负值时双轴对称处理方式,最后能达到0刻度线对其,但是双轴每段刻度参差不齐。
抛开技术不谈,就美观程度来说还是不够的。
遂有一个新需求诞生:需要达到 刻度对齐
。
# 刻度对齐
刻度对其相对来说没那么麻烦,通过Echart提供的API即可达到效果。
interval
:强制设置坐标轴分割间隔
max
:坐标轴刻度最大值。
重点是计算每段坐标轴分割间隔大小。
算法逻辑是先缩小每段刻度的10^n,再向上取整,最后放大回来。
比如:
当每段为241.28571428571428
Math.ceil(241.28571428571428 / 100) * 100 = 300
当每段为81691.42857142857
Math.ceil(81691.42857142857 / 1000) * 1000 = 82000
// 数据
var LeftNum = [0, 1336, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, ]
var LeftNum = [503, 1689, 118, 165, 686, 662, 645, 320, 15, 113, 40, 143, 740, 182, 29];
var LeftData = {
max: Math.max(...LeftNum),
min: Math.min(...LeftNum)
}
var RightNum = [571840, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
RightNum = [2, 0, 6, 2, 2, 3, 11, 6, 7, 4, 1, 2, 1, 6, 7];
var RightData = {
max: Math.max(...RightNum),
min: Math.min(...RightNum)
}
//双轴段数
let intervalData = 7;
console.group("双轴取整后每段大小");
let yAxisIntervalList = [IntergerNode(LeftData.max / intervalData), IntergerNode(RightData.max / intervalData)];
console.log("双轴取整后每段大小", yAxisIntervalList)
console.groupEnd();
console.group("双轴最大值");
let yAxisMaxList = [yAxisIntervalList[0] * intervalData, yAxisIntervalList[1] * intervalData];
console.log("双轴最大值", yAxisMaxList)
console.groupEnd();
// 选中项
var selected = {
注册: true,
活跃: true
}
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
option = null;
option = {
//1、 格式化提示信息
tooltip: {
trigger: 'axis',
},
toolbox: {
feature: {
dataView: {
show: true,
readOnly: false
},
magicType: {
show: true,
type: ['line', 'bar']
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
legend: {
data: ['注册', '活跃'],
selected,
},
grid: {
width: '50%',
height: '50%'
},
xAxis: [{
type: 'category',
data: [
"2022-09-01",
"2022-09-02",
"2022-09-03",
"2022-09-04",
"2022-09-05",
"2022-09-06",
"2022-09-07",
"2022-09-08",
"2022-09-09",
"2022-09-10",
"2022-09-11",
"2022-09-12",
"2022-09-13",
"2022-09-14"
],
axisPointer: {
type: 'shadow'
}
}],
yAxis: [{
type: 'value',
name: '注册',
interval: yAxisIntervalList[0],
max: yAxisMaxList[0],
},
{
type: 'value',
name: '活跃',
interval: yAxisIntervalList[1],
max: yAxisMaxList[1],
}
],
series: [{
name: '注册',
type: 'bar',
data: LeftNum
},
{
name: '活跃',
type: 'bar',
yAxisIndex: 1,
data: RightNum
},
]
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
myChart.on('legendselectchanged', function(params) {
option.legend.selected = params.selected
selected = params.selected
myChart.setOption(option);
})
}
function IntergerNode(data) {
console.group(`节点取整计算:${data}`)
data = data < 0 ? Math.abs(data) : data;
// 数值位数
let len = parseInt(data).toString().length;
console.log("长度", len)
if (len <= 2) {
let value = Math.ceil(data)
console.log("长度 < 2,直接取整", value)
return value;
}
// 缩放倍数系数
let coefficient = len >= 4 ? 2 : 1
// 缩小倍数
let multiple = Math.pow(10, len - coefficient);
console.log(`倍数系数 10^${coefficient}`, )
// 缩小N倍,向上取整,放大N倍
let value = Math.ceil(data / multiple) * multiple;
value = data < 0 ? -value : value;
console.log(`取整结果 Math.ceil(${data} / ${multiple}) * ${multiple} = ${value}`);
console.groupEnd()
return value;
}
# 总结
上面只能应对数据都是正数的情况。如果数据中有负数就会出现0刻度不对其的情况。
暂时能想到的,能解决负数的办法是 镜像正区间部分到负区间-实现0刻度线对齐
在美观性上还是有所欠缺。😅😅😅
# 思考一
按照常理来说 双轴刻度对其
0刻度对其
也算是一个常规需求。
但是市面上的的图表组件好像都没这个效果,难道不好实现?
# 思考二
"魔鬼"客户又又又提了个新需求:
假设图表X轴显示了30天的数据1号~30号,正常图表中X轴是放不下所有时间的,会以省略的方式显示。
对方希望起止日期正常显示,中间部分可以省略显示。市面上也没有这种组件。😅😅😅