Commit 3354548ba2c0622f0d9a6dcbd7f9b4b5edf1ebc3

Authored by 潘钊
1 parent 5bb75329

线调 线路选择

src/main/resources/static/pages/control/line/css/lineControl.css
  1 +label {
  2 + max-width: none;
  3 +}
  4 +.load-text{
  5 + position: absolute;
  6 + top: 50%;
  7 + left: 50%;
  8 + transform: translate(-50%);
  9 + font-size: 14px;
  10 + font-family: 仿宋;
  11 +}
  12 +body{
  13 + overflow: hidden;
  14 +}
  15 +
  16 +/* ^_^ 隐藏logo */
  17 +.anchorBL,
  18 +.anchorBL,
  19 +.amap-logo,
  20 +.amap-copyright{
  21 + display: none;
  22 +}
  23 +
  24 +
1 /* .dropdown-menu { 25 /* .dropdown-menu {
2 background-color: rgba(76, 115, 142, 0.95); 26 background-color: rgba(76, 115, 142, 0.95);
3 border: 1px solid #4C738E; 27 border: 1px solid #4C738E;
@@ -196,7 +220,7 @@ @@ -196,7 +220,7 @@
196 } 220 }
197 221
198 .card_wrap{ 222 .card_wrap{
199 - height: 263px; 223 + height: 268px;
200 text-align: center; 224 text-align: center;
201 } 225 }
202 226
@@ -207,8 +231,8 @@ @@ -207,8 +231,8 @@
207 231
208 .card_wrap .line_chart{ 232 .card_wrap .line_chart{
209 height: 100%; 233 height: 100%;
210 - padding: 0;  
211 - border-top: 1px solid #DADADA; 234 + padding: 0;
  235 + border-top: 1px solid #DADADA;
212 } 236 }
213 237
214 .card_wrap .line_chart .top{ 238 .card_wrap .line_chart .top{
@@ -222,7 +246,7 @@ @@ -222,7 +246,7 @@
222 .card_wrap .line_chart .top .center{ 246 .card_wrap .line_chart .top .center{
223 height: 100%; 247 height: 100%;
224 font-size: 15px; 248 font-size: 15px;
225 - color: #B9B9B9; 249 + color: #5E96D2;
226 padding: 10px 0px; 250 padding: 10px 0px;
227 width: auto; 251 width: auto;
228 float: left; 252 float: left;
@@ -339,7 +363,7 @@ @@ -339,7 +363,7 @@
339 margin-right: 0; 363 margin-right: 0;
340 overflow-y: hidden; 364 overflow-y: hidden;
341 background: #fdfdfd; 365 background: #fdfdfd;
342 - margin-top: 5.8px; 366 + margin-top: 0;
343 /* box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); */ 367 /* box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); */
344 } 368 }
345 369
@@ -358,11 +382,18 @@ @@ -358,11 +382,18 @@
358 382
359 /* svg 样式 */ 383 /* svg 样式 */
360 .line_chart svg{ 384 .line_chart svg{
361 - height: 100%; 385 +/* height: 100%;
362 margin: 0; 386 margin: 0;
363 z-index: 1; 387 z-index: 1;
364 position: absolute; 388 position: absolute;
365 top: 0; 389 top: 0;
  390 + left: 0; */
  391 +
  392 + height: calc(100% - 40px);
  393 + margin: 0;
  394 + z-index: 1;
  395 + position: absolute;
  396 + bottom: 0;
366 left: 0; 397 left: 0;
367 } 398 }
368 /* .station_circle{ 399 /* .station_circle{
@@ -376,16 +407,16 @@ @@ -376,16 +407,16 @@
376 } 407 }
377 408
378 .up_station_circle{ 409 .up_station_circle{
379 - fill: #5e96d2; 410 + fill: #5e96d2;
380 r: 6; 411 r: 6;
381 - stroke: #fff; 412 + stroke: rgb(253, 253, 253);
382 stroke-width: 3; 413 stroke-width: 3;
383 } 414 }
384 415
385 .down_station_circle{ 416 .down_station_circle{
386 - fill: #c92121; 417 + fill: #c92121;
387 r: 6; 418 r: 6;
388 - stroke: #fff; 419 + stroke: rgb(253, 253, 253);
389 stroke-width: 3; 420 stroke-width: 3;
390 } 421 }
391 422
@@ -394,32 +425,36 @@ @@ -394,32 +425,36 @@
394 letter-spacing: -2.6px; 425 letter-spacing: -2.6px;
395 } 426 }
396 427
  428 +.station_text:hover{
  429 + background-color: red;
  430 +}
  431 +
397 .station_text.up{ 432 .station_text.up{
398 - fill: #5e96d2; 433 + fill: #5E96D2;
399 } 434 }
400 435
401 .station_text.down{ 436 .station_text.down{
402 - fill: #c92121; 437 + fill: #C92121
403 } 438 }
404 439
405 .station_text.end{ 440 .station_text.end{
406 - fill: none;  
407 - stroke: #c92121; 441 + fill: none;
  442 + stroke: #C92121;
408 } 443 }
409 444
410 .station_text.start{ 445 .station_text.start{
411 - stroke: #5e96d2; 446 + stroke: #5E96D2;
412 fill: none; 447 fill: none;
413 } 448 }
414 449
415 .up_path{ 450 .up_path{
416 - stroke-width: 7.4px;  
417 - stroke: #5e96d2; 451 + stroke-width: 5.4px;
  452 + stroke: #5E96D2;
418 } 453 }
419 454
420 .down_path{ 455 .down_path{
421 - stroke-width: 7.4px;  
422 - stroke: #c92121; 456 + stroke-width: 5.4px;
  457 + stroke: #C92121;
423 } 458 }
424 459
425 .up_path.arc, 460 .up_path.arc,
@@ -437,6 +472,94 @@ @@ -437,6 +472,94 @@
437 r: 0; 472 r: 0;
438 } 473 }
439 474
  475 +.vehci-g.up{
  476 + transform: translate(-15px, -34px);
  477 +}
  478 +
  479 +.vehci-g.down{
  480 + transform: translate(-15px, 8px);
  481 +}
  482 +
  483 +.vehci-g.up rect,
  484 +.vehci-g.down rect{
  485 + width: 28px;
  486 + height: 25px;
  487 + fill: rgba(253, 253, 253, 0.17);
  488 + rx: 5px;
  489 + stroke: #26c281;
  490 +}
  491 +
  492 +.vehci-g.up text,
  493 +.vehci-g.down text{
  494 + stroke: #26c281;
  495 + font-size: 12px;
  496 + cursor: default;
  497 +}
  498 +
  499 +.vehci-g.updown-error rect,
  500 +.vehci-g.updown-error text{
  501 + stroke: #CACA17;
  502 + fill: rgba(253, 253, 253, 0);
  503 +}
  504 +
  505 +.number-g{
  506 + transform: translate(-13px, -32px);
  507 +}
  508 +.number-g text{
  509 + transform: translate(9px, 17px);
  510 + stroke: white;
  511 +}
  512 +
  513 +.number-g rect{
  514 + width: 25px;
  515 + height: 25px;
  516 + fill: #333333;
  517 + rx: 11px;
  518 + stroke: #FDFDFD;
  519 + stroke-width: 5px;
  520 +}
  521 +
  522 +.number-g.start{
  523 + transform: translate(-38px, 52px);
  524 +}
  525 +
  526 +.number-g.end{
  527 + transform: translate(13px, 52px);
  528 +}
  529 +
  530 +g.park .park-rect{
  531 + width: 50px;
  532 + height: 130px;
  533 + fill: rgba(94, 150, 210, 0.32);
  534 + rx: 5px;
  535 +}
  536 +g.park.start rect,
  537 +g.park.start text{
  538 + transform: translate(-56px, 0);
  539 +}
  540 +
  541 +g.park .gps-rect{
  542 + width: 28px;
  543 + height: 25px;
  544 + fill: #ccc;
  545 + rx: 5px;
  546 + stroke: #ccc;
  547 +}
  548 +
  549 +g.park text{
  550 + stroke: #fafafa;
  551 + font-size: 12px;
  552 + cursor: default;
  553 +
  554 +}
  555 +
  556 +/* .svg-bg{
  557 + width: 100%;
  558 + height: 100%;
  559 + fill: rgba(94, 150, 210, 0.32);
  560 +} */
  561 +
  562 +
440 /* tab_map 地图嵌入样式修正 */ 563 /* tab_map 地图嵌入样式修正 */
441 #tab_map #mapContainer{ 564 #tab_map #mapContainer{
442 margin-top: -8px 565 margin-top: -8px
@@ -513,7 +636,7 @@ @@ -513,7 +636,7 @@
513 color: #000; 636 color: #000;
514 } 637 }
515 #tab_map .mapRightWrap.gaode.vehicle p.head{ 638 #tab_map .mapRightWrap.gaode.vehicle p.head{
516 - color: #7D7777; 639 + color: #504B4B;
517 } 640 }
518 #tab_map .mapRightWrap.vehicle.gaode p.head>span.icon>a:hover{ 641 #tab_map .mapRightWrap.vehicle.gaode p.head>span.icon>a:hover{
519 color: #555555; 642 color: #555555;
@@ -555,4 +678,79 @@ @@ -555,4 +678,79 @@
555 background: #ddd; 678 background: #ddd;
556 color: #333333; 679 color: #333333;
557 } 680 }
558 -/* GaoDe style end------- */  
559 \ No newline at end of file 681 \ No newline at end of file
  682 +/* GaoDe style end------- */
  683 +#tooltipShade {
  684 + position: absolute;
  685 + z-index: 99998;
  686 + width: 100%;
  687 + height: 100%;
  688 + display: none;
  689 + left: 0;
  690 + top: 0;
  691 +
  692 + background: rgba(102, 102, 102, 0.63);
  693 + animation-duration:.2s;
  694 + -webkit-animation-duration:.2s;
  695 +}
  696 +
  697 +#tooltipShade.level2{
  698 + background: rgba(102, 102, 102, 0.13);
  699 +}
  700 +
  701 +#tooltip{
  702 + position: absolute;
  703 + z-index: 99999;
  704 + /* border-radius: 5px !important; */
  705 + border: 1px solid rgba(94, 150, 210, 1);
  706 + background: rgba(255, 255, 255, 0.95);
  707 + box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);
  708 + width: 185px;
  709 +}
  710 +
  711 +#tooltip hr{
  712 + margin: 9px 0 9px -10px;
  713 + border-top: 1px solid #ddd;
  714 + width: calc(100% + 20px);
  715 +}
  716 +
  717 +#tooltip.fixed{
  718 + transition: all .5s ease;
  719 + border: 1px solid #fff;
  720 + background: #fff;
  721 +}
  722 +
  723 +#tooltip #tooltip-Container{
  724 + padding: 10px;
  725 +}
  726 +
  727 +#tooltip #tooltip-Container div{
  728 + margin: 3px;
  729 + font-size: 13.4px;
  730 +}
  731 +
  732 +#tooltip #tooltip-Container div a{
  733 + color: #274865;
  734 +}
  735 +
  736 +#tooltip #tooltip-Container .title a{
  737 + font-size: 16px;
  738 + font-family: 微软雅黑;
  739 + color: blue;
  740 +}
  741 +
  742 +#tooltip #tooltip-Container .subtitle,
  743 +#tooltip #tooltip-Container .subtitle a{
  744 + color: #999;
  745 + font-size: 13px;
  746 +}
  747 +
  748 +#tooltip.tooltip-modal{
  749 +width: 700px;
  750 +height: 400px;
  751 + box-shadow: 0 12px 15px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
  752 +}
  753 +
  754 +#tooltip #tip_map_wrap{
  755 + width: 100%;
  756 + height: 100%;
  757 +}
560 \ No newline at end of file 758 \ No newline at end of file
src/main/resources/static/pages/control/line/index.html
@@ -76,22 +76,33 @@ @@ -76,22 +76,33 @@
76 <div class="tab-content" style="padding: 5px;overflow-y: auto;"> 76 <div class="tab-content" style="padding: 5px;overflow-y: auto;">
77 <div class="tab-pane fade active in" id="tab_home" ></div> 77 <div class="tab-pane fade active in" id="tab_home" ></div>
78 <div class="tab-pane fade" id="tab_map" style="position: relative;"></div> 78 <div class="tab-pane fade" id="tab_map" style="position: relative;"></div>
79 - <div class="tab-pane fade" id="tab_line">单线路调度</div> 79 + <div class="tab-pane fade" id="tab_line">单线路调度aaa</div>
80 </div> 80 </div>
81 </div> 81 </div>
  82 +<div id="tooltipShade" class="animated fadeIn"></div>
  83 +
82 </div> 84 </div>
83 <div id="temps"></div> 85 <div id="temps"></div>
84 86
85 -<script src="js/drawSvg.js"></script>  
86 -<script src="js/data.js"></script>  
87 -<script src="js/main.js"></script> 87 +
  88 +<div id="tooltip" style="display: none;">
  89 +</div>
  90 +
  91 +<script src="/pages/control/line/js/tooltip.js"></script>
  92 +<script src="/pages/control/line/js/drawSvg.js"></script>
  93 +<script src="/pages/control/line/js/data.js"></script>
  94 +<script src="/pages/control/line/js/main.js"></script>
88 <script> 95 <script>
89 $(function() { 96 $(function() {
90 -  
91 - // 关闭左侧栏 http://222.66.0.204:8899/transport_server/rtgps  
92 -/* if (!$('body').hasClass('page-sidebar-closed'))  
93 - $('.menu-toggler.sidebar-toggler').click();  
94 - */  
95 - 97 + //加载模板文件
  98 + getTemp('temps/home_tp.html');
  99 + getTemp('temps/home_table_tp.html');
  100 + getTemp('temps/tooltip_tp.html');
  101 +
  102 + function getTemp(url){
  103 + $.get(url, function(template){
  104 + $('#temps').append(template);
  105 + });
  106 + }
96 }); 107 });
97 </script> 108 </script>
98 \ No newline at end of file 109 \ No newline at end of file
src/main/resources/static/pages/control/line/js/data.js
@@ -4,24 +4,19 @@ @@ -4,24 +4,19 @@
4 var _data = (function(){ 4 var _data = (function(){
5 5
6 var storage = window.localStorage; 6 var storage = window.localStorage;
7 - //写入模拟数据  
8 - storage.setItem('lineControlItems',JSON.stringify(  
9 - [  
10 - {id: 10232, name: '604路', start: '三林世博家园', end: '西营路德州路'},  
11 - {id: 10566, name: '778路', start: '莱阳路五莲路', end: '张江地铁站'} ,  
12 - {id: 10904, name: '新川专线', start: '上海火车站(北广场)', end: '华戴路川环南路'},  
13 - {id: 10069, name: '85路', start: '陆家嘴地铁站', end: '长岛路东陆路'},  
14 - {id: 10474, name: '987路', start: '源华路双桥路', end: '世纪大道地铁站'},  
15 - {id: 10507, name: '636路', start: '龚丰路溪平路', end: '张江地铁站'},  
16 - {id: 10702, name: '浦东23路', start: '南汇汽车站', end: '五七场部'},  
17 - {id: 10220, name: '573路', start: '宁桥路申江路', end: '东方路栖霞路'}  
18 - ]));  
19 7
  8 + //实时GPS数据
  9 + var allGps = {};
  10 + //10秒刷新一次实时GPS
  11 + var realGpsT = 1000 * 30;
20 12
21 var dataObject = { 13 var dataObject = {
22 getLines: function(){ 14 getLines: function(){
23 return JSON.parse(storage.getItem('lineControlItems')); 15 return JSON.parse(storage.getItem('lineControlItems'));
24 }, 16 },
  17 + getLineIds: function(){
  18 + return JSON.parse(storage.getItem('lineIds'));
  19 + },
25 getRealVehic: function(lineArray, cb){ 20 getRealVehic: function(lineArray, cb){
26 var tabList = [ 21 var tabList = [
27 {nbbm: 'W9H108', endDistance: '13.14', endTime: '82', instructions: '', speed: '16', roadSigns: '另1'}, 22 {nbbm: 'W9H108', endDistance: '13.14', endTime: '82', instructions: '', speed: '16', roadSigns: '另1'},
@@ -56,20 +51,37 @@ var _data = (function(){ @@ -56,20 +51,37 @@ var _data = (function(){
56 $get('/stationroute/all', {'line.lineCode_eq': lineId}, function(routes){ 51 $get('/stationroute/all', {'line.lineCode_eq': lineId}, function(routes){
57 var svgData = analyData(routes); 52 var svgData = analyData(routes);
58 53
59 - cb && cb(svgData, container); 54 + cb && cb(lineId, svgData, container);
60 }); 55 });
  56 + },
  57 + /**
  58 + * 实时GPS定时刷新
  59 + */
  60 + startRefreshGpsTimer: function(){
  61 + var f = arguments.callee;
  62 + refreshGpsProxy();
  63 + setTimeout(f, realGpsT);
61 } 64 }
62 }; 65 };
63 66
64 - //加载模板文件  
65 - getTemp('temps/home_tp.html');  
66 - getTemp('temps/home_table_tp.html'); 67 + //地图tab页显示时 注入gps数据
  68 + $('a[href=#tab_map]').on('shown.bs.tab', function(){
  69 + $('#tab_map #mapContainer').trigger('gps_refresh', [allGps]);
  70 + });
67 71
68 - function getTemp(url){  
69 - $.get(url, function(template){  
70 - $('#temps').append(template); 72 + function refreshGpsProxy(){
  73 + refreshGps(function(add, up){
  74 + $('#tab_home,#tab_map #mapContainer').trigger('gps_refresh', [add, up]);
71 }); 75 });
72 } 76 }
  77 +
  78 +
  79 + //初始化lineCodes
  80 + var lineCodes = '';
  81 + $.each(dataObject.getLines(), function(i, obj){
  82 + lineCodes += (obj.lineCode + ',');
  83 + });
  84 + lineCodes = lineCodes.substr(0, lineCodes.length - 1);
73 85
74 var upSort = function(a, b){ 86 var upSort = function(a, b){
75 return a.outStationNmber - b.outStationNmber; 87 return a.outStationNmber - b.outStationNmber;
@@ -84,7 +96,7 @@ var _data = (function(){ @@ -84,7 +96,7 @@ var _data = (function(){
84 96
85 for(var i = start, obj; obj = array[i++];){ 97 for(var i = start, obj; obj = array[i++];){
86 98
87 - if(obj.station.stationName == station.stationName){ 99 + if(obj.stationName == station.stationName){
88 res = i; 100 res = i;
89 break; 101 break;
90 } 102 }
@@ -93,6 +105,50 @@ var _data = (function(){ @@ -93,6 +105,50 @@ var _data = (function(){
93 return res; 105 return res;
94 } 106 }
95 107
  108 +
  109 + /**
  110 + * 刷新GPS车辆信息
  111 + */
  112 + function refreshGps(cb){
  113 + $.ajax({
  114 + url: '/gps/real/line',
  115 + data: {lineCodes: lineCodes},
  116 + timeout: 5000,//5秒超时
  117 + success: getGpsSuccess,
  118 + error: getGpsError
  119 + });
  120 +
  121 + function getGpsSuccess(gpsList){
  122 + if(!gpsList || gpsList.length == 0)
  123 + return;
  124 +
  125 + var prve = allGps
  126 + ,addArray = []
  127 + ,upArray = []
  128 + ,oldGps;
  129 + for(var i = 0, gps; gps=gpsList[i++];){
  130 + oldGps = prve[gps.deviceId];
  131 + if(!oldGps){
  132 + //添加
  133 + prve[gps.deviceId] = gps;
  134 + addArray.push(gps);
  135 + }
  136 + else if(gps.timestamp > oldGps.timestamp){
  137 + //更新
  138 + upArray.push(gps);
  139 + }
  140 + }
  141 + cb && cb(addArray, upArray);
  142 + }
  143 +
  144 + function getGpsError(jqXHR, textStatus){
  145 + if(textStatus === 'error')
  146 + layer.alert('获取GPS数据时,服务器出现异常', {icon: 2});
  147 + else if(textStatus === 'timeout')
  148 + layer.alert('连接服务器超时', {icon: 2});
  149 + }
  150 + }
  151 +
96 /** 152 /**
97 * 解析数据成svg想要的格式 153 * 解析数据成svg想要的格式
98 */ 154 */
@@ -112,9 +168,9 @@ var _data = (function(){ @@ -112,9 +168,9 @@ var _data = (function(){
112 //合并 168 //合并
113 var data = []; 169 var data = [];
114 for(var j = 0; j < up.length; j ++){ 170 for(var j = 0; j < up.length; j ++){
115 - var upS = up[j].station  
116 - , downS = down[j].station  
117 - ,op = {name: [upS.stationName], id: [upS.stationCod, downS.stationCod], type: 2}; 171 + var upS = up[j] == null?{}:up[j]
  172 + ,downS = down[j] == null?{}:down[j]
  173 + ,op = {name: [upS.stationName], id: [upS.stationCode, downS.stationCode], type: 2, stationMark: upS.stationMark};
118 174
119 //编码相同 175 //编码相同
120 if(upS.stationName != downS.stationName){ 176 if(upS.stationName != downS.stationName){
@@ -126,8 +182,8 @@ var _data = (function(){ @@ -126,8 +182,8 @@ var _data = (function(){
126 down.splice(j, 0, {}); 182 down.splice(j, 0, {});
127 }else{ 183 }else{
128 for(var t = j; t < dIndex - 1; t++){ 184 for(var t = j; t < dIndex - 1; t++){
129 - var temp = down[t].station;  
130 - data.push({name: [temp.stationName], type:1, id: [temp.stationCod]}); 185 + var temp = down[t];
  186 + data.push({name: [temp.stationName], type:1, id: [temp.stationCode]});
131 } 187 }
132 //delete 188 //delete
133 down.splice(j, dIndex - 1 - j); 189 down.splice(j, dIndex - 1 - j);
src/main/resources/static/pages/control/line/js/drawSvg.js
@@ -4,10 +4,17 @@ @@ -4,10 +4,17 @@
4 */ 4 */
5 var drawSvg = (function(){ 5 var drawSvg = (function(){
6 6
7 - var mt = 81//顶部距离 7 + var mt = 44//顶部距离
8 ,p = 132//上下行之间的间隔 8 ,p = 132//上下行之间的间隔
9 ,x = d3.scale.linear() 9 ,x = d3.scale.linear()
10 - ,w; 10 + ,w
  11 + ,lineSvgMapp = {}
  12 + ,lineStations = {}
  13 + ,seGps = {} //起终点gps信号;
  14 +
  15 +/* var arcPath = function(cx, cy, arc){
  16 + return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8);
  17 + }*/
11 18
12 var upStation = function(value){ 19 var upStation = function(value){
13 return value.type != 1 ; 20 return value.type != 1 ;
@@ -17,63 +24,65 @@ var drawSvg = (function(){ @@ -17,63 +24,65 @@ var drawSvg = (function(){
17 return value.type != 0; 24 return value.type != 0;
18 } 25 }
19 26
20 - var textY = function(d){  
21 - }  
22 -  
23 - var upLine = d3.svg.line().x(function(d) { 27 + var line = {
  28 + up: d3.svg.line().x(function(d) {
24 return d.cx; 29 return d.cx;
25 - }).y(function(){return mt});  
26 -  
27 - var downLine = d3.svg.line().x(function(d) { 30 + }).y(function(){return mt}),
  31 + down: d3.svg.line().x(function(d) {
28 return d.cx; 32 return d.cx;
29 - }).y(function(){return mt + p}); 33 + }).y(function(){return mt + p})
  34 + }
  35 +
30 36
31 var cx = function(d, i){ 37 var cx = function(d, i){
32 return x(i); 38 return x(i);
33 } 39 }
34 40
  41 + var cutNbbm = function(nbbm){
  42 + return nbbm.substr(nbbm.length - 3, nbbm.length);
  43 + }
  44 +
35 var drawSvgObject = { 45 var drawSvgObject = {
36 - init: function(data, container){ 46 + init: function(lineId, data, container){
  47 + //记录起终点站
  48 + $.each(data, function(){
  49 + if(this.stationMark == 'B' || this.stationMark == 'E' )
  50 + seGps[lineId + '_' + this.id[0]] = [];
  51 + });
  52 +
37 w = $('.line_chart:first').width(); 53 w = $('.line_chart:first').width();
38 var svg = d3.select('#' + container).append('svg') 54 var svg = d3.select('#' + container).append('svg')
39 - .attr('width', w).attr('opacity', 0)  
40 - ,dLen = data.length; 55 + .attr('width', w).attr('opacity', 0)
  56 + .attr('id', lineId);
41 57
42 - x.range([ 50 , w - 10]).domain([ 0, dLen]); 58 + lineSvgMapp[lineId] = svg;
  59 + lineStations[lineId] = data.slice(0);
  60 + //抽站
  61 + cleanStation(data);
  62 + var dLen = data.length;
43 63
44 - //上行线条 path  
45 - svg.append('path')  
46 - .attr('d', function(){  
47 - return upLine([{cx: x(0)}, {cx: x(dLen - 1)}]);  
48 - })  
49 - .attr('class', 'up_path'); 64 + x.range([ 60 , w - 15]).domain([ 0, dLen]);
50 65
51 - //下行线条 path  
52 - svg.append('path')  
53 - .attr('d', function(){  
54 - return downLine([{cx: x(0)}, {cx: x(dLen - 1)}]);  
55 - })  
56 - .attr('class', 'down_path'); 66 + //上行线条
  67 + drawPath(svg, data, 'up', 11);
  68 + //下行线条
  69 + drawPath(svg, data, 'down', 10);
57 70
58 - //左弧线 path 71 +/* //左弧线 path
59 svg.append('path') 72 svg.append('path')
60 .attr('d', function(){ 73 .attr('d', function(){
61 - var cx = x(0) - 8  
62 - ,cy = mt + 5  
63 - ,arc = cx - 18;  
64 - return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8); 74 + var cx = x(0) - 8;
  75 + return arcPath(cx , mt + 5,cx - 20);
65 }) 76 })
66 .attr('class', 'up_path arc'); 77 .attr('class', 'up_path arc');
67 78
68 //右弧线 path 79 //右弧线 path
69 svg.append('path') 80 svg.append('path')
70 .attr('d', function(){ 81 .attr('d', function(){
71 - var cx = x(dLen - 1) + 8  
72 - ,cy = mt + 5  
73 - ,arc = cx + 18;  
74 - return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8); 82 + var cx = x(dLen - 1) + 8;
  83 + return arcPath(cx , mt + 5,cx + 20);
75 }) 84 })
76 - .attr('class', 'down_path arc'); 85 + .attr('class', 'down_path arc');*/
77 86
78 var g = svg.append('g').selectAll('g') 87 var g = svg.append('g').selectAll('g')
79 .data(data) 88 .data(data)
@@ -81,17 +90,13 @@ var drawSvg = (function(){ @@ -81,17 +90,13 @@ var drawSvg = (function(){
81 .append('g').attr('class', 'item'); 90 .append('g').attr('class', 'item');
82 91
83 //上行站点 circle 92 //上行站点 circle
84 - g.append('circle')  
85 - .attr('class', function(d){  
86 - if(d.type != 1)  
87 - return 'up_station_circle';  
88 - })  
89 - .attr('cx', cx)  
90 - .attr('cy', mt); 93 + drawCircle(g, 'up', lineId);
  94 +
  95 + //下行站点 circle
  96 + drawCircle(g.select(function(d){return d.type!=0?this:null}), 'down', lineId);
91 97
92 //站点名称 text 98 //站点名称 text
93 - g.append('text')  
94 - .attr('class', function(d, i){ 99 + g.append('text').attr('class', function(d, i){
95 var c = 'station_text'; 100 var c = 'station_text';
96 if(i == 0) 101 if(i == 0)
97 c += ' start'; 102 c += ' start';
@@ -107,15 +112,6 @@ var drawSvg = (function(){ @@ -107,15 +112,6 @@ var drawSvg = (function(){
107 .attr('x', function(d, i){return (d.type==3?(x(i) - 8):x(i))}) 112 .attr('x', function(d, i){return (d.type==3?(x(i) - 8):x(i))})
108 .attr('y', mt + 10); 113 .attr('y', mt + 10);
109 114
110 - //下行站点  
111 - g.select(function(d){return d.type!=0?this:null})  
112 - .append('circle')  
113 - .attr('class', function(d){  
114 - if(d.type != 0)  
115 - return 'down_station_circle';  
116 - })  
117 - .attr('cx', cx)  
118 - .attr('cy', mt + p);  
119 115
120 //上下行不同名(异站合并) 116 //上下行不同名(异站合并)
121 g.select(function(d){return d.type==3?this:null}) 117 g.select(function(d){return d.type==3?this:null})
@@ -137,8 +133,8 @@ var drawSvg = (function(){ @@ -137,8 +133,8 @@ var drawSvg = (function(){
137 var t = $(this).text() 133 var t = $(this).text()
138 len = t.length; 134 len = t.length;
139 if(len > 7){ 135 if(len > 7){
140 - $(this).data('fullname', t);  
141 - return t.substring(0, 7); 136 + var sortText = t.substring(0, 7);
  137 + return sortText;
142 } 138 }
143 return t; 139 return t;
144 }); 140 });
@@ -146,86 +142,210 @@ var drawSvg = (function(){ @@ -146,86 +142,210 @@ var drawSvg = (function(){
146 $(' .text-load', '#'+container).remove(); 142 $(' .text-load', '#'+container).remove();
147 svg.transition().duration(500).attr('opacity', 1); 143 svg.transition().duration(500).attr('opacity', 1);
148 144
149 - up(svg, data, g); 145 + //GPS点容器
  146 + svg.append('g').attr('class', 'gps-g-wrap');
  147 +
  148 + d3.selectAll('g.item circle').select(function(){
  149 + return $(this).attr('class')?null:this;
  150 + }).remove();
  151 +
  152 + },
  153 +
  154 + //画出GPS点
  155 + drawVehicle: function(gpsArray){
  156 +
  157 + for(var i = 0, gps; gps = gpsArray[i ++];){
  158 + var svg = lineSvgMapp[gps.lineId]
  159 + ,stionId = gps.lineId + '_' + gps.stopNo
  160 + ,station = $('#' + stionId)
  161 + ,c = station.attr('class')||""
  162 + ,start = c.indexOf('start') != -1
  163 + ,end = c.indexOf('end') != -1;
  164 +
  165 + if(station.length == 0)
  166 + continue;
  167 +
  168 + //起终点站GPS信号
  169 + if(seGps[stionId]){
  170 + seGps[stionId].push(gps);
  171 + continue;
  172 + }
  173 +
  174 + var cx = parseInt(station.attr('cx'))
  175 + ,cy = parseInt(station.attr('cy'))
  176 + ,updown = station.attr('updown')
  177 + ,gpsGWrap = svg.select('.gps-g-wrap')
  178 + ,gpscont;
  179 +
  180 + if($('g[for='+stionId+']').length == 0){
  181 + gpscont = gpsGWrap.append('g')
  182 + .attr('class', 'station-gps-container')
  183 + .attr('updown', updown)
  184 + .attr('for', stionId);
  185 + }else{
  186 + gpscont = gpsGWrap.selectAll('g')
  187 + .select(function(){return $(this).attr('for') == stionId?this:null})
  188 + .classed({'multiple': true});
  189 + }
  190 + var vg = gpscont.selectAll('g[deviceId="'+gps.deviceId+'"]')
  191 + .data([gps]).enter().append('g')
  192 + .attr('deviceId', gps.deviceId)
  193 + .attr('class', 'vehci-g ' + (updown==0?'up':'down'))
  194 + .attr('station', gps.stopNo);
  195 +
  196 + //上下行异常
  197 + /*if(!start && !end && updown != gps.upDown){
  198 + vg.classed({'updown-error': true});
  199 + }*/
  200 +
  201 + vg.append('text')
  202 + .attr('x', cx + 4).attr('y', cy + 17)
  203 + .text(cutNbbm(gps.nbbm));
  204 +
  205 + var rect = vg.append('rect').attr('x', cx).attr('y', cy);
  206 +
  207 + //tooltip
  208 + _tooltip.initGpsTip(vg);
  209 + }
  210 +
  211 + //画出起终点GPS信号
  212 + var len;
  213 + for(var eid in seGps){
  214 + len = seGps[eid].length;
  215 + if(len > 0){
  216 + var e = $('#' + eid)
  217 + ,x = parseInt(e.attr('cx'))
  218 + ,y = parseInt(e.attr('cy'));
  219 +
  220 + var svg = lineSvgMapp[seGps[eid][0].lineId];
  221 +
  222 + var gs = svg.append('g').classed({'start': e.attr('class').indexOf('start') != -1, 'park': true})
  223 + .selectAll('g').data(seGps[eid]).enter().append('g');
  224 + //Y轴居中
  225 + y = (y + 66) - len * 13;
  226 + gs.append('rect')
  227 + .attr('x', x + 15)
  228 + .attr('y', function(d, i){
  229 + return y + i * 27;
  230 + })
  231 + .classed({'gps-rect': true});
  232 +
  233 + gs.append('text')
  234 + .attr('x', x + 18)
  235 + .attr('y', function(d, i){
  236 + return y + i * 27 + 17;
  237 + })
  238 + .text(function(d){return cutNbbm(d.nbbm)});
  239 + }
  240 + }
  241 +
  242 + /**
  243 + * 堆叠多个GPS信号
  244 +
  245 + $.each($('.station-gps-container'), function(i, multiGps){
  246 + var tArray = $(multiGps).find('g')
  247 + ,updowm = $(multiGps).attr('updown')
  248 + ,translateY
  249 + ,len = tArray.length;
  250 +
  251 + var circle = $('#' + $(multiGps).attr('for'))
  252 + ,c = circle.attr('class')
  253 + ,start = c.indexOf('start') != -1
  254 + ,end = c.indexOf('end') != -1;
  255 +
  256 + if(start || end || len > 2){
  257 + tArray.hide();
  258 + drawNumber(multiGps, len, this, start, end);
  259 + }if(len == 2){
  260 + if(updowm == 0){
  261 + translateY = -60;
  262 + }else
  263 + translateY = 32;
  264 +
  265 + $(tArray[1]).css('transform', 'translate(-15px, '+ translateY +'px)');
  266 + }
  267 + }); */
  268 +
  269 +/* function drawNumber(multiGps, num, that, start, end){
  270 + var circle = $('#' + $(multiGps).attr('for'))
  271 + ,x = circle.attr('cx')
  272 + ,y = circle.attr('cy');
  273 +
  274 + //数字标记
  275 + var numberG = d3.select(that).append('g').attr('class', 'number-g');
  276 +
  277 + if(start)
  278 + numberG.classed({'start': true});//始发站
  279 + else if(end)
  280 + numberG.classed({'end': true});//终点站
  281 +
  282 + numberG.append('rect').attr('x', x).attr('y', y);
  283 + numberG.append('text').attr('x', x).attr('y', y).text(num);
  284 + }*/
150 } 285 }
151 }; 286 };
152 287
153 - //更新  
154 - function up(svg, data, g){  
155 - /**  
156 - * ------------- 抽站 --------------------------------  
157 - */  
158 - var ms = w / 37  
159 - ,dLen = data.length;  
160 - if(ms < dLen){  
161 - var rs = dLen - ms  
162 - ,s = parseInt(dLen / 2 - rs)  
163 - ,e = (rs + s) * 2;  
164 -  
165 - var rsEmes = [];  
166 - //中间开始,隔站抽  
167 - for(;s < e; s +=2)  
168 - rsEmes.push(g[0][s]);  
169 -  
170 - var i = 0;  
171 - (function(){  
172 - var f = arguments.callee;  
173 - if(i >= rsEmes.length){  
174 - upPosi(svg) 288 + function drawPath(svg, data,updown, noclear){
  289 + svg.append('g').selectAll('path')
  290 + .data(data.slice(0, data.length - 1)).enter().append('path')
  291 + .attr('d', function(d, i) {
  292 + return line[updown]([{cx: x(i)}, {cx: x(i + 1)} ]);
  293 + })
  294 + .attr('class', updown + '_path')
  295 + .attr('stroke-dasharray', function(d){//虚线
  296 + if(d.clear && d.clear != noclear){
  297 + $(this).css('stroke-width', '5px');
  298 + return '2,1';
175 } 299 }
  300 + return 0;
  301 + });
  302 + }
  303 +
  304 + function drawCircle(g, updown, lineId){
  305 + var len = g[0].length;
  306 + g.append('circle')
  307 + .attr('cx', cx)
  308 + .attr('cy', updown=='up'?mt:mt + p)
  309 + .attr('id',function(d){
  310 + if(d.id[0] != -1)
  311 + return lineId + '_' + d.id[0];
  312 + })
  313 + .attr('updown', updown=='up'?0:1)
  314 + .attr('class', function(d, i){
  315 + var no = updown=='up'?1:0
  316 + ,classz= '';
  317 + if(d.type != no)
  318 + classz += (updown + '_station_circle');
176 319
177 - $(rsEmes[i]).fadeOut(30, function(){  
178 - $(this).remove();  
179 - i ++;  
180 - f();  
181 - });  
182 - })();  
183 - } 320 + if(i == 0)
  321 + classz += ' start';
  322 + else if(i == len-1)
  323 + classz += ' end';
  324 +
  325 + return classz;
  326 + });
184 } 327 }
185 328
186 - function upPosi(svg){  
187 - //重新等比例位置  
188 - var gItems = svg.selectAll('g.item')  
189 - ,dLen = gItems[0].length;  
190 - x.domain([ 0, dLen]);  
191 - gItems.select(function(d, i){  
192 - var ts = $(this).find('text')  
193 - ,xv = x(i);  
194 - if(ts.length == 2){  
195 - xv = x(i) - 8;  
196 - d3.select(ts[1])  
197 - .transition().duration(500)//过渡  
198 - .attr('x', x(i) + 8); 329 + function cleanStation(data){
  330 + var ms = w / 52
  331 + ,dLen = data.length;
  332 + if(ms < dLen){
  333 + var end;
  334 + //最多清理一半
  335 + if(ms < dLen / 2)
  336 + end = parseInt(dLen / 2) + 1;
  337 + else
  338 + end = dLen - ms + 1;
  339 +
  340 + for(var i = 1; i < end; i ++){
  341 + var rem = data[i];
  342 + var prev = data[i - 1];
  343 +
  344 + prev.clear = rem.type + 10;//设置哪些点需要虚线连接
  345 + data.splice(i, 1);//要被清理的站点
  346 +
199 } 347 }
200 - d3.select(ts[0])  
201 - .transition().duration(500)//过渡  
202 - .attr('x', xv);  
203 -  
204 - d3.select(this).selectAll('circle')  
205 - .transition().duration(500)//过渡  
206 - .attr('cx', x(i));  
207 - });  
208 - //缩线  
209 - svg.select('path.up_path')  
210 - .transition().delay(500).duration(500)//过渡  
211 - .attr('d', function(){  
212 - return upLine([{cx: x(0)}, {cx: x(dLen - 1)}]);  
213 - });  
214 -  
215 - svg.select('path.down_path')  
216 - .transition().delay(500).duration(500)//过渡  
217 - .attr('d', function(){  
218 - return downLine([{cx: x(0)}, {cx: x(dLen - 1)}]);  
219 - });  
220 -  
221 - svg.select('path.down_path.arc')  
222 - .transition().delay(500).duration(500)//过渡  
223 - .attr('d', function(){  
224 - var cx = x(dLen - 1) + 8  
225 - ,cy = mt + 5  
226 - ,arc = cx + 18;  
227 - return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8);  
228 - }); 348 + }
229 } 349 }
230 350
231 return drawSvgObject; 351 return drawSvgObject;
src/main/resources/static/pages/control/line/js/main.js
1 !function(){ 1 !function(){
2 2
  3 + var gpsOff = 1000 * 60 * 5;
  4 +
3 var homeObject = { 5 var homeObject = {
4 init:function(){ 6 init:function(){
5 //初始化主页 7 //初始化主页
@@ -41,14 +43,27 @@ @@ -41,14 +43,27 @@
41 43
42 //svg线路图 44 //svg线路图
43 $.each(lineArray, function(i, obj){ 45 $.each(lineArray, function(i, obj){
44 - _data.queryStationRoute( obj.id, 'line_chart_' + obj.id , drawSvg.init); 46 + _data.queryStationRoute( obj.lineCode, 'line_chart_' + obj.lineCode , drawSvg.init);
45 }); 47 });
46 48
47 - //_data.queryStationRoute( lineArray[2].id, 'line_chart_' + lineArray[2].id , drawSvg.init);  
48 -  
49 $('.line_chart .top .top-remark').slimscroll({ 49 $('.line_chart .top .top-remark').slimscroll({
50 height: '47px' 50 height: '47px'
51 }); 51 });
  52 +
  53 + //模拟图GPS刷新事件
  54 + $('#tab_home').on('gps_refresh', function(e, add, up){
  55 + drawSvg.drawVehicle(add);
  56 + });
  57 +
  58 + //定时刷新GPS
  59 + _data.startRefreshGpsTimer();
  60 + /* setTimeout(function(){
  61 + homeObject.refreshGps(function(add, update){
  62 + //将新增的点画到模拟图上
  63 + drawSvg.drawVehicle(add);
  64 + });
  65 + }, 300);*/
  66 +
52 } 67 }
53 } 68 }
54 69
@@ -61,10 +76,21 @@ setTimeout(function(){ @@ -61,10 +76,21 @@ setTimeout(function(){
61 }); 76 });
62 $('#top-tabs-wrap .nav-tabs').append(topTabs); 77 $('#top-tabs-wrap .nav-tabs').append(topTabs);
63 78
64 - //加载地图页数据  
65 - //$('#tab_map').load('/pages/mapmonitor/real/real.html');  
66 - 79 + setTimeout(function(){
  80 + //加载地图页数据
  81 + $('#tab_map').load('/pages/mapmonitor/real/real.html');
  82 + }, 500);
67 83
68 homeObject.init(); 84 homeObject.init();
  85 +
69 }, 200) 86 }, 200)
  87 +
  88 +
  89 + function gpslistToMap(gpslist){
  90 + var map = {}
  91 + for(var i = 0, gps; gps = gpslist[i++];){
  92 + map[gps.deviceId] = gps;
  93 + }
  94 + return map;
  95 + }
70 }(); 96 }();
71 \ No newline at end of file 97 \ No newline at end of file
src/main/resources/static/pages/control/line/temps/home_tp.html
@@ -4,11 +4,11 @@ @@ -4,11 +4,11 @@
4 {{each tabList as tabObj i}} 4 {{each tabList as tabObj i}}
5 <div class="tab-pane {{if i == 0}}active in{{/if}}" id="tab_{{tabObj.id}}"> 5 <div class="tab-pane {{if i == 0}}active in{{/if}}" id="tab_{{tabObj.id}}">
6 {{each tabObj.array as lineObj j}} 6 {{each tabObj.array as lineObj j}}
7 -<div class="row card_wrap" style="{{if j == 0}}margin-top: 0px;{{/if}}"> 7 +<div class="row card_wrap" >
8 <div class="col-lg-2 "> 8 <div class="col-lg-2 ">
9 9
10 <div class="title"> 10 <div class="title">
11 - 发往{{lineObj.start}}方向 <span class="badge"> 13 </span> 11 + 发往{{lineObj.startStationName}}方向 <span class="badge"> 13 </span>
12 <div class="help_text dropdown"> 12 <div class="help_text dropdown">
13 <span class=" blue dropdown-toggle col_hide_1440" 13 <span class=" blue dropdown-toggle col_hide_1440"
14 data-toggle="dropdown" aria-expanded="true" 14 data-toggle="dropdown" aria-expanded="true"
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 <div class="table_wrap"> 51 <div class="table_wrap">
52 <table 52 <table
53 class="table table-striped table-bordered table-advance table-hover vehicDataTable" 53 class="table table-striped table-bordered table-advance table-hover vehicDataTable"
54 - style="table-layout: fixed;" id="tab_{{lineObj.id}}_0"> 54 + style="table-layout: fixed;" id="tab_{{lineObj.lineCode}}_0">
55 <colgroup> 55 <colgroup>
56 <col style="width: 20%;"> 56 <col style="width: 20%;">
57 <col style="width: 19%;"> 57 <col style="width: 19%;">
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 </table> 64 </table>
65 </div> 65 </div>
66 </div> 66 </div>
67 - <div class="col-lg-8 line_chart" id="line_chart_{{lineObj.id}}"> 67 + <div class="col-lg-8 line_chart" id="line_chart_{{lineObj.lineCode}}">
68 <div class="top"> 68 <div class="top">
69 <div class="center"> 69 <div class="center">
70 <strong>{{lineObj.name}}</strong> 70 <strong>{{lineObj.name}}</strong>
@@ -75,7 +75,7 @@ @@ -75,7 +75,7 @@
75 <div class="col-lg-2 down"> 75 <div class="col-lg-2 down">
76 76
77 <div class="title"> 77 <div class="title">
78 - 发往{{lineObj.end}}方向 <span class="badge"> 7 </span> 78 + 发往{{lineObj.endStationName}}方向 <span class="badge"> 7 </span>
79 <div class="help_text dropdown"> 79 <div class="help_text dropdown">
80 <span class=" blue dropdown-toggle col_hide_1440" 80 <span class=" blue dropdown-toggle col_hide_1440"
81 data-toggle="dropdown" aria-expanded="true" 81 data-toggle="dropdown" aria-expanded="true"
@@ -114,7 +114,7 @@ @@ -114,7 +114,7 @@
114 <div class="table_wrap"> 114 <div class="table_wrap">
115 <table 115 <table
116 class="table table-striped table-bordered table-advance table-hover vehicDataTable" 116 class="table table-striped table-bordered table-advance table-hover vehicDataTable"
117 - style="table-layout: fixed;" id="tab_{{lineObj.id}}_1"> 117 + style="table-layout: fixed;" id="tab_{{lineObj.lineCode}}_1">
118 <colgroup> 118 <colgroup>
119 <col style="width: 20%;"> 119 <col style="width: 20%;">
120 <col style="width: 19%;"> 120 <col style="width: 19%;">