在使用echarts 封装组件的时候,偶尔会遇到需要x轴坐标进行二层分组的需求。那么如何对echarts 进行二层分组呢,有以下几个步骤:
仅介绍二层分组的逻辑。有兴趣的可以进行三层延伸。
1,修改echarts Options 中xAxis 的配置。
此时若进行e二层分组,则xAxis 应该是一个数组,里面有两个x轴的配置对象。
第一个x轴对象除了需要data属性,其余属性正常配置即可。
第二个x轴对象需要配置
xAxis[
{
// 第一个x轴坐标(最靠近x轴的那个坐标
type:'category',
data:[],
},
{
// 第二个x轴坐标
type:'category',
position: 'bottom', 坐标轴的位置
offset:40, // 该坐标轴x轴文本向下偏移距离
axisTick:{
length: 40, // 增加分组下面父级坐标刻度线长度
interval: // 这个属性很重要下面介绍
},
axisLabel:{
align: 'center',
interval: 0,
formatter:// 这个属性很重要,下面介绍。
},
data:[],
}
]
现在第二个x轴配置只有axisTick.interval,axisLabel.formatter这两个属性没有介绍。在下面会继续介绍的。
2,处理接口中返回的x轴数据,此时返回的x轴数据应该是一个数组并且分为两种情况。
以下图示例
2.1,第一种情况也是最终需要的数据结构
需要单层数据即可表达二级父子关系
interface XAxis {
first: string, // 第一层数据 (距离坐标轴最近的数据)
second: string // 第二层父级数据
}
// 则以上面数据为例,原始x轴数据为
xAxisData = [
{second:'水果',first:'香蕉'},
{second:'水果',first:'苹果'},
{second: '笔', first:'圆珠笔'},
{second:'笔', first:'钢笔'},
]
// 此种数据结构就是最为合适的。第一层x轴数据大家直接将xAxisData 中的first属性过滤即可
// 第二层数据的处理将会在第三步进行介绍
2.2,第二种接口返回的x轴数据
第二种数据结构为二层数据结构,以上图为例应该是
xAxisData = [
{second:'水果',child:[
{first:'香蕉'},
{first:'苹果'}
]},
{second: '笔', child:[
{first:'钢笔'},
{first: '圆珠笔'}
]}
],
如果接口返回的是这种二层数据结构,则需要将其扁平化变成上面那种只有一层的数据结构
3,编写辅助函数,配置Option
3.1,辅助函数
/**
* @description: 计算第N层X轴重复字符串终止索引 n>1
* @param { string[] } list 第n层x轴全部数据
* @return {*}
*/
const countXAxisEndIndex = (list: string[]) => {
const temp = {} as { [key: string]: number };
if (list.length) {
let newVal = list[0];
let newIndex = 0;
temp[list[0]] = 0;
for (let i = 1; i < list.length; i++) {
if (newVal !== list[i]) {
temp[newVal] = newIndex;
newVal = list[i];
}
newIndex++;
}
}
temp[list[list.length - 1]] = list.length - 1;
return temp;
};
/**
* @description: 计算第N层X轴重复字符串起始索引 n>1
* @param { string[] } list 第n层x轴全部数据
* @return {*}
*/
const countXAxisStartIndex = (list: string[]) => {
const temp = {} as { [key: string]: number };
if (list.length) {
let newVal = list[0];
temp[list[0]] = 0;
for (let i = 1; i < list.length; i++) {
if (newVal !== list[i]) {
newVal = list[i];
temp[list[i]] = i;
}
}
}
return temp;
};
3.2,在循环中配置Option
首先已知知最终x轴的数据为
xAxisData = [
{second:'水果',first:'香蕉'},
{second:'水果',first:'苹果'},
{second: '笔', first:'圆珠笔'},
{second:'笔', first:'钢笔'},
]
在循环中配置xAxis中的数据。
当然目前只有两层可以不进行循环遍历。
只需要给option.xAxis[1]中的配置属性进行赋值即可
1,首先对data 属性进行赋值
option.xAxis[1].data = xAxisData.map((item:any)=>{return item.second;})
2,配置option.xAxis[1].axisTick和option.xAxis[1].axisLabel这两个对象
首先大家可能不知道上面两个辅助数组的作用
countXAxisStartIndex,获取第N层重复字符串的起始索引
const tempStartObj = countXAxisStartIndex(xAxisData)的结果为 {水果:0,笔:2 }
countXAxisEndIndex,获取第N层重复字符串的终止索引
const tempEndObj = countXAxisEndIndex(xAxisData); 的结果为 {水果:1,笔:3}
下面就可以开始配置x轴第二层相关属性了
option.xAxis[1] = {
...option.xAxis[1],
aXisTick:{
length: 40,
// 设置第二层刻度线的间隔,当第一个元素,以及每个重复二级元素的最后一个才会设置刻度
interval: (index: number, value: string) => index === tempEndObj[value] || index === 0,
},
axisLabel:{
align:'center',
interval:0,
// 去掉重复的二级坐标刻度,只保留位于一级坐标中间索引的那个二级坐标
formatter: (value: string, index: number) => {
const nowIndex = tempEndObj[value] - tempStartObj[value];
if (index === tempEndObj[value] - Math.ceil(nowIndex / 2)) {
return value;
}
return '';
},
}
};
注意事项:一定要先进行data属性赋值,否则,下面的aXisTick.interval,aXisLabel.formatter 对应的方法就不会有回调参数了。
如何进行三层分组,以及多层分组;
大致逻辑和二层分组的逻辑是相同的。
要在循环中生成option.xAxis数组中的每个配置对象。对除了第一级的x坐标轴都需要进行设置position :'bottom';调整offset 的数值(第N层数据距离x轴的距离。以及增加axisTick.length 刻度的长度,
以上就是echarts 中x轴坐标分组的核心逻辑。