1、时间轴
echart 提供了一种图表,如果x轴是一个时间范围,并且是连续的,如果用传统的数据驱动会很慢,所以用时间轴的方式
function initCurve(_data){ var resultArr=[]; for(var i=0;i<_data.length;i++){ var res=_data[i] resultArr.push({ name:new Date(res.time)+"", value:[res.time,Number(res.value).toFixed(2)] }) } initEc("echart_01",{ title: { text: '历史曲线', x:'center' }, tooltip: {//鼠标放在点上面的时候显示的数据格式2019/03/04 08:30 2455025 trigger: 'axis', formatter: function (params) { params = params[0]; var date = new Date(params.name); return date.getFullYear() +'/' + (date.getMonth() + 1) + '/' +date.getDate()+' '+date.getHours()+":"+date.getSeconds() +' ' + params.value[1]; }, axisPointer: { animation: false } }, xAxis: { type: 'time', splitLine: { show: false } }, yAxis: { type: 'value', name:"kWh", // boundaryGap:[-4000,'110%'], splitLine: { show: false }, max:function(obj){//解决因数据值范围相差太大或是太小曲线显示不美观问题 var ma=obj.max; var mi=obj.min; var val=Math.ceil((ma+(ma-mi)/2)) return val }, min:function(obj){ var ma=obj.max; var mi=obj.min; var val=Math.ceil((mi-(ma-mi)/2)) return mi==0?0:val } }, dataZoom: [ { type: 'slider',//数据滑块 start:0, minSpan:8, //5min // minSpan:16, //10min // minSpan:24, //15min // minSpan:50, //30min dataBackground:{ lineStyle:{ color:'#95BC2F' }, areaStyle:{ color:'#95BC2F', opacity:1, } }, // fillerColor:'rgba(255,255,255,.6)' }, { type:'inside'//使鼠标在图表中时滚轮可用 } ], series: [{ name: '模拟数据', type: 'line', showSymbol: false, hoverAnimation: false, data: resultArr }] }) }
解决因数据值范围相差太大或是太小曲线显示不美观问题
左侧默认显示,右侧是添加了max和min之后显示
算法1、max加上(max-min)/2
算法2、根据min-min的位数,如果是1位加10 n位就加10的n次方
data-zoom 使用(2020年4月24)
举例:
dataZoom: [ { type: 'slider',//数据滑块 start: 0, minSpan: 8, //5min // minSpan:16, //10min // minSpan:24, //15min // minSpan:50, //30min //bottom:-10, height: 10, dataBackground: { lineStyle: { color: '#95BC2F' }, areaStyle: { color: '#95BC2F', opacity: 1, } }, // fillerColor:'rgba(255,255,255,.6)' }, { type: 'inside'//使鼠标在图表中时滚轮可用 } ],
效果如下
但是如果想不需要滑块,但是需要滚轮放大和缩小坐标的功能,可以使用
type: 'inside',
弹出框拖动代码
$("body").on("mousedown",".model-window .model-head",function(event){ var ox=event.offsetX, oy=event.offsetY, ot=$(this).offset().top, ol=$(this).offset().left, pel=$(this).parent(); var flag=0; var osx=ol;//保存计算后的left; var osy=ot;//保存计算后的top; pel.fadeTo(60,0.6); $(document).off('mousemove').on('mousemove',function(e){ var msx=e.pageX,msy=e.pageY; osx=msx-ox;osy=msy-oy; pel.css({left:osx+'px',top:osy+'px',right:'auto',bottom:'auto'}); }); $(document).off('mouseup').on('mouseup',function(event){ $(document).off('mousemove').off('mouseup'); pel.fadeTo('fast',1); }); });
此处需要注意的是
拖动的时候为 弹出框的 head头添加了拖动 mousedown mousemove mouseup的事件,导致div闪电移动,但是在点击的关闭弹框的图标时也会触发拖动事件,所以在点击弹出框的时候应该阻止冒泡
//弹出框关闭的事件 $("#trendCur .clo").on("mousedown",function(){return false}).click(function(){//阻止冒泡 $(this).closest(".def-model").hide(); return false; })
完整代码:
html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 设置 viewport --> <!-- <meta name = "viewport" content ="initial-scale=1.0,maximum-scale=1,user-scalable=no"> --> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"> <!-- iOS 设备 begin --> <meta name="apple-mobile-web-app-title" content="标题"> <!-- IE --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 兼容国产浏览器的高速模式 --> <meta name="renderer" content="webkit"> <title>图形组态浏览</title> <link rel="stylesheet" href="/static/ui/common/plugins/bootstrap/css/bootstrap.min.css" /> <link rel="stylesheet" href="/static/ui/common/plugins/bootstrap-multiselect-master/css/bootstrap-multiselect.css" /> <link href="/static/ui/common/plugins/modals/alertBox/AlertBox.css" rel="stylesheet"> <link href="/static/ui/common/plugins/other/ztree/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css"/> <link href="/static/ui/common/plugins/formElems/newValidator/css/jquery.validator.css" rel="stylesheet" type="text/css"/> <link rel="stylesheet" href="/static/ui/common/plugins/jquery-colorselect/jquery.minicolors.css" /> <link href="/static/ui/common/plugins/formElems/time/bootstrap_datetimepicker/css/bootstrap-datetimepicker.css" rel="stylesheet" type="text/css"> <link rel="stylesheet" href="/static/ui/modules/common/css/style.css"> <link rel="stylesheet" href="/static/ui/modules/common/css/style.css"> <link href="/static/ui/modules/common/css/skin.css" rel="stylesheet"> <link href="/static/ui/skin/Light/modules/maker/css/config.css" rel="stylesheet"> <!-- <link data-skin href="${userSkin}/modules/maker/css/config.css" rel="stylesheet"> --> <link href="/static/ui/modules/maker/css/maker.css" rel="stylesheet"> <script type="text/javascript" src="/static/ui/common/js/libs/require.js" data-main="/static/ui/modules/maker/js/browser" ></script> <script> var path=""; var date=new Date().getTime(); </script> <style> html,body{ width:100%; height:100%; background-color:#000; overflow: auto; } .sign{ cursor:default; } .context{ width:100%; height:100%; overflow: hidden; position: absolute; } /* 弹出层 */ .def-model{ display:none; position:absolute; top:0; left:0; right:0; bottom:0; z-index: 999; } .def-model .model-shadow { width: 100%; height: 100%; background: rgba(0,0,0,.4); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#66000000',endColorstr='#66000000'); } .def-model .model-window{ position:absolute; top:0; left:0; right:0; bottom:0; width:800px; height:400px; margin:auto; background-color:#fff; border-radius: 5px; } /*弹框在手机端显示不友好*/ @media screen and (max-device-830px){ .def-model .model-window{ position:fixed; margin:10px; width:inherit; height:inherit; } } .model-head{ /* border-top:4px solid #ff8500; */ padding:4px 12px; margin:0; border-radius: 5px 5px 0 0; background-color: #0993f2; color: #fff; } .model-content{ height:calc(100% - 28px); padding:0 5px; } .model-head .clo{ float:right; font-size:14px; text-shadow: 0 0 1px #fff; color:#333; font-style: normal; cursor: pointer; } .model-head .clo:hover{ transform: scale(1.1) } .model-content .model-h{ margin:0; height:35px; line-height:35px; color:#333; } .model-content .model-c{ height:calc(100% - 35px); } #echart_01{ width:100%; height:100% } </style> </head> <body unselectable="on" style="-moz-user-select:none;-webkit-user-select:none;" onselectstart="return false;"> <div class="context"></div> <!-- 点击弹出趋势图框 --> <div class="def-model" id="trendCur"> <div class="model-shadow"></div> <div class="model-window"> <p class="model-head"> <span>趋势分析</span> <i class="clo">X</i> </p> <div class="model-content"> <p class="model-h"> <label> <span>开始时间:</span> <input type="text" name="" value="" id="systemtime"> </label> <label> <span>结束时间:</span> <input type="text" name="" value="" id="systemtime_end"> </label> <label for=""> <button type="button" class="but-orange-90 margin-l30" id="search"> <span class="img-search"> </span> <span class="img-text">查询</span> </button> </label> </p> <div class="model-c"> <div id="echart_01" style=""></div> </div> </div> </div> </div> </body> </html>
js
require.config({ baseUrl:'/static/ui/common/', paths:{ 'domReady':'js/functionality/domReady', 'jquery':'js/libs/jquery-1.11.1.min', 'jquery.query':'js/libs/jquery.query', 'bootstrap':'plugins/bootstrap/js/bootstrap.min', 'minicolors':'plugins/jquery-colorselect/jquery.minicolors.min', 'multiselect':'plugins/bootstrap-multiselect-master/js/bootstrap-multiselect', 'ztree.core':'plugins/other/ztree/jquery.ztree.core.min', 'util':'js/functionality/Util', 'ztree.excheck':'plugins/other/ztree/jquery.ztree.excheck', 'alert':'plugins/modals/alertBox/AlertBox', 'nicescroll':'plugins/other/nicescroll/jquery.nicescroll.min', 'echarts':'plugins/chart/echarts.min', 'bootstrap_datetimepicker':'plugins/formElems/time/bootstrap_datetimepicker/js/bootstrap-datetimepicker.min', 'zhCN':'plugins/formElems/time/bootstrap_datetimepicker/js/bootstrap-datetimepicker.zh-CN', 'heatmap':'js/libs/heatmap.min', 'refreshData':'../modules/maker/js/refresh', 'serverAction':'../modules/maker/js/server' }, shim:{ 'minicolors':{ deps:['jquery'] }, 'bootstrap':{ deps:['jquery'] }, 'ztree.core':{ deps:['jquery'] }, 'multiselect':{ deps:['jquery'] }, 'refreshData':{ deps:['jquery'] }, 'serverAction':{ deps:['jquery'] }, 'jquery.query':{ deps:['jquery'] } } }); require(['domReady','jquery','util','echarts','heatmap','bootstrap','bootstrap_datetimepicker','zhCN','ztree.core','minicolors','alert','nicescroll','multiselect','refreshData','serverAction','jquery.query'],function(domReady,$,util,echarts,h337){ /** * 页面初始加载处理 */ domReady(function(){ initTimeFormate("yyyy-mm-dd"); initTimeFormate("yyyy-mm-dd","","","end"); window.ConfigData={ signs:{}, pageConfig:{ style:"100%;height:100%;" } } window.zIndex=0; window.energyData={ } window.historyData={ year:{}, lastYear:{}, month:{}, lastMonth:{}, lastYearMonth:{}, week:{}, lastWeek:{}, day:{}, lastDay:{}, hour:{}, lastHour:{} } window.interval={};//记录定时器 loadPage(); initEvent(); $(".sign").click(function(){ var url=$(this).attr("url"); if(url!=undefined&&url!=""){//有配置跳转 if(url.indexOf("http://")!=0&&url.indexOf("https://")!=0){ url=path+url; } if($(this).attr("openType")=="self"){//当前页面跳转 window.location.href=url; } } }) }) /** * 事件 */ var clickCode="";//点击text时候的code function initEvent(){ //双击文本框的点击事件 //判断是手机端还是会web端 var ua = navigator.userAgent; var ipad = ua.match(/(iPad).*OSs([d_]+)/), isIphone =!ipad && ua.match(/(iPhonesOS)s([d_]+)/), isAndroid = ua.match(/(Android)s+([d.]+)/), isMobile = isIphone || isAndroid; //判断 if(isMobile){ $("body").on("click","[showtype='energyData']",function(){ var str=$(this).attr("addpro"); if(!str){return} obj=eval("("+str+")"); //clickCode=obj[0].code; $('#trendCur').fadeTo(400,1); initTrend(obj); }) }else{ $("body").on("dblclick","[showtype='energyData']",function(){ var str=$(this).attr("addpro"); if(!str){return} obj=eval("("+str+")"); //clickCode=obj[0].code; $('#trendCur').fadeTo(400,1); initTrend(obj); }) } $("#trendCur .clo").on("mousedown",function(){return false}).click(function(){ $(this).closest(".def-model").hide(); return false; }) //趋势点击查询的事件 $("#search").off("click").on('click',function(){ initTrend(clickCode); }) //弹出框的拖动事件(自己写的,没有限制范围) $("body").on("mousedown",".model-window .model-head",function(event){ var ox=event.offsetX,oy=event.offsetY;//鼠标相对于目标元素的左侧和顶部的距离 var pel=$(this).parent(); $(document).off("mousemove").on("mousemove",function(e){ //等于移动后鼠标的位置-点击前鼠标相对于目标元素的距离 pel.css({ left:(e.pageX-ox)+"px", top:(e.pageY-oy)+"px", right:"auto",//这个一定要加上,否则会出现首次点击偏差 bottom:"auto" }) }) $(document).off("mouseup").on("mouseup",function(){ $(document).off('mousemove').off('mouseup'); }) }) //张得版本也ok /*$("body").on("mousedown",".model-window .model-head",function(event){ var ox=event.offsetX, oy=event.offsetY, ot=$(this).offset().top, ol=$(this).offset().left, pel=$(this).parent(); var flag=0; var osx=ol;//保存计算后的left; var osy=ot;//保存计算后的top; pel.fadeTo(60,0.6); $(document).off('mousemove').on('mousemove',function(e){ var msx=e.pageX,msy=e.pageY; osx=msx-ox;osy=msy-oy; pel.css({left:osx+'px',top:osy+'px',right:'auto',bottom:'auto'}); }); $(document).off('mouseup').on('mouseup',function(event){ $(document).off('mousemove').off('mouseup'); pel.fadeTo('fast',1); }); });*/ } /** * 初始化历史曲线的时间 */ function initTimeFormate(format1, format2, view, end) { format1 = !!format1 ? format1 : "yyyy-mm-dd"; format2 = !!format2 ? format2 : "yyyy-MM-dd"; view = !!view ? view : 2; var selector = end ? $("#systemtime_end") : $("#systemtime"); selector.datetimepicker('remove'); selector.datetimepicker({ language:"zh", format: format1, autoclose: true, startView: view, minView: 2 }).on("click", function () { selector.datetimepicker('show'); }).off("changeDate").on("changeDate",function(ev){ var id=$(ev.target).attr("id"); var time=ev.date.Format("yyyy-MM-dd") if(id=="systemtime"){ $("#systemtime_end").datetimepicker("setStartDate",time) }else{ $("#systemtime").datetimepicker("setEndDate",time) } }); if(end){ var _date= new Date().Format(format2); //往前面减十天组成的数组 var sevenDate=getSubSeven(_date,1); selector.val(new Date().Format(format2)); $("#systemtime").val(sevenDate[sevenDate.length-1]); }else{ selector.val(new Date ().Format(format2)); } } /** * 不足10的数前面加0 */ function add0(o){ if(o<10&&String(o).length==1){ return "0"+o; }else{ return o; } } /** * 初始化曲线 */ function initTrend(obj){ clickCode=obj; var dataType=obj.dataKind; var type=""; switch(dataType){ case "YCProperty": type="yc"; break; case "KWHProperty": type="ym"; break; case "YXProperty": type="yx" break; } //模拟的数据 var data = []; var now = +new Date(2019, 1, 13); var oneDay =1000; var value = Math.random() * 1000; for (var i = 0; i < 100; i++) { data.push(randomData()); } function randomData() { now = new Date(+now + oneDay); value = value + Math.random() * 21 - 10; return { name: now.toString(), value: [ [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('-')+"T"+[add0(now.getHours()), add0(now.getMinutes()), add0(now.getSeconds())].join(":")+"Z", Math.round(value) ] } } // var testData=[ // {"time":"2019-02-13T00:03:11Z","time1":"2019-2-13T00:03:11Z","value":"1000.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:04:02Z","time1":"2019-2-13T00:04:02Z","value":"200.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:04:13Z","time1":"2019-2-13T00:04:13Z","value":"2295.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:04Z","time1":"2019-2-13T00:05:04Z","value":"2372.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:13Z","time1":"2019-2-13T00:05:13Z","value":"2372.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:15Z","time1":"2019-2-13T00:05:15Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:33Z","time1":"2019-2-13T00:05:33Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:53Z","time1":"2019-2-13T00:05:53Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:06:06Z","time1":"2019-2-13T00:06:06Z","value":"2173.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:06:17Z","time1":"2019-2-13T00:06:17Z","value":"2225.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"} // ] $.ajax({ url:'/realTimeData/historyDetailSearch', type:"GET", datapro:obj, data:{ valueType: type, startTime: $("#systemtime").val()+" 00:00", endTime: $("#systemtime_end").val()+" 24:00", snames: obj.selectNode, }, dataType:'json', success:function(res){ var rowData=res.data; if(!rowData){return} initCurve(rowData,obj) } }); } function initCurve(_data){ //if(_data.length==0){alert("此时间段无历史数据,请更换时间!")} var resultArr=[]; for(var i=0;i<_data.length;i++){ var res=_data[i] resultArr.push({ name:new Date(res.time)+"", value:[res.time,Number(res.value).toFixed(2)] }) } initEc("echart_01",{ title: { text: !!obj.selectName?obj.selectName:'', x:'center' }, tooltip: { trigger: 'axis', formatter: function (params) { params = params[0]; var date = new Date(params.name); return date.getFullYear() +'/' + (date.getMonth() + 1) + '/' +date.getDate()+' '+date.getHours()+":"+date.getSeconds() +' ' + params.value[1]; }, axisPointer: { animation: false } }, xAxis: { type: 'time', splitLine: { show: false } }, yAxis: { type: 'value', //name:"kWh", // boundaryGap:[-4000,'110%'], splitLine: { show: false }, max:function(obj){ var ma=obj.max; var mi=obj.min; var val=Math.ceil((ma+(ma-mi)/2)) return val }, min:function(obj){ var ma=obj.max; var mi=obj.min; var val=Math.ceil((mi-(ma-mi)/2)); if(val<0){ val=mi>0?0:val; } return mi==0?0:val } }, grid:{ height:'60%'//图表的高度 }, dataZoom: [ { type: 'slider',//数据滑块 start:0, minSpan:8, //5min // minSpan:16, //10min // minSpan:24, //15min // minSpan:50, //30min dataBackground:{ lineStyle:{ color:'#95BC2F' }, areaStyle:{ color:'#95BC2F', opacity:1, } }, // fillerColor:'rgba(255,255,255,.6)' }, { type:'inside'//使鼠标在图表中时滚轮可用 } ], series: [{ name: '模拟数据', type: 'line', showSymbol: false, hoverAnimation: false, data: resultArr }] }) } function initEc(id,op){ var color=['#0093F1','#45BF98','#F28D4E','#C1232B','#B5C334','#FCCE10', '#E87C25','#27727B','#FE8463','#9BCA63','#FAD860','#F3A43B','#60C0DD', '#D7504B','#C6E579','#F4E001','#F0805A','#26C0C0']; //var unit=unitList[$('#'+id).prev('div').find('.bar-type dt.cur').attr('unit')]; var option = { color:color, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, calculable:true, toolbox: { right:'10px', zlevel:600, z:600, feature: { dataView: {show: true, readOnly: false}, magicType: {show: true, type: ['line', 'bar','stack']}, restore: {show: true}, saveAsImage: {show: true} } }, grid:{ left:'70px', right:'70px', bottom:'60px', //x:'10%', //y2:'13%',//距离最下面的边距 }, legend: { data:['bar'], }, calculable:true, noDataLoadingOption:{ //没有数据时, effect: "bubble", text:"暂无数据", effectOption:{ effect:{ n:0 } }, textStyle:{ fontSize:32, fontWeight:'bold' } }, xAxis: [ { type: 'category', data:[], axisPointer: { type: 'shadow' } } ], yAxis: [ { type: 'value', //name:unit, name:"千瓦时", axisLabel: { formatter: '{value}' } } ], series: [{ name:'bar', type:'bar', data:[] }] }; var myChart = echarts.init(document.getElementById(id)); myChart.setOption($.extend({},option,op),true); myChart.resize(); } function loadPage(){ if($.query.get("groupName")==""||$.query.get("fileName")==""){ alert("groupName和fileName参数不能为空"); return; } serverData=$.loadConfig($.query.get("groupName"),$.query.get("fileName")+".js"); $(".context").attr(serverData.pageConfig); if(serverData.pageConfig.sizeType=="window"){//适应窗口大小 window.onresize=function(){ var scaleX=$(window).width()/$(".context").width(); var scaleY=$(window).height()/$(".context").height(); $(".context").css({"transform":"scale("+scaleX+","+scaleY+")","transform-origin":"0 0"}); } window.onresize(); }else{ $("html,body").css("overflow","auto"); } var energyCodes={} $(serverData.signs).each(function(i,d){ var sign=$('<div type="'+d.type+'" id="'+d.type+'_'+new Date().getTime()+'"></div>').appendTo($(".context")); if(d.echarts!=undefined){ d.echarts=echarts; } if(d.h337!=undefined){ d.h337=h337; } sign.createSign(d); if(d.url!=undefined&&d.url!=""){ sign.css("cursor","pointer");//设置有url的图元鼠标为pointer } sign.refresh(); if(d.energycodes!=undefined){ $(JSON.parse(d.energycodes)).each(function(i,e){ energyCodes[e.code]=e.name; }) } }) $(".context .sign").removeAttr("active");//移除选择 var codeStr=""; for(var code in energyCodes){ codeStr+=code+";"; } /*$.loadNewData({codes:codeStr,type:0});//首次获取本页面所关联的所有能耗点的所有类型数据 setInterval(function(){ $.loadNewData({codes:codeStr});//每五秒更新一次实时数据 },5000);*/ $.post('/realTimeData/findWebSocketIpAndPortMS',{},function(data){ var websocketUrl=data.WebSocketIpAndPort; if(websocketUrl==""||websocketUrl==undefined){ console.error("服务器未返回ip"); return; } /**websock*/ /****************使用websoct获取实时数据********************************/ var websocket = null; //判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket(websocketUrl); } else { alert('当前浏览器 Not support websocket') } //连接发生错误的回调方法 websocket.onerror = function () { console.error("WebSocket连接发生错误"); }; //连接成功建立的回调方法 websocket.onopen = function () { socketsend({codes:codeStr,type:0}) console.info("WebSocket连接成功"); } //接收到消息的回调方法 websocket.onmessage = function (event) { if(event.data==""){return} var data=eval("("+event.data+")"); console.info(data); $(data.rows).each(function(){ var tag=this.sname if(window.energyData[tag]==undefined){ window.energyData[tag]={}; } for(var code in this){ window.energyData[tag][code]=this[code]; } //window.energyData[this.code]=this; }) } //连接关闭的回调方法 websocket.onclose = function () { console.info("WebSocket连接关闭"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { closeWebSocket(); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML) { document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //关闭WebSocket连接 function closeWebSocket() { websocket.close(); } //发送消息 function socketsend(obj) { obj.interval=5; var _obj={}; console.log("发消息了!"); _obj.interval=5; //_obj.codes="yc_1;"; //console.log(_obj); websocket.send(JSON.stringify(obj)); } var historyType={}; $("[type='graph']").each(function(){ var graph=$(this); if(graph.attr("energyCodes")!=undefined){ var energyCodes=JSON.parse(graph.attr("energyCodes")); $(energyCodes).each(function(){ window.historyData[graph.attr("dataType")][this.code]=this.name; }) if(graph.attr("isShowLast")=="true"){ var lastCode="last"+graph.attr("dataType").charAt(0).toUpperCase()+graph.attr("dataType").substring(1); window.historyData[lastCode]=window.historyData[graph.attr("dataType")]; } } }) var params={}; for(var type in window.historyData){ params[type]=""; var typedata=window.historyData[type]; for(var code in typedata){ params[type]+=code+";" } } var list=$.loadHistoryData(params); var data=[] while(data.length<60){ data.push(""); } for(var type in list){ window.historyData[type]={}; $(list[type]).each(function(){ if(window.historyData[type][this.code]==undefined){ window.historyData[type][this.code]=$.extend(true, [], data); } window.historyData[type][this.code]=this.data; }) } $("[type='graph']").each(function(){ $(this).refresh(); }) }) } /** * 传入一个日期的天数,往前面减day天,得到数组 */ function getSubSeven(sDate,day){ var arr=[]; var sTime=new Date(sDate).getTime(); var subTime=sTime-(86400000*day) for(var i=sTime;i>subTime;i-=86400000){ arr.push(dateTransform(i)); } return arr; } function dateTransform(time){ var _time=new Date(time); str=_time.getFullYear()+"-"+add0(_time.getMonth()+1)+"-"+add0(_time.getDate()); return str; } }); require.config({ baseUrl:'/static/ui/common/', paths:{ 'domReady':'js/functionality/domReady', 'jquery':'js/libs/jquery-1.11.1.min', 'jquery.query':'js/libs/jquery.query', 'bootstrap':'plugins/bootstrap/js/bootstrap.min', 'minicolors':'plugins/jquery-colorselect/jquery.minicolors.min', 'multiselect':'plugins/bootstrap-multiselect-master/js/bootstrap-multiselect', 'ztree.core':'plugins/other/ztree/jquery.ztree.core.min', 'util':'js/functionality/Util', 'ztree.excheck':'plugins/other/ztree/jquery.ztree.excheck', 'alert':'plugins/modals/alertBox/AlertBox', 'nicescroll':'plugins/other/nicescroll/jquery.nicescroll.min', 'echarts':'plugins/chart/echarts.min', 'bootstrap_datetimepicker':'plugins/formElems/time/bootstrap_datetimepicker/js/bootstrap-datetimepicker.min', 'zhCN':'plugins/formElems/time/bootstrap_datetimepicker/js/bootstrap-datetimepicker.zh-CN', 'heatmap':'js/libs/heatmap.min', 'refreshData':'../modules/maker/js/refresh', 'serverAction':'../modules/maker/js/server' }, shim:{ 'minicolors':{ deps:['jquery'] }, 'bootstrap':{ deps:['jquery'] }, 'ztree.core':{ deps:['jquery'] }, 'multiselect':{ deps:['jquery'] }, 'refreshData':{ deps:['jquery'] }, 'serverAction':{ deps:['jquery'] }, 'jquery.query':{ deps:['jquery'] } } }); require(['domReady','jquery','util','echarts','heatmap','bootstrap','bootstrap_datetimepicker','zhCN','ztree.core','minicolors','alert','nicescroll','multiselect','refreshData','serverAction','jquery.query'],function(domReady,$,util,echarts,h337){ /** * 页面初始加载处理 */ domReady(function(){ initTimeFormate("yyyy-mm-dd"); initTimeFormate("yyyy-mm-dd","","","end"); window.ConfigData={ signs:{}, pageConfig:{ style:"100%;height:100%;" } } window.zIndex=0; window.energyData={ } window.historyData={ year:{}, lastYear:{}, month:{}, lastMonth:{}, lastYearMonth:{}, week:{}, lastWeek:{}, day:{}, lastDay:{}, hour:{}, lastHour:{} } window.interval={};//记录定时器 loadPage(); initEvent(); $(".sign").click(function(){ var url=$(this).attr("url"); if(url!=undefined&&url!=""){//有配置跳转 if(url.indexOf("http://")!=0&&url.indexOf("https://")!=0){ url=path+url; } if($(this).attr("openType")=="self"){//当前页面跳转 window.location.href=url; } } }) }) /** * 事件 */ var clickCode="";//点击text时候的code function initEvent(){ //双击文本框的点击事件 //判断是手机端还是会web端 var ua = navigator.userAgent; var ipad = ua.match(/(iPad).*OSs([d_]+)/), isIphone =!ipad && ua.match(/(iPhonesOS)s([d_]+)/), isAndroid = ua.match(/(Android)s+([d.]+)/), isMobile = isIphone || isAndroid; //判断 if(isMobile){ $("body").on("click","[showtype='energyData']",function(){ var str=$(this).attr("addpro"); if(!str){return} obj=eval("("+str+")"); //clickCode=obj[0].code; $('#trendCur').fadeTo(400,1); initTrend(obj); }) }else{ $("body").on("dblclick","[showtype='energyData']",function(){ var str=$(this).attr("addpro"); if(!str){return} obj=eval("("+str+")"); //clickCode=obj[0].code; $('#trendCur').fadeTo(400,1); initTrend(obj); }) } $("#trendCur .clo").on("mousedown",function(){return false}).click(function(){ $(this).closest(".def-model").hide(); return false; }) //趋势点击查询的事件 $("#search").off("click").on('click',function(){ initTrend(clickCode); }) //弹出框的拖动事件(自己写的,没有限制范围) $("body").on("mousedown",".model-window .model-head",function(event){ var ox=event.offsetX,oy=event.offsetY;//鼠标相对于目标元素的左侧和顶部的距离 var pel=$(this).parent(); $(document).off("mousemove").on("mousemove",function(e){ //等于移动后鼠标的位置-点击前鼠标相对于目标元素的距离 pel.css({ left:(e.pageX-ox)+"px", top:(e.pageY-oy)+"px", right:"auto",//这个一定要加上,否则会出现首次点击偏差 bottom:"auto" }) }) $(document).off("mouseup").on("mouseup",function(){ $(document).off('mousemove').off('mouseup'); }) }) //张得版本也ok /*$("body").on("mousedown",".model-window .model-head",function(event){ var ox=event.offsetX, oy=event.offsetY, ot=$(this).offset().top, ol=$(this).offset().left, pel=$(this).parent(); var flag=0; var osx=ol;//保存计算后的left; var osy=ot;//保存计算后的top; pel.fadeTo(60,0.6); $(document).off('mousemove').on('mousemove',function(e){ var msx=e.pageX,msy=e.pageY; osx=msx-ox;osy=msy-oy; pel.css({left:osx+'px',top:osy+'px',right:'auto',bottom:'auto'}); }); $(document).off('mouseup').on('mouseup',function(event){ $(document).off('mousemove').off('mouseup'); pel.fadeTo('fast',1); }); });*/ } /** * 初始化历史曲线的时间 */ function initTimeFormate(format1, format2, view, end) { format1 = !!format1 ? format1 : "yyyy-mm-dd"; format2 = !!format2 ? format2 : "yyyy-MM-dd"; view = !!view ? view : 2; var selector = end ? $("#systemtime_end") : $("#systemtime"); selector.datetimepicker('remove'); selector.datetimepicker({ language:"zh", format: format1, autoclose: true, startView: view, minView: 2 }).on("click", function () { selector.datetimepicker('show'); }).off("changeDate").on("changeDate",function(ev){ var id=$(ev.target).attr("id"); var time=ev.date.Format("yyyy-MM-dd") if(id=="systemtime"){ $("#systemtime_end").datetimepicker("setStartDate",time) }else{ $("#systemtime").datetimepicker("setEndDate",time) } }); if(end){ var _date= new Date().Format(format2); //往前面减十天组成的数组 var sevenDate=getSubSeven(_date,1); selector.val(new Date().Format(format2)); $("#systemtime").val(sevenDate[sevenDate.length-1]); }else{ selector.val(new Date ().Format(format2)); } } /** * 不足10的数前面加0 */ function add0(o){ if(o<10&&String(o).length==1){ return "0"+o; }else{ return o; } } /** * 初始化曲线 */ function initTrend(obj){ clickCode=obj; var dataType=obj.dataKind; var type=""; switch(dataType){ case "YCProperty": type="yc"; break; case "KWHProperty": type="ym"; break; case "YXProperty": type="yx" break; } //模拟的数据 var data = []; var now = +new Date(2019, 1, 13); var oneDay =1000; var value = Math.random() * 1000; for (var i = 0; i < 100; i++) { data.push(randomData()); } function randomData() { now = new Date(+now + oneDay); value = value + Math.random() * 21 - 10; return { name: now.toString(), value: [ [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('-')+"T"+[add0(now.getHours()), add0(now.getMinutes()), add0(now.getSeconds())].join(":")+"Z", Math.round(value) ] } } // var testData=[ // {"time":"2019-02-13T00:03:11Z","time1":"2019-2-13T00:03:11Z","value":"1000.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:04:02Z","time1":"2019-2-13T00:04:02Z","value":"200.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:04:13Z","time1":"2019-2-13T00:04:13Z","value":"2295.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:04Z","time1":"2019-2-13T00:05:04Z","value":"2372.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:13Z","time1":"2019-2-13T00:05:13Z","value":"2372.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:15Z","time1":"2019-2-13T00:05:15Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:33Z","time1":"2019-2-13T00:05:33Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:05:53Z","time1":"2019-2-13T00:05:53Z","value":"2181.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:06:06Z","time1":"2019-2-13T00:06:06Z","value":"2173.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"}, // {"time":"2019-02-13T00:06:17Z","time1":"2019-2-13T00:06:17Z","value":"2225.2391000000002","status":"1.0","sname":"KJ_GKDZ_P","score":"192.0"} // ] $.ajax({ url:'/realTimeData/historyDetailSearch', type:"GET", datapro:obj, data:{ valueType: type, startTime: $("#systemtime").val()+" 00:00", endTime: $("#systemtime_end").val()+" 24:00", snames: obj.selectNode, }, dataType:'json', success:function(res){ var rowData=res.data; if(!rowData){return} initCurve(rowData,obj) } }); } function initCurve(_data){ //if(_data.length==0){alert("此时间段无历史数据,请更换时间!")} var resultArr=[]; for(var i=0;i<_data.length;i++){ var res=_data[i] resultArr.push({ name:new Date(res.time)+"", value:[res.time,Number(res.value).toFixed(2)] }) } initEc("echart_01",{ title: { text: !!obj.selectName?obj.selectName:'', x:'center' }, tooltip: { trigger: 'axis', formatter: function (params) { params = params[0]; var date = new Date(params.name); return date.getFullYear() +'/' + (date.getMonth() + 1) + '/' +date.getDate()+' '+date.getHours()+":"+date.getSeconds() +' ' + params.value[1]; }, axisPointer: { animation: false } }, xAxis: { type: 'time', splitLine: { show: false } }, yAxis: { type: 'value', //name:"kWh", // boundaryGap:[-4000,'110%'], splitLine: { show: false }, max:function(obj){ var ma=obj.max; var mi=obj.min; var val=Math.ceil((ma+(ma-mi)/2)) return val }, min:function(obj){ var ma=obj.max; var mi=obj.min; var val=Math.ceil((mi-(ma-mi)/2)); if(val<0){ val=mi>0?0:val; } return mi==0?0:val } }, grid:{ height:'60%'//图表的高度 }, dataZoom: [ { type: 'slider',//数据滑块 start:0, minSpan:8, //5min // minSpan:16, //10min // minSpan:24, //15min // minSpan:50, //30min dataBackground:{ lineStyle:{ color:'#95BC2F' }, areaStyle:{ color:'#95BC2F', opacity:1, } }, // fillerColor:'rgba(255,255,255,.6)' }, { type:'inside'//使鼠标在图表中时滚轮可用 } ], series: [{ name: '模拟数据', type: 'line', showSymbol: false, hoverAnimation: false, data: resultArr }] }) } function initEc(id,op){ var color=['#0093F1','#45BF98','#F28D4E','#C1232B','#B5C334','#FCCE10', '#E87C25','#27727B','#FE8463','#9BCA63','#FAD860','#F3A43B','#60C0DD', '#D7504B','#C6E579','#F4E001','#F0805A','#26C0C0']; //var unit=unitList[$('#'+id).prev('div').find('.bar-type dt.cur').attr('unit')]; var option = { color:color, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, calculable:true, toolbox: { right:'10px', zlevel:600, z:600, feature: { dataView: {show: true, readOnly: false}, magicType: {show: true, type: ['line', 'bar','stack']}, restore: {show: true}, saveAsImage: {show: true} } }, grid:{ left:'70px', right:'70px', bottom:'60px', //x:'10%', //y2:'13%',//距离最下面的边距 }, legend: { data:['bar'], }, calculable:true, noDataLoadingOption:{ //没有数据时, effect: "bubble", text:"暂无数据", effectOption:{ effect:{ n:0 } }, textStyle:{ fontSize:32, fontWeight:'bold' } }, xAxis: [ { type: 'category', data:[], axisPointer: { type: 'shadow' } } ], yAxis: [ { type: 'value', //name:unit, name:"千瓦时", axisLabel: { formatter: '{value}' } } ], series: [{ name:'bar', type:'bar', data:[] }] }; var myChart = echarts.init(document.getElementById(id)); myChart.setOption($.extend({},option,op),true); myChart.resize(); } function loadPage(){ if($.query.get("groupName")==""||$.query.get("fileName")==""){ alert("groupName和fileName参数不能为空"); return; } serverData=$.loadConfig($.query.get("groupName"),$.query.get("fileName")+".js"); $(".context").attr(serverData.pageConfig); if(serverData.pageConfig.sizeType=="window"){//适应窗口大小 window.onresize=function(){ var scaleX=$(window).width()/$(".context").width(); var scaleY=$(window).height()/$(".context").height(); $(".context").css({"transform":"scale("+scaleX+","+scaleY+")","transform-origin":"0 0"}); } window.onresize(); }else{ $("html,body").css("overflow","auto"); } var energyCodes={} $(serverData.signs).each(function(i,d){ var sign=$('<div type="'+d.type+'" id="'+d.type+'_'+new Date().getTime()+'"></div>').appendTo($(".context")); if(d.echarts!=undefined){ d.echarts=echarts; } if(d.h337!=undefined){ d.h337=h337; } sign.createSign(d); if(d.url!=undefined&&d.url!=""){ sign.css("cursor","pointer");//设置有url的图元鼠标为pointer } sign.refresh(); if(d.energycodes!=undefined){ $(JSON.parse(d.energycodes)).each(function(i,e){ energyCodes[e.code]=e.name; }) } }) $(".context .sign").removeAttr("active");//移除选择 var codeStr=""; for(var code in energyCodes){ codeStr+=code+";"; } /*$.loadNewData({codes:codeStr,type:0});//首次获取本页面所关联的所有能耗点的所有类型数据 setInterval(function(){ $.loadNewData({codes:codeStr});//每五秒更新一次实时数据 },5000);*/ $.post('/realTimeData/findWebSocketIpAndPortMS',{},function(data){ var websocketUrl=data.WebSocketIpAndPort; if(websocketUrl==""||websocketUrl==undefined){ console.error("服务器未返回ip"); return; } /**websock*/ /****************使用websoct获取实时数据********************************/ var websocket = null; //判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket(websocketUrl); } else { alert('当前浏览器 Not support websocket') } //连接发生错误的回调方法 websocket.onerror = function () { console.error("WebSocket连接发生错误"); }; //连接成功建立的回调方法 websocket.onopen = function () { socketsend({codes:codeStr,type:0}) console.info("WebSocket连接成功"); } //接收到消息的回调方法 websocket.onmessage = function (event) { if(event.data==""){return} var data=eval("("+event.data+")"); console.info(data); $(data.rows).each(function(){ var tag=this.sname if(window.energyData[tag]==undefined){ window.energyData[tag]={}; } for(var code in this){ window.energyData[tag][code]=this[code]; } //window.energyData[this.code]=this; }) } //连接关闭的回调方法 websocket.onclose = function () { console.info("WebSocket连接关闭"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { closeWebSocket(); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML) { document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //关闭WebSocket连接 function closeWebSocket() { websocket.close(); } //发送消息 function socketsend(obj) { obj.interval=5; var _obj={}; console.log("发消息了!"); _obj.interval=5; //_obj.codes="yc_1;"; //console.log(_obj); websocket.send(JSON.stringify(obj)); } var historyType={}; $("[type='graph']").each(function(){ var graph=$(this); if(graph.attr("energyCodes")!=undefined){ var energyCodes=JSON.parse(graph.attr("energyCodes")); $(energyCodes).each(function(){ window.historyData[graph.attr("dataType")][this.code]=this.name; }) if(graph.attr("isShowLast")=="true"){ var lastCode="last"+graph.attr("dataType").charAt(0).toUpperCase()+graph.attr("dataType").substring(1); window.historyData[lastCode]=window.historyData[graph.attr("dataType")]; } } }) var params={}; for(var type in window.historyData){ params[type]=""; var typedata=window.historyData[type]; for(var code in typedata){ params[type]+=code+";" } } var list=$.loadHistoryData(params); var data=[] while(data.length<60){ data.push(""); } for(var type in list){ window.historyData[type]={}; $(list[type]).each(function(){ if(window.historyData[type][this.code]==undefined){ window.historyData[type][this.code]=$.extend(true, [], data); } window.historyData[type][this.code]=this.data; }) } $("[type='graph']").each(function(){ $(this).refresh(); }) }) } /** * 传入一个日期的天数,往前面减day天,得到数组 */ function getSubSeven(sDate,day){ var arr=[]; var sTime=new Date(sDate).getTime(); var subTime=sTime-(86400000*day) for(var i=sTime;i>subTime;i-=86400000){ arr.push(dateTransform(i)); } return arr; } function dateTransform(time){ var _time=new Date(time); str=_time.getFullYear()+"-"+add0(_time.getMonth()+1)+"-"+add0(_time.getDate()); return str; } });
延生:以上是时间轴曲线只有一条,如果有多条,该如何显示?
办法:如果有多条,那么就跟以前的曲线一样,添加series,添加legend即可,但是会有一个问题,默认鼠标放上去的时候只能显示一个线的值,需要修改toptips
修改如下:
tooltip: { trigger: 'axis', formatter: function (params) { console.log(params); var str=""; for(var i=0;i<params.length;i++){ var _params = params[i]; var date = new Date(_params.name); str+=_params.seriesName+' '+date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' : ' + _params.value[1]+"<br>"; } console.log(str); return str }, axisPointer: { animation: false } },
如果y轴的数据最大值和最小值相差太大 会导致图表显示不好看,如下图(2020年3月29)
解决办法:
可以尝试使用将y轴原本是value的改成如下的
type: 'log',