文档章节

Echarts 关于axisLabel中值太长自动换行的问题处理

KevinLi1230
 KevinLi1230
发布于 2015/11/23 12:18
字数 2262
阅读 1313
收藏 0
点赞 1
评论 3

在使用Echars做一个报表功能时,发现axisLabel(即:报表X轴中的lable)显示不能自动换行,导致前面的多个超长的axisLabel叠加在一起,很少写博客,不知道说没说清楚,还是直接上两张换行前的效果图吧。见下图:

                                                    换行前效果图(1)

                                                    换行前效果图(2)


解决方法思路:

解决方案中的计算参考图:

以柱状图为例:

1)图表初始化容器宽度 = x(x轴左间隙宽度,默认80) + width(X轴宽度) + x2(x轴右间隙宽度,默认80);

2)图表X轴宽度(width) = 图表初始化容器宽度 - (x + width + x2);

3)每个axisLabel所在单元格宽度(xAxisWidth) = 图表X轴宽度(width) / 要显示的axisLabel个数(axisDataCount)

4)每个axisLabel单元格显示的字数 = xAxisWidth  / 每个文件子的宽度尺寸(默认12)

5)每个axisLabel显示的字数 = 图表容器div的宽度 / axisLable个数(x轴柱子个数)

为了axisLabel显示的更好看点儿,可以将axisLabel的宽度多减去两到三个字的宽度

故:可将第4步 中的计算改为:

4)每个axisLabel单元格显示的字数 = xAxisWidth  / 单个文子的宽度(默认12) - (个文子的宽度 * 2

经过上面的计算后,将可知道每个axisLabel单元格间可显示的字数,所以在显示时,只需要按照这个字数循环截取并拼接上\n换行符进行换行


上代码:

/**
 * <li>Echarts 中axisLabel中值太长自动换行处理;经测试:360、IE7-IE11、google、火狐均能正常换行显示</li>
 * <li>处理echarts 柱状图 x 轴数据显示根据柱子间隔距离自动换行显示</li>
 * @param title			    将要换行处理x轴值
 * @param datas(xAxisDataLength	)  报表需显示的axisLabel个数(X轴显示的title数)
 * @param fontSize		    x轴上axisLabel字体大小,根据图表字体大小设置而定,此处内部默认为12
 * @param barContainerWidth	    柱状图初始化所在的外层容器的宽度
 * @param xWidth		    柱状图x轴左边的空白间隙 x 的值,详见echarts文档中grid属性,默认80
 * @param x2Width		    柱状图x轴右边的空白间隙 x2 的值,详见echarts文档中grid属性,默认80
 * @param insertContent		    每次截取后要拼接插入的内容, 不传则默认为换行符:\n
 * @returns titleStr		    截取拼接指定内容后的完整字符串
 * @author lixin
 */
function getEchartBarXAxisTitle(title, datas, fontSize, barContainerWidth, xWidth, x2Width, insertContent){
	
	if(!title || title.length == 0) {
		alert("截取拼接的参数值不能为空!");return false;
	}
	if(!datas || datas.length == 0) {
		alert("用于计算柱状图柱子个数的参数datas不合法!"); return false;
	}
	if(isNaN(barContainerWidth)) {
		alert("柱状图初始化所在的容器的宽度不是一个数字");return false;
	}
	if(!fontSize){
		fontSize = 12;
	}
	if(isNaN(xWidth)) {
		xWidth = 80;//默认与echarts的默认值一致
	}
	if(isNaN(x2Width)) {
		xWidth = 80;//默认与echarts的默认值一致
	}
	if(!insertContent) {
		insertContent = "\n";
	}
	
	//柱状图x轴宽度 = 图表初始化容器div宽度 - 柱状图x轴的左右空白间隙宽度(x + x2)
	var xAxisWidth =  parseInt(barContainerWidth) - (parseInt(xWidth) + parseInt(x2Width));
	//x轴单元格的个数(即为获取x轴的数据的条数)
	var barCount = datas.length;
	//统计x轴每个单元格的间隔								
	var preBarWidth = Math.floor(xAxisWidth / barCount);		
	//柱状图每个柱所在x轴间隔能容纳的字数 = 每个柱子的 x轴间隔宽度 / 每个字的宽度(12px)
	var preBarFontCount = Math.floor(preBarWidth / fontSize) ;	
	//为了x轴标题显示美观,每个标题显示留两个字的间隙,如:原本一个格能一样显示5个字,处理后一行就只显示3个字
	if(preBarFontCount > 3) {	
		preBarFontCount -= 2;
	} else if(preBarFontCount <= 3 && preBarFontCount >= 2) {//若每个间隔距离刚好能放两个或者字符时,则让其只放一个字符
		preBarFontCount -= 1;
	}
	
	var newTitle = "";		//拼接每次截取的内容,直到最后为完整的值
	var titleSuf = "";		//用于存放每次截取后剩下的部分
	var rowCount = Math.ceil(title.length / preBarFontCount);	//标题显示需要换行的次数 
	if(rowCount > 1) {		//标题字数大于柱状图每个柱子x轴间隔所能容纳的字数,则将标题换行
		for(var j = 1; j <= rowCount; j++) {
			if(j == 1) {
				
				newTitle += title.substring(0, preBarFontCount) + insertContent;
				titleSuf = title.substring(preBarFontCount);	//存放将截取后剩下的部分,便于下次循环从这剩下的部分中又从头截取固定长度
			} else {
				
				var startIndex = 0;
				var endIndex = preBarFontCount;
				if(titleSuf.length > preBarFontCount) {	//检查截取后剩下的部分的长度是否大于柱状图单个柱子间隔所容纳的字数
					
					newTitle += titleSuf.substring(startIndex, endIndex) + insertContent;
					titleSuf = titleSuf.substring(endIndex);	//更新截取后剩下的部分,便于下次继续从这剩下的部分中截取固定长度
				} else if(titleSuf.length > 0){
					newTitle += titleSuf.substring(startIndex);
				}
			}
		}
	} else {
		newTitle = title;
	}
	return newTitle;
}


解决后的效果图:


附加一个完整的demo吧

1、图片展示的html容器div

<div class="hold track_mid" id="hw_recode">
                	<div class="lx_l2">
                        <div class="tj_mod_subTit scroll2">作业记录</div>
                        <div id="hw_record_bar_chart" class="work_graph" style="height: 350px;">
                        	<%-- <img src="${ctx}/resource/statistics/student/images/zygj.gif" width="435" height="320" /> --%>
                        </div>
                        <div class="remind" id="hw_remind" style="display: none;">
                        	<i class="remind_ico"></i><span id="hw_prompt"><!-- 您的作业有不及格的作业和未完成的作业,可以去课件下查看那些作业 --></span>
                        </div>
                    </div>
                </div>

2、初始化图片展示的js代码

//初始化总入口
$(function(){
    //初始化echart图形,其中成绩详情饼图、个人学习时长折线图、作业轨迹柱状图、测试轨迹柱状图
    initEchartConfig();		
});

/**
 * 通过模块化单文件引入方式引入echart图形插件中具体的图形js
 */
function initEchartConfig(){
	
	// 为模块加载器配置echarts的路径,从当前页面链接到echarts.js,定义所需图表路径
	require.config({
            paths:{
                echarts: basePath+'/resource/common/js/plugins/echarts-2.1.8/js'
            }
        });
	
	// 动态加载echarts然后在回调函数中开始使用,注意保持按需加载结构定义图表路径
	require(
	    [
	        'echarts',
	        'echarts/chart/line',
	        'echarts/chart/bar',
	        'echarts/chart/pie'
	    ],
	    statisticsCallback
	);
}

/**
 * echart统计总回调函数
 */
function statisticsCallback(ec){
    stuHwRecordBar(ec);	
}

/**
 * 学生作业轨迹柱状图
 * @param ec echarts实例
 */
function stuHwRecordBar(ec){
	
	var hwBarChart = ec.init(document.getElementById('hw_record_bar_chart'));
	hwBarChart.showLoading({
	    text: '正在努力的读取数据中...'    //loading话术
	});
	
	var _data = getHomeworkRecord();
	var titleRowNum = _data.titleRowNum || 0;
	var xAxisData = _data.xData;
	var seriesData = _data.seriesData;
	
	var _y2 = null;
	if (titleRowNum) {
		_y2 = titleRowNum * 14 + 7; //y2=标题显示的行数 * 每个字高度 + x轴卡标高度
		if(_y2 > 140) {	//标题自适应高度超过高时设置默认217
			_y2 = 147;
		}
	}
	
	if(xAxisData == null || xAxisData.length == 0) {
		$("#hw_record_bar_chart").text("您没有作业记录信息!");
		$("#hw_remind").text("");
		return false;
	}
	
	hwBarChart.hideLoading();
	hwBarChart.setOption({
        tooltip : {
        	show: true,
            trigger: 'axis',
            axisPointer: {
            	type : 'shadow',	//可选为:'line' | 'cross' | 'shadow' | 'none'(无)
        		shadowStyle : {
				  	size: 'auto',
				  	color: 'rgba(150,150,150,0.3)'
				}
            },
			formatter: function(a) {
				var title = a[0][1]; 
            	if(title.length > 20){	//如果标题大于20个文字,这换行
            		title = title.substring(0, 20)+"</br>"+title.substring(20);
            	}
				return "题目:"+title+"</br>"+a[0][0]+":"+a[0][2];
			}
        },
        grid: {
        	x: 30,
        	y: 30,
        	x2: 30,
        	y2: _y2 || 70	//默认显示4行文字,y2 = x轴文字行数(4) * 文字高度14(12px的文字高度为14) + axisTick.length(X轴卡标线的长度)
        	//,height: 250	//直角坐标系内绘图网格(不含坐标轴)高度,默认为 =总高度 - y - y2,数值单位px,指定height后将忽略y2
        },
        calculable : false,	//{boolean} false,是否启用拖拽重计算特性
        xAxis : [
            {
            	name : '标题',
            	type : 'category',
            	axisTick : {length: 7, lineStyle: {color: '#4488BB', width: 1.5}},
            	splitLine : {show: true, lineStyle: {color: ['#EEEEEE'], width: 1, type: 'solid'}},
                axisLabel : {
                	interval: 0, 
                	rotate: 0, 
                	textStyle: {
//                		color: '#5AB1EF', 
                 		fontFamily: '宋体',
            			/*fontWeight: 'bold'*/
                		baseline: 'top'
                	},
                	formatter: '{value}'
            	},
                data : xAxisData
            }
        ],
        yAxis : [
            {
            	name : '分数',
                type : 'value',
                splitArea : {show: true, areaStyle: {color: ['rgba(250,250,250,0.3)','rgba(240,240,240,0.5)']}},
                splitLine : {show: true, lineStyle: {color: ['#EEEEEE'], width: 1, type: 'solid'}},
                splitNumber : 5
            }
        ],
        series : [
            {
            	name:'分数',
                type:'bar',
                barWidth: 20,
                itemStyle: {
                	normal: {
                		color: '#5AB1EF',
                		label:{
                			show:true,
                			position:'top',
                			textStyle:{
                				fontSize:12
//                				color:"#5AB1EF"
                			},
                			formatter: function(a, b, c){
                				if(!isNaN(parseInt(c))) {
                					return c+"分";
                				}
                				return c;
                			}
                		}
                	}
                },
                data: seriesData
            }
        ]
	});
}

/**
 * 获取学生作业轨迹数据(json)
 */
function getHomeworkRecord(){
	
	var titleRowNum = null;	//x轴标题换行的行数 
	var xAxisData = [];
	var seriesData = [];
	$.ajax({
		url: basePath + '/course/statistics/courseStatisticsStudent_getHomeworkRecord.action',
		data: {courseId: courseId, loginId: loginId},
		type: 'post',
		dataType: 'json',
		async: false,
		cache: false,
		success: function(data){	//成功:{success: true, result: 结果};失败:{success: false, errorCause: 错误原因}
			if(data.success && data.result) {
				
				var rowNums = [];				//存放测试每个标题根据柱子间隔换行后的行数
				var hasUnCompleteHw = false;	//是否有为完成的作业标记,为了显示提示信息,默认false:没有
				var res = data.result;
				$(res).each(function(i, obj) {
//					if(i<9){
					var hwTitle = this.homeworkInfo.title;
					var newHwTitle = getEchartBarXAxisTitle(hwTitle, res, 12, 983, 30, 30, "\n");	//处理标题,使其根据柱状图x轴每个柱子的间隔距离自动换行
					xAxisData.push(newHwTitle);
					if(this.enumConstByFlagHomeworkStatus != null){
						 if(this.enumConstByFlagHomeworkStatus.code=='1') {
							seriesData.push({
								value: "未\n批\n改",
								itemStyle: {normal: {color: '#00AA00'}}
							});
						}else if(this.enumConstByFlagHomeworkStatus.code=='2') {
							seriesData.push(this.totalScore);
						}else if(this.enumConstByFlagHomeworkStatus.code=='3') {
							hasUnCompleteHw = true;
							seriesData.push({
								value: "已\n退\n回",
								itemStyle: {normal: {color: '#FF0000'}}
							});
						} else if(this.enumConstByFlagHomeworkStatus.code=='0'){
							seriesData.push({
								value: "未\n提\n交",
								itemStyle: {normal: {color: '#ff8723'}}
							});
						}else{
							hasUnCompleteHw = true;
							seriesData.push({
								value: "未\n做",
								itemStyle: {normal: {color: '#ff8723'}}
							});
						}
					}else{
						hasUnCompleteHw = true;
						seriesData.push({
							value: "未\n做",
							itemStyle: {normal: {color: '#ff8723'}}
						});
					}
					rowNums.push((newHwTitle.split("\n").length + 1));	//将每个标题占的行数存入数据,便于获取最大标题占的行数去动态设置echars的grid的y2的值
//					}
				});
				
				titleRowNum = rowNums.sort(function(a,b){return a < b ? 1 : -1;})[0];	//有大到小排序
				
				if(hasUnCompleteHw) {
					$("#hw_prompt").text("您有未完成的作业,可以去课件下查看");
					$("#hw_remind").show();
				}
			}
		},
		error: function(){alert("请求失败,请刷新重试或联系管理员!");}
	});
	return {xData: xAxisData, seriesData: seriesData, titleRowNum: titleRowNum};
}



欢迎大牛们给我指点指点



© 著作权归作者所有

共有 人打赏支持
KevinLi1230
粉丝 1
博文 2
码字总数 3200
作品 0
北京
后端工程师
加载中

评论(3)

KevinLi1230
KevinLi1230

引用来自“mendacity_jenny”的评论

请问能给个调用的例题莫?我这样调用,换行OK,但其他的还是不显示啊,就像不换行时,其中几个就不显示的形式一样,
我刚刚在上面文章里面追加了完整demo,不知道您能不能看明白,没时间整理,比较混乱
KevinLi1230
KevinLi1230

引用来自“mendacity_jenny”的评论

请问能给个调用的例题莫?我这样调用,换行OK,但其他的还是不显示啊,就像不换行时,其中几个就不显示的形式一样,
这儿回复没法格式化代码,凑合着看吧 function getHomeworkRecord(){ var titleRowNum = null; //x轴标题换行的行数 var xAxisData = []; var seriesData = []; $.ajax({ url: basePath + '/course/statistics/courseStatisticsStudent_getHomeworkRecord.action', data: {courseId: courseId, loginId: loginId}, type: 'post', dataType: 'json', async: false, cache: false, success: function(data){ //成功:{success: true, result: 结果};失败:{success: false, errorCause: 错误原因} if(data.success && data.result) { var rowNums = []; //存放测试每个标题根据柱子间隔换行后的行数 var res = data.result; $(res).each(function(i, obj) { var hwTitle = this.homeworkInfo.title; var newHwTitle = getEchartBarXAxisTitle(hwTitle, res, 12, 983, 30, 30, "\n"); //处理标题,使其根据柱状图x轴每个柱子的间隔距离自动换行 xAxisData.push(newHwTitle); }); titleRowNum = rowNums.sort(function(a,b){return a < b ? 1 : -1;}); //有大到小排序 } }, error: function(){alert("请求失败,请刷新重试或联系管理员!");} }); return {xData: xAxisData, seriesData: seriesData, titleRowNum: titleRowNum}; }
m
mendacity_jenny
请问能给个调用的例题莫?我这样调用,换行OK,但其他的还是不显示啊,就像不换行时,其中几个就不显示的形式一样,
百度Echarts图表在Vue项目的完整引入以及按需加载

导语 近日在项目中需要进行图表展示,百度的Echarts图表是非常合适的一个选择。项目是vue-cli搭建的,如何在项目中引入Echarts就是一个问题了。亲自动手实践了下,整理总结,希望对小伙伴提供...

JustBeCoder ⋅ 06/15 ⋅ 0

vue之将echart封装为组件

最近的新项目里,有大量数据图表类的需求,为了增强代码的复用性,减少冗余,我开始思考如何将echart封装为组件调用。本文将会以雷达图为案例,一步步讲解在vue项目中如何使用echart,如何将...

四小七 ⋅ 05/21 ⋅ 0

Echarts视频教程从入门到实战

Echarts视频教程从入门到实战 网盘地址:https://pan.baidu.com/s/1p-G9UbKmXFtnuJEdiLSw2w 密码:0e9u 备用地址(腾讯微云):https://share.weiyun.com/5sKBF8E 密码:4ms8rp 有这样一款制...

放风筝好不 ⋅ 04/16 ⋅ 0

ssh结合echarts做图表展示

在日常的开发中,我们常常需要使用图表对数据进行展示,在这里作者使用百度的开源图表echarts动态的展示数据。 看过echarts的API都知道,要想使用某种类型的图表展示数据,必须封装好一个JSO...

_Artisan ⋅ 06/04 ⋅ 0

Echarts-百度地图省分着色

通过Echarts3结合百度地图,对全国省分进行着色。 起因 由于Echarts3中,不再使用china.js文件: ECharts 之前提供下载的矢量地图数据来自第三方,由于部分数据不符合国家《测绘法》规定,目...

莫显辉 ⋅ 05/04 ⋅ 0

Vue教程(五)在vue项目中使用echarts

1安装Echart cnpm install echarts --save 2项目页面引用Echart import echarts from 'echarts' 3启动项目 npm run dev...

凌雲木 ⋅ 04/20 ⋅ 0

echarts3.0在IE9中,bar图在使用datazoom时,数据显示不完全的问题

我在swt控件中调用browser,然后用echarts来展现我的数据,IE是IE9,柱状图设置了dataZoom,但是当我拖动dataZoom滑竿时,展现的数据没有全部展现出来,只有当dataZoom覆盖全部时,数据才全部...

kmust123 ⋅ 04/26 ⋅ 0

NEV与其他图表引擎的横向对比

本文由 网易云 发布 作者:刘阳 本篇文章仅限内部分享,如需转载,请联系网易获取授权。 NEV与其他图表引擎的横向对比 对比的其他图表库包括vega、HighCharts、 ECharts以及G2 图表类型 柱状...

wangyiyungw ⋅ 05/14 ⋅ 0

【前端图表】echarts散点图鼠标划过散点显示信息

在做项目的过程中,总会遇到这样或者那样的bug,这个时候就要看自己的动手能力有多强了,着手解决了一个bug之后,整个人都感觉很开心,端午下班之前遇到了一个小问题,echarts散点图鼠标划过...

祈澈姑娘 ⋅ 昨天 ⋅ 0

关于echarts有多条曲绘制的问题

前端在调用echarts时,有两条曲线。一条曲线的气泡值是跟y轴坐标值对应。另一条却不对应。值有出入,请问大神们有没碰到这个问题?

zb1481792443586 ⋅ 06/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Boot整合模板引擎thymeleaf

项目结构 引入依赖pom.xml <!-- 引入 thymeleaf 模板依赖 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId......

yysue ⋅ 19分钟前 ⋅ 0

ConstraintLayout使用解析

AndroidStudio3.0创建Project默认的布局就是ConstraintLayout。 AndroidStudio3.0前的可以自己修改,使用ConstraintLayout。 为了要使用ConstraintLayout,我们需要在app/build.gradle文件中...

_OUTMAN_ ⋅ 30分钟前 ⋅ 0

OSChina 周三乱弹 —— 这样的女人私生活太混乱了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 胖达panda :你经历过体验到人生的大起大落吗?我一朋友在10秒内体验了,哈哈。@小小编辑 请点一首《almost lover》送给他。 《almost love...

小小编辑 ⋅ 今天 ⋅ 9

自己动手写一个单链表

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对...

公众号_好好学java ⋅ 今天 ⋅ 0

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部