index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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" @change="forecastType=='dq'?ago=1:ago=8">
  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. this.tableData.forEach(t => {
  241. times.push(t.time)
  242. zqlDatas.push(t.accuracy.replace("%", ""))
  243. pcDatas.push(t.deviationSum == null ? "" : t.deviationSum.replace("%", ""))
  244. })
  245. this.pcDraw(times, pcDatas)
  246. this.zqlDraw(times, zqlDatas,this.forecastType)
  247. this.loading = false
  248. }).catch(() => {
  249. this.loading = false
  250. })
  251. },
  252. getStationCode() {
  253. this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
  254. this.stationList = response.data
  255. if (this.stationList.length > 0) {
  256. this.stationCode = this.stationList[0].value
  257. this.dataQuery()
  258. }
  259. })
  260. },
  261. zqlDraw(times, datas,forecastType) {
  262. this.zqlChart = echarts.init(document.getElementById('zqlCharts'), "dark", {renderer: 'svg'})
  263. let option = {
  264. backgroundColor: 'transparent',
  265. title: {
  266. top: 20,
  267. text: '准确率(%)',
  268. textStyle: {
  269. fontWeight: 'normal',
  270. fontSize: 16,
  271. // //color: this.lineColor
  272. },
  273. left: '1%'
  274. },
  275. tooltip: {
  276. trigger: 'axis',
  277. axisPointer: {
  278. lineStyle: {
  279. color: '#57617B'
  280. }
  281. }
  282. },
  283. legend: {
  284. top: 20,
  285. width: '70%',
  286. icon: 'rect',
  287. itemWidth: 14,
  288. itemHeight: 5,
  289. itemGap: 13,
  290. data: ["准确率(%)"],
  291. right: '4%',
  292. textStyle: {
  293. fontSize: 12,
  294. // //color: this.lineColor
  295. },
  296. selected: {}
  297. },
  298. dataZoom: [{
  299. show: true,
  300. realtime: true,
  301. start: 0,
  302. end: 100,
  303. top: "90%",
  304. left: "15%",
  305. right: "15%",
  306. textStyle: {
  307. // //color: this.lineColor
  308. }
  309. }, {
  310. type: 'inside'
  311. }],
  312. grid: {
  313. top: '12%',
  314. left: '3%',
  315. right: '4%',
  316. bottom: '10%',
  317. containLabel: true
  318. },
  319. xAxis: [{
  320. type: 'category',
  321. boundaryGap: false,
  322. axisLine: {
  323. lineStyle: {
  324. //color: this.lineColor
  325. }
  326. },
  327. data: times
  328. }],
  329. yAxis: [{
  330. type: 'value',
  331. // name: '%',
  332. max: 100,
  333. min: 0,
  334. axisTick: {
  335. show: false
  336. },
  337. axisLine: {
  338. lineStyle: {
  339. //color: this.lineColor
  340. }
  341. },
  342. axisLabel: {
  343. margin: 10,
  344. textStyle: {
  345. fontSize: 14,
  346. //color: this.lineColor
  347. },
  348. formatter: '{value}',
  349. },
  350. splitLine: {
  351. lineStyle: {
  352. color: '#57617B'
  353. }
  354. }
  355. }],
  356. }
  357. if (forecastType === 'cdq'){
  358. option.series=[
  359. {
  360. name: '准确率(%)',
  361. type: 'line',
  362. smooth: false,
  363. symbol: 'circle',
  364. symbolSize: 5,
  365. showSymbol: true,
  366. lineStyle: {
  367. normal: {
  368. width: 2
  369. }
  370. },
  371. markLine: {
  372. silent: true,
  373. itemStyle: {
  374. normal: {
  375. show: true,
  376. color: 'red'
  377. }
  378. },
  379. data: [{
  380. label: {
  381. position: 'start',
  382. formatter: "合格(75%)"
  383. },
  384. yAxis: 75
  385. }]
  386. },
  387. itemStyle: {
  388. normal: {
  389. color: 'rgb(213,219,50)',
  390. borderColor: 'rgba(16,217,16,0.96)',
  391. borderWidth: 12
  392. }
  393. },
  394. data: datas
  395. }
  396. ]
  397. }else {
  398. option.series= [
  399. {
  400. name: '准确率(%)',
  401. type: 'line',
  402. smooth: false,
  403. symbol: 'circle',
  404. symbolSize: 5,
  405. showSymbol: true,
  406. lineStyle: {
  407. normal: {
  408. width: 2
  409. }
  410. },
  411. markLine: {
  412. silent: true,
  413. itemStyle: {
  414. normal: {
  415. show: true,
  416. color: 'red'
  417. }
  418. },
  419. },
  420. itemStyle: {
  421. normal: {
  422. color: 'rgb(213,219,50)',
  423. borderColor: 'rgba(16,217,16,0.96)',
  424. borderWidth: 12
  425. }
  426. },
  427. data: datas
  428. }
  429. ]
  430. }
  431. this.zqlChart.setOption(option, true)
  432. var _this = this
  433. window.addEventListener("resize", function () {
  434. _this.zqlChart.resize();
  435. });
  436. },
  437. pcDraw(times, datas) {
  438. this.pcChart = echarts.init(document.getElementById('pcCharts'), "dark", {renderer: 'svg'})
  439. let option = {
  440. backgroundColor: 'transparent',
  441. title: {
  442. top: 20,
  443. text: '单点平均偏差(cap*%)',
  444. textStyle: {
  445. fontWeight: 'normal',
  446. fontSize: 16,
  447. //color: this.lineColor
  448. },
  449. left: '1%'
  450. },
  451. tooltip: {
  452. trigger: 'axis',
  453. axisPointer: {
  454. lineStyle: {
  455. color: '#57617B'
  456. }
  457. }
  458. },
  459. legend: {
  460. top: 20,
  461. width: '70%',
  462. icon: 'rect',
  463. itemWidth: 14,
  464. itemHeight: 5,
  465. itemGap: 13,
  466. data: ["单点平均偏差(cap*%)"],
  467. right: '4%',
  468. textStyle: {
  469. fontSize: 12,
  470. //color: this.lineColor
  471. },
  472. selected: {}
  473. },
  474. dataZoom: [{
  475. show: true,
  476. realtime: true,
  477. start: 0,
  478. end: 100,
  479. left: "15%",
  480. right: "15%",
  481. top: "90%",
  482. textStyle: {
  483. //color: this.lineColor
  484. }
  485. }, {
  486. type: 'inside'
  487. }],
  488. grid: {
  489. top: 100,
  490. left: '4%',
  491. right: '4%',
  492. bottom: '10%',
  493. containLabel: true
  494. },
  495. xAxis: [{
  496. type: 'category',
  497. boundaryGap: false,
  498. axisLine: {
  499. lineStyle: {
  500. //color: this.lineColor
  501. }
  502. },
  503. data: times
  504. }],
  505. yAxis: [{
  506. type: 'value',
  507. name: 'cap*h',
  508. axisTick: {
  509. show: false
  510. },
  511. axisLine: {
  512. lineStyle: {
  513. //color: this.lineColor
  514. }
  515. },
  516. axisLabel: {
  517. margin: 10,
  518. textStyle: {
  519. fontSize: 14,
  520. //color: this.lineColor
  521. },
  522. formatter: '{value}',
  523. },
  524. splitLine: {
  525. lineStyle: {
  526. color: '#57617B'
  527. }
  528. }
  529. }],
  530. series: [
  531. {
  532. name: '单点平均偏差(cap*%)',
  533. type: 'line',
  534. smooth: false,
  535. symbol: 'circle',
  536. symbolSize: 5,
  537. showSymbol: true,
  538. lineStyle: {
  539. normal: {
  540. width: 2
  541. }
  542. },
  543. itemStyle: {
  544. normal: {
  545. color: 'rgb(140,50,219)',
  546. borderColor: 'rgba(140,50,219,0.2)',
  547. borderWidth: 12
  548. }
  549. },
  550. data: datas
  551. }
  552. ]
  553. }
  554. this.pcChart.setOption(option, true)
  555. var _this = this
  556. window.addEventListener("resize", function () {
  557. _this.pcChart.resize();
  558. });
  559. },
  560. points() {
  561. let points = []
  562. if (this.forecastType == 'dq') {
  563. for (let i = 1; i < 11; i++) {
  564. points.push({label: i + "", value: i})
  565. }
  566. } else {
  567. for (let i = 1; i < 17; i++) {
  568. points.push({label: i + "", value: i})
  569. }
  570. }
  571. return points
  572. }
  573. },
  574. }
  575. </script>
  576. <style scoped>
  577. /* //然后给对应的单元格样式 */
  578. >>> .vxe-table .vxe-body--row .vxe-body--column.class-style-yellow {
  579. background-color: #FFFF00;
  580. }
  581. >>> .vxe-table .vxe-body--row .vxe-body--column.class-style-red {
  582. background-color: #FF0000;
  583. color: #ffffff;
  584. }
  585. </style>
  586. <!--&gt;>>.vxe-table .vxe-body&#45;&#45;row .vxe-body&#45;&#45;column.class-style .vxe-cell .vxe-cell&#45;&#45;label{-->