入職已有兩個月了,從以前的前後臺均開發到目前的專向做前端,最大的感觸便是更加有耐心了,不管什麼樣的效果及佈局,都能靜下心來從解決方案到觀摩別人解決方案,進而實現。這樣看來人的精力是有限的是對的。然而寫着寫着會越加意識到自己該提高下代碼質量,特別是對於日漸龐大的工程及需要不斷維護和拓展的實現來說,代碼規範、高質量是至關重要的一個環節,這是自己接下來需要提高和注意的地方。
在此以自己近期遇到的一個開發任務:時間線的開發過程,來記錄下自己此刻的思路與狀態。最終實現效果如下圖:
整體佈局思路:純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);
}