Echarts折线图表断点如何补全

Echarts折线图如何补全断点以及如何隐藏断点的title

  做报表的时候,尤其是做图表的时候时常会碰到某一记录的值中缺少某个时间段(比如月份或季度)的值,导致图表显示残缺不全,for example:

如果照实显示的话确实不太美观(除非贵公司确实需要特别准确的数据除外~),当然我们的客户是做信托的,算钱的系统和时常开会追KPI的时候看报表系统~;给领导写报告图表当然不能太另类~\(≧▽≦)/~,遂业务部门的同学要求我们尽可能在数据准确的情况下将图表做的更美观些些,...吾以为这个貌似难难滴欸。。。。,怎么办。。。。,研究来研究去,之后我们将报表做成了这样纸>>> 

    感觉挺好的,不知业务的妹纸是否满意(✿◡‿◡)

 且细看....细看,比如图中34个月与35个月是没有数据滴,哈哈,成功!!

一下分享下我的思路:

        A>首先要取得所有部门的期限内的所有数据(当然这个过程你需要自己码代码获得一份完整的月份数据,要不然你怎么知道记录的断点位置呢,是不?)

        B>然~,整理你的数据,分层是必要的(如果数据库能按按部门分层月份,干嘛还要这么累啊(=@__@=))

        C>再~,两层遍历,等等干什么呢?-->这是要找出断点,并用统一的mark以标示

          (具体就是外层循环月份List,然后遍历所有的按部门归类的部门的月份找出此部门再哪个期限缺值)

        D>然~,看似以上已经找出了断点了,但试想下如果这些断点都是以‘—’补全,图还是会断啊~~~,怎么办;

           啊哈 so easy~ 将此断点补上前后两个值的平均值不就是一条直线啦,啦啦啦~

        E>啦啦啦,搞定\(^o^)/YES!   。。。。,浏览器打开页面~ (⊙﹏⊙)b 为什么为什么为什么还会显示title呢,

           这样会暴露程序猿的审美····,how? 官方API搞定....

 直接放代码可能让各位一头雾水,先给一份样例数据方便大家调试:

下图是具体代码:

   注:echarts需要的数据样例如19~31注释部分

      37~40行获取limits数据,也就是x轴月份数据

      30~56行处理echarts分层数据(按部门划分)

      62~121行处理断点数据(将已经分层的里面的月份‘—’处理成前后值的平均数,使折线平滑)

          在这个之前需要对月份数据排序(从小到大排序),方法在最下面哈

      至于怎么将断点数据默认不显示,呢,答案很简单->请注意104行里面有个参数:“symbol:'none'”,这是官方API

        如对最后的图表的结构数据不懂,请看这里,看这里:http://echarts.baidu.com/echarts2/doc/example/line2.html

  1     function generateChart04() {
  2         var detailData = module.page["allFundStatD4s"].detaillist,
  3                legendData=[],//标题名称组
  4                limits=[],//期限
  5                myData={},//系列数据
  6                label={normal:{
  7                          show: true,
  8                          //position: 'top',
  9                          formatter: '{c}%'
 10                      }},
 11                seriesData=[];
 12         /**
 13          * A>构建系列结构数据
 14          * B>系列数据格式化和断点处理
 15          * C>图表显示样式处理
 16          */
 17         /*
 18          * 系列数据样例->
 19          * {"广州管理部":{
 20          *                             "期限":{1:0.173,6:0.863,9:0.777,12:0.66,36:0.039},#myLimits
 21          *                             "datas"{"广州管理部",type:"line",data:"(取)期限",
 22          *                                     label:{
 23          *                                              normal: {
 24                                                      show: true,
 25                                                      position: 'top',
 26                                                      formatter: '{c}%'
 27                                                  },
 28          *                                     }
 29          *                                     }
 30          *                         }
 31          * }
 32          */
 33         for(var i in detailData){
 34             //如果没有当前legend值,先初始化新建个;如果有,则更新当前期限值
 35             if(!myData[detailData[i].deptName]){
 36                 legendData.push(detailData[i].deptName);//放入图表标题数组中
 37                 if(limits.indexOf(detailData[i].realTimeLimit)==-1){//不存在
 38                 //if(!(limits.includes(detailData[i].realTimeLimit))){
 39                     limits.push(detailData[i].realTimeLimit);//放入期限数组中
 40                 }
 41                 myData[detailData[i].deptName]={};//声明
 42                 myData[detailData[i].deptName].myLimits={};//声明
 43                 myData[detailData[i].deptName].myLimits[detailData[i].realTimeLimit]=detailData[i].compositeCost;//放入期限
 44                 myData[detailData[i].deptName].datas={};
 45                 myData[detailData[i].deptName].datas.name=detailData[i].deptName;//当前legend放入名称
 46                 myData[detailData[i].deptName].datas.type="line";//当前legend放入类型
 47                 myData[detailData[i].deptName].datas.data=[];//先预留,取到所有系列数据后再填入数据
 48                 myData[detailData[i].deptName].datas.label=label;//线型预设值
 49             }else{
 50                 if(limits.indexOf(detailData[i].realTimeLimit)==-1){//不存在
 51                 //if(!(limits.includes(detailData[i].realTimeLimit))){
 52                     limits.push(detailData[i].realTimeLimit);//放入期限数组中
 53                 }
 54                 myData[detailData[i].deptName].myLimits[detailData[i].realTimeLimit]=detailData[i].compositeCost;//放入期限
 55             }
 56         }
 57         limits.sort();//从小到大排序
 58         /**
 59          * 遍历各个legend
 60          * 填补当前legend的节点数据为‘-’(以便后续对此节点补充平均值以使折线不出现明显的断点)
 61          */
 62         for(var j in myData){
 63             for(var k in limits){
 64                 if(myData[j].myLimits[limits[k]]){
 65                     myData[j].datas.data.push((myData[j].myLimits[limits[k]]*100).toFixed(2));
 66                     //myData[j].datas.data.push(myData[j].myLimits[limits[k]]==-1?0:(myData[j].myLimits[limits[k]]*100).toFixed(2));
 67                 }else{
 68                     myData[j].datas.data.push("-");
 69                 }
 70             }
 71 
 72             /**
 73              * 中间断点的补全中间断点
 74              */
 75             //[-,-,0,99,-,5,-,-];
 76             var before=0,after=0,cnode=0,idx=0;
 77             for(var m in myData[j].datas.data){
 78                 idx=idx+1;
 79                 if(myData[j].datas.data[m]=="-"){
 80                     //continue;//返回,进行下一次循环
 81                     if(m==0){
 82                         continue;
 83                     }else{
 84                         if(before>0){
 85                             cnode=cnode+1;
 86                             after=idx-1;
 87                         }
 88                     }
 89                     if(myData[j].datas.data[m]==(myData[j].datas.data.length-1)){
 90                         //初始化标记值
 91                         before=0;
 92                         after=0;
 93                         cnode=0;
 94                     }
 95                 }else{
 96                     if(cnode==0){
 97                         before=idx-1;//当前数据的下标的位置
 98                         after=idx-1;//当前数据下标的位置
 99                     }else{
100                         after=idx-1;
101                         cnode=cnode+1;
102                         for(var n=1;n<cnode;n++){
103                             //myData[j].datas.data[before+n]=(Number(myData[j].datas.data[before])+(myData[j].datas.data[after]-myData[j].datas.data[before])/cnode*n).toFixed(2);
104                             myData[j].datas.data[before+n]={name:limits[before+n]+ "个月", symbol:'none', value:(Number(myData[j].datas.data[before])+(myData[j].datas.data[after]-myData[j].datas.data[before])/cnode*n).toFixed(2)};
105                         }
106                         cnode=0;
107                         before=idx-1;
108                     }
109                     if(!(myData[j].datas.data[Number(m)+1])){//下一个节点是否存在
110                         //存在"-":continue;
111                         //存在number:
112                         
113                         //初始化标记值
114                         before=0;
115                         after=0;
116                         cnode=0;
117                     }
118                 }
119             }
120             seriesData.push(myData[j].datas);
121         }
122         
123         //X轴数据添加后缀
124         for(var l in limits){
125             limits[l]=limits[l]+"个月";
126         }
127         var myChart = echarts.init(document.getElementById('chart4'),'macarons');
128         option = {
129             title : {
130                 text: '按部门期限分布',
131                 x:'center',
132                 y:'20px',
133                 position:'top'
134             },
135             grid:{ 
136                 y:'80px',            //直角坐标系内绘图网格左上角纵坐标,默认值60
137                 x:'150px',
138                 x2:'1%',
139                 y2:'9%'
140             },
141             tooltip : {
142                 trigger: 'axis',
143                 formatter:function(params)
144                 {
145                     var relVal;
146                     if (Array.isArray(params)) {    //显示各项数据时,params为数组
147                         relVal = params[0].name;
148                         for (var i = 0, l = params.length; i < l; i++) {
149                             relVal += '<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + params[i].color + '"></span>'
150                             relVal +=  params[i].seriesName + ' : ' + params[i].value+"%";
151                         }
152                     } else {    //显示平均数时,params为对象
153                         relVal = params.name;
154                         relVal += '<br/>' + params.seriesName + ' : ' + params.value+"%";
155                     }
156                     return relVal;
157                 }
158             
159             },
160             legend: {
161                 data: legendData,//['资金成本','指导价'],
162                 y:"center",//y:'20px;',
163                 x:"left",
164                 orient:"vertical"
165             },
166             toolbox: {
167                 show : true,
168                // orient:"vertical",
169                 feature: {
170                     dataView : {show: true, readOnly: false},
171                     magicType : {show: true, type: ['line', 'bar']},
172                     restore : {show: true},
173                     saveAsImage : {show: true, backgroundColor:'transparent'}
174                 }        
175             },
176             xAxis:{
177                 /* type: 'category', */
178                 position:'right',
179                 data: limits,
180                 boundaryGap: true,
181                 axisLabel:{
182                     interval:0,
183                     rotate:45,//倾斜度 -90 至 90 默认为0
184                 },
185             },
186             yAxis: {
187                 type: 'value',
188                 boundaryGap: [0.3, 0.3],
189                 scale: true,
190                 axisLabel: {
191                     //formatter: '{value}%'
192                     formatter: function (value, index) {
193                         if(value.toString().length>5){
194                               return Number(value.toFixed(5))+"%";    
195                         }else{
196                             return value+"%";
197                         }
198                               
199                      }
200                 }
201             },            
202             series :seriesData,
203         };
204         myChart.setOption(option);
205     }
1     //数组按按数字从小到大排序
2     function (val, nextVal) {
3             return val-nextVal;
4     }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极客生活

python爬虫隔一段时间一乐之海子的诗

每隔一段时间(一周到一个月)拿出1到2天来做一个好玩的东西,不求回报,只为快感。 前两天刚买了一本电子书《海子的诗》,晚上读了快一半,好多诗里面都提及了麦子和...

10410
来自专栏java一日一条

关于 Unicode 每个程序员应该知道的 5 件事

上周末,曝出了山寨WhatsApp Android应用程序的新闻,看似由相同的开发者提供作为了官方应用程序。欺诈分子通过在开发者名字中包含unicode非输出空...

9620
来自专栏Netkiller

Solidity 0.4.23 代币合约的变化

中国广东省深圳市龙华新区民治街道溪山美地 518131 +86 13113668890 <netkiller@msn.com>

516100
来自专栏FreeBuf

Python工具分析风险数据

小安前言 随着网络安全信息数据大规模的增长,应用数据分析技术进行网络安全分析成为业界研究热点,小安在这次小讲堂中带大家用Python工具对风险数据作简单分析,主...

28590
来自专栏算法+

WebRTC 音频算法 附完整C代码

AEC是声学回声消除(Acoustic Echo Canceller for Mobile)

58350
来自专栏编舟记

生成式测试(Generative Testing)

满足需求是所有软件存在的必要条件,单元测试一定是为它服务的。从这一点出发,我们可以总结出写单元测试的两个动机:驱动(如:TDD)和验证功能实现。另外,软件需求易...

18630
来自专栏跟着阿笨一起玩NET

EF中Repository模式应用场景

   在DDD领域构架系统中,为了将领域模型从领域逻辑层中和数据映射层之间解耦出来,我们引用到了Repository模式,属于属于泛型编程中一个比较常用的模式,...

38230
来自专栏向治洪

Android Project Butter分析

一 背景知识介绍 随着时间的推移,Android OS系统一直在不断进化、壮大,日趋完善。但直到Android 4.0问世,有关UI显示不流畅的问题也一直未得到...

28990
来自专栏IT大咖说

关于 Unicode 每个程序员应该知道的 5 件事

摘要 Unicode是一个令人难以置信的有用标准,它能使全世界的计算机、智能手机和智能手表以同样的方式显示相同的信息。不幸的是,它的复杂性使它成为了欺诈分子和恶...

29170
来自专栏怀英的自我修炼

怀英漫谈3-百度Echarts中日期控件的使用总结

你好, 今天下午在用百度的Echarts做一个日历图的效果,其中跌跌碰碰遇到了几个问题,好在最终都解决了,今天想跟你聊聊这几个问题。 本篇偏编程,可以跳至最后看...

40690

扫码关注云+社区

领取腾讯云代金券