Gzqdtqyb.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <div>
  3. <Title title="天气预报">
  4. <template v-slot:title-slot>
  5. <div class="slot-unit">单位:{{unit}}</div>
  6. </template>
  7. </Title>
  8. <div class="tabs yse-events">
  9. <div class="lbtn"><div class="text" :key="btnIndex" :class="getActive(1)" @click="change(1)">温度</div></div>
  10. <div class="btn"><div class="text" :key="btnIndex" :class="getActive(2)" @click="change(2)">湿度</div></div>
  11. <div class="btn"><div class="text" :key="btnIndex" :class="getActive(3)" @click="change(3)">降雨</div></div>
  12. <div class="rbtn"><div class="text" :key="btnIndex" :class="getActive(4)" @click="change(4)">光照</div></div>
  13. </div>
  14. <div ref="chartDom" class="content-box yse-events"></div>
  15. </div>
  16. </template>
  17. <script setup>
  18. import Highcharts from 'highcharts/highstock';
  19. import HighchartsMore from 'highcharts/highcharts-more';
  20. import HighchartsDrilldown from 'highcharts/modules/drilldown';
  21. import Highcharts3D from 'highcharts/highcharts-3d';
  22. import Highmaps from 'highcharts/modules/map';
  23. import {onMounted, ref, watch} from "vue";
  24. import {useStore} from "vuex";
  25. import Title from "../../../components/title";
  26. //初始化Highcharts
  27. HighchartsMore(Highcharts)
  28. HighchartsDrilldown(Highcharts);
  29. Highcharts3D(Highcharts);
  30. Highmaps(Highcharts);
  31. let state = useStore().state;
  32. let chartDom = ref(null);
  33. const btnIndex = ref(null);
  34. const mychat = ref(null);
  35. const unit = ref("")
  36. const weather7D = ref(null)
  37. function getActive(index){
  38. return btnIndex.value == index ? "active" : "";
  39. }
  40. function change(index) {
  41. btnIndex.value = index;
  42. switch (index) {
  43. case 1:
  44. init1();
  45. break;
  46. case 2:
  47. init2();
  48. break;
  49. case 3:
  50. init3();
  51. break;
  52. case 4:
  53. init4();
  54. break;
  55. }
  56. }
  57. onMounted(async () => {
  58. await initWeather()
  59. change(1)
  60. })
  61. const options = {
  62. tooltip:{
  63. useHTML:true,
  64. backgroundColor:"#00000000",
  65. formatter:function(){
  66. let {name,unit} = this.series.userOptions;
  67. return "<div class='tooltip1'><div>"+this.x+"</div><div>" + name + this.y+ unit +"</div></div>"
  68. }
  69. },
  70. chart: {
  71. backgroundColor:"#ffffff00",
  72. type: 'areaspline',
  73. },
  74. title: {
  75. text: null
  76. },
  77. credits: {
  78. enabled:false,
  79. },
  80. xAxis: {
  81. gridLineWidth: 1,
  82. type: 'datetime',
  83. gridLineColor:"#e6e6e630",
  84. categories: ['04-28', '04-29', '04-30', '05-01','05-02','05-03', '05-04'],
  85. labels: {
  86. style: {
  87. color: '#fff',
  88. fontSize:'11px',
  89. fontWeight: 400,
  90. fontFamily:'PingFangSC-Regular, PingFang SC'
  91. }
  92. },
  93. },
  94. yAxis: {
  95. min: 0,
  96. title: null,
  97. gridLineWidth: 1,
  98. gridLineColor:"#e6e6e630",
  99. labels: {
  100. format:"{value}",
  101. style: {
  102. color: '#fff',
  103. fontSize:'11px',
  104. fontWeight: 400,
  105. fontFamily:'PingFangSC-Regular, PingFang SC'
  106. }
  107. },
  108. },
  109. legend: {
  110. /* 图例显示顺序反转
  111. * 这是因为堆叠的顺序默认是反转的,可以设置
  112. * yAxis.reversedStacks = false 来达到类似的效果
  113. */
  114. enabled:false,
  115. reversed: true,
  116. padding:0,
  117. itemStyle: {
  118. color: '#fff',
  119. fontFamily:'ArialMT'
  120. }
  121. },
  122. plotOptions: {
  123. areaspline: {
  124. marker: {
  125. radius: 0
  126. },
  127. lineWidth: 0,
  128. states: {
  129. hover: {
  130. lineWidth: 0
  131. }
  132. },
  133. threshold: null
  134. }
  135. },
  136. series: []
  137. }
  138. function setPer(data){
  139. let sum = 0;
  140. for(let i of data){
  141. sum = sum + i;
  142. }
  143. let res = new Array()
  144. for(let i of data){
  145. res.push({val:i, y : parseInt((i / sum * 100).toFixed(0))});
  146. }
  147. return res;
  148. }
  149. async function initWeather(){
  150. let {code,data} = await VE_API.system.weather();
  151. weather7D.value = data.daily;
  152. }
  153. function init1() {
  154. unit.value = "C°"
  155. let data = weather7D.value;
  156. let categories = [];
  157. let seritsData1 = [];
  158. let seritsData2 = [];
  159. data.forEach((item)=>{
  160. categories.push(item.fxDate.substring(5,10))
  161. seritsData1.push(parseFloat(item.tempMax))
  162. seritsData2.push(parseFloat(item.tempMin))
  163. })
  164. options.xAxis.categories = categories;
  165. options.series = [{
  166. name:"最高气温",
  167. unit:"C°",
  168. data: seritsData1,
  169. fillColor: {
  170. linearGradient: {
  171. x1: 0,
  172. y1: 0,
  173. x2: 0,
  174. y2: 1
  175. },
  176. stops: [
  177. [0, '#F35600'], // start
  178. [1, '#F3A90000'], // middle
  179. ]
  180. },
  181. },{
  182. name:"最低气温",
  183. unit:"C°",
  184. data: seritsData2,
  185. fillColor: {
  186. linearGradient: {
  187. x1: 0,
  188. y1: 0,
  189. x2: 0,
  190. y2: 1
  191. },
  192. stops: [
  193. [0, '#F3A90080'], // middle
  194. [0.5, '#F3A90080'], // middle
  195. [1, '#00E9E370'] // end
  196. ]
  197. },
  198. }];
  199. mychat.value = new Highcharts.Chart(chartDom.value, options);
  200. }
  201. function init2() {
  202. unit.value = "%rh"
  203. let data = weather7D.value;
  204. let categories = [];
  205. let seritsData1 = [];
  206. data.forEach((item)=>{
  207. categories.push(item.fxDate.substring(5,10))
  208. seritsData1.push(parseFloat(item.humidity))
  209. })
  210. options.xAxis.categories = categories;
  211. options.series = [{
  212. name:"湿度",
  213. unit:"%rh",
  214. data: seritsData1,
  215. fillColor: {
  216. linearGradient: {
  217. x1: 0,
  218. y1: 0,
  219. x2: 0,
  220. y2: 1
  221. },
  222. stops: [
  223. [0, '#0c45ee90'], // middle
  224. [0.5, '#46dee390'], // middle
  225. [1, '#e9af0090'] // end
  226. ]
  227. },
  228. }];
  229. mychat.value = new Highcharts.Chart(chartDom.value, options);
  230. }
  231. function init3() {
  232. unit.value = "mm"
  233. let data = weather7D.value;
  234. let categories = [];
  235. let seritsData1 = [];
  236. data.forEach((item)=>{
  237. categories.push(item.fxDate.substring(5,10))
  238. seritsData1.push(parseFloat(item.precip))
  239. })
  240. options.xAxis.categories = categories;
  241. options.series = [{
  242. name:"降雨量",
  243. unit:"mm",
  244. data: seritsData1,
  245. fillColor: {
  246. linearGradient: {
  247. x1: 0,
  248. y1: 0,
  249. x2: 0,
  250. y2: 1
  251. },
  252. stops: [
  253. [0, '#0c45ee90'], // middle
  254. [0.5, '#46dee390'], // middle
  255. [1, '#e9af0090'] // end
  256. ]
  257. },
  258. }];
  259. mychat.value = new Highcharts.Chart(chartDom.value, options);
  260. }
  261. function init4() {
  262. unit.value = "LX"
  263. let data = weather7D.value;
  264. let categories = [];
  265. let seritsData1 = [];
  266. data.forEach((item)=>{
  267. categories.push(item.fxDate.substring(5,10))
  268. seritsData1.push(parseFloat(item.uvIndex))
  269. })
  270. options.xAxis.categories = categories;
  271. options.series = [{
  272. name:"照度",
  273. unit:"LX",
  274. data: seritsData1,
  275. fillColor: {
  276. linearGradient: {
  277. x1: 0,
  278. y1: 0,
  279. x2: 0,
  280. y2: 1
  281. },
  282. stops: [
  283. [0, '#f3008690'], // middle
  284. [0.5, '#F3A90080'], // middle
  285. [1, '#00E9E370'] // end
  286. ]
  287. },
  288. }];
  289. mychat.value = new Highcharts.Chart(chartDom.value, options);
  290. }
  291. </script>
  292. <style lang="scss" scoped>
  293. .tabs{
  294. position: absolute;
  295. top:25%;
  296. width:100%;
  297. z-index: 3;
  298. display: flex;
  299. flex-direction: row;
  300. justify-content: center;
  301. align-items: center;
  302. .text{
  303. text-align: center;
  304. width: 88px;
  305. height: 38px;
  306. line-height: 38px;
  307. font-size: 14px;
  308. font-family: PingFangSC-Regular, PingFang SC;
  309. font-weight: 400;
  310. color: #B4FFFB;
  311. }
  312. .lbtn{
  313. cursor: pointer;
  314. background-image: url(@/assets/img/left_btn.png);
  315. background-repeat: no-repeat;
  316. background-size: 100% 100%;
  317. width: 88px;
  318. height: 38px;
  319. .active{
  320. width: 88px;
  321. height: 38px;
  322. background-image: url(@/assets/img/left_btn_active.png);
  323. background-repeat: no-repeat;
  324. background-size: 100% 100%;
  325. }
  326. }
  327. .btn{
  328. cursor: pointer;
  329. background-image: url(@/assets/img/center_btn.png);
  330. background-repeat: no-repeat;
  331. background-size: 100% 100%;
  332. width: 88px;
  333. height: 38px;
  334. .active{
  335. width: 88px;
  336. height: 36px;
  337. background: rgba(3,44,57,0.8);
  338. box-shadow: inset 0px 0px 20px 4px rgba(0,255,240,0.5);
  339. border-radius: 0px 0px 0px 0px;
  340. border: 1px solid #51E9F0;
  341. }
  342. }
  343. .rbtn{
  344. background-image: url(@/assets/img/right_btn.png);
  345. background-repeat: no-repeat;
  346. background-size: 100% 100%;
  347. width: 88px;
  348. height: 38px;
  349. cursor: pointer;
  350. .active{
  351. width: 88px;
  352. height: 38px;
  353. background-image: url(@/assets/img/right_btn_active.png);
  354. background-repeat: no-repeat;
  355. background-size: 100% 100%;
  356. }
  357. }
  358. }
  359. .content-box{
  360. position: absolute;
  361. width: 100%;
  362. height: calc(75% - 48px + 15px);
  363. bottom: -10px;
  364. }
  365. .slot-unit{
  366. color: #f0f0f0;
  367. text-align: right;
  368. padding: 10px;
  369. width: 100%;
  370. }
  371. </style>