入职已有两个月了,从以前的前后台均开发到目前的专向做前端,最大的感触便是更加有耐心了,不管什么样的效果及布局,都能静下心来从解决方案到观摩别人解决方案,进而实现。这样看来人的精力是有限的是对的。然而写着写着会越加意识到自己该提高下代码质量,特别是对于日渐庞大的工程及需要不断维护和拓展的实现来说,代码规范、高质量是至关重要的一个环节,这是自己接下来需要提高和注意的地方。
在此以自己近期遇到的一个开发任务:时间线的开发过程,来记录下自己此刻的思路与状态。最终实现效果如下图:
整体布局思路:纯css布局,大小采用百分比,以便适应各种分辨率环境;
时间轴算法:依据已有时间点,找出最大时间及最小时间,以最小时间为起点,包含最大时间且为6的倍数时间点为结束时间;
时间段定位:根据开始时间点及时间段跨度,进行百分比绝对定位;
时间线绘制:利用模板,动态添加dom元素;
js实现过程:插件化,便于移植、复用和维护。无奈当前水平首先,封装的不好,以后要多看看别人源码,学习模块化,面向对象js编程了。个人封装js逻辑如下:
//时间线刷新定时器 var timeLineTimer=null; //当前时间线渲染数据集,用来控制定时器中时间线是否需要刷新 var currentData=""; // 时间线类 function OwnTimeLine (arg) { var $that=this; //告警时间线主体参数 var timeLineArg={"entityName":"告警描述信息","alarmCount":"0条告警","okNum":0,"infoCount":0, "warningCount":0,"errorCount":0,"minTime":new Date(),"maxTime":new Date(),"alarms":[]}; //告警时间线参数(示例) var timeParam={"timelines":[{"beginPriorityColor":OwnTimeLine.alarmlevel[1],"endPriorityColor":OwnTimeLine.alarmlevel[0], "beginTime":"2016/4/7 10:00:","endTime":"2016/4/7 10:10"}],"alarmName":"Test"}; if(arg==null||arg==undefined){ arg=timeLineArg; } //主告警名称 this.entityName=arg.entityName; //告警总数 this.alarmCount=arg.alarmCount; //正常告警数量 this.okNum=arg.okNum==null?0:arg.okNum; //提示告警数量 this.infoCount=arg.infoCount==null?0:arg.infoCount; //警告告警数量 this.warningCount=arg.warningCount==null?0:arg.warningCount; //验证告警数量 this.errorCount=arg.errorCount==null?0:arg.errorCount; // 时间轴开始时间 this.minTime=arg.minTime==null?new Date():arg.minTime; // 最大结束时间 this.maxTime=arg.maxTime==null?new Date():arg.maxTime; // 时间线跨度(分钟为单位) this.timeLineWidthMins=60; //初始化时间线对象 this.initAll(); //初始化时间线 if(arg.alarms!=null&&arg.alarms.length>0){ $.each(arg.alarms,function(index,item){ $that.appendTimeArr(item); }); } } // 渲染子告警及其时间线数据 OwnTimeLine.prototype.appendTimeArr = function (param) { $that=this; if(param.timelines!=null && param.timelines.length>0){ //console.log(JSON.stringify(param.timelines)); if(OwnTimeLine.currentTimeNo>OwnTimeLine.timeTotal){ this.appAlarmDom(); OwnTimeLine.timeTotal++; $(".div-flex-verticalline").css("height",(parseInt($(".div-flex-verticalline").css("height"))+30)+"px"); } $.each(param.timelines,function (index,item){ //console.log(this);//this指item function产生闭包 var $domTime=$($("#tmp-time").html()); $domTime.css("left",$that.getLeft(item.beginTime)).css("width",$that.getWidth(item.beginTime,item.endTime)); $domTime.find(".span-timestart").css("background-color",item.beginPriorityColor).attr("title",item.beginTime).tooltip(); $domTime.find(".div-hrline").css("border-bottom-color",item.beginPriorityColor); if(item.endTime!=null && item.endTime!="" && item.endTime!=undefined){ $domTime.find(".span-timeend").css("background-color",item.endPriorityColor).attr("title",item.endTime).tooltip(); } $("#div-timeline-"+OwnTimeLine.currentTimeNo).find(".div-time-left").append($domTime); }); // 设置告警信息 var $domName=$("#div-timeline-"+OwnTimeLine.currentTimeNo); var lastItem=param.timelines[param.timelines.length-1]; if(lastItem.endTime!=null && lastItem.endTime!="" && lastItem.endTime!=undefined){ $domName.find(".div-alarm-right").find(".span-level-circle").css("background-color",lastItem.endPriorityColor); } else{ $domName.find(".div-alarm-right").find(".span-level-circle").css("background-color",lastItem.beginPriorityColor); } $domName.find(".font12").html(param.alarmName); // $("#div-timeline-"+OwnTimeLine.currentTimeNo).find(".div-flex-sys").find(".font12").html(param.sys); OwnTimeLine.currentTimeNo++; } }; // 添加子告警dom OwnTimeLine.prototype.appAlarmDom=function(){ var $dom=$($("#tmp-timeline").html()); $dom.attr("id","div-timeline-"+OwnTimeLine.currentTimeNo); $(".div-timeline").append($dom); }; // 渲染时间线基本信息 OwnTimeLine.prototype.initBaseInfo=function(){ $("#span-alarm-description").html(this.entityName); $("#span-alarm-total").html(this.alarmCount); $("#span-ok-num").html(this.okNum); $("#span-level1-num").html(this.infoCount); $("#span-level2-num").html(this.warningCount); $("#span-level3-num").html(this.errorCount); }; // 初始化时间线计算刻度 OwnTimeLine.prototype.initTimeInfo=function(min,max){ var timeInterval=0; if(min!=null&&min!=undefined&&min!=""&&max!=""&&max!=null&&max!=undefined){ this.minTime=new Date(min); this.maxTime=new Date(max); } var temp=this.maxTime-this.minTime; if(temp>0){ temp=temp/(1000*60); if(temp>60){ var mod = temp%6; if(mod!=0){ this.timeLineWidthMins=temp+6-mod; } else{ this.timeLineWidthMins=temp; } } else{ this.timeLineWidthMins=60; } } timeInterval=this.timeLineWidthMins/6*60*1000; // 时间跨度 var minSuffix=""; if(this.timeLineWidthMins%60!=0){ minSuffix=this.timeLineWidthMins%60+"分钟"; } $("#span-time-scope").html(parseInt(this.timeLineWidthMins/60)+"小时"+minSuffix); var dateTmpMs=this.minTime-0; var dateTmp=this.minTime; var suffix="am"; for(var i=1;i<=6;i++){ var hourVal=dateTmp.getHours(); var minVal=dateTmp.getMinutes()<10?"0"+dateTmp.getMinutes():dateTmp.getMinutes(); if(hourVal>12){ suffix="pm"; hourVal-=12; } $("#div-flex-time"+i).find(".span-date").html(dateTmp.getMonth()+1+"月"+dateTmp.getDate()+"日"); $("#div-flex-time"+i).find(".span-time").html(hourVal+":"+minVal+suffix); dateTmpMs+=timeInterval; dateTmp=new Date(dateTmpMs); } }; // 根据起始时间计算左偏移距离 OwnTimeLine.prototype.getLeft=function(time1){ var dateTmpVal=((new Date(time1)-this.minTime)/60000)/this.timeLineWidthMins*100+"%"; return dateTmpVal; }; // 根据起止时间计算宽度 OwnTimeLine.prototype.getWidth=function(time1,time2){ if(time2==null || time2==""){ time2=this.maxTime; } if(new Date(time2)-new Date(time1)<=0){ return 0; } else{ var dateTmpVal=((new Date(time2)-new Date(time1))/60000)/this.timeLineWidthMins*100+"%"; return dateTmpVal; } }; // 初始化 OwnTimeLine.prototype.initAll=function(){ OwnTimeLine.clearTimeLine(); this.initBaseInfo(); this.initTimeInfo(); }; // 展示子告警时间线总数 OwnTimeLine.timeTotal=10; // 原始时间线总数 OwnTimeLine.standardTotal=10; // 下一可渲染时间线序号 OwnTimeLine.currentTimeNo=1; // 媒体查询控制时间线渲染数量 OwnTimeLine.setSize=function(){ if($(".div-timeline-wrap").css("width")=="1200px"){ OwnTimeLine.timeTotal=15; OwnTimeLine.standardTotal=15; for(var i=11;i<16;i++){ var $dom=$($("#tmp-timeline").html()); $dom.attr("id","div-timeline-"+i); $(".div-timeline").append($dom); } } }; // 清空已渲染时间线信息 OwnTimeLine.clearTimeLine=function(){ if(OwnTimeLine.timeTotal>OwnTimeLine.standardTotal){ for(var i=OwnTimeLine.standardTotal+1;i<=OwnTimeLine.timeTotal;i++){ $("#div-timeline-"+i).remove(); } OwnTimeLine.timeTotal=OwnTimeLine.standardTotal; OwnTimeLine.setSize(); $(".div-flex-verticalline").css("height","100%"); } for(var i=1;i<OwnTimeLine.currentTimeNo;i++){ $("#div-timeline-"+i).find(".div-time-left").empty(); $("#div-timeline-"+i).find(".div-alarm-right").find(".span-level-circle").css("background-color",""); $("#div-timeline-"+i).find(".div-alarm-right").find(".font-lh-29").html(""); } OwnTimeLine.currentTimeNo=1; }; //告警状态颜色 OwnTimeLine.alarmlevel=["#7EC92E","#42a8ef","#EF7742","#FF3A3A"]; OwnTimeLine.setSize(); //弹窗打开时停止主页定时器 $('#alarm-timeline').on('show.bs.modal', function () { endTimer(); }); //弹窗关闭时开始主页定时器,停止弹窗定时器 $('#alarm-timeline').off('hidden.bs.modal').on('hidden.bs.modal',function() { startTimer(); //停止时间线定时器 clearInterval(timeLineTimer); currentData=""; }); /** * @des 渲染时间线 * @author QIAN * @since 2016年4月11日 * @return */ function loadTimeLine(data) { var timeLineNode={}; timeLineNode.entityName=data.entityName; timeLineNode.alarmCount=data.alarmCount==null?0:data.alarmCount+" 条告警"; timeLineNode.errorCount=data.errorCount==null?0:data.errorCount; timeLineNode.warningCount=data.warningCount==null?0:data.warningCount; timeLineNode.infoCount=data.infoCount==null?0:data.infoCount; timeLineNode.okNum=data.okNum==null?0:data.okNum; timeLineNode.minTime=new Date(); timeLineNode.maxTime=null; timeLineNode.alarms=[]; if(data.alarms!=null&&data.alarms.length>0){ $.each(data.alarms,function(index,item){ var lineNode={}; lineNode.alarmName=item.alarmName; lineNode.timelines=[]; if(item.timelines!=null&&item.timelines.length>0){ var t1=item.timelines[0].beginTime; var t2=item.timelines[item.timelines.length-1].endTime; var time1=(t1==null||t1=="")?new Date():new Date(t1); var time2=(t2==null||t2=="")?new Date():new Date(t2); if(timeLineNode.minTime-time1>0){ timeLineNode.minTime=time1; } if(timeLineNode.maxTime==null){ timeLineNode.maxTime=time2; } else if(time2-timeLineNode.maxTime>0){ timeLineNode.maxTime=time2; } $.each(item.timelines,function(index,line){ var node={}; if(line.beginTime==null||line.beginTime==""){ return; } else{ node.beginTime=line.beginTime; node.beginPriorityColor=OwnTimeLine.alarmlevel[line.beginPriority]; } node.endTime=line.endTime; if(line.endTime!=null && line.endTime!=""){ (line.endPriority==null||line.endPriority==="")?line.endPriority=0:line.endPriority; node.endPriorityColor=OwnTimeLine.alarmlevel[line.endPriority]; } lineNode.timelines.push(node); }); } timeLineNode.alarms.push(lineNode); }); } new OwnTimeLine(timeLineNode); } //测试数据 var data1={"entityName": "主告警1","alarmCount": 10,"errorCount": 1,"warningCount": 5, "infoCount": 10,"alarms": [ {"timelines": [{"beginPriority": 1,"endPriority": 0,"beginTime": "2016/4/11 10:00","endTime": "2016/4/11 10:10"}, {"beginPriority": 1,"endPriority": 0,"beginTime": "2016/4/11 10:25","endTime": "2016/4/11 10:50"}], "alarmName": "Alarm Test1"}, {"timelines": [{"beginPriority": 3,"endPriority": 0,"beginTime": "2016/4/11 10:23","endTime": "2016/4/11 10:40"},{"beginPriority": 3, "endPriority": 0,"beginTime": "2016/4/11 10:45","endTime": "2016/4/11 11:05"}],"alarmName": "Alarm Test2"}, {"timelines": [{"beginPriority": 2,"endPriority": 0,"beginTime": "2016/4/11 10:04","endTime": "2016/4/11 10:33"},{"beginPriority": 2, "endPriority": "","beginTime": "2016/4/11 10:40","endTime": "2016/4/11 11:10"}],"alarmName": "Alarm Test3"}, {"timelines": [{"beginPriority": 1,"endPriority": 0,"beginTime": "2016/4/11 10:11","endTime": "2016/4/11 10:22"},{"beginPriority": 1, "endPriority": 0,"beginTime": "2016/4/11 10:30","endTime": "2016/4/11 10:45"},{"beginPriority": 1, "endPriority": "","beginTime": "2016/4/11 10:50","endTime": "2016/4/11 11:20"}],"alarmName": "Alarm Test4"}]}; var data2={"entityName": "主告警1","alarmCount": 10,"errorCount": 1,"warningCount": 5, "infoCount": 10,"alarms": [ {"timelines": [{"beginPriority": 3,"endPriority": 0,"beginTime": "2016/4/11 10:35","endTime": "2016/4/11 10:55"}, {"beginPriority": 3,"endPriority": 0,"beginTime": "2016/4/11 11:05","endTime": "2016/4/11 11:20"}], "alarmName": "Alarm Test1"}, {"timelines": [{"beginPriority": 2,"endPriority": 0,"beginTime": "2016/4/11 10:43","endTime": "2016/4/11 10:58"},{"beginPriority": 2, "endPriority": 0,"beginTime": "2016/4/11 11:22","endTime": "2016/4/11 11:50"}],"alarmName": "Alarm Test2"} ]}; //显示时间线 function showTimeLine(){ var data=data1; loadTimeLine(data); currentData=JSON.stringify(data1); //获取时间线数据,并启动技术器定时刷新 timeLineTimer = setInterval(function(){ if(currentData==JSON.stringify(data2)){ data=data1; } else{ data=data2; } //如果数据发生变化则更新时间线渲染 if(currentData!=JSON.stringify(data)){ currentData=JSON.stringify(data); loadTimeLine(data); } },5000); }