最近看了很多BI产品,柱状图的X轴标签文字能够随着系列柱体宽度自动旋转(如果在范围内就横向,不在范围内就自动变成竖向)
效果如下:
需求前提:
每个label不能超过10个字符,否则以...结尾代替
实现思路:
基于echarts的尿性。笔者查阅了许多互联网的资料,都没有一个完整的好的解决方案实现自动旋转。那么就只能自己来干了。
Step1:获取echarts组件容器的宽度
<template>
<div ref="chartDom"></div>
</template>
<script>
...
// 计算包裹柱状图的grid长度
gridWidth() {
const width = this.$refs.chartDom.clientWidth;
// 这里是用户自定义配置或默认配置
const { left = '0%', right = '0%' } = this.chartsOption.grid;
const decrease = +left.replace('%', '') + +right.replace('%', '');
return (width * (100 - decrease)) / 100;
}
</script>
Step2:动态配置柱状图配置
xAxis: {
...,
axisLabel: {
...,
rotate: handleAxisRotate(
chartOption.axisLabel, //用户配置
gridWidth, //上文提到的grid长度
userData.series, // 指标数据(y轴)
),
// 这一块是为了简化label
formatter: function() {
return name.length > 10 ? `${name.substr(0, 7)}...` : name;
}
},
data: userData.xAxis //x轴数据
},
...
function handleAxisRotate(opt, width, dataArr) {
const customShowNum = 45;
let dataColumn = 0;
dataColumn = dataArr.length;
if (dataColumn <= customShowNum) {
endValue = dataColumn ? Math.floor(customShowNum / dataColumn) - 1 : 0;
}
const length = dataArr[0].data.length;
const { fontSize = 12 } = opt;
return width / (endValue > length ? length : endValue * 10) >= fontSize
? 0
: 90;
}
这里讲一下handleAxisRotate的逻辑,先看一下面的图,系列是指一个维度的系列,组列是指一个系列(维度)里包含了多少组(列)数据。
?
? ? const customShowNum = 45;? // 为了好看,每个图表的当前面不超过45个柱体。详见:【Echarts】解决[柱状图设置barMinWidth导致的柱体重叠]与解决[柱状图设置barMinHeight导致数值0也有高度]_AID3_WebEngineer的博客-CSDN博客解决echarts柱状图问题https://blog.csdn.net/weixin_42274805/article/details/125265161 ? ? let dataColumn = 0; ? ? dataColumn = dataArr.length; // 一个系列里一共有多少组列
? ? // 为了避免指标过多 ? ? if (dataColumn <= customShowNum) { ? ? ?endValue = dataColumn ? Math.floor(customShowNum / dataColumn) - 1 : 0; ? ? }
? ? //? endValue计算出我们每个滑动面最多需要展示多少个系列数据。而length则告诉我们如果把数据都揉在一个滑动面会有多少个系列数据 ? ? const length = dataArr[0].data.length;
? ? // 一个字符12px ? ? const { fontSize = 12 } = opt;
? ?// 字符12px *?最长十个字符? * 一个滚动面有endValue或length个系列 跟gridWidth比大小,超出则变成竖排展示 ? ? return width / (endValue > length ? length : endValue * 10) >= fontSize ? ? ? ? 0 ? ? ? : 90;
Step3:监听页面变化
import { addListener, removeListener } from 'resize-detector';
mounted() {
...
const chartDom = this.$refs.chartDom;
addListener(this.$refs.chartDom, this.chartResize);
}
chartResize() {
this.myChart.resize();
this.reBuildShowOPT({width:this.gridWidth()});
}
|