index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. <template>
  2. <div class="app-container">
  3. <div class="dark-el-input dark-el-button">
  4. <el-form ref="queryForm" size="small" :inline="true">
  5. <el-form-item label="时间">
  6. <el-date-picker
  7. :clearable="false"
  8. v-model="dateTime"
  9. type="datetimerange"
  10. range-separator="至"
  11. start-placeholder="开始日期"
  12. end-placeholder="结束日期"
  13. :default-time="['00:00:00', '23:45:00']"
  14. popper-class="cpp-popper"
  15. :picker-options="pickerOptions"
  16. />
  17. </el-form-item>
  18. <el-form-item label="场站名称">
  19. <el-select v-model="stationCode" placeholder="请选择" popper-class="cpp-popper">
  20. <el-option
  21. v-for="item in stationList"
  22. :key="item.value"
  23. :label="item.label"
  24. :value="item.value">
  25. </el-option>
  26. </el-select>
  27. </el-form-item>
  28. <el-form-item label="预测类型">
  29. <el-select v-model="forecastType" placeholder="请选择" popper-class="cpp-popper">
  30. <el-option
  31. v-for="item in forecastTypeList"
  32. :key="item.value"
  33. :label="item.label"
  34. :value="item.value">
  35. </el-option>
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item :label="this.forecastType=='dq'?'预测D+':'预测T+'">
  39. <el-select v-model="ago" placeholder="请选择" popper-class="cpp-popper">
  40. <el-option
  41. v-for="item in this.points()"
  42. :key="item.value"
  43. :label="item.label"
  44. :value="item.value">
  45. </el-option>
  46. </el-select>
  47. </el-form-item>
  48. <el-form-item>
  49. <el-button type="primary" popper-class="cpp-popper" style="margin-left: 5px" icon="el-icon-search"
  50. @click="dataQuery">查询
  51. </el-button>
  52. </el-form-item>
  53. </el-form>
  54. </div>
  55. <div style="padding-top: 10px">
  56. <div>当前结果为:[<span style="color: #FF0000">{{ this.stationCodeInfo }}</span>发电站]-[预测<span
  57. style="color: #FF0000">{{ this.forecastTypeInfo }}</span>]-[预测<span
  58. style="color: #FF0000">{{ this.forecastTypeInfo == '短期' ? 'D+' : 'T+' }}{{ this.agoInfo }}</span>]-结果统计
  59. </div>
  60. <el-row :gutter="20" style="">
  61. <el-col :span="8">
  62. <vxe-table
  63. align="center"
  64. :loading="loading"
  65. ref="xTable"
  66. auto-resize
  67. border
  68. resizable
  69. highlight-current-row
  70. show-overflow
  71. height="700"
  72. :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
  73. :cell-class-name="cellClassName"
  74. >
  75. <vxe-table-column
  76. v-for="(item, index) in fromHead"
  77. :key="index"
  78. align="center"
  79. :title="item.label"
  80. :field="item.field"
  81. ></vxe-table-column>
  82. </vxe-table>
  83. <vxe-pager
  84. perfect
  85. :current-page.sync="currentPage"
  86. :page-size.sync="pageSize"
  87. :total="total"
  88. :page-sizes=[10,50,100]
  89. :layouts="['PrevJump', 'PrevPage','JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
  90. @page-change="handlePageChange"
  91. >
  92. </vxe-pager>
  93. </el-col>
  94. <el-col :span="16" style="margin-top: -47px">
  95. <el-row>
  96. <div style="float:left;width: 100%;height: 410px" id="zqlCharts"></div>
  97. </el-row>
  98. <el-row>
  99. <div style="float:left;width: 100%;height: 410px" id="pcCharts"></div>
  100. </el-row>
  101. </el-col>
  102. </el-row>
  103. </div>
  104. </div>
  105. </template>
  106. <script>
  107. import * as echarts from "echarts";
  108. export default {
  109. name: 'inverterinfo',
  110. data() {
  111. return {
  112. fromHead: [
  113. {
  114. label: "时间",
  115. field: "time"
  116. },
  117. {
  118. label: "准确率(%)",
  119. field: "accuracy"
  120. },
  121. {
  122. label: "单点平均偏差(cap*%)",
  123. field: "deviationSum"
  124. }
  125. ],
  126. pcChart: null,
  127. zqlChart: null,
  128. activeName: 'first',
  129. dateTime: [new Date(new Date().toLocaleDateString()).getTime() - 15 * 60 * 60 * 24 * 1000, new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000],
  130. total: 0,
  131. sortOrder: 'asc',
  132. pageSize: 10,
  133. currentPage: 1,
  134. stationList: [],
  135. stationCode: [],
  136. searchForm: {},
  137. tableData: [],
  138. nameList: [],
  139. loading: false,
  140. modId: '',//备用id
  141. lineColor: '#3b3b3b',
  142. forecastTypeList: [
  143. {
  144. label: "短期",
  145. value: "dq"
  146. },
  147. {
  148. label: "超短期",
  149. value: "cdq"
  150. }
  151. ],
  152. forecastType: "dq",
  153. ago: 1,
  154. forecastTypeInfo: "",
  155. agoInfo: "",
  156. stationCodeInfo: "",
  157. pickerOptions: {
  158. disabledDate: (time) => {
  159. return time.getTime() > new Date(new Date().toLocaleDateString()).getTime() -1
  160. }
  161. },
  162. }
  163. },
  164. created() {
  165. this.getStationCode()
  166. },
  167. mounted() {
  168. },
  169. beforeDestroy() {
  170. if (this.zqlChart) {
  171. this.zqlChart.dispose()
  172. this.zqlChart = null
  173. }
  174. if (this.pcChart) {
  175. this.pcChart.dispose()
  176. this.pcChart = null
  177. }
  178. },
  179. computed: {},
  180. methods: {
  181. cellClassName({row, rowIndex, column, columnIndex}) {
  182. if (columnIndex == 10) {
  183. if (row.cz === '—') {
  184. return "class-style-yellow"
  185. }
  186. if (row.cz != '' && row.cz != undefined && row.cz != 0) {
  187. return "class-style-red"
  188. }
  189. }
  190. },
  191. tabClick(tab) {
  192. if (this.activeName == 'second') {
  193. this.$nextTick(function () {
  194. this.wsChart.resize();
  195. })
  196. }
  197. },
  198. nameFormat({cellValue, row, column}) {
  199. const item = this.nameList.find(item => item.value === cellValue)
  200. return item ? item.label : ''
  201. },
  202. stationCodeFormat({cellValue, row, column}) {
  203. const item = this.stationList.find(item => item.value === cellValue)
  204. return item ? item.label : ''
  205. },
  206. handlePageChange({currentPage, pageSize}) {
  207. this.currentPage = currentPage
  208. this.pageSize = pageSize
  209. },
  210. async dataQuery() {
  211. let startTime = Math.round(this.dateTime[0])
  212. let endTime = Math.round(this.dateTime[1])
  213. if (endTime <= startTime) {
  214. this.$message.warning("开始时间不能大于结束时间")
  215. return
  216. }
  217. if (endTime - startTime > 60 * 60 * 24 * 1000 * 30) {
  218. this.$message.warning("查询数据不能超过30天!")
  219. return
  220. }
  221. let queryParams = {
  222. "stationCode": this.stationCode,
  223. "startTime": startTime,
  224. "endTime": endTime,
  225. "forecastType": this.forecastType,
  226. "dataSources": 'E4',
  227. "forecastModel": '',
  228. "ago": this.ago
  229. }
  230. this.loading = true
  231. this.$axios.get('/accuracyPassRate/getByTimeBetweenAndForecastTypeAndDataSourcesAndForecastModelAndStationCode', {params: queryParams}).then(response => {
  232. this.agoInfo = this.points().filter(s => s.value == this.ago)[0].label
  233. this.forecastTypeInfo = this.forecastTypeList.filter(s => s.value == this.forecastType)[0].label
  234. this.stationCodeInfo = this.stationList.filter(s => s.value == this.stationCode)[0].label
  235. this.tableData = response.data
  236. this.total = response.data.length
  237. let times = []
  238. let pcDatas = []
  239. let zqlDatas = []
  240. console.log(this.tableData)
  241. this.tableData.forEach(t => {
  242. times.push(t.time)
  243. zqlDatas.push(t.accuracy.replace("%", ""))
  244. pcDatas.push(t.deviationSum == null ? "" : t.deviationSum.replace("%", ""))
  245. })
  246. this.pcDraw(times, pcDatas)
  247. this.zqlDraw(times, zqlDatas)
  248. this.loading = false
  249. }).catch(() => {
  250. this.loading = false
  251. })
  252. },
  253. getStationCode() {
  254. this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
  255. this.stationList = response.data
  256. if (this.stationList.length > 0) {
  257. this.stationCode = this.stationList[0].value
  258. this.dataQuery()
  259. }
  260. })
  261. },
  262. zqlDraw(times, datas) {
  263. this.zqlChart = echarts.init(document.getElementById('zqlCharts'), "dark", {renderer: 'svg'})
  264. let option = {
  265. backgroundColor: 'transparent',
  266. title: {
  267. top: 20,
  268. text: '准确率(%)',
  269. textStyle: {
  270. fontWeight: 'normal',
  271. fontSize: 16,
  272. // //color: this.lineColor
  273. },
  274. left: '1%'
  275. },
  276. tooltip: {
  277. trigger: 'axis',
  278. axisPointer: {
  279. lineStyle: {
  280. color: '#57617B'
  281. }
  282. }
  283. },
  284. legend: {
  285. top: 20,
  286. width: '70%',
  287. icon: 'rect',
  288. itemWidth: 14,
  289. itemHeight: 5,
  290. itemGap: 13,
  291. data: ["准确率(%)"],
  292. right: '4%',
  293. textStyle: {
  294. fontSize: 12,
  295. // //color: this.lineColor
  296. },
  297. selected: {}
  298. },
  299. dataZoom: [{
  300. show: true,
  301. realtime: true,
  302. start: 0,
  303. end: 100,
  304. top: "90%",
  305. left: "15%",
  306. right: "15%",
  307. textStyle: {
  308. // //color: this.lineColor
  309. }
  310. }, {
  311. type: 'inside'
  312. }],
  313. grid: {
  314. top: 100,
  315. left: '3%',
  316. right: '3%',
  317. bottom: '10%',
  318. containLabel: true
  319. },
  320. xAxis: [{
  321. type: 'category',
  322. boundaryGap: false,
  323. axisLine: {
  324. lineStyle: {
  325. //color: this.lineColor
  326. }
  327. },
  328. data: times
  329. }],
  330. yAxis: [{
  331. type: 'value',
  332. name: '%',
  333. max: 100,
  334. min: 0,
  335. axisTick: {
  336. show: false
  337. },
  338. axisLine: {
  339. lineStyle: {
  340. //color: this.lineColor
  341. }
  342. },
  343. axisLabel: {
  344. margin: 10,
  345. textStyle: {
  346. fontSize: 14,
  347. //color: this.lineColor
  348. },
  349. formatter: '{value}',
  350. },
  351. splitLine: {
  352. lineStyle: {
  353. color: '#57617B'
  354. }
  355. }
  356. }],
  357. series: [
  358. {
  359. name: '准确率(%)',
  360. type: 'line',
  361. smooth: false,
  362. symbol: 'circle',
  363. symbolSize: 5,
  364. showSymbol: true,
  365. lineStyle: {
  366. normal: {
  367. width: 2
  368. }
  369. },
  370. markLine: {
  371. silent: true,
  372. itemStyle: {
  373. normal: {
  374. show: true,
  375. color: 'red'
  376. }
  377. },
  378. data: [{
  379. label: {
  380. position: 'start',
  381. formatter: "标准线"
  382. },
  383. yAxis: 75
  384. }]
  385. },
  386. itemStyle: {
  387. normal: {
  388. color: 'rgb(213,219,50)',
  389. borderColor: 'rgba(16,217,16,0.96)',
  390. borderWidth: 12
  391. }
  392. },
  393. data: datas
  394. }
  395. ]
  396. }
  397. this.zqlChart.setOption(option, true)
  398. var _this = this
  399. window.addEventListener("resize", function () {
  400. _this.zqlChart.resize();
  401. });
  402. },
  403. pcDraw(times, datas) {
  404. this.pcChart = echarts.init(document.getElementById('pcCharts'), "dark", {renderer: 'svg'})
  405. let option = {
  406. backgroundColor: 'transparent',
  407. title: {
  408. top: 20,
  409. text: '单点平均偏差(cap*%)',
  410. textStyle: {
  411. fontWeight: 'normal',
  412. fontSize: 16,
  413. //color: this.lineColor
  414. },
  415. left: '1%'
  416. },
  417. tooltip: {
  418. trigger: 'axis',
  419. axisPointer: {
  420. lineStyle: {
  421. color: '#57617B'
  422. }
  423. }
  424. },
  425. legend: {
  426. top: 20,
  427. width: '70%',
  428. icon: 'rect',
  429. itemWidth: 14,
  430. itemHeight: 5,
  431. itemGap: 13,
  432. data: ["单点平均偏差(cap*%)"],
  433. right: '4%',
  434. textStyle: {
  435. fontSize: 12,
  436. //color: this.lineColor
  437. },
  438. selected: {}
  439. },
  440. dataZoom: [{
  441. show: true,
  442. realtime: true,
  443. start: 0,
  444. end: 100,
  445. left: "15%",
  446. right: "15%",
  447. top: "90%",
  448. textStyle: {
  449. //color: this.lineColor
  450. }
  451. }, {
  452. type: 'inside'
  453. }],
  454. grid: {
  455. top: 100,
  456. left: '3%',
  457. right: '3%',
  458. bottom: '10%',
  459. containLabel: true
  460. },
  461. xAxis: [{
  462. type: 'category',
  463. boundaryGap: false,
  464. axisLine: {
  465. lineStyle: {
  466. //color: this.lineColor
  467. }
  468. },
  469. data: times
  470. }],
  471. yAxis: [{
  472. type: 'value',
  473. name: 'cap*h',
  474. axisTick: {
  475. show: false
  476. },
  477. axisLine: {
  478. lineStyle: {
  479. //color: this.lineColor
  480. }
  481. },
  482. axisLabel: {
  483. margin: 10,
  484. textStyle: {
  485. fontSize: 14,
  486. //color: this.lineColor
  487. },
  488. formatter: '{value}',
  489. },
  490. splitLine: {
  491. lineStyle: {
  492. color: '#57617B'
  493. }
  494. }
  495. }],
  496. series: [
  497. {
  498. name: '单点平均偏差(cap*%)',
  499. type: 'line',
  500. smooth: false,
  501. symbol: 'circle',
  502. symbolSize: 5,
  503. showSymbol: true,
  504. lineStyle: {
  505. normal: {
  506. width: 2
  507. }
  508. },
  509. itemStyle: {
  510. normal: {
  511. color: 'rgb(140,50,219)',
  512. borderColor: 'rgba(140,50,219,0.2)',
  513. borderWidth: 12
  514. }
  515. },
  516. data: datas
  517. }
  518. ]
  519. }
  520. this.pcChart.setOption(option, true)
  521. var _this = this
  522. window.addEventListener("resize", function () {
  523. _this.pcChart.resize();
  524. });
  525. },
  526. points() {
  527. let points = []
  528. if (this.forecastType == 'dq') {
  529. for (let i = 1; i < 11; i++) {
  530. points.push({label: i + "", value: i})
  531. }
  532. } else {
  533. for (let i = 1; i < 17; i++) {
  534. points.push({label: i + "", value: i})
  535. }
  536. }
  537. return points
  538. }
  539. },
  540. }
  541. </script>
  542. <style scoped>
  543. /* //然后给对应的单元格样式 */
  544. >>> .vxe-table .vxe-body--row .vxe-body--column.class-style-yellow {
  545. background-color: #FFFF00;
  546. }
  547. >>> .vxe-table .vxe-body--row .vxe-body--column.class-style-red {
  548. background-color: #FF0000;
  549. color: #ffffff;
  550. }
  551. </style>
  552. <!--&gt;>>.vxe-table .vxe-body&#45;&#45;row .vxe-body&#45;&#45;column.class-style .vxe-cell .vxe-cell&#45;&#45;label{-->