echarts横坐标自动判断文字遮挡问题-简单记录-仅供参考

1.简介

熟悉echarts的同学应该知道,echarts中的直角系图表当坐标轴为类目型(常为x轴)而且数据又特别多时,默认会隐藏掉一部分x轴文字。效果就类似于这样:
auto
然而,echarts自带的计算有时候是过于苛刻的,即使文字实际上不存在遮挡问题,当文字与文字间的间隔小于一定值时同样会触发隐藏机制,例如上面那张图,如果设置{xAxis:{axisLabel:{interval:0}}}显示出所有的横坐标文字,实际上文字也不会产生遮挡。
interval0
另外,有时候即使文字产生遮挡了,我们通过将文字旋转一定的角度也能使文字完全显示,不过遗憾的是,echarts本身并不提供这个功能。先上一张效果图。
rotate
还有一种情况,当数据个数较多或文字较长的时候,此时旋转文字已经于事无补,这里我们的解决方案是将图表进行转置,即柱形图变为条形图,同时对左边文字进行预换行处理,而后根据UI提供的柱子宽度和间隔对承载echarts的DOM元素做增高处理。效果是这样的。
(下面的效果图在DOM元素外又包了一层用于实现展开收起动画,并且默认显示所有label)
待展开
close
已展开(缩放可能有些模糊)
reverse

2.简单分析

首先声明,本文并不是一篇多实用的教程,因为功能比较复杂,设计的知识点比较多,而且代码和页面结构具有一定的耦合性,所以看了本文的人不一定就写的出本文的效果,仅供大家参考,也是为我自己做一些记录,万一以后有类似的需求就可以快速部署。不懂原理只会复制粘贴的人可以止步了,复制过去也会有很多错误。
另外,代码中所涉及的页面结构如下:

//伪代码
<div class="chart-container">
	<div id="chart"></div>
</div>

// var chartDOM = globalTools.data.echartsDOM = $('#chart')[0];
//var chart = globalTools.data.echartsContainer = echarts.init(chartDOM);

注:本文所有的函数一般有附带有其还原操作或函数,例如showAllLabel(显示所有label)和hideAllLabel(隐藏所有label)两个函数相对应。
另外,对坐标轴文字进行换行的操作用到了我之前写的另外一篇文章里的函数,dc.getWrapString();//文章链接如下:
JS文本换行算法-模拟计算文字换行位置-基于DOM元素自发换行行为和字符分割原理-支持实体编码、不支持标签嵌套和富文本
并在xAxis的axisLabel.fomatter进行了如下设置:

var xAxis = {
	axisLabel: {
					color: "#999999",
					textStyle: {
						fontSize: 12
					},
					formatter: function(value,index){
						var fontSize;
						try{
							fontSize = globalTools.data.echartsContainer.getOption().xAxis[0].axisLabel.fontSize;
						}catch(e){fontSize=12}
						width = '135px';
						if(globalTools.data.isReverse) width = '219px';
						var result = dc.getWrapString(value,{
							fontSize: fontSize+'px',
							width: width
						});
						if(typeof index === 'number'){
							if(index==0){
								d.data.xAxisLabel = []
							}
							if(d.data.xAxisLabel&&d.data.xAxisLabel.indexOf(result)<0) d.data.xAxisLabel.push(result);
						}
						return result;
					},
					showMaxLabel: true,
					showMinLabel: true
				}
}

效果是这样的:
wrap
以下对xAxis的计算全部基于上述设置(即文本预换行和强制显示首尾项)

2.1代码思路介绍

//注,代码中的短标识符d等同于长标识符globalTools,而dc则是另外一个标识符。两者都是一个对象,对象中定义了某些函数或常变量。
先解释一下我的思路:
首先,判断x轴文字是否产生遮挡问题并进行适应的函数名称为rotateXAxisIfNeed,取名含义就是字面上的意思。要完成这个算法要求用到一些辅助函数,其中有一些我已经提到过,例如计算一行字符占用宽度的js函数(d.getStringWidth()或globalTools.getStringWidth())。链接:
js小工具-模拟计算一行文本的宽度
此函数的思路如下:
1.先计算出当前图表可用的宽度大小,即chartDOM的宽度-grid占用-y轴占用宽度 之后剩下的宽度就是实际绘图的可用宽度。
2.区别对待x轴为类目轴(category)和数值轴(value)的情况,主要处理类目轴。
3.假设所有坐标文字都有进行显示,取坐标文字中占用宽度最大的一项的宽度作为平均宽度,估算坐标文字的宽度累加值是否超过绘图可用宽度。若没超过则直接显示所有坐标文字,结束函数,否则继续判断。
4.假定旋转角度为45度,先记录正弦值和余弦值用来等下判断两端溢出。然后取坐标文字中行数最多的一项的行数乘以字体大小作为旋转后的占用宽度,判断宽度累加值是否超过绘图可用宽度,若没超过,则对文字进行旋转,结束函数,否则继续。
5.当旋转后还是无法显示所有坐标文字时,则进行图表转置,转置的代码定义在d.chartReverse中。

图表的转置其实是非常简单的,但是这里由于项目需要的关系,我在转置中还调用了一些其他函数,例如d.chartSizeFix()用来对图表进行自动增高或还原等。
同时代码还结合在另外两篇文章里提到的计算图例高度和标题高度来对图片进行适应性设置(d.getTitleHeight和d.getLegendHeight&

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月桦剑士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值