statistics.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. <template>
  2. <view>
  3. <view class="status_bar"></view>
  4. <view class="" style="position: relative;top: 44px;">
  5. <view style="position: fixed;z-index: 100;">
  6. <uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="害虫统计"></uni-nav-bar>
  7. </view>
  8. <view class="statistics">
  9. <view class="top_text">
  10. <view :class="topindex==index?'title_text_color':'tltle_text'" v-for="(item,index) in toptext" :key="index" @click="changeindex(index)">
  11. {{item}}
  12. </view>
  13. </view>
  14. <view class="shuju_one">
  15. <p class="shuju_one_title">害虫趋势统计</p>
  16. <view class="shuju_one_btn">
  17. <view class="schedule_box">
  18. <view class="schedule" @click="pickertfone=!pickertfone">
  19. <p class="schedule_value">{{titletext[indexone]}}</p>
  20. <p class="schedule_icon">
  21. <u-icon name="arrow-down"></u-icon>
  22. </p>
  23. </view>
  24. <u-picker v-model="pickertfone" mode="selector" @confirm="confirmFun" :default-selector="[indexone]" :range="titletext"></u-picker>
  25. <view class="schedule" @click="pickertftwo=!pickertftwo" v-if="tishitf">
  26. <p class="schedule_value">{{wormdata[indextwo]}}</p>
  27. <p class="schedule_icon">
  28. <u-icon name="arrow-down"></u-icon>
  29. </p>
  30. <u-picker v-model="pickertftwo" mode="selector" @confirm="confirmFun2" :default-selector="[indextwo]" :range="wormdata"></u-picker>
  31. </view>
  32. </view>
  33. </view>
  34. <view class="canvastishi" v-if="!canvastishiTF">
  35. 暂无数据
  36. </view>
  37. <canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
  38. @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
  39. </view>
  40. <view class="shuju_two">
  41. <p class="shuju_one_title">害虫比例</p>
  42. <view class="canvastishi" v-if="!canvastishiTF">
  43. 暂无数据
  44. </view>
  45. <canvas v-if="canvastishiTF" canvas-id="canvasRing" id="canvasRing" class="charts" @touchstart="touchRing" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
  46. </view>
  47. <view class="shuju_table" v-if="tableval.length">
  48. <table class="table">
  49. <tr class="tr">
  50. <th>害虫名称</th>
  51. <th>害虫数量</th>
  52. <th>害虫比例</th>
  53. </tr>
  54. <tr class="tr" v-for="(item,index) in tableval" :key="index">
  55. <td class="td">{{item.name}}</td>
  56. <td class="td">{{item.data}}</td>
  57. <td class="td">{{(item.prop*100).toFixed(2)+"%"}}</td>
  58. </tr>
  59. </table>
  60. </view>
  61. </view>
  62. </view>
  63. </view>
  64. </template>
  65. <style lang="scss">
  66. .top_text {
  67. width: 90%;
  68. position: absolute;
  69. top: 54px;
  70. display: flex;
  71. left: 5%;
  72. .tltle_text {
  73. width: 50%;
  74. border: 2rpx solid #F0F0F0;
  75. text-align: center;
  76. }
  77. .title_text_color {
  78. width: 50%;
  79. border: 2rpx solid #64CC82;
  80. text-align: center;
  81. }
  82. }
  83. .tishi {
  84. position: absolute;
  85. top: 250rpx;
  86. left: 40%;
  87. font-size: 32rpx;
  88. color: #7A7373;
  89. }
  90. .shuju_one_title {
  91. font-size: 32rpx;
  92. font-weight: 700;
  93. width: 100%;
  94. text-align: center;
  95. margin-bottom: 20rpx;
  96. }
  97. .shuju_one_btn {
  98. width: 90%;
  99. margin: 0 auto;
  100. display: flex;
  101. justify-content: space-between;
  102. .schedule_box {
  103. display: flex;
  104. }
  105. .schedule {
  106. display: flex;
  107. width: 280rpx;
  108. height: 50rpx;
  109. border: 2rpx solid #F0F0F0;
  110. margin-left: 20rpx;
  111. .schedule_value {
  112. width: 70%;
  113. text-align: center;
  114. line-height: 50rpx;
  115. font-size: 24rpx;
  116. }
  117. .schedule_icon {
  118. width: 30%;
  119. background-color: #F2F2F2;
  120. text-align: center;
  121. line-height: 50rpx;
  122. }
  123. }
  124. }
  125. </style>
  126. <script>
  127. import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
  128. var canvaColumnA = null;
  129. var canvasRing = null;
  130. var newtime = +new Date()
  131. var strrttime = newtime - 24 * 60 * 60 * 1000
  132. export default {
  133. data() {
  134. return {
  135. cWidth: '400',
  136. cHeight: '400',
  137. pixelRatio: 1,
  138. canvastishiTF: false,
  139. d_id: '',
  140. start_time: strrttime,
  141. end_time: newtime,
  142. titletext: ["24小时", "近一个月", "近半年", "近一年"],
  143. device_id: '',
  144. pest_name: '',
  145. wormdata: [],
  146. pickertfone: false,
  147. pickertftwo: false,
  148. indexone: 0,
  149. indextwo: 0,
  150. tishitf: false,
  151. tishi: false,
  152. toptext: ["自动统计", "手动统计"],
  153. topindex: 0,
  154. tableval:[]
  155. }
  156. },
  157. methods: {
  158. async historys() { //获取统计虫子 自动统计 初始化统计 没有传入害虫名称
  159. const res = await this.$myRequest({
  160. url: '/api/api_gateway?method=forecast.worm_lamp.pest_statistics',
  161. data: {
  162. d_id: this.d_id,
  163. start_time: parseInt(this.start_time / 1000),
  164. end_time: parseInt(this.end_time / 1000),
  165. }
  166. })
  167. this.historydatas = res
  168. console.log(this.historydatas)
  169. if (this.historydatas.date.length == 0) {
  170. this.canvastishiTF = false
  171. this.tishitf = false
  172. } else {
  173. this.canvastishiTF = true
  174. this.tishitf = true
  175. this.wormdata = []
  176. for (var i = 0; i < res.percentage.length; i++) {
  177. this.wormdata.unshift(res.percentage[i].name_num)
  178. }
  179. var arr1 = []
  180. var arr2 = []
  181. var arr3 = []
  182. var xtitle = []
  183. var ringarr = []
  184. for (var i = 0; i < res.date.length; i++) {
  185. var times = new Date(res.date[i].addtime * 1000)
  186. xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
  187. arr1.unshift(res.date[i].temperature == "" ? "0" : res.date[i].temperature)
  188. arr2.unshift(res.date[i].humidity == "" ? "0" : res.date[i].humidity)
  189. arr3.unshift(res.date[i]._sums == "" ? "0" : res.date[i]._sums)
  190. }
  191. var maxnumarr = []
  192. for(var i = 0; i < res.percentage.length; i++){
  193. var obj = {}
  194. obj.name = res.percentage[i].name_num
  195. obj.data = Number(res.percentage[i].num)
  196. maxnumarr.unshift(obj)
  197. }
  198. var temp;
  199. for(var i=0;i<maxnumarr.length-1;i++){
  200. for(var j=0;j<maxnumarr.length-1;j++){
  201. if(maxnumarr[j].data<maxnumarr[j+1].data){
  202. temp=maxnumarr[j];
  203. maxnumarr[j]=maxnumarr[j+1];
  204. maxnumarr[j+1]=temp;
  205. }
  206. }
  207. }
  208. if(maxnumarr.length<20){
  209. ringarr = maxnumarr
  210. }else{
  211. ringarr = maxnumarr.splice(0,20)
  212. this.tableval = maxnumarr.splice(20)
  213. }
  214. var tablevalsum = 0
  215. for(var i = 0; i < maxnumarr.length; i++){
  216. tablevalsum += maxnumarr[i].data
  217. }
  218. for(var i = 0; i < this.tableval.length; i++){
  219. this.tableval[i].prop = this.tableval[i].data/tablevalsum
  220. }
  221. console.log(this.tableval)
  222. console.log(maxnumarr)
  223. var obj = [{
  224. name: '温度',
  225. data: arr1,
  226. color: '#00E29D'
  227. }, {
  228. name: '湿度',
  229. data: arr2,
  230. color: '#6CBBFF'
  231. }, {
  232. name: '害虫总数',
  233. data: arr3,
  234. color: '#FF3F3F'
  235. }]
  236. this.showColumn("canvasColumnA", xtitle, obj)
  237. this.showRing(ringarr)
  238. }
  239. },
  240. async history() { //获取统计虫子 //自动统计 传入害虫名称统计 在historys之后
  241. const res = await this.$myRequest({
  242. url: '/api/api_gateway?method=forecast.worm_lamp.pest_statistics',
  243. data: {
  244. pest_name: this.pest_name,
  245. d_id: this.d_id,
  246. start_time: parseInt(this.start_time / 1000),
  247. end_time: parseInt(this.end_time / 1000)
  248. }
  249. })
  250. this.historydatas = res
  251. console.log(this.historydatas)
  252. if (this.historydatas.date.length == 0) {
  253. this.canvastishiTF = false
  254. this.tishitf = false
  255. } else {
  256. this.canvastishiTF = true
  257. this.tishitf = true
  258. var arr1 = []
  259. var arr2 = []
  260. var arr3 = []
  261. var xtitle = []
  262. for (var i = 0; i < res.date.length; i++) {
  263. var times = new Date(res.date[i].addtime * 1000)
  264. xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
  265. arr1.unshift(res.date[i].temperature == "" ? "0" : res.date[i].temperature)
  266. arr2.unshift(res.date[i].humidity == "" ? "0" : res.date[i].humidity)
  267. arr3.unshift(res.date[i]._sums == "" ? "0" : res.date[i]._sums)
  268. }
  269. var obj = [{
  270. name: '温度',
  271. data: arr1,
  272. color: '#00E29D'
  273. }, {
  274. name: '湿度',
  275. data: arr2,
  276. color: '#6CBBFF'
  277. }, {
  278. name: '害虫总数',
  279. data: arr3,
  280. color: '#FF3F3F'
  281. }]
  282. this.showColumn("canvasColumnA", xtitle, obj)
  283. }
  284. },
  285. // forecast.worm_lamp.pest_manual_statistics手动统计
  286. async selfhistorys() { //获取统计虫子 手动统计 初始化统计 不传入害虫名称
  287. const res = await this.$myRequest({
  288. url: '/api/api_gateway?method=forecast.worm_lamp.pest_manual_statistics',
  289. data: {
  290. device_id: this.d_id,
  291. start_time: parseInt(this.start_time / 1000),
  292. end_time: parseInt(this.end_time / 1000)
  293. }
  294. })
  295. console.log(res)
  296. if (res.date.length == 0) {
  297. this.tishitf = false
  298. this.canvastishiTF = false
  299. } else {
  300. this.tishitf = true
  301. this.canvastishiTF = true
  302. this.wormdata = []
  303. for (var i = 0; i < res.date.length; i++) {
  304. this.wormdata.unshift(res.date[i].pest_name)
  305. }
  306. var arr1 = []
  307. var xtitle = []
  308. var ringarr = []
  309. for (var i = 0; i < res.date.length; i++) {
  310. var times = new Date(res.date[i].add_time * 1000)
  311. xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
  312. arr1.unshift(res.date[i].pest_num == "" ? "0" : res.date[i].pest_num)
  313. var obj ={}
  314. obj.name = res.date[i].pest_name
  315. obj.data = Number(res.date[i].pest_num)
  316. ringarr.unshift(obj)
  317. }
  318. var obj = [{
  319. name: '害虫总数',
  320. data: arr1,
  321. color: '#00E29D'
  322. }]
  323. this.showColumn("canvasColumnA", xtitle, obj)
  324. this.showRing(ringarr)
  325. }
  326. },
  327. async selfhistory() { //获取统计虫子 //手动统计 传入害虫名称
  328. const res = await this.$myRequest({
  329. url: '/api/api_gateway?method=forecast.worm_lamp.pest_manual_statistics',
  330. data: {
  331. pest_name: this.pest_name,
  332. device_id: this.d_id,
  333. start_time: parseInt(this.start_time / 1000),
  334. end_time: parseInt(this.end_time / 1000)
  335. }
  336. })
  337. this.historydatas = res
  338. console.log(this.historydatas)
  339. if (res.date.length == 0) {
  340. this.tishitf = false
  341. this.canvastishiTF = false
  342. } else {
  343. this.tishitf = true
  344. this.canvastishiTF = true
  345. var arr1 = []
  346. var xtitle = []
  347. for (var i = 0; i < res.pests.pest_list.length; i++) {
  348. var times = new Date(res.pests.pest_list[i].add_time * 1000)
  349. xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
  350. arr1.unshift(res.pests.pest_list[i].pest_num == "" ? "0" : res.pests.pest_list[i].pest_num)
  351. }
  352. var obj = [{
  353. name: '害虫总数',
  354. data: arr1,
  355. color: '#00E29D'
  356. }]
  357. this.showColumn("canvasColumnA", xtitle, obj)
  358. }
  359. },
  360. clickLeft() {
  361. uni.navigateBack({
  362. delta: 1
  363. })
  364. },
  365. confirmFun(index) {
  366. this.indexone = index[0]
  367. var now = new Date()
  368. this.$forceUpdate()
  369. if (index[0] == 0) {
  370. this.start_time = strrttime
  371. if (this.topindex == 0) {
  372. if (this.pest_name == '') {
  373. this.historys()
  374. } else {
  375. this.history()
  376. }
  377. } else {
  378. if (this.pest_name == '') {
  379. this.selfhistorys()
  380. } else {
  381. this.selfhistory()
  382. }
  383. }
  384. } else if (index[0] == 1) {
  385. var oldtime = now.setMonth(now.getMonth() - 1)
  386. this.start_time = parseInt(oldtime)
  387. if (this.topindex == 0) {
  388. if (this.pest_name == '') {
  389. this.historys()
  390. } else {
  391. this.history()
  392. }
  393. } else {
  394. if (this.pest_name == '') {
  395. this.selfhistorys()
  396. } else {
  397. this.selfhistory()
  398. }
  399. }
  400. } else if (index[0] == 2) {
  401. var oldtime = now.setMonth(now.getMonth() - 6)
  402. this.start_time = parseInt(oldtime)
  403. if (this.topindex == 0) {
  404. if (this.pest_name == '') {
  405. this.historys()
  406. } else {
  407. this.history()
  408. }
  409. } else {
  410. if (this.pest_name == '') {
  411. this.selfhistorys()
  412. } else {
  413. this.selfhistory()
  414. }
  415. }
  416. } else if (index[0] == 3) {
  417. var oldtime = now.setFullYear(now.getFullYear() - 1)
  418. this.start_time = parseInt(oldtime)
  419. if (this.topindex == 0) {
  420. if (this.pest_name == '') {
  421. this.historys()
  422. } else {
  423. this.history()
  424. }
  425. } else {
  426. if (this.pest_name == '') {
  427. this.selfhistorys()
  428. } else {
  429. this.selfhistory()
  430. }
  431. }
  432. }
  433. },
  434. confirmFun2(index) {
  435. console.log(index)
  436. console.log(this.wormdata)
  437. this.indextwo = index[0]
  438. this.pest_name = this.wormdata[this.indextwo]
  439. if (this.topindex == 0) {
  440. this.history()
  441. } else {
  442. this.selfhistory()
  443. }
  444. },
  445. changeindex(index) {
  446. this.tableval = []
  447. this.topindex = index
  448. if (this.topindex == 0) {
  449. this.pest_name = ''
  450. this.tishitf = false
  451. this.historys()
  452. } else {
  453. this.pest_name = ''
  454. this.tishitf = false
  455. this.selfhistorys()
  456. }
  457. },
  458. showColumn(id, xtitle, xinfo) {
  459. var _self = this
  460. canvaColumnA = new uCharts({
  461. canvasId: id,
  462. type: 'line',
  463. legend: {
  464. position: "top"
  465. },
  466. fontSize: 11,
  467. background: '#FFFFFF',
  468. pixelRatio: 1,
  469. animation: true,
  470. dataLabel: false,
  471. categories: xtitle,
  472. series: xinfo,
  473. enableScroll: true, //开启图表拖拽功能
  474. xAxis: {
  475. disableGrid: true,
  476. type: 'grid',
  477. gridType: 'dash',
  478. itemCount: 5, //x轴单屏显示数据的数量,默认为5个
  479. scrollShow: true, //新增是否显示滚动条,默认false
  480. // scrollAlign: 'left', //滚动条初始位置
  481. scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
  482. scrollColor: '#DEE7F7', //默认为 #A6A6A6
  483. },
  484. yAxis: {},
  485. width: _self.cWidth * 1,
  486. height: _self.cHeight * 1,
  487. extra: {
  488. line: {
  489. type: 'curve'
  490. }
  491. }
  492. });
  493. },
  494. touchLineA(e) {
  495. console.log(e)
  496. canvaColumnA.scrollStart(e);
  497. },
  498. moveLineA(e) {
  499. canvaColumnA.scroll(e);
  500. },
  501. touchEndLineA(e) {
  502. canvaColumnA.scrollEnd(e);
  503. //下面是toolTip事件,如果滚动后不需要显示,可不填写
  504. canvaColumnA.showToolTip(e, {
  505. format: function(item, category) {
  506. return category + ' ' + item.name + ':' + item.data
  507. }
  508. });
  509. },
  510. showRing(data) {
  511. var _self = this
  512. canvasRing = new uCharts({
  513. canvasId: "canvasRing",
  514. type: 'ring',
  515. fontSize: 11,
  516. legend: {
  517. show:true,
  518. },
  519. extra: {
  520. pie: {
  521. offsetAngle: -45,
  522. ringWidth: 40 * _self.pixelRatio,
  523. labelWidth: 15
  524. }
  525. },
  526. background: '#FFFFFF',
  527. pixelRatio: _self.pixelRatio,
  528. series: data,
  529. animation: true,
  530. width: _self.cWidth * _self.pixelRatio,
  531. height: _self.cHeight * _self.pixelRatio,
  532. disablePieStroke: true,
  533. dataLabel: true,
  534. });
  535. },
  536. touchRing(e) {
  537. canvasRing.showToolTip(e, {
  538. format: function(item) {
  539. return item.name + ':' + item.data
  540. }
  541. });
  542. },
  543. },
  544. onLoad(option) {
  545. this.d_id = option.d_id
  546. this.device_id = option.device_id
  547. this.cWidth = uni.upx2px(650);
  548. this.cHeight = uni.upx2px(500);
  549. this.historys()
  550. }
  551. }
  552. </script>
  553. <style lang="scss">
  554. .shuju_one{
  555. position: absolute;
  556. top: 84px;
  557. width: 90%;
  558. left: 5%;
  559. box-shadow: 0 0 10rpx #bcb9ca;
  560. padding-top: 20rpx;
  561. box-sizing: border-box;
  562. height: 650rpx;
  563. .canvastishi {
  564. font-size: 32rpx;
  565. position: absolute;
  566. top: 50%;
  567. left: 50%;
  568. margin-left: -64rpx;
  569. margin-top: -21rpx;
  570. }
  571. }
  572. .shuju_two{
  573. position: absolute;
  574. top: 840rpx;
  575. width: 90%;
  576. left: 5%;
  577. box-shadow: 0 0 10rpx #bcb9ca;
  578. padding-top: 20rpx;
  579. box-sizing: border-box;
  580. height: 650rpx;
  581. margin-bottom: 40rpx;
  582. .canvastishi {
  583. font-size: 32rpx;
  584. position: absolute;
  585. top: 50%;
  586. left: 50%;
  587. margin-left: -64rpx;
  588. margin-top: -21rpx;
  589. }
  590. }
  591. .shuju_table{
  592. position: absolute;
  593. top: 1510rpx;
  594. width: 90%;
  595. left: 5%;
  596. box-shadow: 0 0 10rpx #bcb9ca;
  597. padding-top: 20rpx;
  598. box-sizing: border-box;
  599. margin-bottom: 40rpx;
  600. .table{
  601. .th,
  602. .td {
  603. padding: 5rpx;
  604. width: 240rpx;
  605. text-align: center;
  606. height: 52rpx;
  607. line-height: 52rpx;
  608. font-size: 28rpx !important;
  609. }
  610. }
  611. }
  612. .condition {
  613. position: absolute;
  614. top: 600rpx;
  615. display: flex;
  616. flex-wrap: wrap;
  617. width: 90%;
  618. left: 5%;
  619. box-shadow: 0 0 10rpx #bcb9ca;
  620. margin-bottom: 30rpx;
  621. .scroll-X {
  622. width: 95%;
  623. margin: 20rpx auto;
  624. .tr {
  625. display: flex;
  626. overflow: hidden;
  627. .th,
  628. .td {
  629. display: inline-block;
  630. padding: 5rpx;
  631. width: 240rpx;
  632. text-align: center;
  633. height: 52rpx;
  634. line-height: 52rpx;
  635. border: 2rpx solid #F1F1F1;
  636. }
  637. }
  638. }
  639. .pagenumber {
  640. display: flex;
  641. margin: 20rpx auto;
  642. button {
  643. width: 150rpx;
  644. height: 50rpx;
  645. line-height: 50rpx;
  646. font-size: 26rpx;
  647. text-align: center;
  648. background-color: #17BB89;
  649. color: #FFFFFF;
  650. }
  651. .pagenumber_page {
  652. width: 150rpx;
  653. height: 50rpx;
  654. line-height: 50rpx;
  655. font-size: 26rpx;
  656. text-align: center;
  657. }
  658. }
  659. }
  660. </style>