| <%@ page contentType="text/html;charset=UTF-8" language="java" %> | 
| <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | 
| <%@page isELIgnored="false" %> | 
| <% | 
|     String version ="1.000003"; | 
|     response.setHeader("Cache-Control","no-store"); | 
|     response.setHeader("Pragrma","no-cache"); | 
|     response.setDateHeader("Expires",0); | 
| %> | 
| <!DOCTYPE html> | 
| <html lang="en"> | 
| <head> | 
|     <meta charset="UTF-8"> | 
|     <title>设备警报数据</title> | 
|     <style> | 
|         .align-center{ | 
|             margin:0 auto; /* 居中 这个是必须的,,其它的属性非必须 */ | 
|             /* background:red; 背景色  */ | 
|             text-align:center; /* 文字等内容居中 */ | 
|         } | 
|         body { | 
|             font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | 
|             margin: 0; | 
|             padding: 0; | 
|             border: 0; | 
|             position: relative; | 
|             width: 100%; | 
|         } | 
|         .dev-desc{ | 
|             position: relative; | 
|             height: 480px; | 
|         } | 
|         .dev-alarm-s0{ | 
|             background:url('/img/bg-s0.png') repeat-x fixed top; | 
|         } | 
|         .dev-alarm-s1{ | 
|             background:url('/img/bg-s1.png') repeat-x fixed top; | 
|         } | 
|         .dev-alarm-s2{ | 
|             background:url('/img/bg-s2.png') repeat-x fixed top; | 
|         } | 
|         .dev-alarm-s3{ | 
|             background:url('/img/bg-s3.png') repeat-x fixed top; | 
|         } | 
|         .dev-desc .state-summary{ | 
|             color: white; | 
|             font-size: 38px; | 
|             font-weight: 100; | 
|             position: relative; | 
|             left: 30%; | 
|         } | 
|         .dev-desc .state-summary td{ | 
|             padding: 0; | 
|             margin: 0; | 
|             border: 0; | 
|         } | 
|         .ui-block-a{ | 
|             height: 240px; | 
|         } | 
|         .dev-desc .dev-state{ | 
|             position: absolute; | 
|             text-align: center; | 
|             padding-top: 2%; | 
|             left:10%; | 
|             top:30px; | 
|             /* background: white; */ | 
|             /* opacity:0.1; */ | 
|             background-color: rgba(255,255,255,0.2); | 
|             color: white; | 
|             width: 420px; | 
|             height: 240px; | 
|             border:1px solid #f8f8f8; | 
|             border-radius: 10px; | 
|             z-index:999; | 
|         } | 
|         /*.dev-desc .dev-state-bg{*/ | 
|             /*left: 8%;*/ | 
|             /*top:30px;*/ | 
|             /*position: absolute;*/ | 
|             /*width: 420px;*/ | 
|             /*height: 240px;*/ | 
|             /*border:3px solid #f8f8f8;*/ | 
|             /*border-radius: 10px;*/ | 
|             /*!**background-color:rgb(0,152,50);**!*/ | 
|             /*background:white;*/ | 
|             /*opacity: 0.3;*/ | 
|             /*filter:alpha(opacity=30);*/ | 
|         /*}*/ | 
|         .dev-desc .dev-state .dev-state-title{ | 
|             font-size: 100px; | 
|             font-weight: 500; | 
|         } | 
|         .dev-desc .dev-state .dev-state-subtitle{ | 
|             font-size: 40px; | 
|             font-weight: 100; | 
|         } | 
|         .dev-desc .dev-state .dev-state-time{ | 
|             margin-top: 3%; | 
|             display: block; | 
|             font-size: 36px; | 
|             font-weight: 100; | 
|         } | 
|         .dev-desc .dev-info{ | 
|             position: relative; | 
|             margin-left: 8%; | 
|             color: black; | 
|         } | 
|         .dev-desc .dev-info .dev-name{ | 
|             font-size: 60px; | 
|             font-weight: 300; | 
|         } | 
|         .dev-desc .dev-info .dev-name .dev-name-suffix{ | 
|             font-size: 40px; | 
|             font-weight: 200; | 
|         } | 
|         .dev-desc .dev-info .dev-address{ | 
|             font-size: 30px; | 
|             font-weight: 200; | 
|         } | 
|         .bullet { font: 36px sans-serif; } | 
|         .bullet .marker { stroke: #000; stroke-width: 2px; } | 
|         .bullet .tick line { stroke: #666; stroke-width: .5px; } | 
|         .bullet .range.s0 { fill: #969696; } | 
|         .bullet .range.s1 { fill: #afafaf; } | 
|         .bullet .range.s2 { fill: #d6d6d6; } | 
|         .bullet .range.s3 { fill: #f1f1f1; } | 
|         .bullet .measure.s0_0 { fill: #0eb929; } | 
|         .bullet .measure.s1_0 { fill: #0eb929; } | 
|         .bullet .measure.s0_1 { fill: #b1aa02; } | 
|         .bullet .measure.s1_1 { fill: #b1aa02; } | 
|         .bullet .measure.s0_2 { fill: #e66404; } | 
|         .bullet .measure.s1_2 { fill: #e66404; } | 
|         .bullet .measure.s0_3 { fill: #bf031a; } | 
|         .bullet .measure.s1_3 { fill: #bf031a; } | 
|         .bullet .meaning.state {fill:white; font-size: 36px;} | 
|         .bullet .meaning.text {fill:black; font-size: 36px;} | 
|         .bullet .title { font-size: 42px;} | 
|         .bullet .subtitle { fill: #999; } | 
|         .bullet-content { | 
|             width: 100%; | 
|         } | 
|         .bullet-content .bullet-row{ | 
|             border: 0; | 
|             border-bottom: 1px solid #d3d3d3; | 
|             padding: 4% 0 0; | 
|             height: 180px; | 
|         } | 
|         .bullet-row:hover{ | 
|             background: #e8e8e8; | 
|         } | 
|         /* .bullet-content .bullet-row .bullet-col{ | 
|           padding: 7% 0 6%; | 
|         } */ | 
|     </style> | 
|     <link rel="stylesheet" href="/css/jquery.mobile-1.4.5.min.css"> | 
|     <script src="/js/moment-with-locales.js"></script> | 
|     <script src="/js/jquery.min.js"></script> | 
|     <script src="/js/jquery.mobile-1.4.5.min.js"></script> | 
|     <script src="/js/d3.min.js"charset="utf-8"></script> | 
|     <script src="/js/bullet.js"></script> | 
|     <title>监控数据</title> | 
| </head> | 
| <body> | 
| <div id="parms" style="display: none;"> | 
|      <div id="alarm">${requestScope.alarm}</div> | 
|      <div id="device">${requestScope.device}</div> | 
|      <div id="sensors">${requestScope.sensors}</div> | 
|      <div id="data">${requestScope.data}</div> | 
|     <div id="alarmLevels">${requestScope.alarmLevels}</div> | 
| </div> | 
| <div data-role="page" id="page-init"> | 
|     <div data-role="header" class="dev-desc"> | 
|         <div data-role="main" class="ui-content"> | 
|             <div class="ui-grid-a"> | 
|                 <div class="ui-block-a"> | 
|                     <%--<div class="dev-state-bg ui-corner-all"></div>--%> | 
|                     <div class="dev-state"> | 
|                           <span id="alarm-state" class="dev-state-title"> | 
|                           </span> | 
|                         <span class="dev-state-subtitle"> | 
|                             状态 | 
|                           </span> | 
|                         <br/> | 
|                         <span id="alarm-time" class="dev-state-time"> | 
|                         </span> | 
|                     </div> | 
|                 </div> | 
|                 <div class="ui-block-b"> | 
|                     <div class="state-summary"> | 
|                         <table data-role="table" class="ui-responsive"> | 
|                             <thead> | 
|                             <tr> | 
|                                 <th></th> | 
|                                 <th></th> | 
|                                 <th></th> | 
|                                 <th></th> | 
|                             </tr> | 
|                             </thead> | 
|                             <tbody> | 
|                             <tr> | 
|                                 <td style="width:20%">严重</td> | 
|                                 <td ><span id="state3_count"></span></td> | 
|                             </tr> | 
|                             <tr> | 
|                                 <td>中度</td> | 
|                                 <td><span id="state2_count"></span></td> | 
|                             </tr> | 
|                             <tr> | 
|                                 <td>轻度</td> | 
|                                 <td><span id="state1_count"></span></td> | 
|                             </tr> | 
|                             <tr> | 
|                                 <td>正常</td> | 
|                                 <td><span id="state0_count"></span></td> | 
|                             </tr> | 
|                             <tr> | 
|                                 <td></td> | 
|                                 <td></td> | 
|                             </tr> | 
|                             </tbody> | 
|                         </table> | 
|                     </div> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|         <div data-role="main" class="ui-content"> | 
|             <div class="ui-grid-solo"> | 
|                 <div class="ui-block-a"> | 
|                     <div class="dev-info"> | 
|                         <div class="dev-name"> | 
|                             <span id="device-name">金浦路云山诗意01</span> | 
|                             <span  class="dev-name-suffix">设备</span> | 
|                         </div> | 
|                         <div class="dev-address"> | 
|                                   <span> | 
|                                       地址: | 
|                                   </span> | 
|                             <span id="device-address"> | 
|                             </span> | 
|                         </div> | 
|                     </div> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|     </div> | 
|     <div data-role="main" class="ui-content"> | 
|         <div class="bullet-content ui-grid-solo"> | 
|         </div> | 
|         <!-- <div data-role="footer"> | 
|           <h1>底部文本</h1> | 
|         </div> --> | 
|     </div> | 
|   | 
| </div> | 
| </body> | 
| </html> | 
| <script> | 
|     function  createBullet(data) { | 
|         var margin = {top: 5, right:100, bottom: 20, left:140}, | 
|             width = window.innerWidth*0.95 - margin.left - margin.right, | 
|             height = 90 - margin.top - margin.bottom; | 
|         // bullet 函数对象 | 
|         var chart = d3.bullet() | 
|             .width(width) | 
|             .height(height); | 
|         var svg = d3.select(".bullet-content").selectAll("svg") | 
|             .data(data) | 
|             .enter() | 
|             .append("div") | 
|             .attr("class","ui-block-a bullet-row") | 
|             .append("svg") | 
|             .attr("class", "bullet") | 
|             .attr("width", width + margin.left + margin.right) | 
|             .attr("height", height + margin.top + margin.bottom) | 
|             .append("g") | 
|             .attr("transform", "translate(" + margin.left + "," + margin.top + ")") | 
|             .call(chart); | 
|   | 
|         var title = svg.append("g") | 
|             .style("text-anchor", "end") | 
|             .attr("transform", "translate(60," + (height / 2+5)+ ")"); | 
|   | 
|         title.append("text") | 
|             .attr("class", "title") | 
|             .text(function(d) { return d.title; }); | 
|   | 
|         title.append("text") | 
|             .attr("class", "subtitle") | 
|             .attr("dy", "1em") | 
|             .text(function(d) { return d.subtitle; }); | 
|     } | 
|   | 
|     /** | 
|      * | 
|      * @param sortKeys 排序好的key数组 | 
|      * @param data  监控数据 | 
|      * @param sensors 设备明细 | 
|      * @param alarmData 报警数据 | 
|      * @param alarmLevels 报警阀值配置 | 
|      * @returns {Array} | 
|      */ | 
|     function createBulletData(sortKeys,data,sensors,alarmData,alarmLevels) { | 
|         var bullets = []; | 
|         for(var index = 0; index<sortKeys.length;index++){ | 
|               var bullet = {"ranges":[],"measures":[],"markers":[]}; | 
|               var sensorKey = sortKeys[index]; | 
|               var sensor = sensors.find(function (value) { | 
|                     return value.sensorKey == sensorKey; | 
|               }); | 
|             sensorLevel = alarmLevels[sensorKey]; | 
|             if(!sensor) break; | 
|             bullet.title = !!sensor["description"]?sensor["description"]:sensor.name; | 
|             bullet.subtitle = sensor.unit; | 
|             bullet.state = !!alarmData[sensorKey]?alarmData[sensorKey]:0; | 
|             bullet.measures.push(data[sensorKey]); | 
|             bullet.markers.push(data[sensorKey]); | 
|             var start = 0; | 
|             if(!!sensorLevel&&!!sensorLevel.enable){ | 
|                 var ranges = sensorLevel.increment; | 
|                 if(!!sensorLevel.degressEnable){ | 
|                     var inFirst = sensorLevel.increment[0]; | 
|                     var deFirst = sensorLevel.degression[0]; | 
|                     start = (inFirst+deFirst)/2; | 
|                     ranges = Math.abs(data[sensorKey]-inFirst) >  Math.abs(data[sensorKey]-deFirst) ? sensorLevel.degression:sensorLevel.increment; | 
|                     bullet.startPoint = start; | 
|                 } | 
|                 bullet.ranges = ranges; | 
|             }else { | 
|                 var range = data[sensorKey]*10; | 
|                 for(var n=0;n<3;n++){ | 
|                     bullet.ranges.push(range); | 
|                 } | 
|             } | 
|             bullets.push(bullet); | 
|         } | 
|         console.log(bullets); | 
|         return bullets; | 
|     } | 
|     // init page | 
|     (function () { | 
|         var alarm = $.parseJSON($("#alarm").text()); | 
|         alarm["json"] = $.parseJSON(alarm.json); | 
|         var device = $.parseJSON($("#device").text()); | 
|         var sensors = $.parseJSON($("#sensors").text()); | 
|         var data = $.parseJSON($("#data").text()); | 
|         var alarmLevels = $.parseJSON($("#alarmLevels").text()); | 
|         // 载入数据 | 
|         var alarmState; | 
|         var alarmStateClass = 'dev-alarm-s'+ alarm.state; | 
|         switch (alarm.state){ | 
|             case 1: alarmState = '轻度'; | 
|             break; | 
|             case 2: alarmState = '中度';break; | 
|             case 3: alarmState = '重度';break; | 
|             default: alarmState = '正常';break; | 
|         } | 
|         $(".dev-desc").addClass(alarmStateClass) | 
|         $("#alarm-state").text(alarmState); | 
|         $("#alarm-time").text(moment(alarm.time).format("YYYY-MM-DD HH:mm:ss")); | 
|         $("#device-address").text(device.address); | 
|         $("#device-name").text(device.name); | 
|         var stateSummary = [0,0,0,0];// index 0 正常的数量 | 
|         Object.keys(data).forEach(function (value) { | 
|             var _value = !!alarm.json[value]? alarm.json[value]:0; | 
|             stateSummary[_value] +=1; | 
|         }) | 
|         stateSummary.forEach(function (value, index) { | 
|             $("#state"+index+"_count").text(value); | 
|         }); | 
|         var alarmSortKeys = Object.keys(data).sort(function (a, b) { | 
|                var aValue = !!alarm.json[a]? alarm.json[a]:0; | 
|                var bValue = !!alarm.json[b]? alarm.json[b]:0; | 
|                return bValue - aValue; | 
|         }); | 
|         var bulletData = createBulletData(alarmSortKeys,data,sensors,alarm.json,alarmLevels); | 
|         // console.log(bulletData); | 
|         createBullet(bulletData); | 
|     })(); | 
| </script> |