const url = "http://47.107.28.109:8006/"; // const url = "http://127.0.0.1:8006/"; var myPieEchart = echarts.init($('.pie')[0]); // 饼图 var myLineEchart = echarts.init($('.line')[0]); // 折线图 var myBarEchart = echarts.init($('.users .bar')[0]); // 柱状图 var myMapChart = echarts.init($('.map .geo')[0]); // 地图 var mapOption; // 地图参数 var heartbeatTime, breakTime, showTime; // 定时任务 var partId; // 机构id var colorList = ['#00f2f1','#006cff', '#eab408', '#ed8884', '#ff9f7f', '#0096ff', '#9fe6b8', '#32c5e9', '#1d9dff']; /*大屏*/ //自调用函数 (function () { // 1、页面一加载就要知道页面宽度计算 var setFont = function () { // 因为要定义变量可能和别的变量相互冲突,污染,所有用自调用函数 var html = document.documentElement;// 获取html // 获取宽度 var width = html.clientWidth; // 判断 if (width < 1024) width = 1024 if (width > 1920) width = 1920 // 设置html的基准值 var fontSize = width / 80 + 'px'; // 设置给html html.style.fontSize = fontSize; } setFont(); $(".geo").height($(".map").height()); // 2、页面改变的时候也需要设置 // 尺寸改变事件 window.onresize = function () { setFont(); $(".geo").height($(".map").height()); } //时间 // $('.clock').FlipClock({ // clockFace: 'TwentyFourHourClock' // }); })(); // 请求后台获取数据 (function () { partId = getQuery("partId"); if (partId) { // 连接webSocket initWebSocket(); // 打开定时器 openTimer(); } })(); // 获取看板用户信息 function getUserInfo() { $.get(url + "bulletinBoard/user_info/" + partId, function (data, status) { console.log(data.partInfo.shop_name); $(".title").text(data.partInfo.shop_name); $("#allCount").text(data.userCount.all_count); // 总用户 $("#quarterly-addition").text(data.userCount.quarterly_count); // 季度新增 $("#monthly-addition").text(data.userCount.month_count); // 月度新增 $("#manCount").text(data.userCount.man_count ? data.userCount.man_count : 0); // 男生人数 $("#womanCount").text(data.userCount.woman_count ? data.userCount.woman_count : 0); // 女生人数 // 地图人员分布 mapOption = initMap(); if (data.memberList.length > 0) { var d = [] data.memberList.forEach((item, index) => { d.push({ name: item.nickname, value: item.lng_lat.split(","), size: 10, text: formatText(item), }) }) mapOption.series[1].data = d; // mapOption.bmap.center = [114.08259, 22.356868]; // 114.08259, 22.556868 mapOption.bmap.center = d[0].value; // 114.08259, 22.556868 mapOption.bmap.zoom = 16; } myMapChart.setOption(mapOption); window.addEventListener('resize', myMapChart.resize); // 年龄段饼图 var pieOption = initPieChar(); pieOption.series[0].data = data.pieData; myPieEchart.setOption(pieOption); }); } // 获取看板事件报警信息 function getSOSInfo() { $.get(url + "bulletinBoard/sos_info/" + partId, function (data, status) { // 最新事件报警表格 var rows = [] $.each(data.actionList, function (i, n) { var row = '
\n' + ''+unixToDate(n.create_date, "MM-dd hh:mm")+'\n' + ''+n.from_member_name+'\n' + ''+n.from_device_name+'\n' + '\n' + '
'; rows.push(row) }); $("#vsLogTable").html(rows.join('')) // 报警分布 var xData = [], yData = []; data.barList.forEach((item, index) => { xData.push(item.name) yData.push(item.value) }) var barOption = initBarChar(); barOption.xAxis[0].data = xData; barOption.series[0].data = yData; myBarEchart.setOption(barOption); // 动态报警折线图 initDynamicAlarm(data); }); } // 获取看板体征信息 function getLogInfo() { $.get(url + "bulletinBoard/log_info/" + partId, function (data, status) { $("#dayCount").text(data.logCount.day_count); // 今日测量数 $("#hourCount").text(data.logCount.hour_count); // 近1小时测量数 // 动态测量项 initMeasureItem(data); // 体征报警表格 var rows = [] $.each(data.errVsLogList, function (i, n) { var row = '
\n' + ''+unixToDate(n.log_time, "MM-dd hh:mm")+'\n' + ''+n.member_nickname+'\n' + ''+n.param_name+'\n' + ''+n.vs_value+'\n' + '\n' + '
'; rows.push(row) }); $("#errVsLogTable").html(rows.join('')) // $.each(data.errVsLogList, function (i, n) { // var row = $("#errVsLogTemplate").clone(); // row.find(".errVsLogTime").text(unixToDate(n.log_time, "MM-dd hh:mm")); // row.find(".errVsLogUser").text(n.member_nickname); // row.find(".errVsLogItem").text(n.param_name); // row.find(".errVsLogValue").text(n.vs_value); // row.appendTo("#errVsLogTable"); // }); }); } function initWebSocket() { var time = Math.round(new Date()) + "" + Math.round(Math.random()*100); console.log(time) // var s = "ws://127.0.0.1:8006/bulletinBoard/" + time + "/" + partId; var s = "ws://47.107.28.109:8006/bulletinBoard/" + time + "/" + partId; console.log(s) var ws = new WebSocket(s); ws.onopen = function(evt) { console.log("webSocket连接成功 ..."); clearInterval(breakTime); breakTime = null; heartbeatTime = setInterval(function () { ws.send("ping"); }, 55000); // 55秒心跳包 // 获取看板用户信息 getUserInfo(); // 获取看板事件报警信息 getSOSInfo(); // 获取看板体征信息 getLogInfo(); }; ws.onmessage = function(e) { console.log("收到消息: " + e.data); if (e.data === 'pong') { return } // {"address":"广东省深圳市南山区留仙大道大学城创客小镇","ageUnit":"岁","birthday":-189417600,"createTime":1661990011,"data":"15秒红外报警", // "frameId":1155,"id":457,"lngLat":"113.961957,22.579848","memberId":54658,"mobile":"18174091244","named":"小米面","partId":2, // "renewType":"SOS","sex":1,"status":0} const data = JSON.parse(e.data); if (data.renewType === 'SOS') { openSOSMap(data); // 地图高亮 getSOSInfo(); // 刷新看板 } else if ("LOG") { openSOSMap(data); // 地图高亮 getLogInfo(); // 刷新体征 } else { // USER getUserInfo(); // 刷新用户 } }; ws.onclose = function(evt) { console.log("webSocket连接关闭.", breakTime); if (!breakTime) { console.log('新的定时任务....') clearInterval(heartbeatTime); breakTime = setInterval(function () { console.log('正在重连...') initWebSocket(); }, 5000); // 5秒重连一次 } // heartbeatTime. }; } // 地图高亮 function openSOSMap(data) { if (data.lngLat) { var d = [] d.push({ name: data.named, value: data.lngLat.split(","), size: 20, text: formatSOSText(data), }) mapOption.series[0].data = d; mapOption.bmap.center = d[0].value; mapOption.bmap.zoom = 18; myMapChart.setOption(mapOption); myMapChart.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: 0 }); clearTimeout(showTime); showTime = setTimeout(clearSOSMap, 15000); } } // 清除百度地图报警点 function clearSOSMap() { console.log("我要清除报警高亮点了", mapOption.series[0].data, mapOption.series[1].data[0].value) mapOption.series[0].data = []; mapOption.bmap.center = mapOption.series[1].data[0].value; mapOption.bmap.zoom = 16; myMapChart.setOption(mapOption); } // 打开定时器 function openTimer() { // 测量时间段定时器 var i = 0, ii = 0; var aclick = $('.order a'); setInterval(function () { i++; if (i > 3) { i = 0; } //每3秒调用点击事件 aclick.eq(i).click(); }, 3000); // 报警统计折线图定时器 setInterval(function () { ii++; if (ii > 4) { ii = 0; } $('.alarms .caption a').eq(ii).click(); }, 5000); } (function () { //事件委托 $('.monitor').on('click', ' a', function () { //点击当前的a 加类名 active 他的兄弟删除类名 $(this).addClass('active').siblings().removeClass('active'); //获取一一对应的下标 var index = $(this).index(); //选取content 然后对应下标的 显示 当前的兄弟.content隐藏 $('.content').eq(index).show().siblings('.content').hide(); }); //滚动 //原理:把marquee下面的子盒子都复制一遍 加入到marquee中 // 然后动画向上滚动,滚动到一半重新开始滚动 //因为选取的是两个marquee 所以要遍历 $('.monitor .marquee').each(function (index, dom) { //将每个 的所有子级都复制一遍 var rows = $(dom).children().clone(); //再将新的到的加入原来的 $(dom).append(rows); }); })(); // 报警分布柱状图 function initBarChar() { return { // 工具提示 tooltip: { // 触发类型 经过轴触发axis 经过轴触发item trigger: 'item', // 轴触发提示才有效 axisPointer: { // 默认为直线,可选为:'line' 线效果 | 'shadow' 阴影效果 type: 'shadow' } }, // 图表边界控制 grid: { // 距离 上右下左 的距离 left: '0', right: '3%', bottom: '3%', top: '5%', // 大小是否包含文本【类似于boxsizing】 containLabel: true, //显示边框 show: true, //边框颜色 borderColor: 'rgba(0, 240, 255, 0.3)' }, // 控制x轴 xAxis: [ { // 使用类目,必须有data属性 type: 'category', // 使用 data 中的数据设为刻度文字 data: [], // 刻度设置 axisTick: { // true意思:图形在刻度中间 // false意思:图形在刻度之间 alignWithLabel: false, show: false }, //文字 axisLabel: { color: '#4c9bfd' } } ], // 控制y轴 yAxis: [ { // 使用数据的值设为刻度文字 type: 'value', axisTick: { // true意思:图形在刻度中间 // false意思:图形在刻度之间 alignWithLabel: false, show: false }, //文字 axisLabel: { color: '#4c9bfd' }, splitLine: { lineStyle: { color: 'rgba(0, 240, 255, 0.3)' } }, } ], // 控制x轴 series: [ { // series配置 // 颜色 itemStyle: { // 提供的工具函数生成渐变颜色 color: new echarts.graphic.LinearGradient( // (x1,y2) 点到点 (x2,y2) 之间进行渐变 0, 0, 0, 1, [ {offset: 0, color: '#00fffb'}, // 0 起始颜色 {offset: 1, color: '#0061ce'} // 1 结束颜色 ] ) }, // 图表数据名称 name: '报警分布', // 图表类型 type: 'bar', // 柱子宽度 barWidth: '60%', // 数据 data: [] } ] }; } // 性别饼图 function initPieChar() { return { // 控制提示 tooltip: { // 非轴图形,使用item的意思是放到数据对应图形上触发提示 trigger: 'item', // 格式化提示内容: // a 代表图表名称 b 代表数据名称 c 代表数据 d代表 当前数据/总数据的比例 formatter: "{a}
{b} : {c} ({d}%)" }, // 控制图表 series: [ { // 图表名称 name: '年龄段', // 图表类型 type: 'pie', // 南丁格尔玫瑰图 有两个圆 内圆半径10% 外圆半径70% // 百分比基于 图表DOM容器的半径 radius: ['10%', '70%'], // 图表中心位置 left 50% top 50% 距离图表DOM容器 center: ['50%', '50%'], // 半径模式,另外一种是 area 面积模式 roseType: 'radius', // 数据集 value 数据的值 name 数据的名称 data: [], //文字调整 label: { fontSize: 10 }, //引导线 labelLine: { length: 8, length2: 10 } }, ], color: ['#006cff', '#60cda0', '#ed8884', '#ff9f7f', '#0096ff', '#9fe6b8', '#32c5e9', '#1d9dff'] }; } // 报警统计折线图 function initLineChar() { return { //鼠标提示工具 tooltip: { trigger: 'axis' }, xAxis: { // 类目类型 type: 'category', // x轴刻度文字 data: [], axisTick: { show: false//去除刻度线 }, axisLabel: { color: '#4c9bfd'//文本颜色 }, axisLine: { show: false//去除轴线 }, boundaryGap: false//去除轴内间距 }, yAxis: { // 数据作为刻度文字 type: 'value', axisTick: { show: false//去除刻度线 }, axisLabel: { color: '#4c9bfd'//文本颜色 }, axisLine: { show: false//去除轴线 }, boundaryGap: false//去除轴内间距 }, //图例组件 legend: { textStyle: { color: '#4c9bfd' // 图例文字颜色 }, right: '10%'//距离右边10% }, // 设置网格样式 grid: { show: true,// 显示边框 top: '20%', left: '3%', right: '4%', bottom: '3%', borderColor: '#012f4a',// 边框颜色 containLabel: true // 包含刻度文字在内 }, series: [{ // 数据 data: [], // 图表类型 type: 'line', // 圆滑连接 smooth: true, itemStyle: { color: '#00f2f1' // 线颜色 } }] }; } // 动态测量项 function initMeasureItem(data) { // 365天、90、30、7天测量 var item = { day365: { count: data.logCount.year_count + data.logCount.year_err_count, errCount: data.logCount.year_err_count }, day90: { count: data.logCount.season_count + data.logCount.season_err_count, errCount: data.logCount.season_err_count }, day30: { count: data.logCount.month_count + data.logCount.month_err_count, errCount: data.logCount.month_err_count }, day7: { count: data.logCount.week_count + data.logCount.week_err_count, errCount: data.logCount.week_err_count } }; $('.order .item h4:eq(0)').text(item.day365.count); $('.order .item h4:eq(1)').text(item.day365.errCount); // 点击事件 $('.order').on('click', '.filter a', function () { //点击之后加类名 $(this).addClass('active').siblings().removeClass('active'); // 先获取点击a的 data-key自定义属性 var key = $(this).attr('data-key'); key = item[key]; $('.order .item h4:eq(0)').text(key.count); $('.order .item h4:eq(1)').text(key.errCount); }); } // 动态报警折线图 function initDynamicAlarm(item) { var lineOption = initLineChar(); lineOption.series = []; if (item.week[0].length > 0) { item.week[0].forEach((t, i) => { var d = { name: item.week[2][i], type: 'line', stack: 'year总量' + i, data: t, smooth: true, emphasis: { focus: 'series', blurScope: 'coordinateSystem' }, itemStyle: { color: colorList[i] // 线颜色 } }; lineOption.series.push(d); }); } // lineOption.series[0].data = item.year[0]; lineOption.legend.data = item.week[2]; lineOption.xAxis.data = item.week[1]; var data = { year: item.year, month: item.month, week: item.week }; myLineEchart.setOption(lineOption); $('.alarms ').on('click', '.caption a', function () { $(this).addClass('active').siblings('a').removeClass('active'); lineOption = initLineChar(); //option series data //获取自定义属性值 var k = $(this).attr('data-type'); //取出对应的值 var key = data[k]; //将值设置到 图表中 if (key[0].length > 0) { if (k === 'week') { lineOption = initLineChar(); myLineEchart.setOption(lineOption); } key[0].forEach((t, i) => { var d = { name: key[2][i], type: 'line', stack: k + '总量' + i, data: t, smooth: true, emphasis: { focus: 'series', blurScope: 'coordinateSystem' }, itemStyle: { color: colorList[i] // 线颜色 } } lineOption.series.push(d); }) // lineOption.series[0].data = key[0]; } else { var dd = []; key[1].forEach((t, i) => { dd.push('0'); }); lineOption.series.push({ name: '', type: 'line', stack: k + '总量0', data: dd, smooth: true, emphasis: { focus: 'series', blurScope: 'coordinateSystem' }, itemStyle: { color: '#00f2f1' // 线颜色 } }); key[2] = ['']; } lineOption.legend.data = key[2]; // 坐标修改 lineOption.xAxis.data = key[1]; //再次调用才能在页面显示 myLineEchart.setOption(lineOption); }); } // 初始化百度地图 function initMap() { return { backgroundColor: 'transparent', title: { text: '用户地图一览', left: 'center', textStyle: { color: '#fff' } }, tooltip: { trigger: 'item', formatter: function (params) { //console.log(params); return params.data.text } }, bmap: { center: [114.25, 30.34], //地图中心点 zoom: 11, //默认缩放倍数 roam: true, //禁止放大缩小 geo: { aspectScale: 0.3 }, mapStyleV2: { styleJson: returnMapStyleJson() } }, series: [ { name: '体征告警', type: 'effectScatter', //气泡动态效果 coordinateSystem: 'bmap', // 地图选择项bmap为百度地图 data: [], symbolSize: function (val1, val2) { // console.log(val1,val2) return val2.data.size; }, //标记大小 showEffectOn: 'render', // 配置何时显示特效。 render 绘制完成后显示特效。emphasis 高亮(hover)的时候显示特效。 rippleEffect: { brushType: 'stroke', // 波纹的绘制方式 stroke 和 fill number: 3, // 波纹的数量 scale: 5, // 波纹放大的倍数 color: '#8FD1C3' }, hoverAnimation: true, label: { formatter: '{b}', position: 'right', show: true }, itemStyle: { color: '#f37b1d', shadowBlur: 10, shadowColor: '#333' }, zlevel: 1 }, { name: '正常体征', type: 'scatter', //气泡静态效果 coordinateSystem: 'bmap', data: [], symbolSize: function (val1, val2) { return val2.data.size; }, //标记的大小 label: { formatter: '{b}', position: 'right' }, itemStyle: { color: '#ddb926' }, emphasis: { // 高亮的图形和标签样式 label: { show: true } } } ] }; } // 获取网页链接参数 function getQuery(name){ let reg = new RegExp('(^|&)'+ name + "=([^&]*)", "i"); let r = decodeURI(window.location.search.substr(1)).match(reg); if(r!=null) return r[2]; return null; } // 用户显示文字 function formatText(item) { var str = ""; if (item.address) { str = item.address + "
"; } str += item.nickname + "," + formatSex(item.sex) + (item.birthday ? ("," + formatAge(item.birthday)) : ""); return str; } // SOS显示报警文字 function formatSOSText(item) { var str = ""; if (item.address) { str = item.address + "
"; } str += item.named + "," + formatSex(item.sex); if (item.birthday) { str += "," + formatAge(item.birthday); } str += "
"; str += "报警内容:" + item.data + "
"; if (item.relativeMobile) { str += "联系亲属:" + item.relativeMobile + "
"; } if (item.sOSLngLat) { str += "报警位置:" + item.sOSLngLat; } return str; } // 时间转换 function unixToDate(unix, format) { if (!unix) return unix var _format = format || 'yyyy-MM-dd hh:mm:ss' const d = new Date(unix * 1000) const o = { 'M+': d.getMonth() + 1, 'd+': d.getDate(), 'h+': d.getHours(), 'm+': d.getMinutes(), 's+': d.getSeconds(), 'q+': Math.floor((d.getMonth() + 3) / 3), S: d.getMilliseconds() } if (/(y+)/.test(_format)) _format = _format.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length)) for (const k in o) if (new RegExp('(' + k + ')').test(_format)) _format = _format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) return _format } // 性别转换 function formatSex(sex) { return sex === 1 ? '男' : sex === 0 ? '女' : '未知' } // 生日转换 function formatAge(birthday) { const data = formatBirthdayToAge(birthday * 1000) return data.age + data.ageunit } // 将生日转换成年龄 function formatBirthdayToAge(birthday) { const birth = new Date(birthday) const birthYear = birth.getFullYear() // 出生年 const birthMonth = birth.getMonth() + 1 // 出生月 const birthDay = birth.getDate() // 出生日 const nowYear = new Date().getFullYear() // 出生年 const nowMonth = new Date().getMonth() + 1 // 出生月 const nowDay = new Date().getDate() // 出生日 if (nowYear === birthYear) { // 同年 if (nowMonth === birthMonth) { // 同月 return { age: nowDay - birthDay, ageunit: '天' } } else { return { age: nowMonth - birthMonth, ageunit: '月' } } } else { // 计算周岁 const ageDiff = nowYear - birthYear // 年之差 if (ageDiff > 0) { if (nowMonth === birthMonth) { // 同月 const dayDiff = nowDay - birthDay// 日之差 if (dayDiff < 0) { return { age: ageDiff - 1, ageunit: '岁' } } else { return { age: ageDiff, ageunit: '岁' } } } else { const monthDiff = nowMonth - birthMonth // 月之差 if (monthDiff < 0) { return { age: ageDiff - 1, ageunit: '岁' } } else { return { age: ageDiff, ageunit: '岁' } } } } } }