monitorEcharts.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <template>
  2. <div>
  3. <!-- <weatherTitle :title="'近24小时气象监测站过程线'" /> -->
  4. <div>
  5. <div class="total222">
  6. <!-- {{ windSpeeCharts }} -->
  7. <a-tabs @change="changeTabs" v-model:activeKey="activeKey">
  8. <a-tab-pane key="1">
  9. <template #tab>
  10. <span> 温度 </span>
  11. </template>
  12. <div v-if="showCharts1" id="mo-echarts1" style="width: 100%; height: 280px"> </div>
  13. <div v-else style="width: 100; height: 280px">
  14. <img class="none-data" src="../../../assets/images/weatheHome/none-data.png" />
  15. </div>
  16. </a-tab-pane>
  17. <a-tab-pane key="2">
  18. <template #tab>
  19. <span> 风速/风向标 </span>
  20. </template>
  21. <div v-if="showCharts2" id="mo-echarts2" style="width: 100%; height: 280px"> </div>
  22. <div v-else style="width: 100; height: 280px">
  23. <img class="none-data" src="../../../assets/images/weatheHome/none-data.png" />
  24. </div>
  25. </a-tab-pane>
  26. <template #renderTabBar="{ DefaultTabBar, ...props }">
  27. <component :is="DefaultTabBar" v-bind="props" :style="{ zIndex: 1, textAlign: 'center' }" />
  28. </template>
  29. </a-tabs>
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script lang="ts" setup>
  35. import { toRef, ref, getCurrentInstance, onMounted, watch } from 'vue';
  36. import weatherTitle from '../../../components/Title/weatherTitle.vue';
  37. import { useMapStore } from '/@/store/modules/map';
  38. import eventBus from '/@/utils/eventBus';
  39. // 导入图片
  40. import imgangle from '/@/assets/images/weatheHome/trend-icon.png';
  41. import screenImg from '/@/assets/images/weatheHome/full-screen-icon.png';
  42. eventBus.on('monitorRefreshName', () => {
  43. activeKey.value = '1';
  44. });
  45. const props = defineProps({
  46. temperatureCharts: {
  47. type: Object,
  48. default: () => {
  49. return {};
  50. },
  51. },
  52. windSpeeCharts: {
  53. type: Object,
  54. default: () => {
  55. return {};
  56. },
  57. },
  58. windDirection: {
  59. type: Object,
  60. default: () => {
  61. return {};
  62. },
  63. },
  64. });
  65. const temperatureChartsData = toRef(props, 'temperatureCharts');
  66. const windSpeeCharts = toRef(props, 'temperatureCharts');
  67. let showCharts1 = ref(true);
  68. let showCharts2 = ref(true);
  69. // 监听参数是否变化
  70. watch(temperatureChartsData, (newData) => {
  71. showCharts1.value = true;
  72. showCharts2.value = true;
  73. // 判断是否数据为空
  74. if (windSpeeCharts.value.data.length == 0) {
  75. showCharts2.value = false;
  76. }
  77. if (newData.data.length == 0) {
  78. showCharts1.value = false;
  79. return;
  80. }
  81. setTimeout(() => {
  82. echarts1();
  83. echarts2();
  84. }, 200);
  85. });
  86. let showChartsMax = ref(false);
  87. // 引入图表插件
  88. const { proxy } = getCurrentInstance();
  89. const echarts = proxy.$echarts;
  90. function echarts1() {
  91. const chart = echarts.init(document.getElementById('mo-echarts1'));
  92. let option;
  93. option = {
  94. tooltip: {
  95. trigger: 'axis',
  96. axisPointer: {
  97. type: 'shadow',
  98. },
  99. },
  100. dataZoom: [
  101. {
  102. // 这个dataZoom组件,默认控制x轴。
  103. type: 'inside', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
  104. },
  105. {
  106. // 这个dataZoom组件,也控制x轴。
  107. type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
  108. },
  109. ],
  110. grid: {
  111. left: '3%', //默认10%
  112. right: '4%', //默认10%
  113. bottom: '4%', //默认60
  114. containLabel: true,
  115. //grid区域是否包含坐标轴的刻度标签
  116. },
  117. xAxis: {
  118. type: 'category',
  119. data: temperatureChartsData.value.name,
  120. axisLabel: {
  121. //x轴文字的配置
  122. show: true,
  123. textStyle: {
  124. color: '#fff',
  125. },
  126. formatter: function (val) {
  127. var strs = val.split(''); //字符串数组
  128. var str = '';
  129. for (var i = 0, s; (s = strs[i++]);) {
  130. //遍历字符串数组
  131. if (i > 5 && i < 17) {
  132. str += s;
  133. }
  134. if (!(i % 10)) str += '\n'; //按需要求余
  135. }
  136. return str;
  137. },
  138. },
  139. },
  140. yAxis: [
  141. {
  142. splitLine: {
  143. //网格线
  144. lineStyle: {
  145. type: 'dotted', //设置网格线类型 dotted:虚线 solid:实线
  146. width: 1, //y轴线的宽度
  147. color: '#484849',
  148. },
  149. show: true, //隐藏或显示
  150. },
  151. axisLabel: {
  152. //y轴文字的配置
  153. textStyle: {
  154. color: '#fff',
  155. margin: 15,
  156. },
  157. formatter: function (value) {
  158. return value.toFixed(1);
  159. },
  160. // formatter: '{value} %'//y轴的每一个刻度值后面加上‘%’号
  161. },
  162. scale: true,
  163. },
  164. {
  165. type: 'value',
  166. name: '单位:℃', //单位
  167. nameLocation: 'end',
  168. //单位的样式设置
  169. nameTextStyle: {
  170. color: 'rgba(255, 255, 255, 0.8)', //颜色
  171. padding: [15, 25, 15, -700],
  172. },
  173. scale: true,
  174. },
  175. ],
  176. series: [
  177. {
  178. data: temperatureChartsData.value.data,
  179. type: 'line',
  180. smooth: true,
  181. },
  182. ],
  183. };
  184. option && chart.setOption(option);
  185. }
  186. function changeTabs(e) {
  187. if (e == 2) {
  188. setTimeout(() => {
  189. echarts2();
  190. }, 0);
  191. }
  192. }
  193. let chart2 = null;
  194. function echarts2() {
  195. chart2 = echarts.init(document.getElementById('mo-echarts2'));
  196. var option = {
  197. // toolbox: {
  198. // itemSize: 25, // 设置图标大小
  199. // },
  200. tooltip: {
  201. trigger: 'axis',
  202. axisPointer: {
  203. type: 'shadow',
  204. },
  205. formatter: function (params) {
  206. // console.log('time',params)
  207. return `<div>
  208. <div>
  209. 时间:${params[0].axisValueLabel}
  210. </div>
  211. <div>
  212. 风速(m/s):${params[0].data}
  213. </div>
  214. <div>
  215. 风向:${props.windDirection.data[params[0].dataIndex] ? setWd(props.windDirection.data[params[0].dataIndex]) : '-'}
  216. </div>
  217. </div>`;
  218. },
  219. },
  220. dataZoom: [
  221. {
  222. // 这个dataZoom组件,默认控制x轴。
  223. type: 'inside', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
  224. },
  225. {
  226. // 这个dataZoom组件,也控制x轴。
  227. type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
  228. },
  229. ],
  230. grid: {
  231. left: '3%', //默认10%
  232. right: '4%', //默认10%
  233. bottom: '4%', //默认60
  234. containLabel: true,
  235. //grid区域是否包含坐标轴的刻度标签
  236. },
  237. legend: {
  238. // data: ['风速', '风向'],
  239. data: ['风速'],
  240. symbol:'none',
  241. textStyle: {
  242. fontSize: 14, //字体大小
  243. color: '#ffffff', //字体颜色
  244. },
  245. orient:'horizontal',
  246. itemHeight:2
  247. // itemStyle: {
  248. // color: '#fff',
  249. // },
  250. },
  251. xAxis: {
  252. type: 'category',
  253. data: props.windSpeeCharts.name,
  254. axisLabel: {
  255. //x轴文字的配置
  256. show: true,
  257. textStyle: {
  258. color: '#fff',
  259. },
  260. formatter: function (val) {
  261. var strs = val.split(''); //字符串数组
  262. var str = '';
  263. for (var i = 0, s; (s = strs[i++]);) {
  264. //遍历字符串数组
  265. if (i > 5 && i < 17) {
  266. str += s;
  267. }
  268. if (!(i % 10)) str += '\n'; //按需要求余
  269. }
  270. return str;
  271. },
  272. },
  273. },
  274. yAxis: [
  275. {
  276. name: '风速(m/s)',
  277. type: 'value',
  278. axisLabel: {
  279. //y轴文字的配置
  280. textStyle: {
  281. color: '#fff',
  282. margin: 15,
  283. },
  284. formatter: function (value) {
  285. return value.toFixed(1);
  286. },
  287. // formatter: '{value} %'//y轴的每一个刻度值后面加上‘%’号
  288. },
  289. splitLine: {
  290. //网格线
  291. lineStyle: {
  292. type: 'dashed', //设置网格线类型 dotted:虚线 solid:实线
  293. width: 1, //y轴线的宽度
  294. color: '#484849',
  295. },
  296. show: true, //隐藏或显示
  297. },
  298. nameTextStyle: {
  299. color: 'rgba(255, 255, 255, 0.8)', //颜色
  300. },
  301. scale: true,
  302. },
  303. // {
  304. // type: 'value',
  305. // name: '风向',
  306. // axisLabel: {
  307. // //y轴文字的配置
  308. // textStyle: {
  309. // color: '#fff',
  310. // margin: 15,
  311. // },
  312. // // formatter: '{value} %'//y轴的每一个刻度值后面加上‘%’号
  313. // },
  314. // splitLine: {
  315. // //网格线
  316. // lineStyle: {
  317. // type: 'dotted', //设置网格线类型 dotted:虚线 solid:实线
  318. // width: 1, //y轴线的宽度
  319. // color: '#484849',
  320. // },
  321. // show: true, //隐藏或显示
  322. // },
  323. // nameTextStyle: {
  324. // color: 'rgba(255, 255, 255, 0.8)', //颜色
  325. // padding: [0, 0, 0, 30],
  326. // },
  327. // scale: true,
  328. // },
  329. ],
  330. series: [
  331. {
  332. name: '风速',
  333. data: props.windSpeeCharts.data,
  334. type: 'line',
  335. smooth: true,
  336. // symbol: 'path://M0,0L20,0L20,3L3,3L3,8L20,8L20,11L3,11L3,16L20,16L20,19L3,19L3,40L0,40L0,0Z',
  337. symbol: function (params) {
  338. console.log('params',params)
  339. // 设置不同等级的图标
  340. let level1 = 'path://M0,0L20,0L20,3L3,3L3,8L3,8L3,11L3,11L3,16L3,16L3,19L3,19L3,40L0,40L0,0Z'
  341. let level2 = 'path://M0,0L20,0L20,3L3,3L3,8L20,8L20,11L3,11L3,16L3,16L3,19L3,19L3,40L0,40L0,0Z'
  342. let level3 = 'path://M0,0L20,0L20,3L3,3L3,8L20,8L20,11L3,11L3,16L20,16L20,19L3,19L3,40L0,40L0,0Z'
  343. let level4 = 'path://M0,0L20,0L20,3L3,3L3,8L20,8L20,11L3,11L3,16L20,16L20,19L3,19L3,40L0,40L0,0Z'
  344. let level5 = 'path://M0,0L20,0L20,3L3,3L3,8L3,8L3,11L3,11L3,16L3,16L3,19L3,19L3,40L0,40L0,0Z'
  345. let svgData = ''
  346. if(params >= 0 && params <=3.3){
  347. svgData = level1
  348. }
  349. if(params >= 3.4 && params <=7.9){
  350. svgData = level2
  351. }
  352. if(params >= 8 && params <=13.8){
  353. svgData = level3
  354. }
  355. if(params >= 13.9 && params <=20.7){
  356. svgData = level4
  357. }
  358. if(params >= 20.8){
  359. svgData = level5
  360. }
  361. return svgData
  362. },
  363. symbolSize: 18,
  364. symbolRotate: (value, params) => {
  365. return props.windDirection.data[params.dataIndex] * -1;
  366. },
  367. },
  368. // {
  369. // name: '风向',
  370. // yAxisIndex: 1,
  371. // data: props.windDirection.data,
  372. // type: 'line',
  373. // smooth: true,
  374. // },
  375. ],
  376. };
  377. option && chart2.setOption(option);
  378. }
  379. function fnResize() {
  380. setTimeout(() => {
  381. chart2.resize();
  382. }, 100);
  383. }
  384. // 处理风向
  385. function setWd(wds) {
  386. let wd = wds * 1
  387. console.log(wd)
  388. if (wd >= 348.76 || wd <= 11.25) {
  389. return 'N';
  390. }
  391. if (wd >= 11.26 && wd <= 33.75) {
  392. return 'NNE';
  393. }
  394. if (wd >= 33.76 && wd <= 56.25) {
  395. return 'NE';
  396. }
  397. if (wd >= 56.26 && wd <= 78.75) {
  398. return 'ENE';
  399. }
  400. if (wd >= 78.76 && wd <= 101.25) {
  401. return 'E';
  402. }
  403. if (wd >= 101.26 && wd <= 123.75) {
  404. return 'ESE';
  405. }
  406. if (wd >= 123.76 && wd <= 146.25) {
  407. return 'SE';
  408. }
  409. if (wd >= 146.26 && wd <= 168.75) {
  410. return 'SSE';
  411. }
  412. if (wd >= 168.76 && wd <= 191.25) {
  413. return 'S';
  414. }
  415. if (wd >= 191.26 && wd <= 213.75) {
  416. return 'SSW';
  417. }
  418. if (wd >= 213.76 && wd <= 236.25) {
  419. return 'SW';
  420. }
  421. if (wd >= 236.26 && wd <= 258.75) {
  422. return 'WSW';
  423. }
  424. if (wd >= 258.76 && wd <= 281.25) {
  425. return 'W';
  426. }
  427. if (wd >= 281.76 && wd <= 303.75) {
  428. return 'WNW';
  429. }
  430. if (wd >= 303.76 && wd <= 326.25) {
  431. return 'NW';
  432. }
  433. if (wd >= 326.26 && wd <= 348.75) {
  434. return 'NNW';
  435. }
  436. return '-'
  437. }
  438. function checkFull() {
  439. //判断浏览器是否处于全屏状态 (需要考虑兼容问题)
  440. //火狐浏览器
  441. let isFull =
  442. document.mozFullScreen ||
  443. document.fullScreen ||
  444. //谷歌浏览器及Webkit内核浏览器
  445. document.webkitIsFullScreen ||
  446. document.webkitRequestFullScreen ||
  447. document.mozRequestFullScreen ||
  448. document.msFullscreenEnabled;
  449. if (isFull === undefined) {
  450. isFull = false;
  451. }
  452. return isFull;
  453. }
  454. // 图表方法结束
  455. onMounted(() => {
  456. window.onresize = function () {
  457. if (!checkFull()) {
  458. // 退出全屏后要执行的动作
  459. fnResize();
  460. }
  461. };
  462. });
  463. let activeKey = ref('1');
  464. </script>
  465. <style lang="less" scoped>
  466. .main {
  467. box-sizing: border-box;
  468. padding: 2px;
  469. margin-top: 20px;
  470. border-radius: 0px 30px 0px 30px;
  471. background-image: linear-gradient(200deg, rgba(40, 165, 255, 0.9) 9%, rgba(100, 255, 255, 0) 34%, rgba(40, 126, 255, 0) 66%, #28a5ff 100%);
  472. }
  473. .main_in {
  474. width: 100%;
  475. height: 100%;
  476. border-radius: 0px 30px 0px 30px;
  477. background: rgba(6, 37, 70, 0.9);
  478. }
  479. // 修改组件样式
  480. ::v-deep(.total222 .ant-tabs-nav .ant-tabs-tab-active) {
  481. // background: url('../../assets/images/sjx1.png') no-repeat 42px 9px;
  482. background: url('../../../assets/images/weatheHome/active-bar.png') no-repeat;
  483. // width: 45px;
  484. background-size: 100%;
  485. height: 40px;
  486. width: 169px;
  487. }
  488. ::v-deep(.total222 .ant-tabs-nav > div > div:nth-child(2).ant-tabs-tab-active) {
  489. // background: url('../../assets/images/sjx1.png') no-repeat 42px 9px;
  490. // background: url('../../../assets/images/tab.png') no-repeat;
  491. // width: 45px;
  492. // background-position: 6px 3px;
  493. background-size: 100% 100%;
  494. height: 42px;
  495. // line-height: 42px;
  496. // margin-left: -6px;
  497. }
  498. // ::v-deep(.total222 .ant-tabs-nav > div > div:nth-child(2).ant-tabs-tab-active span) {
  499. // position: relative;
  500. // // top: 10px !important;
  501. // }
  502. ::v-deep(.total222 .ant-tabs-nav .ant-tabs-tab) {
  503. // background-position: 6px 3px;
  504. background-size: 100% 100%;
  505. height: 40px;
  506. // line-height: 42px;
  507. padding: 12px 0px 12px 0px;
  508. margin: 0;
  509. width: 149px;
  510. }
  511. ::v-deep(.total222 .ant-tabs-nav .ant-tabs-tab span) {
  512. position: relative;
  513. top: -4px;
  514. color: #377dff;
  515. }
  516. ::v-deep(.total222 .ant-tabs-nav .ant-tabs-tab-active span) {
  517. color: #c9d1d9 !important;
  518. }
  519. ::v-deep(.ant-tabs-top-bar) {
  520. margin-bottom: 0px !important;
  521. }
  522. ::v-deep(.ant-tabs-ink-bar) {
  523. visibility: hidden;
  524. }
  525. ::v-deep(.ant-tabs-top > .ant-tabs-nav::before,
  526. .ant-tabs-bottom > .ant-tabs-nav::before,
  527. .ant-tabs-top > div > .ant-tabs-nav::before,
  528. .ant-tabs-bottom > div > .ant-tabs-nav::before) {
  529. border-bottom: 0px;
  530. }
  531. ::v-deep(.ant-tabs) {
  532. color: #fff;
  533. }
  534. ::v-deep(.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
  535. color: #ffe75c;
  536. }
  537. ::v-deep(.ant-tabs-tab) {
  538. // font-size: 18px;
  539. // font-weight: bold;
  540. font-size: 16px;
  541. font-weight: normal !important;
  542. }
  543. ::v-deep(.ant-tabs-bar) {
  544. border-bottom: 0px solid #303030 !important;
  545. }
  546. ::v-deep(.ant-tabs-nav) {
  547. background: url('../../../assets/images/weatheHome/bar-bg.png') no-repeat;
  548. background-size: 100%;
  549. width: 318px !important;
  550. height: 48px !important;
  551. padding-top: 3px;
  552. margin: 0 auto;
  553. }
  554. // 修改组件样式结束
  555. .none-data {
  556. width: 150px;
  557. margin: 0 auto;
  558. padding-top: 50px;
  559. }
  560. </style>