pestdistribute.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. <!-- -->
  2. <template>
  3. <div
  4. class="pestbox"
  5. v-loading="pestboxloading"
  6. element-loading-text="拼命加载中"
  7. element-loading-spinner="el-icon-loading"
  8. element-loading-background="rgba(0, 0, 0, 0.8)"
  9. >
  10. <div
  11. :style="{ height: '100%', width: '100%' }"
  12. id="mychart"
  13. ref="mychart"
  14. ></div>
  15. <div class="searchbox">
  16. <el-select v-model="wornvalue" placeholder="请选择害虫名称" size="mini">
  17. <el-option
  18. v-for="item in wornoptions"
  19. :key="item.point_id"
  20. :label="item.point_name"
  21. :value="item.point_id"
  22. >
  23. </el-option>
  24. </el-select>
  25. <el-select
  26. v-model="inoffvalue"
  27. placeholder="请选择所在监测点"
  28. size="mini"
  29. >
  30. <el-option
  31. v-for="item in inoffoptions"
  32. :key="item.point_name"
  33. :label="item.point_name"
  34. :value="item.point_name"
  35. >
  36. </el-option>
  37. </el-select>
  38. <el-select
  39. v-model="versionsvalue2"
  40. placeholder="请选择隶属海关"
  41. size="mini"
  42. >
  43. <el-option
  44. v-for="item in versionsoptions2"
  45. :key="item.org_name"
  46. :label="item.org_name"
  47. :value="item.org_name"
  48. >
  49. </el-option>
  50. </el-select>
  51. <el-date-picker
  52. v-model="timevalue"
  53. type="daterange"
  54. range-separator="至"
  55. start-placeholder="开始日期"
  56. end-placeholder="结束日期"
  57. @change="oickchange"
  58. size="mini"
  59. :editable="false"
  60. >
  61. </el-date-picker>
  62. <el-button type="info" @click="search" size="mini">搜索</el-button>
  63. <el-button @click="reset" size="mini">重置</el-button>
  64. <el-button type="warning" @click="dialogVisible = true" size="mini"
  65. >设置</el-button
  66. >
  67. </div>
  68. <div class="piebox">
  69. <p
  70. :class="
  71. pietf ? 'iconbox el-icon-arrow-right' : 'iconbox el-icon-arrow-left'
  72. "
  73. @click="pietf = !pietf"
  74. style="cursor: pointer;"
  75. ></p>
  76. <div
  77. :style="{
  78. height: '500px',
  79. width: width,
  80. transition: 'all 1s ease',
  81. borderRadius: '10px',
  82. }"
  83. id="mychartpie"
  84. ref="mychartpie"
  85. v-loading="loading"
  86. element-loading-text="拼命加载中"
  87. element-loading-spinner="el-icon-loading"
  88. element-loading-background="rgba(0, 0, 0, 0.8)"
  89. ></div>
  90. </div>
  91. <el-dialog title="设置" :visible.sync="dialogVisible" width="450px">
  92. <div class="shezhibox">
  93. <el-form
  94. :model="ruleForm"
  95. :rules="rules"
  96. ref="ruleForm"
  97. class="demo-ruleForm"
  98. >
  99. <el-form-item label="最大害虫数量设置可标红" prop="threshold">
  100. <el-input v-model="ruleForm.threshold" size="mini"></el-input>
  101. </el-form-item>
  102. </el-form>
  103. </div>
  104. <span slot="footer" class="dialog-footer">
  105. <el-button @click="resetForm('ruleForm')" size="mini">取 消</el-button>
  106. <el-button type="primary" @click="submitForm('ruleForm')" size="mini"
  107. >确 定</el-button
  108. >
  109. </span>
  110. </el-dialog>
  111. </div>
  112. </template>
  113. <script>
  114. //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  115. import * as echarts from "echarts";
  116. import { map } from "highcharts";
  117. export default {
  118. //import引入的组件需要注入到对象中才能使用
  119. components: {},
  120. data() {
  121. //这里存放数据
  122. var checklnglat = (rule, value, callback) => {
  123. if (isNaN(value)) {
  124. callback(new Error("请输入数字"));
  125. } else {
  126. callback();
  127. }
  128. };
  129. return {
  130. pietf: true,
  131. width: "500px",
  132. wornvalue: "", //有害生物名称 选择
  133. wornoptions: [], //有害生物列表
  134. inoffvalue: "", //监测点 选择
  135. inoffoptions: [], //监测点列表
  136. versionsvalue2: "", //隶属海关选择
  137. versionsoptions2: [], //隶属海关列表
  138. timevalue: "",
  139. start_time: "",
  140. end_time: "",
  141. loading: false,
  142. dialogVisible: false,
  143. ruleForm: {
  144. threshold: "100", //阈值
  145. },
  146. rules: {
  147. name: [
  148. { required: true, message: "请输入值", trigger: "blur" },
  149. { validator: checklnglat, trigger: "blur" },
  150. ],
  151. },
  152. pestboxloading: true,
  153. };
  154. },
  155. //监听属性 类似于data概念
  156. computed: {},
  157. //监控data中的数据变化
  158. watch: {
  159. pietf: function (val) {
  160. // console.log(this.width)
  161. if (val) {
  162. this.width = "500px";
  163. } else {
  164. this.width = "0";
  165. }
  166. // console.log(this.width)
  167. },
  168. },
  169. //方法集合
  170. methods: {
  171. init(trap_data_arr) {
  172. console.log(trap_data_arr);
  173. var that = this;
  174. let myChart = echarts.init(document.getElementById("mychart"));
  175. var arr = [];
  176. const mapData = require("./json/shenzhen.json");
  177. // const name = "深圳";
  178. arr.push(mapData.features);
  179. // echarts.registerMap(name, mapData);
  180. const mapData2 = require("./json/shanwei.json");
  181. console.log(mapData2);
  182. arr.push(mapData2.features);
  183. // const name2 = "汕尾";
  184. // echarts.registerMap(name2, mapData2);
  185. const mapData3 = require("./json/huizhou.json");
  186. arr.push(mapData3.features);
  187. // const name3 = "惠州";
  188. // echarts.registerMap(name3, mapData3);
  189. var arr2 = arr.reduce(function (a, b) {
  190. return a.concat(b);
  191. });
  192. // console.log(arr2);
  193. var xbMap = {
  194. type: "FeatureCollection",
  195. features: arr2,
  196. };
  197. echarts.registerMap("深圳", xbMap);
  198. // let myChart = echarts.init(document.getElementById("mychart"));
  199. window.addEventListener("resize", function () {
  200. // undefined;
  201. myChart.resize();
  202. });
  203. myChart.setOption({
  204. backgroundColor: "#252b45",
  205. title: {
  206. left: "center",
  207. textStyle: {
  208. color: "#000",
  209. },
  210. },
  211. visualMap: {
  212. min: 0,
  213. max: Number(that.ruleForm.threshold),
  214. calculable: true,
  215. inRange: {
  216. color: ["#50a3ba", "#eac736", "#d94e5d"],
  217. },
  218. textStyle: {
  219. color: "#fff",
  220. },
  221. },
  222. geo:
  223. // [
  224. {
  225. map: "深圳",
  226. label: {
  227. normal: {
  228. show: true,
  229. color: "#fff",
  230. },
  231. emphasis: {
  232. show: true,
  233. },
  234. },
  235. roam: true, //是否允许缩放
  236. layoutCenter: ["50%", "110%"], //地图位置
  237. layoutSize: "200%",
  238. itemStyle: {
  239. normal: {
  240. color: "#031525", //地图背景色
  241. borderColor: "rgba(100,149,237,1)", //省市边界线
  242. },
  243. emphasis: {
  244. color: "rgba(37, 43, 61, .5)", //悬浮背景
  245. },
  246. },
  247. scaleLimit: {
  248. //所属组件的z分层,z值小的图形会被z值大的图形覆盖
  249. min: 0.5, //最小的缩放值
  250. max: 50,
  251. },
  252. },
  253. tooltip: {
  254. show: true,
  255. // formatter: "{a}{b}{c}{d}",
  256. formatter: function (e) {
  257. // console.log(e);
  258. if (e.seriesType == "scatter") {
  259. var str = ``;
  260. for (var i = 0; i < e.data.pest_data.length; i++) {
  261. str +=
  262. `<p>` +
  263. e.data.pest_data[i].pest_name +
  264. ` :` +
  265. e.data.pest_data[i].sum +
  266. ` 只</p>`;
  267. }
  268. return (
  269. `<div><p>设备id :` + e.data.device_id + `</p>` + str + `</div>`
  270. );
  271. } else {
  272. return e.name;
  273. }
  274. // var name = e.seriesName
  275. },
  276. },
  277. series: [
  278. {
  279. type: "map",
  280. map: "深圳",
  281. geoIndex: 0,
  282. aspectScale: 0.75, //长宽比
  283. showLegendSymbol: false, // 存在legend时显示
  284. label: {
  285. normal: {
  286. show: false,
  287. },
  288. emphasis: {
  289. show: false,
  290. textStyle: {
  291. color: "#fff",
  292. },
  293. },
  294. },
  295. roam: true,
  296. itemStyle: {
  297. normal: {
  298. areaColor: "#031525",
  299. borderColor: "#3B5077",
  300. },
  301. emphasis: {
  302. areaColor: "#2B91B7",
  303. },
  304. },
  305. animation: false,
  306. data: [],
  307. },
  308. // ["scatter","effectScatter"]
  309. {
  310. name: "害虫",
  311. type: "scatter",
  312. coordinateSystem: "geo",
  313. // geoIndex: 2,
  314. symbolSize: function (val) {
  315. // var num = Number(that.ruleForm.threshold)
  316. // if(val<Math.floor(num*0.2)){
  317. // return 12
  318. // }else if(val<Math.floor(num*0.4)){
  319. // return 14
  320. // }else if(val<Math.floor(num*0.6)){
  321. // return 16
  322. // }else if(val<Math.floor(num*0.8)){
  323. // return 18
  324. // }else if(val<num){
  325. // return 20
  326. // }else{
  327. // return 22
  328. // }
  329. return 12;
  330. },
  331. data: trap_data_arr,
  332. label: {
  333. normal: {
  334. formatter: "{b}",
  335. position: "right",
  336. show: true,
  337. },
  338. emphasis: {
  339. show: true,
  340. },
  341. },
  342. itemStyle: {
  343. normal: {
  344. color: "#05C3F9",
  345. },
  346. },
  347. },
  348. ],
  349. });
  350. this.pestboxloading = false;
  351. },
  352. initpie(data) {
  353. var data = data;
  354. var placeHolderStyle = {
  355. normal: {
  356. label: {
  357. show: false,
  358. },
  359. labelLine: {
  360. show: false,
  361. },
  362. color: "rgba(0, 0, 0, 0)",
  363. borderColor: "rgba(0, 0, 0, 0)",
  364. borderWidth: 0,
  365. },
  366. };
  367. var data1 = [];
  368. var data2 = [];
  369. var colorIn = [
  370. "rgb(33, 166, 161)",
  371. "rgb(102,113,209)",
  372. "rgb(230,144,78)",
  373. "rgb(38,185,211)",
  374. "rgb(82,125,12)",
  375. "rgb(35,70,209)",
  376. ];
  377. var colorOut = [
  378. "rgba(33, 166, 161, 0.5)",
  379. "rgba(102,113,209, 0.5)",
  380. "rgba(230,144,78, 0.5)",
  381. "rgba(38,185,211, 0.5)",
  382. "rgb(82,125,12,0.5)",
  383. "rgb(35,70,209,0.5)",
  384. ];
  385. for (var i = 0; i < data.length; i++) {
  386. data1.push({
  387. data: data[i].value,
  388. value: data[i].value,
  389. name: data[i].name,
  390. itemStyle: {
  391. normal: {
  392. color: colorOut[i],
  393. },
  394. },
  395. });
  396. data2.push({
  397. data: data[i].value,
  398. value: data[i].value,
  399. name: data[i].name,
  400. itemStyle: {
  401. normal: {
  402. color: colorIn[i],
  403. },
  404. },
  405. });
  406. }
  407. var dataArr = [];
  408. for (var i = 0; i < 100; i++) {
  409. if (i % 2 === 0) {
  410. dataArr.push({
  411. name: (i + 1).toString(),
  412. value: 25,
  413. itemStyle: {
  414. normal: {
  415. color: "#2ac9e1",
  416. borderWidth: 0,
  417. borderColor: "rgba(0,0,0,0)",
  418. },
  419. },
  420. });
  421. } else {
  422. dataArr.push({
  423. name: (i + 1).toString(),
  424. value: 20,
  425. itemStyle: {
  426. normal: {
  427. color: "rgba(0,0,0,0)",
  428. borderWidth: 0,
  429. borderColor: "rgba(0,0,0,0)",
  430. },
  431. },
  432. });
  433. }
  434. }
  435. var option = {
  436. title: {
  437. text: "有害生物占比",
  438. subtext: "",
  439. sublink: "",
  440. left: "center",
  441. textStyle: {
  442. color: "#fff",
  443. },
  444. top: "5%",
  445. },
  446. backgroundColor: "#04243E",
  447. tooltip: {
  448. title: "详情",
  449. trigger: "item",
  450. formatter: "{a} <br/>{b}: {c} ({d}%)",
  451. },
  452. legend: {
  453. orient: "horizontal",
  454. bottom: "5%",
  455. itemWidth: 10,
  456. itemHeight: 10,
  457. x: "center",
  458. textStyle: {
  459. color: "#fff",
  460. fontSize: 12,
  461. },
  462. show: true,
  463. data: data,
  464. },
  465. series: [
  466. {
  467. type: "pie",
  468. zlevel: 3,
  469. silent: true,
  470. // center: ['50%', '40%'],
  471. radius: ["43%", "45%"],
  472. label: {
  473. normal: {
  474. show: false,
  475. },
  476. },
  477. labelLine: {
  478. normal: {
  479. show: false,
  480. },
  481. },
  482. data: dataArr,
  483. },
  484. {
  485. name: "详情",
  486. type: "pie",
  487. selectedMode: "single",
  488. radius: [0, "40%"],
  489. label: {
  490. formatter: "{d}%",
  491. position: "inner",
  492. },
  493. data: data2,
  494. },
  495. {
  496. name: "详情",
  497. type: "pie",
  498. radius: ["48%", "50%"],
  499. labelLine: {
  500. normal: {
  501. length: 10,
  502. length2: 14,
  503. },
  504. },
  505. label: {
  506. show: true,
  507. position: "outer",
  508. alignTo: "labelLine",
  509. // ·圆点
  510. backgroundColor: "auto",
  511. height: 0,
  512. width: 0,
  513. lineHeight: 0,
  514. distanceToLabelLine: 0,
  515. borderRadius: 2.5,
  516. padding: [2.5, -2.5, 2.5, -2.5],
  517. formatter: "{a|{b} }",
  518. rich: {
  519. a: {
  520. padding: [0, 0, 0, 10],
  521. color: "#aebfe8",
  522. fontSize: 14,
  523. },
  524. b: {
  525. padding: [0, 10, 0, 0],
  526. fontSize: 14,
  527. },
  528. },
  529. },
  530. data: data1,
  531. },
  532. ],
  533. };
  534. echarts.init(document.getElementById("mychartpie")).setOption(option);
  535. },
  536. getwornlist() {
  537. this.loading = true;
  538. this.$axios({
  539. method: "POST",
  540. url: "/api/api_gateway?method=monitor_manage.home_map.pest_distribute",
  541. data: this.qs.stringify({
  542. pest_name: this.wornvalue, // 非必传(string) 有害生物名称 搜索项
  543. point_name: this.inoffvalue, // 非必传(string) 设备所属监测点 搜索项
  544. org_name: this.versionsvalue2, // 非必传(string) 设备所属组织 搜索项
  545. start_time: this.start_time, // 非必传(string) 开始时间 搜索项 2022-01-20
  546. end_time: this.end_time, // 非必传(string) 结束时间 搜索项 2022-01-23
  547. }),
  548. }).then((res) => {
  549. this.loading = false;
  550. console.log(res.data.data.pest_count);
  551. var trap_data = res.data.data.trap_data;
  552. var num = 0;
  553. var trap_data_arr = [];
  554. for (var i = 0; i < trap_data.length; i++) {
  555. if (trap_data[i].pest_total > num) {
  556. num = trap_data[i].pest_total;
  557. }
  558. var obj = {
  559. value: [
  560. trap_data[i].lng,
  561. trap_data[i].lat,
  562. trap_data[i].pest_total,
  563. ],
  564. device_id: trap_data[i].device_id,
  565. pest_data: trap_data[i].pest_data,
  566. };
  567. trap_data_arr.push(obj);
  568. }
  569. if (res.data.data.threshold == 0) {
  570. this.ruleForm.threshold = num;
  571. } else {
  572. this.ruleForm.threshold = res.data.data.threshold;
  573. }
  574. this.init(trap_data_arr);
  575. var pest_count = res.data.data.pest_count;
  576. var arr = [];
  577. for (var i = 0; i < pest_count.length; i++) {
  578. var obj = {
  579. value: pest_count[i].sum,
  580. name: pest_count[i].pest_name,
  581. };
  582. arr.push(obj);
  583. }
  584. this.initpie(arr);
  585. });
  586. },
  587. getwornlistflex(){
  588. this.$axios({
  589. method: "POST",
  590. url: "/api/api_gateway?method=monitor_manage.home_map.pest_name_list",
  591. }).then((res) => {
  592. console.log(res.data.data)
  593. this.wornoptions = [];
  594. var pest_list = res.data.data
  595. for (var i = 0; i < pest_list.length; i++) {
  596. var obj2 = {
  597. point_id: pest_list[i].pest_name,
  598. point_name: pest_list[i].pest_name,
  599. };
  600. this.wornoptions.push(obj2);
  601. }
  602. })
  603. },
  604. tabtime(times) {
  605. //时间转换
  606. var years = times.getFullYear();
  607. var month = times.getMonth() + 1;
  608. var date = times.getDate();
  609. return years + "-" + month + "-" + date;
  610. },
  611. oickchange(e) {
  612. this.start_time = this.tabtime(e[0]);
  613. this.end_time = this.tabtime(e[1]);
  614. },
  615. search() {
  616. this.getwornlist();
  617. },
  618. reset() {
  619. this.wornvalue = "";
  620. this.inoffvalue = "";
  621. this.versionsvalue2 = "";
  622. this.timevalue = "";
  623. this.getwornlist()
  624. },
  625. getmon2() {
  626. this.$axios({
  627. method: "POST",
  628. url: "/api/api_gateway?method=monitor_manage.trap_manage.pest_trap_org",
  629. }).then((res) => {
  630. console.log(res.data.data);
  631. this.versionsoptions2 = res.data.data.org_list;
  632. this.inoffoptions = res.data.data.point_data;
  633. });
  634. },
  635. submitForm(formName) {
  636. this.$refs[formName].validate((valid) => {
  637. if (valid) {
  638. this.$axios({
  639. method: "POST",
  640. url: "/api/api_gateway?method=monitor_manage.home_map.pest_distribute_threshold",
  641. data: this.qs.stringify({
  642. threshold: this.ruleForm.threshold,
  643. }),
  644. }).then((res) => {
  645. if (res.data.data) {
  646. this.dialogVisible = false;
  647. this.$message({
  648. showClose: true,
  649. message: "设置成功",
  650. type: "success",
  651. });
  652. this.getwornlist()
  653. } else {
  654. this.$message({
  655. showClose: true,
  656. message: "设置失败",
  657. type: "success",
  658. });
  659. }
  660. });
  661. } else {
  662. this.$message({
  663. showClose: true,
  664. message: "设置失败" + res.data.message,
  665. type: "warning",
  666. });
  667. // return false;
  668. }
  669. });
  670. },
  671. resetForm(formName) {
  672. this.dialogVisible = false;
  673. this.$refs[formName].resetFields();
  674. },
  675. },
  676. beforeCreate() {}, //生命周期 - 创建之前
  677. //生命周期 - 创建完成(可以访问当前this实例)
  678. created() {},
  679. beforeMount() {}, //生命周期 - 挂载之前
  680. //生命周期 - 挂载完成(可以访问DOM元素)
  681. mounted() {
  682. setTimeout(() => {
  683. this.init();
  684. }, 500);
  685. this.getwornlist();
  686. this.getwornlistflex()
  687. // this.getmon();
  688. this.getmon2();
  689. },
  690. beforeUpdate() {}, //生命周期 - 更新之前
  691. updated() {}, //生命周期 - 更新之后
  692. beforeDestroy() {}, //生命周期 - 销毁之前
  693. destroyed() {}, //生命周期 - 销毁完成
  694. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  695. };
  696. </script>
  697. <style lang="less" scoped>
  698. .pestbox {
  699. width: 100%;
  700. height: 97%;
  701. position: relative;
  702. overflow: hidden;
  703. .searchbox {
  704. position: absolute;
  705. top: 10px;
  706. left: 15px;
  707. /deep/.el-select {
  708. margin-right: 10px;
  709. }
  710. /deep/.el-date-editor {
  711. margin-right: 10px;
  712. }
  713. /deep/.el-button--info {
  714. background-color: #409eff;
  715. border-color: #409eff;
  716. }
  717. }
  718. .piebox {
  719. position: absolute;
  720. top: 0;
  721. right: 0;
  722. display: flex;
  723. height: 100%;
  724. transition: width 1s ease;
  725. .iconbox {
  726. width: 30px;
  727. height: 50px;
  728. background-color: chocolate;
  729. color: #fff;
  730. line-height: 50px;
  731. text-align: center;
  732. font-size: 25px;
  733. }
  734. /deep/canvas {
  735. border-radius: 10px;
  736. }
  737. #mychartpie {
  738. background-color: #04243e;
  739. border-radius: 10px;
  740. }
  741. }
  742. }
  743. /deep/.el-dialog__body {
  744. padding-bottom: 0;
  745. }
  746. .shezhibox {
  747. /deep/.el-input {
  748. width: 50%;
  749. }
  750. }
  751. /deep/.el-date-editor{
  752. cursor: pointer;
  753. .el-range-input{
  754. cursor: pointer;
  755. }
  756. }
  757. </style>