GeneratorData2.html 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. <!DOCTYPE html>
  2. <html class="x-admin-sm">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="renderer" content="webkit">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <meta name="viewport"
  8. content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
  9. <link rel="shortcut icon" href="/static/favicon.ico">
  10. <link rel="bookmark" href="/static/favicon.ico">
  11. <link rel="stylesheet" href="/static/css/font.css">
  12. <link rel="stylesheet" href="/static/css/xadmin.css">
  13. <script src="/static/js/jquery.min.js"></script>
  14. <script src="/static/js/jquery.cookie.min.js"></script>
  15. <script src="/static/lib/layui/layui.js" charset="utf-8"></script>
  16. <script type="text/javascript" src="/static/js/xadmin.js"></script>
  17. <script src="/static/js/echarts.min.js"></script>
  18. </head>
  19. <body>
  20. <div class="x-nav">
  21. <span class="layui-breadcrumb">
  22. <a href="">首页</a>
  23. <a><cite>数据展示</cite></a>
  24. </span>
  25. <a class="layui-btn layui-btn-normal" style="line-height:1.6em;margin-top:3px;float:right"
  26. onclick="location.reload()" title="刷新">
  27. <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
  28. </a>
  29. </div>
  30. <div class="layui-fluid">
  31. <div class="layui-row" style="display: flex;">
  32. <!-- 传感器 选择 start-->
  33. <div style="width: 340px;">
  34. <div class="layui-card">
  35. <div class="layui-card-body ">
  36. <form class="layui-form layui-col-space5" οnsubmit="return false;">
  37. <div class="layui-input-inline layui-show-xs-block">
  38. <input value="" type="text" id="D_T_sn" name="D_T_sn" placeholder="请输入 SN"
  39. autocomplete="off"
  40. class="layui-input"></div>
  41. <div class="layui-input-inline layui-show-xs-block">
  42. <input value="" type="text" id="D_Name" name="D_Name" placeholder="请输入 传感器名称"
  43. autocomplete="off"
  44. class="layui-input"></div>
  45. <div class="layui-input-inline layui-show-xs-block" style="width: 168px">
  46. <select id="Class_1" name="Class_1">
  47. <option value=0>所有分类</option>
  48. {{range $index, $elem := .Class_List}}
  49. <option value={{$elem.Id}}>{{$elem.T_name}}</option>
  50. {{end}}
  51. </select>
  52. </div>
  53. <div class="layui-input-inline layui-show-xs-block">
  54. <div class="layui-btn layui-btn-normal"
  55. onclick="get_DeviceSensor_list(0)">
  56. <i class="layui-icon">&#xe615;</i></div>
  57. </div>
  58. </form>
  59. <hr>
  60. </div>
  61. <div class="layui-card-body " style="margin-top: -20px">
  62. <!-- <div class="layui-progress " >-->
  63. <!-- <div id="progress" class="layui-progress-bar layui-bg-blue" lay-percent="80%"></div>-->
  64. <!-- </div>-->
  65. <div id="DeviceSensor_list" style="width: 98%; overflow: hidden;max-height: 616px;overflow-y: auto">
  66. <div style="color: #1E9FFF;text-align: center;font-size: 15px;margin-top: 150px">加载中...</div>
  67. </div>
  68. </div>
  69. <div class="layui-card-body ">
  70. <div style="height: 70px">
  71. <div class="layui-card-body " style="text-align: center">
  72. <div class="layui-input-inline layui-show-xs-block">
  73. <div class="layui-btn layui-btn-normal"
  74. onclick="checkAll()">
  75. <i class="layui-icon">全选择</i>
  76. </div>
  77. </div>
  78. <div class="layui-input-inline layui-show-xs-block">
  79. <div class="layui-btn layui-btn-normal"
  80. onclick="checkCancel()">
  81. <i class="layui-icon">全取消</i>
  82. </div>
  83. </div>
  84. <div class="layui-input-inline layui-show-xs-block">
  85. <div class="layui-btn layui-btn-normal"
  86. onclick="checkReverse()">
  87. <i class="layui-icon">反选</i>
  88. </div>
  89. </div>
  90. <div style="color: #1E9FFF;text-align: center" id="DeviceSensor_list_Pages_x"></div>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. <!-- 传感器 选择 end-->
  97. <div style="padding-left: 15px; height: 100%;flex:1;">
  98. <div class="layui-card">
  99. <div class="layui-card-body">
  100. <div class="layui-inline">
  101. <div class="layui-input-inline">数据时间:</div>
  102. <div class="layui-input-inline">
  103. <input type="text" class="layui-input" id="startTime" placeholder="开始时间">
  104. </div>
  105. <span style="padding: 5px">~</span>
  106. <div class="layui-input-inline">
  107. <input type="text" class="layui-input" id="endTime" placeholder="结束时间">
  108. </div>
  109. <div class="layui-input-inline">
  110. <a class="layui-btn layui-btn-normal" onclick="loadEcharts()" title="刷新">
  111. <!-- <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>-->
  112. 加载
  113. </a>
  114. </div>
  115. </div>
  116. <div class="layui-inline " style="padding-left: 15px">
  117. <div class="layui-inline">选择时间:</div>
  118. <div class="layui-input-inline">
  119. <input type="text" class="layui-input" id="selectStartTime" placeholder="开始时间">
  120. </div>
  121. <span style="padding: 5px">~</span>
  122. <div class="layui-input-inline">
  123. <input type="text" class="layui-input " id="selectEndTime" placeholder="结束时间">
  124. </div>
  125. </div>
  126. </div>
  127. <div class="layui-inline">
  128. <!--按钮-->
  129. <div class="layui-clear" style="margin-left: 15px">
  130. <button onclick="offset()" class="layui-btn layui-btn-normal layui-btn-sm">偏移(固定)</button>
  131. <button onclick="offsetRandom()" class="layui-btn layui-btn-normal layui-btn-sm">偏移(随机)
  132. <button onclick="ProportionalScaling()" class="layui-btn layui-btn-normal layui-btn-sm">等比缩放
  133. </button>
  134. <!-- <button onclick="copyFrom()" class="layui-btn layui-btn-normal layui-btn-sm">复制到</button>-->
  135. <button onclick="repair()" class="layui-btn layui-btn-normal layui-btn-sm">补漏</button>
  136. <button onclick="smooth()" class="layui-btn layui-btn-normal layui-btn-sm">平滑</button>
  137. <!-- <button onclick="trend()" class="layui-btn layui-btn-normal layui-btn-sm">趋势</button>-->
  138. <button onclick="Delete()" class="layui-btn layui-btn-normal layui-btn-sm">删除</button>
  139. <!-- <button onclick="importExcel()" class="layui-btn layui-btn-normal">导入表格</button>-->
  140. </div>
  141. </div>
  142. <hr>
  143. <div class="layui-card-body" id="echartsBox" style="height: 100%">
  144. </div>
  145. </div>
  146. </div>
  147. </div>
  148. </div>
  149. <!--固定偏移-->
  150. <div style="display: none;padding: 20px" id="offsetFix">
  151. <div class="layui-form">
  152. <div class="layui-form-item">
  153. 温度:
  154. <input type="number" class="layui-input" lay-verify="number" placeholder="固定下调温度" id="fixTemperature"
  155. value="0">
  156. </div>
  157. <div class="layui-form-item">
  158. 湿度:
  159. <input type="number" class="layui-input" lay-verify="number" placeholder="固定下调湿度" id="fixHumidity"
  160. value="0">
  161. </div>
  162. </div>
  163. </div>
  164. <div style="display: none;padding: 20px" id="ProportionalScaling">
  165. <div class="layui-form">
  166. <div class="layui-form-item">
  167. 温度:
  168. <input type="number" class="layui-input" lay-verify="number" placeholder="固定下调温度" id="Temperature"
  169. value="0">
  170. </div>
  171. <div class="layui-form-item">
  172. 湿度:
  173. <input type="number" class="layui-input" lay-verify="number" placeholder="固定下调湿度" id="Humidity"
  174. value="0">
  175. </div>
  176. </div>
  177. </div>
  178. <!--随机偏移-->
  179. <div style="display: none;padding: 20px;justify-content: center" id="offsetRand">
  180. <div class="layui-form">
  181. <div class="layui-form-item " style="display: flex;align-items: center">
  182. 温度:
  183. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  184. placeholder="温度min"
  185. id="temperatureStart">
  186. <span style="padding-right: 10px">~</span>
  187. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  188. placeholder="温度max"
  189. id="temperatureEnd">
  190. </div>
  191. <div class="layui-form-item" style="display: flex;align-items: center">
  192. 湿度:
  193. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  194. placeholder="湿度min"
  195. id="humidityStart">
  196. <span style="padding-right: 10px">~</span>
  197. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  198. placeholder="湿度max"
  199. id="humidityEnd">
  200. </div>
  201. </div>
  202. </div>
  203. <!--复制移动-->
  204. <div id="copyMove" style="display: none;padding: 20px">
  205. <div class="layui-form" style="display: flex;justify-content: center;flex-direction: column">
  206. <div id="copyInfo">
  207. 您选择的了从 2023-01-01 00:00:00 ~ 2023-01-02 23:59:59 共 100条记录
  208. </div>
  209. <div>
  210. <input class="layui-input" type="text" id="copyPosition" placeholder="拷贝到的开始时间">
  211. </div>
  212. </div>
  213. </div>
  214. <!--数据补漏-->
  215. <div id="dataRepair" style="padding: 20px;display: none">
  216. 发现了缺少100条数据,确认需要补充数据吗?
  217. </div>
  218. <!--数据补漏-->
  219. <div id="Delete" style="padding: 20px;display: none">
  220. 确认删除数据吗?
  221. </div>
  222. <div style="display: none;padding: 20px;justify-content: center" id="smoothBox">
  223. <div class="layui-form">
  224. <div class="layui-form-item " style="display: flex;align-items: center">
  225. 温度浮动范围:
  226. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  227. placeholder="温度浮动范围"
  228. id="temperatureRange">
  229. </div>
  230. <div class="layui-form-item" style="display: flex;align-items: center">
  231. 湿度浮动范围:
  232. <input type="number" value="0" class="layui-input layui-input-inline" lay-verify="number"
  233. placeholder="湿度浮动范围" id="humidityRange">
  234. </div>
  235. </div>
  236. </div>
  237. <!--数据导入-->
  238. <div id="importDataBox" style="display: none;padding: 20px;width: 300px">
  239. <div class="layui-form">
  240. <button onclick="document.getElementById('excelInput').click()" class="layui-btn layui-btn-danger">
  241. 选择文件
  242. </button>
  243. <span id="fileName"></span>
  244. <input type="file" id="excelInput" style="display: none" class="layui-input" placeholder="选择上传文件!">
  245. </div>
  246. </div>
  247. <script>
  248. //温度数据
  249. let temperatureData = []
  250. //湿度数据
  251. let humidityData = []
  252. //当页面加载完毕后会执行的函数
  253. $(function () {
  254. //初始化页面元素
  255. layui.use(['laydate', 'form', 'element'], function () {
  256. let laydate = layui.laydate
  257. laydate.render({
  258. elem: '#startTime',
  259. type: 'datetime',
  260. value: new Date(new Date().setUTCDate(new Date().getDate() - 1))
  261. })
  262. laydate.render({
  263. elem: '#endTime',
  264. type: 'datetime',
  265. value: new Date()
  266. })
  267. laydate.render({
  268. elem: '#selectStartTime',
  269. type: 'datetime',
  270. done: function(value){
  271. onTimeRangeChange(value, selectEndTime.value);
  272. }
  273. })
  274. laydate.render({
  275. elem: '#selectEndTime',
  276. type: 'datetime',
  277. done: function(value){
  278. onTimeRangeChange(selectStartTime.value, value);
  279. }
  280. })
  281. laydate.render({
  282. elem: '#copyPosition',
  283. type: 'datetime',
  284. })
  285. })
  286. //添加图
  287. // addCharts()
  288. //获取设备探头列表
  289. get_DeviceSensor_list(0)
  290. })
  291. //获取设备探头列表
  292. function get_DeviceSensor_list(page) {
  293. T_sn = $("#D_T_sn").val();
  294. T_name = $("#D_Name").val();
  295. T_class_id = $("#Class_1").val();
  296. $.ajax({
  297. type: 'POST',
  298. url: '/Data/Device_Sensor_List',//发送请求
  299. data: {
  300. User_tokey: $.cookie("User_tokey"),
  301. T_sn: T_sn,
  302. T_name: T_name,
  303. T_class_id: parseInt(T_class_id),
  304. page: page,
  305. page_z: 1000,
  306. },
  307. success: function (result) {
  308. console.log(result)
  309. if (result.Code == 200) {
  310. if (page == 0)
  311. $('#DeviceSensor_list').html("")
  312. // $('#DeviceSensor_list_Pages').html("")
  313. // $('#DeviceSensor_list_Pages_x').html("")
  314. DeviceSensor_lite = result.Data.DeviceSensor_lite
  315. if (DeviceSensor_lite.length == 0) {
  316. $('#DeviceSensor_list').html("<div style=\"color: #1E9FFF;text-align: center;font-size: 15px;margin-top: 150px\">没有设备</div>")
  317. return
  318. }
  319. Add_DeviceSensor_list(result.Data.DeviceSensor_lite) // 列表
  320. // Add_DeviceSensor_list_Pages(result.Data.Pages) // 分页
  321. $('#DeviceSensor_list_Pages_x').html(" 传感器 总数:" + result.Data.Num);
  322. if (result.Data.Page_size > result.Data.Page) {
  323. get_DeviceSensor_list(result.Data.Page + 1)
  324. }
  325. } else {
  326. }
  327. }
  328. });
  329. return false
  330. }
  331. var T_name = ""
  332. var T_sn = ""
  333. var T_class_id = 0
  334. var T_id = 0
  335. var T_sn_T_id = ""
  336. var Time_start = ""
  337. var Time_end = ""
  338. //添加设备探头数据
  339. function Add_DeviceSensor_list(DS_lite) {
  340. for (let i = 0; i < DS_lite.length; i++) {
  341. if (T_id == 0) {
  342. T_id = DS_lite[i].T_id;
  343. T_sn_T_id = DS_lite[i].T_sn;
  344. }
  345. $('#DeviceSensor_list').append(`
  346. <div style="display: flex; user-select: none;align-items: center;" class="layui-row">
  347. <input type="checkbox" data-sn="${DS_lite[i].T_sn}" data-id="${DS_lite[i].T_id}" style="width: 18px;height: 18px">
  348. <img src="/static/images/温湿度传感器-1.png" height="50" width="50" alt="">
  349. <div style="display: flex;flex-direction: column;margin-left: 10px">
  350. <div>${DS_lite[i].T_name}</div>
  351. <div>${DS_lite[i].T_sn}</div>
  352. </div>
  353. </div>
  354. `)
  355. }
  356. }
  357. //修改选择状态
  358. function changeCheckStatus(event) {
  359. let check = $(event).find("> input[type='checkbox']");
  360. check.prop('checked', !check.prop('checked'))
  361. }
  362. //全选
  363. function checkAll() {
  364. $('#DeviceSensor_list > div > input[type="checkbox"]').each((index, item) => {
  365. $(item).prop('checked', true)
  366. })
  367. }
  368. //反选
  369. function checkReverse() {
  370. $('#DeviceSensor_list > div > input[type="checkbox"]').each((index, item) => {
  371. $(item).prop('checked', !$(item).prop('checked'))
  372. })
  373. }
  374. //取消全选
  375. function checkCancel() {
  376. $('#DeviceSensor_list > div > input[type="checkbox"]').each((index, item) => {
  377. $(item).prop('checked', false)
  378. })
  379. }
  380. //获取选择的sn
  381. function getSelectedSn() {
  382. let sns = []
  383. $('#DeviceSensor_list > div > input[type="checkbox"]').each((index, item) => {
  384. let dom = $(item)
  385. if (dom.prop('checked')) {
  386. let sn = dom.attr('data-sn')
  387. let id = dom.attr('data-id')
  388. sns.push([sn, id])
  389. }
  390. })
  391. return sns
  392. }
  393. let chartsData = new Map()
  394. //加载图
  395. function loadEcharts() {
  396. //1.获取选中的设备
  397. let sns = getSelectedSn()
  398. //1.1是否选有设备选中
  399. if (sns.length === 0) {
  400. layui.layer.msg('没有选中操作设备!')
  401. return
  402. }
  403. let startTime = $('#startTime').val()
  404. let endTime = $('#endTime').val()
  405. //2.请求对应设备数据
  406. let index = loading();
  407. $.ajax({
  408. type: "POST",
  409. url: "/Data/DeviceSensorData",
  410. data: {
  411. sns: JSON.stringify(sns),
  412. startTime: startTime,
  413. endTime: endTime,
  414. },
  415. success: function (rlt) {
  416. layui.layer.close(index)
  417. if (rlt.Code === 200) {
  418. //2.1清空图
  419. $('#echartsBox').html('');
  420. //2.2添加图
  421. /*
  422. for (let v of rlt.Data) {
  423. chartsData.set(v.sn.join('|'), v)
  424. addCharts(v)
  425. // console.log(v)
  426. }
  427. */
  428. handleEchartData(rlt.Data)
  429. }
  430. layui.layer.msg(rlt.Msg)
  431. }
  432. })
  433. }
  434. //处理图的数据
  435. let temperatureChar = null
  436. let humidityChar = null
  437. function handleEchartData(data) {
  438. //1.将图中数据分开
  439. let temperatureList = []
  440. let humidityList = []
  441. for (let v of data) {
  442. let t = []
  443. let h = []
  444. if (v.data == null) continue
  445. for (let val of v.data) {
  446. t.push([val.t_time, val.t_t])
  447. h.push([val.t_time, val.t_rh])
  448. }
  449. temperatureList.push([v.sn.join(' | '), t])
  450. humidityList.push([v.sn.join(' | '), h])
  451. chartsData.set(v.sn.join(' | '), v)
  452. }
  453. temperatureChar = addCharts(temperatureList, '温度t_t', 'temperature', true)
  454. humidityChar = addCharts(humidityList, '湿度t_rh', 'humidity', false)
  455. }
  456. var myChar;
  457. //添加图
  458. function addCharts(data, name, type, show) {
  459. //没有数据
  460. if (data == null || data.length === 0) {
  461. return null
  462. }
  463. //获取容器
  464. let eChartsBox = $('#echartsBox')[0]
  465. //设置要放置图的框架
  466. let eChar = $(`<div class="layui-row" style="width: 100%;height: 500px"></div>`)[0]
  467. eChartsBox.appendChild(eChar)
  468. //初始化
  469. myChar = echarts.init(eChar)
  470. // myChart=myChar
  471. //图标配置选项
  472. let options = {
  473. title: {
  474. text: name
  475. },
  476. grid: {
  477. left: '10%',
  478. right: '10%',
  479. // containLabel: true,
  480. // width: '100%',
  481. // x: '35px',
  482. // y: '40px'
  483. },
  484. xAxis: {
  485. type: 'time',
  486. splitLine: {
  487. show: false
  488. }
  489. },
  490. yAxis: {
  491. type: 'value',
  492. splitLine: {
  493. show: false
  494. },
  495. },
  496. toolbox: {
  497. feature: {
  498. restore: {},
  499. }
  500. },
  501. dataZoom: [
  502. {
  503. type: 'inside',
  504. start: 0,
  505. end: 100
  506. },
  507. {
  508. start: 0,
  509. end: 100
  510. }
  511. ],
  512. tooltip: {
  513. trigger: 'axis',
  514. formatter: function (params) {
  515. let v = params[0]
  516. return `${v.seriesName}\n
  517. 时间:${v.data[0]} 数据:${v.data[1]}`
  518. },
  519. // position: function (pt) {
  520. // return [pt[0], '10%'];
  521. // }
  522. },
  523. brush: {
  524. xAxisIndex: 0,
  525. toolbox: ['lineX', 'keep', 'clear'],
  526. brushMode: 'multiple',
  527. throttleType: 'debounce',
  528. throttleDelay: 600
  529. },
  530. series: []
  531. }
  532. for (let v of data) {
  533. console.log(v)
  534. options.series.push({
  535. name: v[0],
  536. data: v[1],
  537. type: 'line',
  538. })
  539. }
  540. if (!show) {
  541. options.dataZoom[1]["show"] = false
  542. options.toolbox = null
  543. options.brush = null
  544. }
  545. console.log(options)
  546. //设置参数
  547. myChar.setOption(options)
  548. //设置选中后的函数
  549. myChar.on('brushSelected', brushSelected)
  550. myChar.on('dataZoom', brushDataZoom)
  551. return myChar
  552. }
  553. function brushDataZoom(param) {
  554. console.log(param)
  555. let option = humidityChar.getOption();
  556. if (param.start !== undefined) {
  557. option.dataZoom[0].start = param.start
  558. option.dataZoom[0].end = param.end
  559. } else {
  560. option.dataZoom[0].start = param.batch[0].start
  561. option.dataZoom[0].end = param.batch[0].end
  562. }
  563. humidityChar.setOption(option)
  564. }
  565. //图获取选中数据
  566. let timeRange = []
  567. function brushSelected(param) {
  568. if (!param.batch || !param.batch[0] || !param.batch[0].areas || !param.batch[0].areas[0]) {
  569. return; // 如果参数不完整,直接返回避免错误
  570. }
  571. let coordRange = param.batch[0].areas[0].coordRange;
  572. timeRange = [Math.floor(coordRange[0]), Math.floor(coordRange[1])];
  573. $("#selectStartTime").val(dateFormat(new Date(timeRange[0])));
  574. $("#selectEndTime").val(dateFormat(new Date(timeRange[1])));
  575. }
  576. function onTimeRangeChange(startTimeStr, endTimeStr) {
  577. var startTime = new Date(startTimeStr).getTime();
  578. var endTime = new Date(endTimeStr).getTime();
  579. console.log("============")
  580. console.log(startTime, endTime)
  581. if (startTime > endTime) {
  582. alert("开始时间不能大于结束时间");
  583. return;
  584. }
  585. // 清除现有的画刷区域(如果存在)
  586. myChar.dispatchAction({
  587. type: 'brush',
  588. areas: [] // 清空画刷区域
  589. });
  590. console.log("前:",myChar.getOption())
  591. // 设置新的画刷区域
  592. myChar.dispatchAction({
  593. type: 'brush',
  594. areas: [{
  595. brushType: 'lineX',
  596. range: [startTime, endTime]
  597. }]
  598. });
  599. console.log("后:",myChar.getOption())
  600. }
  601. //温湿度偏移
  602. function offset() {
  603. if (timeRange.length === 0) {
  604. layui.layer.msg('请在图中选择要操作数据的区域!')
  605. return
  606. }
  607. //2.layer 打开一个窗口设置要统一设置下移的数据
  608. layui.layer.open({
  609. type: 1,
  610. area: ['300px', '270px'],
  611. content: $('#offsetFix'),
  612. btn: '确定',
  613. btnAlign: 'c',
  614. yes: function (index, elem) {
  615. let fixTemperature = $('#fixTemperature').val();
  616. let fixHumidity = $('#fixHumidity').val();
  617. if (fixHumidity === "" || fixTemperature === "") {
  618. //提示消息
  619. layui.layer.msg("没有设置固定温湿度偏移")
  620. return
  621. }
  622. //3.发送修改数据区域进行循环对值进行统一下调
  623. let index2 = loading();
  624. $.ajax({
  625. type: 'POST',
  626. url: '/Data/UpdateFix',
  627. data: JSON.stringify({
  628. fixTemperature: fixTemperature,
  629. fixHumidity: fixHumidity,
  630. sns: getSelectedSn(),
  631. data: timeRange
  632. }),
  633. contentType: 'application/json;charset=utf-8',
  634. processData: false,
  635. success: function (rlt) {
  636. layui.layer.close(index2)
  637. if (rlt.Code === 200) {
  638. //3.1判断是否处理成功
  639. //3.1.1成功更新该设备的数据
  640. timeRange = []
  641. loadEcharts()
  642. layui.layer.close(index)
  643. }
  644. //提示消息
  645. layui.layer.msg(rlt.Msg)
  646. }
  647. })
  648. }
  649. })
  650. }
  651. //等比缩放
  652. function ProportionalScaling() {
  653. if (timeRange.length === 0) {
  654. layui.layer.msg('请在图中选择要操作数据的区域!')
  655. return
  656. }
  657. //2.layer 打开一个窗口设置要统一设置下移的数据
  658. layui.layer.open({
  659. type: 1,
  660. area: ['300px', '270px'],
  661. content: $('#ProportionalScaling'),
  662. btn: '确定',
  663. btnAlign: 'c',
  664. yes: function (index, elem) {
  665. let Temperature = $('#Temperature').val();
  666. let Humidity = $('#Humidity').val();
  667. if (Humidity === "" || Temperature === "") {
  668. //提示消息
  669. layui.layer.msg("没有设置固定温湿度偏移")
  670. return
  671. }
  672. //3.发送修改数据区域进行循环对值进行统一下调
  673. let index2 = loading();
  674. $.ajax({
  675. type: 'POST',
  676. url: '/Data/ProportionalScaling',
  677. data: JSON.stringify({
  678. fixTemperature: Temperature,
  679. fixHumidity: Humidity,
  680. sns: getSelectedSn(),
  681. data: timeRange
  682. }),
  683. contentType: 'application/json;charset=utf-8',
  684. processData: false,
  685. success: function (rlt) {
  686. layui.layer.close(index2)
  687. if (rlt.Code === 200) {
  688. //3.1判断是否处理成功
  689. //3.1.1成功更新该设备的数据
  690. timeRange = []
  691. loadEcharts()
  692. layui.layer.close(index)
  693. }
  694. //提示消息
  695. layui.layer.msg(rlt.Msg)
  696. }
  697. })
  698. }
  699. })
  700. }
  701. //删除
  702. function Delete() {
  703. if (timeRange.length === 0) {
  704. layui.layer.msg('请在图中选择要操作数据的区域!')
  705. return
  706. }
  707. //2.layer 打开一个窗口设置要统一设置下移的数据
  708. layui.layer.open({
  709. type: 1,
  710. area: ['300px', '270px'],
  711. content: $('#Delete'),
  712. btn: '确定',
  713. btnAlign: 'c',
  714. yes: function (index, elem) {
  715. //3.发送修改数据区域进行循环对值进行统一下调
  716. let index2 = loading();
  717. $.ajax({
  718. type: 'POST',
  719. url: '/Data/Delete',
  720. data: JSON.stringify({
  721. sns: getSelectedSn(),
  722. data: timeRange
  723. }),
  724. contentType: 'application/json;charset=utf-8',
  725. processData: false,
  726. success: function (rlt) {
  727. layui.layer.close(index2)
  728. if (rlt.Code === 200) {
  729. //3.1判断是否处理成功
  730. //3.1.1成功更新该设备的数据
  731. timeRange = []
  732. loadEcharts()
  733. layui.layer.close(index)
  734. }
  735. //提示消息
  736. layui.layer.msg(rlt.Msg)
  737. }
  738. })
  739. }
  740. })
  741. }
  742. //温湿度随机偏移
  743. function offsetRandom() {
  744. if (timeRange.length === 0) {
  745. layui.layer.msg('请在图中选择要操作数据的区域!')
  746. return
  747. }
  748. layui.layer.open({
  749. type: 1,
  750. area: ['520px', '240px'],
  751. content: $('#offsetRand'),
  752. btn: '确定',
  753. btnAlign: 'c',
  754. yes: function (index, elem) {
  755. let t_s = Number.parseFloat($('#temperatureStart').val()) * 100
  756. let t_e = Number.parseFloat($('#temperatureEnd').val()) * 100
  757. let h_s = Number.parseFloat($('#humidityStart').val()) * 100
  758. let h_e = Number.parseFloat($('#humidityEnd').val()) * 100
  759. if (!t_s && !t_e && !h_s && !h_e) {
  760. layui.layer.msg('随机值设置错误!因该从最小到最大!')
  761. return
  762. }
  763. let index2 = loading();
  764. $.ajax({
  765. type: 'POST',
  766. url: '/Data/UpdateRand',
  767. data: JSON.stringify({
  768. temperatureMax: Math.max(Math.floor(t_e), Math.floor(t_s)),
  769. temperatureMin: Math.min(Math.floor(t_e), Math.floor(t_s)),
  770. humidityMax: Math.max(Math.floor(h_e), Math.floor(h_s)),
  771. humidityMin: Math.min(Math.floor(h_e), Math.floor(h_s)),
  772. sns: getSelectedSn(),
  773. data: timeRange
  774. }),
  775. contentType: "application/json;charset=utf-8",
  776. processData: false,
  777. success: function (rlt) {
  778. layui.layer.close(index2)
  779. if (rlt.Code === 200) {
  780. //操作成功
  781. layui.layer.close(index)
  782. rangeData = []
  783. loadEcharts()
  784. }
  785. layui.layer.msg(rlt.Msg)
  786. }
  787. })
  788. }
  789. })
  790. //2.layer 打开一个窗口设置随机值范围,温湿度
  791. //3.发送修改数据区域进行循环对值进行随机值统一下调(layer点击确定之后)
  792. //3.1判断是否处理成功
  793. //3.1.1成功更新该设备的数据
  794. //3.1.2失败提示
  795. }
  796. //复制时间段内的数据到另一个时间段
  797. function copyFrom() {
  798. if (timeRange.length === 0) {
  799. layui.layer.msg('请在图中选择要操作数据的区域!')
  800. return
  801. }
  802. //2.layer 提示选区的内容条目数,选区内的开始时间和结束时间(可以进行修改)(layer点击确定之后),要复制到的区域时间
  803. $('#copyInfo').html(`<p style="color: red">${dateFormat(new Date(timeRange[0]))} ~ ${dateFormat(new Date(timeRange[1]))}</p>`)
  804. layui.layer.open({
  805. type: 1,
  806. title: '数据复制(指定开始时间)',
  807. areas: ['300px', '200px'],
  808. content: $('#copyMove'),
  809. btn: '确定',
  810. btnAlign: 'c',
  811. yes: function (index, elem) {
  812. let copyPosition = $('#copyPosition').val();
  813. if (copyPosition === '') {
  814. layui.layer.msg('复制到时间节点不能为空!', {icon: 6})
  815. return
  816. }
  817. let index2 = loading();
  818. $.ajax({
  819. type: "POST",
  820. url: "/Data/CopyFromPosition",
  821. data: JSON.stringify({
  822. copyPosition: copyPosition,
  823. sns: getSelectedSn(),
  824. data: timeRange
  825. }),
  826. processData: false,
  827. contentType: "application/json;charset=utf-8",
  828. success: function (rlt) {
  829. layui.layer.close(index2)
  830. if (rlt.Code === 200) {
  831. layui.layer.close(index)
  832. }
  833. layui.layer.msg(rlt.Msg, {icon: 1})
  834. }
  835. })
  836. }
  837. })
  838. }
  839. //补漏数据
  840. function repair() {
  841. if (timeRange.length === 0) {
  842. layui.layer.msg('请在图中选择要操作数据的区域!')
  843. return
  844. }
  845. let index2 = loading();
  846. layui.layer.confirm(`确认对${dateFormat(new Date(timeRange[0]))}~${dateFormat(new Date(timeRange[1]))} 时间的数据进行查询补漏吗?`, function (index) {
  847. layui.layer.load();
  848. $.ajax({
  849. type: "POST",
  850. url: '/Data/RepairSensorData',
  851. data: {
  852. sns: JSON.stringify(getSelectedSn()),
  853. data: JSON.stringify(timeRange)
  854. },
  855. success: function (rlt) {
  856. if (rlt.Code === 200) {
  857. layui.layer.closeAll('loading');
  858. loadEcharts()
  859. }
  860. layui.layer.msg(rlt.Msg)
  861. },
  862. error: function(xhr, status, error) {
  863. layui.layer.close(index2)
  864. layui.layer.msg('数据补漏请求出错!');
  865. }
  866. });
  867. },function(index) {
  868. layui.layer.close(index2); // 用户点击取消时,关闭加载提示
  869. layui.layer.close(index); //
  870. });
  871. //3.需要补漏,则将数据处理后生成中间缺失的数据发送到服务
  872. //4.提示结果,成功刷新
  873. }
  874. //选区内做平滑
  875. function smooth() {
  876. if (timeRange.length === 0) {
  877. layui.layer.msg('请在图中选择要操作数据的区域!')
  878. return
  879. }
  880. //2.获取选区内的最开始第一条数据和最后一条数据,中间存在多少条数据,
  881. if (timeRange.length === 0) {
  882. layui.layer.msg('请在图中选择要操作数据的区域!')
  883. return
  884. }
  885. layui.layer.open({
  886. type: 1,
  887. area: ['300px', '240px'],
  888. content: $('#smoothBox'),
  889. btn: '提交',
  890. btnAlign: 'c',
  891. yes: function (index, elem) {
  892. let index2 = loading();
  893. $.ajax({
  894. type: "POST",
  895. url: "/Data/DataSensorDataSmooth",
  896. data: {
  897. sns: JSON.stringify(getSelectedSn()),
  898. data: JSON.stringify(timeRange),
  899. tRange: Number.parseFloat($('#temperatureRange').val()),
  900. hRange: Number.parseFloat($('#humidityRange').val()),
  901. },
  902. success: function (rlt) {
  903. layui.layer.close(index2)
  904. if (rlt.Code === 200) {
  905. layui.layer.close(index)
  906. loadEcharts()
  907. }
  908. layui.layer.msg(rlt.Msg)
  909. }
  910. })
  911. }
  912. })
  913. //count = (time_end -time_start) / time_threshold
  914. //(temperature_end - temperature_start) / count
  915. //3.生成数据发送,判断是否发送成功数据
  916. }
  917. //趋势
  918. function trend() {
  919. if (timeRange.length === 0) {
  920. layui.layer.msg('请在图中选择要操作数据的区域!')
  921. return
  922. }
  923. layui.layer.confirm("1.确保数据没有存在遗漏!\n2.确定对选区做数据趋势吗?", function (index) {
  924. let index2 = loading();
  925. $.ajax({
  926. type: "POST",
  927. url: "/Data/DataSensorDataTrend",
  928. data: {
  929. sns: JSON.stringify(getSelectedSn()),
  930. data: JSON.stringify(timeRange),
  931. },
  932. success: function (rlt) {
  933. layui.layer.close(index2)
  934. if (rlt.Code === 200) {
  935. layui.layer.close(index)
  936. loadEcharts()
  937. }
  938. layui.layer.msg(rlt.Msg)
  939. }
  940. })
  941. })
  942. }
  943. //导入excel
  944. function importExcel() {
  945. let sns = getSelectedSn();
  946. if (sns.length === 0) {
  947. //没有选择设备
  948. layui.layer.msg("没有选择设备,请选择设备后再执行导入!")
  949. return
  950. }
  951. $('#excelInput').change(function () {
  952. let f = this.files[0]
  953. let suffix = f.name.split(".")[1];
  954. if (suffix !== 'xlsx' && suffix !== 'xls') {
  955. layui.layer.msg("上传文件必须为 excel 类型的文件")
  956. this.files[0] = null
  957. return
  958. }
  959. $('#fileName').text(f.name)
  960. })
  961. //1.弹出需要导入的页面
  962. layui.layer.open({
  963. type: 1,
  964. title: '导入数据',
  965. areas: ['400px', '300px'],
  966. content: $('#importDataBox'),
  967. btn: '提交',
  968. btnAlign: 'c',
  969. yes: function (index, elem) {
  970. let data = new FormData()
  971. let file = $('#excelInput')[0].files[0];
  972. console.log(file.name)
  973. data.set("file", file)
  974. data.set("sn", sns.join("|"))
  975. let index2 = loading();
  976. $.ajax({
  977. type: "POST",
  978. url: "/Data/ImportSensorData",
  979. data: data,
  980. contentType: false,
  981. processData: false,
  982. success: function (rlt) {
  983. layui.layer.close(index2)
  984. if (rlt.Code === 200) {
  985. layui.layer.close(index)
  986. }
  987. layui.layer.msg(rlt.Msg)
  988. }
  989. })
  990. }
  991. })
  992. //判断是否有存在文件,文件后缀是否正确
  993. //如果正确则上传到服务器处理
  994. //2.提示处理结果
  995. }
  996. function dateFormat(date) {
  997. date.setHours(date.getHours() + 8);
  998. let year = date.getUTCFullYear();
  999. let month = date.getUTCMonth()+1;
  1000. month = month < 10 ? `0${month}` : month
  1001. let day = date.getUTCDate()
  1002. day = day < 10 ? `0${day}` : day
  1003. let hour = date.getUTCHours()
  1004. hour = hour < 10 ? `0${hour}` : hour
  1005. let minute = date.getUTCMinutes()
  1006. minute = minute < 10 ? `0${minute}` : minute
  1007. let second = date.getUTCSeconds()
  1008. second = second < 10 ? `0${second}` : second
  1009. return `${year}-${month}-${day} ${hour}:${minute}:${second}`
  1010. }
  1011. function loading() {
  1012. return layui.layer.load("Loading...", {
  1013. icon: 16,
  1014. shade: 0.2
  1015. })
  1016. }
  1017. </script>
  1018. </body>
  1019. </html>