predictionA.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <div class="main">
  3. <div class="main_in">
  4. <weatherTitle2 :title="title.titleText" :title2="title.pageTitle"></weatherTitle2>
  5. <div>
  6. <div ref="prediction" style="width: 100%; height: 360px"></div>
  7. </div>
  8. </div>
  9. </div>
  10. </template>
  11. <script lang="ts" setup>
  12. import { toRef, ref, getCurrentInstance, onMounted } from 'vue';
  13. import eventBus from '/@/utils/eventBus';
  14. import weatherTitle2 from '../../../components/Title/weatherTitle2.vue';
  15. const jump = () => {
  16. eventBus.emit('mapjump', props.title);
  17. };
  18. let activeKey = ref('1');
  19. //组件传参
  20. const props = defineProps({
  21. title: { type: Object },
  22. nodeId: { type: String },
  23. predictionData: {
  24. type: Object,
  25. default: () => {
  26. return {};
  27. },
  28. },
  29. });
  30. let datas = toRef(props, 'predictionData');
  31. // // 计算最大值
  32. function getMaxValue(arr) {
  33. const max = Math.max(...arr);
  34. // 这样处理是为了不让最大值刚好到坐标轴最顶部
  35. return Math.ceil(max / 9.5) * 10;
  36. }
  37. // 计算最小值
  38. function getMinValue(arr) {
  39. const min = Math.min(...arr);
  40. // 这样处理是为了不让最大值刚好到坐标轴最底部
  41. return Math.floor(min / 12) * 10;
  42. }
  43. // 引入图表插件
  44. const { proxy } = getCurrentInstance();
  45. const echarts = proxy.$echarts;
  46. let prediction = ref(null);
  47. function echarts1() {
  48. let maxList = [...props.predictionData.qs, ...props.predictionData.qf];
  49. let max1 = getMaxValue(maxList) * 2;
  50. let min1 = getMinValue(maxList),
  51. max2 = getMaxValue(props.predictionData.rain) * 2;
  52. let min2 = getMinValue(props.predictionData.rain);
  53. const chart = echarts.init(prediction.value);
  54. var option;
  55. option = {
  56. tooltip: {
  57. trigger: 'axis',
  58. axisPointer: {
  59. type: 'cross',
  60. animation: false,
  61. label: {
  62. backgroundColor: '#505765',
  63. },
  64. },
  65. formatter(params) {
  66. var relVal = params[0].name;
  67. for (var i = 0, l = params.length; i < l; i++) {
  68. console.log('tooltip数据值', params[i].value)
  69. //遍历出来的值一般是字符串,需要转换成数字,再进项tiFixed四舍五入
  70. // relVal += '<br/>' + params[i].marker + params[i].seriesName + ' : ' + params[i].value == '--'? Number(params[i].value) : params[i].value
  71. relVal += `<br/>${params[i].marker}${params[i].seriesName} : ${params[i].value == '--' ? params[i].value : Number(params[i].value)}`
  72. }
  73. return relVal;
  74. },
  75. },
  76. dataZoom: [
  77. {
  78. // 这个dataZoom组件,默认控制x轴。
  79. type: 'inside', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
  80. },
  81. {
  82. // 这个dataZoom组件,也控制x轴。
  83. type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
  84. },
  85. ],
  86. legend: {
  87. data: ['实测流量', '预测流量', '降雨'],
  88. textStyle: {
  89. fontSize: 12, //字体大小
  90. color: '#ffffff', //字体颜色
  91. },
  92. },
  93. xAxis: [
  94. {
  95. show: false,
  96. data: props.predictionData.name,
  97. axisLabel: {
  98. show: true,
  99. textStyle: {
  100. color: '#ffffff',
  101. },
  102. formatter: function (val) {
  103. var strs = val.split(''); //字符串数组
  104. var str = '';
  105. for (var i = 0, s; (s = strs[i++]);) {
  106. //遍历字符串数组
  107. if (i > 5 && i < 17) {
  108. str += s;
  109. }
  110. if (!(i % 10)) str += '\n'; //按需要求余
  111. }
  112. return str;
  113. },
  114. },
  115. },
  116. {
  117. data: props.predictionData.name,
  118. gridIndex: 1,
  119. axisLabel: {
  120. show: true,
  121. textStyle: {
  122. color: '#ffffff',
  123. },
  124. formatter: function (val) {
  125. var strs = val.split(''); //字符串数组
  126. var str = '';
  127. for (var i = 0, s; (s = strs[i++]);) {
  128. //遍历字符串数组
  129. if (i > 5 && i < 17) {
  130. str += s;
  131. }
  132. if (!(i % 10)) str += '\n'; //按需要求余
  133. }
  134. return str;
  135. },
  136. },
  137. },
  138. ],
  139. yAxis: [
  140. {
  141. position: 'right',
  142. name: '降雨(mm)',
  143. nameLocation: 'start',
  144. axisLabel: {
  145. textStyle: {
  146. color: '#ffffff',
  147. },
  148. formatter: function (value) {
  149. return value.toFixed(1) + '';
  150. },
  151. },
  152. nameTextStyle: {
  153. color: '#fff',
  154. fontSize: 12,
  155. },
  156. splitLine: {
  157. lineStyle: {
  158. type: 'dashed', //虚线
  159. color: '#484849',
  160. },
  161. },
  162. inverse: true,
  163. scale: true,
  164. },
  165. {
  166. // position: 'right',
  167. name: '流量(m³/s)',
  168. gridIndex: 1,
  169. axisLabel: {
  170. textStyle: {
  171. color: '#ffffff',
  172. },
  173. formatter: function (value) {
  174. if (value < 100) {
  175. return value.toPrecision(3)
  176. } else {
  177. return Number(value.toPrecision(3))
  178. }
  179. },
  180. },
  181. nameTextStyle: {
  182. color: '#fff',
  183. fontSize: 12,
  184. },
  185. formatter: function (value) {
  186. if (value < 100) {
  187. return value.toPrecision(3)
  188. } else {
  189. return Number(value.toPrecision(3))
  190. }
  191. },
  192. splitLine: {
  193. lineStyle: {
  194. type: 'dashed', //虚线
  195. color: '#484849',
  196. },
  197. },
  198. scale: true,
  199. min: function (value) {
  200. return value.min - value.min * 0.01;
  201. },
  202. max: function (value) {
  203. return value.max + value.max * 0.01;
  204. }
  205. },
  206. ],
  207. grid: [
  208. {
  209. bottom: '65%',
  210. left: '50',
  211. right: '50',
  212. },
  213. {
  214. top: '45%',
  215. left: '50',
  216. right: '50',
  217. bottom: '40',
  218. },
  219. ],
  220. series: [
  221. {
  222. name: '降雨',
  223. data: props.predictionData.rain,
  224. type: 'bar',
  225. barWidth: 5, // 设置每个柱子的宽度为40
  226. showSymbol: false,
  227. lineStyle: {
  228. width: 1,
  229. },
  230. itemStyle: {
  231. color: '#00CB98',
  232. },
  233. emphasis: {
  234. focus: 'series',
  235. },
  236. itemStyle: {
  237. normal: {
  238. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  239. offset: 0,
  240. color: 'rgba(14, 133, 225, 1)' // 0% 处的颜色
  241. }, {
  242. offset: 1,
  243. color: 'rgba(18, 196, 255, 1)' // 100% 处的颜色
  244. }], false),
  245. barBorderRadius: [30, 30, 30, 30],
  246. // shadowColor: 'rgba(0,160,221,1)',
  247. shadowBlur: 4,
  248. }
  249. },
  250. },
  251. {
  252. name: '实测流量',
  253. smooth: true,
  254. type: 'line',
  255. showSymbol: false,
  256. data: props.predictionData.qs,
  257. xAxisIndex: 1,
  258. yAxisIndex: 1,
  259. itemStyle: {
  260. color: `rgba(0, 243, 143, 1)`
  261. }
  262. },
  263. {
  264. name: '预测流量',
  265. type: 'line',
  266. showSymbol: false,
  267. smooth: true,
  268. data: props.predictionData.qf,
  269. xAxisIndex: 1,
  270. yAxisIndex: 1,
  271. lineStyle: {
  272. type: 'dashed', // 设置为虚线
  273. color: `rgba(255, 187, 41, 1)`
  274. }
  275. },
  276. ],
  277. };
  278. option && chart.setOption(option);
  279. }
  280. onMounted(() => {
  281. echarts1();
  282. });
  283. </script>
  284. <style lang="less" scoped>
  285. .main {
  286. margin-bottom: 10px;
  287. box-sizing: border-box;
  288. padding: 2px;
  289. border-radius: 0px 30px 0px 30px;
  290. // 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%);
  291. }
  292. .main_in {
  293. width: 100%;
  294. height: 100%;
  295. border-radius: 0px 30px 0px 30px;
  296. // background: rgba(6, 37, 70, 0.9);
  297. }
  298. .sub-title {
  299. cursor: pointer;
  300. text-align: left;
  301. padding-left: 20px;
  302. padding-top: 10px;
  303. padding-bottom: 0px;
  304. color: #dffeff;
  305. font-size: 18px;
  306. span {
  307. background: linear-gradient(0deg, #fbf70e 0%, #f4af10 100%);
  308. -webkit-background-clip: text;
  309. -webkit-text-fill-color: transparent;
  310. background-clip: text;
  311. text-fill-color: transparent;
  312. }
  313. }
  314. </style>