js实现的时间轴效果

今天整理以前的资料发现以前写的一个时间轴效果,当时也是网上找了很久没有找到,就自己写了一个,现在发出来给有需要的人,代码写的可能有点乱。

效果图:

下面是美工做的设计图的效果(有个美工就是好):

下面是客户端源代码:

  1 <html>
  2 <head>
  3 <style type="text/css">
  4     #container
  5     {
  6         font-size: 12px;
  7         background-color: #ffffff;
  8         border: 1px solid #cccccc;
  9         position: relative;
 10         margin: 0;
 11     }
 12     #stationContainer
 13     {
 14         background-color: #E5ECFF;
 15         float: left;
 16         width: 150px;
 17         padding-top: 30px;
 18         position: relative;
 19         z-index: 200;
 20         border-right: 1px solid black;
 21     }
 22     #stationContainer .station
 23     {
 24         border-top: 1px solid black;
 25         width: 100%;
 26         float: left;
 27         height: 100px;
 28         z-index: 300;
 29     }
 30     #timeContainer
 31     {
 32         float: left;
 33         display: inline;
 34         position: absolute;
 35         z-index: 100;
 36         width: 900px;
 37         overflow: hidden;
 38     }
 39     #scrollContainer
 40     {
 41         position: relative;
 42     }
 43     #timeHeader
 44     {
 45         height: 30px;
 46         background-color: #eeeeee;
 47         position: relative;
 48         overflow: hidden;
 49     }
 50     #timeHeader .unitTime
 51     {
 52         width: 4px;
 53         float: left;
 54         border-left: 1px solid black;
 55         z-index: 100;
 56         height: 10px;
 57         margin-top: 20px;
 58         position: absolute;
 59     }
 60     #timeHeader .halfHour
 61     {
 62         margin-top: 10px;
 63         height: 20px;
 64     }
 65     #timeHeader .hour
 66     {
 67         height: 30px;
 68         margin-top: 0px;
 69     }
 70     #timeBody
 71     {
 72         position: relative;
 73     }
 74     #timeBody .horizontalStation
 75     {
 76         position: relative;
 77         width: 100%;
 78         border-top: 1px solid black;
 79         height: 100px;
 80         z-index: 10;
 81     }
 82     #footer
 83     {
 84         clear: both;
 85         width: 100%;
 86         height: 20px;
 87         background-color: #808080;
 88         border-bottom: 1px solid #808080;
 89     }
 90     #timeLine
 91     {
 92         left: 500px;
 93         border-right: 1px solid red;
 94         float: left;
 95         z-index: 100;
 96         background-color: Red;
 97         margin-top: 30px;
 98         position: absolute;
 99     }
100     
101     .techinian
102     {
103         width: 100%;
104         height: 100%;
105     }
106     .techinian td
107     {
108         text-align: center;
109     }
110     .techinian .stationTd
111     {
112         width: 60px;
113         border-right: 1px solid black;
114     }
115     .car
116     {
117         height: 25%;
118         display: inline;
119         float: left;
120         width: 100px;
121         border: 1px solid #000000;
122         padding: 0px;
123         background-color: lightsteelblue;
124         text-decoration: none;
125         position: absolute;
126         outline: none;
127         margin-top: 5px;
128         top: 1px;
129         bottom: 1px;
130         font-family: 黑体;
131         color: Black;
132         font-size: large;
133     }
134     .virtual
135     {
136         border: 2px dashed #000000;
137     }
138     a.car:hover
139     {
140         cursor: pointer;
141         background-color: Fuchsia;
142         text-decoration: none;
143     }
144     .color0
145     {
146         background-color: Green;
147     }
148     .color70
149     {
150         background-color: Yellow;
151     }
152     .color100
153     {
154         background-color: Red;
155     }
156 </style>
157 <style type="text/css">
158     .border_bottom
159     {
160         border-bottom: 1px solid black;
161     }
162     .border_top
163     {
164         border-top: 1px solid black;
165     }
166     .border_right
167     {
168         border-right: 1px solid black;
169     }
170     .border_left
171     {
172         border-left: 1px solid black;
173     }
174     .border_none
175     {
176         border: 0 none;
177     }
178 </style>
179 <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
180 <script type="text/javascript">
181     Date.prototype.format = function (format) {
182         var o =
183     {
184         "M+": this.getMonth() + 1, //month
185         "d+": this.getDate(),    //day
186         "h+": this.getHours(),   //hour
187         "m+": this.getMinutes(), //minute
188         "s+": this.getSeconds(), //second
189         "q+": Math.floor((this.getMonth() + 3) / 3),  //quarter
190         "S": this.getMilliseconds() //millisecond
191     }
192         if (/(y+)/.test(format))
193             format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
194         for (var k in o)
195             if (new RegExp("(" + k + ")").test(format))
196                 format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
197         return format;
198     }
199 
200     
201     function MockTime(hour)
202     {
203         var now = new Date();
204         return new Date(now.getFullYear()+'-'+(now.getMonth()+1)+'-'+now.getDate()+' '+hour+':00:00');
205     }
206 
207 </script>
208 <script type="text/javascript">
209     var unitMinute = 5, halfHourCount = 30 / unitMinute, hourCount = 60 / unitMinute;
210     var unitCount = 24 * (60 / unitMinute);
211     var unitPx = 5; //每个格子的宽度加边框
212     var timelineInitLeft = 150;
213     var headerHeight = 30;
214     // 从服务端读取时间轴的开始和结束时间
215     //var validTime = new Date('<%=DateTime.Today.Date.Add(Xindeco.Bmw.Infrastruction.DefaultSetting.StationStartValid).ToString("yyyy/MM/dd HH:mm:ss")%>');
216     //var invalidTime = new Date('<%=DateTime.Today.Date.Add(Xindeco.Bmw.Infrastruction.DefaultSetting.StationEndInvalid).ToString("yyyy/MM/dd HH:mm:ss")%>');
217     var now = new Date();
218     //从服务端读取服务器时间,使客户端和服务器时间同步
219     var serverTime = now; //静态页面测试直接赋值为客户端时间
220     var offsetTime = now -serverTime ;
221     var validTime = MockTime(8);
222     var invalidTime= MockTime(18);
223 
224     $(function () {
225         var headerWidth = $("#container").width() - $("#stationContainer").width();
226         unitPx = headerWidth / ((invalidTime - validTime) / 60000 / unitMinute);
227 
228         for (var i = 0; i < unitCount; i++) {
229             var classstr = " ";
230             var hourstr = "";
231             if (i % hourCount == 0) {
232                 classstr = "hour";
233                 hourstr = i / hourCount;
234             }
235             else if (i % halfHourCount == 0)
236                 classstr = "halfHour";
237             var unitTime = $("<div id='time_" + i + "' class='unitTime " + classstr + "'>" + hourstr + "</div>");
238             unitTime.css('left', i * unitPx);
239             $("#timeHeader").append(unitTime);
240 
241         }
242         $("#scrollContainer").width(unitCount * unitPx);
243         $("#timeLine").height($("#stationContainer").height());
244         $("#timeContainer").width($("#footer").width() - timelineInitLeft);
245         ScrollToTime(validTime.getHours(), invalidTime.getMinutes());
246         SetTimeNow();
247     });
248 
249     function SetTimeNow() {
250         serverTime.setTime(new Date().getTime() + offsetTime);
251         SetTimeLineByTime(serverTime.getHours(), serverTime.getMinutes());
252     }
253 
254     function ScrollToTime(hour, min) {
255         var count = (hourCount * hour + Math.round(min / unitMinute));
256         $("#scrollContainer").css("left", -$("#time_" + count).position().left);
257     }
258 
259 
260     function SetTimeLineByTime(hour, min) {
261 
262         var dateTime = new Date(serverTime.getFullYear(), serverTime.getMonth(), serverTime.getDate(), hour, min, 0);    console.log(dateTime);
263         if (dateTime < validTime || dateTime > invalidTime) {
264             $("#timeLine").hide();
265             return;
266         }
267         $("#timeLine").show();
268         var count = (hourCount * hour + Math.round(min / unitMinute));
269         $("#timeLine").css("left", $("#time_" + count).position().left + $("#scrollContainer").position().left + $("#stationContainer").width());
270     }
271 
272     function SetCarPositionByTime(car, hour, min) {
273         var count = (hourCount * hour + Math.round(min / unitMinute));
274         $(car).css('left', $("#time_" + count).position().left);
275         SetHeight($(car));
276     }
277 
278     function AutoScroll() {
279         try {
280             serverTime.setTime(new Date().getTime() + offsetTime);
281             SetTimeLineByTime(serverTime.getHours(), serverTime.getMinutes());
282         } catch (e) {
283         }
284     }
285 
286 
287 </script>
288 <script type="text/javascript">
289     window['selectedCar'] = '';
290     function Car(carData) {
291         var id = carData.ID;
292         var carNo = carData.CarNo;
293         var text = carData.DisplayText;
294         var stationId = carData.StationId;
295         //模拟的数据不需要做转换
296         //var startTime = ConvertJSONDateToJSDateObject(carData.StartTime);
297         //var endTime = ConvertJSONDateToJSDateObject(carData.EndTime);
298         var startTime = carData.StartTime;
299         var endTime = carData.EndTime;
300         var durationMinute = carData.TotalMinutes;
301         var isVirtual = carData.IsVirtual;
302         var title = "";
303         var colorClass = "";
304         if (carData.DisplayStartTime != null && carData.DisplayEndTime != null) {
305             title = ConvertJSONDateToJSDateObject(carData.DisplayStartTime).format("yyyy/MM/dd hh:mm") + "-" + ConvertJSONDateToJSDateObject(carData.DisplayEndTime).format("yyyy/MM/dd hh:mm");
306         }
307         if (carData.Percent != null) {
308             var color = "";
309             if (carData.Percent < 70)
310                 color = 0;
311             else if (carData.Percent >= 70 && carData.Perent < 100)
312                 color = 70;
313             else if (carData.Percent >= 100)
314                 color = 100;
315             colorClass = "color" + color;
316         }
317         var car = $("<a id='car_" + id + "' href=\"#\" title='" + title + "' stationId='" + stationId + "' class=\"car  " + colorClass + "  " + (isVirtual ? 'virtual' : '') + "\"><div>" + text + "</div></a>");
318         car.width(unitPx * durationMinute / unitMinute);
319         car.click(function () {
320             if (carData.ReachId != null) {
321                 $(".panel .dxb img").hide();
322                 if (typeof ShowMsg != 'undefined') ShowMsg($("#msg"), "已选择:" + carNo);
323                 window["selectedId"] = carData.ReachId;
324             }
325         });
326         Car.prototype.Show = function () {
327             $("#station_" + stationId).append(car);
328             SetCarPositionByTime(car, startTime.getHours(), startTime.getMinutes());
329         }
330     }
331 
332     function SetHeight(dstCar) {
333         var cars = $("a[stationid='" + dstCar.attr("stationId") + "']");
334         for (var i = 0; i < cars.length; i++) {
335             var car = $(cars[i]);
336             if (car.attr('id') != dstCar.attr('id') && (car.position().left + car.width()) > dstCar.position().left + 2) {
337                 dstCar.css('top', car.position().top + car.height() + 4);
338             }
339         }
340     }
341 
342     function Station(stationId) {
343         var station = $("<div id='station_" + stationId + "' class=\"horizontalStation\"></div>");
344         station.height($(".station:first").height());
345         Station.prototype.Show = function () {
346             $("#timeBody").append(station);
347         }
348     }
349 
350     function ConvertJSONDateToJSDateObject(jsondate) {
351         var date = new Date(parseInt(jsondate.replace("/Date(", "").replace(")/", ""), 10));
352         return date;
353     }
354 
355     function LoadData() {
356         return MockData();
357         //从服务端读取面板上需要显示的数据,包括所在工位,开始时间结束时间,以及其他需要显示的备注信息
358         var url = '<%=ResolveClientUrl("~/Handler/AutoDispatcher.ashx") %>?groupcodes=<%=string.Join(",", groupCodes) %>&r=' ;
359         $.getJSON(url+ Math.random(), function (data) {
360             window["data"] = data;
361             var stations = $("div.station[data-key]");
362             $("#timeBody").html('');
363             for (var i = 0; i < stations.length; i++) {
364                 var stationId = $(stations[i]).attr('data-key');
365                 var station = new Station(stationId);
366                 station.Show();
367                 var carList = data[stationId];
368                 if (typeof carList == 'undefined') continue;
369                 for (var j = 0; j < carList.length; j++) {
370                     var startTime = new Date();
371                     var carData = carList[j];
372                     var car = new Car(carData);
373                     car.Show();
374                 }
375             }
376         });
377     }
378 
379     function MockData()
380     {
381         var data= {'1':[
382             {ID:1,CarNo:'闽12345',DisplayText:'维修中',StationId:1,StartTime:MockTime(9),EndTime:MockTime(13),isVirtual:false,TotalMinutes:300,Percent:80},
383             {ID:2,CarNo:'闽22345',DisplayText:'等待中',StationId:1,StartTime:MockTime(14),EndTime:MockTime(16),isVirtual:false,TotalMinutes:200,Percent:50}
384         ],'2':[
385             {ID:3,CarNo:'闽12345',DisplayText:'维修中',StationId:2,StartTime:MockTime(8),EndTime:MockTime(12),isVirtual:false,TotalMinutes:300,Percent:80},
386             {ID:4,CarNo:'闽22345',DisplayText:'等待中',StationId:2,StartTime:MockTime(13),EndTime:MockTime(14),isVirtual:false,TotalMinutes:200,Percent:50}
387         ],'3':[
388             {ID:5,CarNo:'闽12345',DisplayText:'维修中',StationId:3,StartTime:MockTime(10),EndTime:MockTime(13),isVirtual:false,TotalMinutes:300,Percent:80},
389             {ID:6,CarNo:'闽22345',DisplayText:'等待中',StationId:3,StartTime:MockTime(15),EndTime:MockTime(16),isVirtual:false,TotalMinutes:200,Percent:50}
390         ],'4':[
391             {ID:7,CarNo:'闽12345',DisplayText:'维修中',StationId:4,StartTime:MockTime(9),EndTime:MockTime(12),isVirtual:false,TotalMinutes:300,Percent:80},
392             {ID:8,CarNo:'闽22345',DisplayText:'等待中',StationId:4,StartTime:MockTime(13),EndTime:MockTime(15),isVirtual:false,TotalMinutes:200,Percent:50}
393         ]};
394         window["data"] = data;
395             var stations = $("div.station[data-key]");
396             $("#timeBody").html('');
397             for (var i = 0; i < stations.length; i++) {
398                 var stationId = $(stations[i]).attr('data-key');
399                 var station = new Station(stationId);
400                 station.Show();
401                 var carList = data[stationId];
402                 if (typeof carList == 'undefined') continue;
403                 for (var j = 0; j < carList.length; j++) {
404                     var carData = carList[j];
405                     var car = new Car(carData);
406                     car.Show();
407                 }
408             }
409     }
410 
411     function Loop() {
412         AutoScroll();
413         LoadData();//.complete(function () { setTimeout('Loop()', 20000) });
414     }
415 
416     window['LoadData'] = LoadData;
417 
418     $(function () {
419         Loop();
420     });
421 </script>
422 </head>
423 <body>
424 <div id="container">
425     <div id="stationContainer">
426         <div class="station" data-key='1'>
427             <table border="0" class="techinian" cellpadding="0" cellspacing="0">
428                 <tr>
429                     <td rowspan='4' class="stationTd">
430                         工位1
431                     </td>
432                     <td class='border_bottom'>
433                         技师1
434                     </td>
435                 </tr>
436                 <tr>
437                     <td class='border_bottom'>
438                         技师2
439                     </td>
440                 </tr>
441                 <tr>
442                     <td class='border_bottom'>
443                         技师3
444                     </td>
445                 </tr>
446                 <tr>
447                     <td class=''>
448                         技师4
449                     </td>
450                 </tr>
451             </table>
452         </div>
453          <div class="station" data-key='2'>
454             <table border="0" class="techinian" cellpadding="0" cellspacing="0">
455                 <tr>
456                     <td rowspan='4' class="stationTd">
457                         工位2
458                     </td>
459                     <td class='border_bottom'>
460                         技师5
461                     </td>
462                 </tr>
463                 <tr>
464                     <td class='border_bottom'>
465                         技师6
466                     </td>
467                 </tr>
468                 <tr>
469                     <td class='border_bottom'>
470                         技师7
471                     </td>
472                 </tr>
473                 <tr>
474                     <td class=''>
475                         技师8
476                     </td>
477                 </tr>
478             </table>
479         </div>
480          <div class="station" data-key='3'>
481             <table border="0" class="techinian" cellpadding="0" cellspacing="0">
482                 <tr>
483                     <td rowspan='4' class="stationTd">
484                         工位3
485                     </td>
486                     <td class='border_bottom'>
487                         技师9
488                     </td>
489                 </tr>
490                 <tr>
491                     <td class='border_bottom'>
492                         技师10
493                     </td>
494                 </tr>
495                 <tr>
496                     <td class='border_bottom'>
497                         技师11
498                     </td>
499                 </tr>
500                 <tr>
501                     <td class=''>
502                         技师12
503                     </td>
504                 </tr>
505             </table>
506         </div>
507          <div class="station" data-key='4'>
508             <table border="0" class="techinian" cellpadding="0" cellspacing="0">
509                 <tr>
510                     <td rowspan='4' class="stationTd">
511                         工位4
512                     </td>
513                     <td class='border_bottom'>
514                         技师13
515                     </td>
516                 </tr>
517                 <tr>
518                     <td class='border_bottom'>
519                         技师14
520                     </td>
521                 </tr>
522                 <tr>
523                     <td class='border_bottom'>
524                         技师3
525                     </td>
526                 </tr>
527                 <tr>
528                     <td class=''>
529                         技师15
530                     </td>
531                 </tr>
532             </table>
533         </div>
534     </div>
535     <div id="timeContainer">
536         <div id="scrollContainer">
537             <div id="timeHeader">
538                  <div class="unitTime">
539                     <!--1111111111111111111-->
540                 </div>
541             </div>
542             <div id="timeBody">
543                 <div class="horizontalStation">
544                     <a href="#" class="car">
545                         <div>
546                             车辆1
547                         </div>
548                     </a><a href="#" class="car">
549                         <div>
550                             车辆1
551                         </div>
552                     </a><a href="#" class="car">
553                         <div>
554                             车辆1
555                         </div>
556                     </a><a href="#" class="car">
557                         <div>
558                             车辆1
559                         </div>
560                     </a>
561                 </div>
562             </div>
563         </div>
564     </div>
565     <div id="timeLine">
566     </div>
567     <div style="clear: both;">
568     </div>
569 </div>
570 <div id="footer">
571 </div>
572 </body>
573 </html>
View Code
原文地址:https://www.cnblogs.com/huolong/p/3728475.html