在使用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}; }
欢迎大牛们给我指点指点