自定義時間線插件

入職已有兩個月了,從以前的前後臺均開發到目前的專向做前端,最大的感觸便是更加有耐心了,不管什麼樣的效果及佈局,都能靜下心來從解決方案到觀摩別人解決方案,進而實現。這樣看來人的精力是有限的是對的。然而寫着寫着會越加意識到自己該提高下代碼質量,特別是對於日漸龐大的工程及需要不斷維護和拓展的實現來說,代碼規範、高質量是至關重要的一個環節,這是自己接下來需要提高和注意的地方。

在此以自己近期遇到的一個開發任務:時間線的開發過程,來記錄下自己此刻的思路與狀態。最終實現效果如下圖:

整體佈局思路:純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);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章