GeneratorData2.html 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  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/Delete',
  821. data: JSON.stringify({
  822. sns: getSelectedSn(),
  823. data: [new Date(copyPosition).getTime(), new Date(copyPosition).getTime() + Math.abs(new Date(timeRange[0]).getTime() - new Date(timeRange[1]).getTime())]
  824. }),
  825. contentType: 'application/json;charset=utf-8',
  826. processData: false,
  827. success: function (rlt) {
  828. $.ajax({
  829. type: "POST",
  830. url: "/Data/CopyFromPosition",
  831. data: JSON.stringify({
  832. copyPosition: copyPosition,
  833. sns: getSelectedSn(),
  834. data: timeRange
  835. }),
  836. processData: false,
  837. contentType: "application/json;charset=utf-8",
  838. success: function (rlt) {
  839. layui.layer.close(index2)
  840. if (rlt.Code === 200) {
  841. layui.layer.close(index)
  842. }
  843. layui.layer.msg(rlt.Msg, {icon: 1})
  844. }
  845. })
  846. }
  847. })
  848. }
  849. })
  850. }
  851. //补漏数据
  852. function repair() {
  853. if (timeRange.length === 0) {
  854. layui.layer.msg('请在图中选择要操作数据的区域!')
  855. return
  856. }
  857. let index2 = loading();
  858. layui.layer.confirm(`确认对${dateFormat(new Date(timeRange[0]))}~${dateFormat(new Date(timeRange[1]))} 时间的数据进行查询补漏吗?`, function (index) {
  859. layui.layer.load();
  860. $.ajax({
  861. type: "POST",
  862. url: '/Data/RepairSensorData',
  863. data: {
  864. sns: JSON.stringify(getSelectedSn()),
  865. data: JSON.stringify(timeRange)
  866. },
  867. success: function (rlt) {
  868. if (rlt.Code === 200) {
  869. layui.layer.closeAll('loading');
  870. loadEcharts()
  871. }
  872. layui.layer.msg(rlt.Msg)
  873. },
  874. error: function(xhr, status, error) {
  875. layui.layer.close(index2)
  876. layui.layer.msg('数据补漏请求出错!');
  877. }
  878. });
  879. },function(index) {
  880. layui.layer.close(index2); // 用户点击取消时,关闭加载提示
  881. layui.layer.close(index); //
  882. });
  883. //3.需要补漏,则将数据处理后生成中间缺失的数据发送到服务
  884. //4.提示结果,成功刷新
  885. }
  886. //选区内做平滑
  887. function smooth() {
  888. if (timeRange.length === 0) {
  889. layui.layer.msg('请在图中选择要操作数据的区域!')
  890. return
  891. }
  892. //2.获取选区内的最开始第一条数据和最后一条数据,中间存在多少条数据,
  893. if (timeRange.length === 0) {
  894. layui.layer.msg('请在图中选择要操作数据的区域!')
  895. return
  896. }
  897. layui.layer.open({
  898. type: 1,
  899. area: ['300px', '240px'],
  900. content: $('#smoothBox'),
  901. btn: '提交',
  902. btnAlign: 'c',
  903. yes: function (index, elem) {
  904. let index2 = loading();
  905. $.ajax({
  906. type: "POST",
  907. url: "/Data/DataSensorDataSmooth",
  908. data: {
  909. sns: JSON.stringify(getSelectedSn()),
  910. data: JSON.stringify(timeRange),
  911. tRange: Number.parseFloat($('#temperatureRange').val()),
  912. hRange: Number.parseFloat($('#humidityRange').val()),
  913. },
  914. success: function (rlt) {
  915. layui.layer.close(index2)
  916. if (rlt.Code === 200) {
  917. layui.layer.close(index)
  918. loadEcharts()
  919. }
  920. layui.layer.msg(rlt.Msg)
  921. }
  922. })
  923. }
  924. })
  925. //count = (time_end -time_start) / time_threshold
  926. //(temperature_end - temperature_start) / count
  927. //3.生成数据发送,判断是否发送成功数据
  928. }
  929. //趋势
  930. function trend() {
  931. if (timeRange.length === 0) {
  932. layui.layer.msg('请在图中选择要操作数据的区域!')
  933. return
  934. }
  935. layui.layer.confirm("1.确保数据没有存在遗漏!\n2.确定对选区做数据趋势吗?", function (index) {
  936. let index2 = loading();
  937. $.ajax({
  938. type: "POST",
  939. url: "/Data/DataSensorDataTrend",
  940. data: {
  941. sns: JSON.stringify(getSelectedSn()),
  942. data: JSON.stringify(timeRange),
  943. },
  944. success: function (rlt) {
  945. layui.layer.close(index2)
  946. if (rlt.Code === 200) {
  947. layui.layer.close(index)
  948. loadEcharts()
  949. }
  950. layui.layer.msg(rlt.Msg)
  951. }
  952. })
  953. })
  954. }
  955. //导入excel
  956. function importExcel() {
  957. let sns = getSelectedSn();
  958. if (sns.length === 0) {
  959. //没有选择设备
  960. layui.layer.msg("没有选择设备,请选择设备后再执行导入!")
  961. return
  962. }
  963. $('#excelInput').change(function () {
  964. let f = this.files[0]
  965. let suffix = f.name.split(".")[1];
  966. if (suffix !== 'xlsx' && suffix !== 'xls') {
  967. layui.layer.msg("上传文件必须为 excel 类型的文件")
  968. this.files[0] = null
  969. return
  970. }
  971. $('#fileName').text(f.name)
  972. })
  973. //1.弹出需要导入的页面
  974. layui.layer.open({
  975. type: 1,
  976. title: '导入数据',
  977. areas: ['400px', '300px'],
  978. content: $('#importDataBox'),
  979. btn: '提交',
  980. btnAlign: 'c',
  981. yes: function (index, elem) {
  982. let data = new FormData()
  983. let file = $('#excelInput')[0].files[0];
  984. console.log(file.name)
  985. data.set("file", file)
  986. data.set("sn", sns.join("|"))
  987. let index2 = loading();
  988. $.ajax({
  989. type: "POST",
  990. url: "/Data/ImportSensorData",
  991. data: data,
  992. contentType: false,
  993. processData: false,
  994. success: function (rlt) {
  995. layui.layer.close(index2)
  996. if (rlt.Code === 200) {
  997. layui.layer.close(index)
  998. }
  999. layui.layer.msg(rlt.Msg)
  1000. }
  1001. })
  1002. }
  1003. })
  1004. //判断是否有存在文件,文件后缀是否正确
  1005. //如果正确则上传到服务器处理
  1006. //2.提示处理结果
  1007. }
  1008. function dateFormat(date) {
  1009. date.setHours(date.getHours() + 8);
  1010. let year = date.getUTCFullYear();
  1011. let month = date.getUTCMonth()+1;
  1012. month = month < 10 ? `0${month}` : month
  1013. let day = date.getUTCDate()
  1014. day = day < 10 ? `0${day}` : day
  1015. let hour = date.getUTCHours()
  1016. hour = hour < 10 ? `0${hour}` : hour
  1017. let minute = date.getUTCMinutes()
  1018. minute = minute < 10 ? `0${minute}` : minute
  1019. let second = date.getUTCSeconds()
  1020. second = second < 10 ? `0${second}` : second
  1021. return `${year}-${month}-${day} ${hour}:${minute}:${second}`
  1022. }
  1023. function loading() {
  1024. return layui.layer.load("Loading...", {
  1025. icon: 16,
  1026. shade: 0.2
  1027. })
  1028. }
  1029. </script>
  1030. </body>
  1031. </html>