dataDetails.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <template>
  2. <div class="body">
  3. <div
  4. :class="index < 3 ? 'showContents' : 'showContents'"
  5. v-for="(item, index) in station"
  6. :key="index"
  7. >
  8. <div class="stationName">
  9. <div class="titleName">{{ item.name }}</div>
  10. <div class="titleNames" v-if="item.schedulingName">
  11. ({{ item.schedulingName }})
  12. </div>
  13. <img
  14. v-if="
  15. !allDate[item.id]?.Status?.value ||
  16. allDate[item.id]?.Status?.value === 0
  17. "
  18. class="statusIcons"
  19. src="@assets/img/controlcenter/daraTrue.png"
  20. />
  21. <img
  22. v-else
  23. class="statusIcons"
  24. src="@assets/img/controlcenter/dataFalse.png"
  25. />
  26. <div
  27. class="titleNames"
  28. v-if="
  29. allDate[item.id]?.Status?.value &&
  30. allDate[item.id]?.Status?.value !== 0
  31. "
  32. >
  33. {{
  34. (
  35. (1 -
  36. this.allDate[item.id]?.PowerSet?.value /
  37. this.allDate[item.id]?.InstalledCapacity?.value) *
  38. 100
  39. ).toFixed(2)
  40. }}%
  41. </div>
  42. </div>
  43. <div class="dataList">
  44. <div
  45. class="data"
  46. @dblclick="dbClicks(allDate[item.id]?.PowerSet, '有功设定限值')"
  47. >
  48. <div class="name">有功设定限值:</div>
  49. <div :class="index < 3 ? 'nums' : 'nums'">
  50. {{ allDate[item.id]?.PowerSet?.value ?? 0 }}
  51. </div>
  52. <div class="unit">MW</div>
  53. </div>
  54. <div
  55. class="data"
  56. @dblclick="dbClicks(allDate[item.id]?.ActualPower, '实发有功')"
  57. >
  58. <div class="name">实发有功:</div>
  59. <div :class="index < 3 ? 'nums' : 'nums'">
  60. {{ allDate[item.id]?.ActualPower?.value ?? 0 }}
  61. </div>
  62. <div class="unit">MW</div>
  63. </div>
  64. <div
  65. class="data"
  66. @dblclick="dbClicks(allDate[item.id]?.AgcUp, 'AGC可调上限')"
  67. >
  68. <div class="name">AGC可调上限:</div>
  69. <div :class="index < 3 ? 'nums' : 'nums'">
  70. {{ allDate[item.id]?.AgcUp?.value ?? 0 }}
  71. </div>
  72. <div class="unit">MW</div>
  73. </div>
  74. <div
  75. class="data"
  76. @dblclick="dbClicks(allDate[item.id]?.TheoryPower, '理论功率')"
  77. >
  78. <div class="name">理论功率:</div>
  79. <div :class="index < 3 ? 'nums' : 'nums'">
  80. {{ allDate[item.id]?.TheoryPower?.value ?? 0 }}
  81. </div>
  82. <div class="unit">MW</div>
  83. </div>
  84. <div
  85. class="data"
  86. @dblclick="dbClicks(allDate[item.id]?.AgcLower, 'AGC可调下限')"
  87. >
  88. <div class="name">AGC可调下限:</div>
  89. <div :class="index < 3 ? 'nums' : 'nums'">
  90. {{ allDate[item.id]?.AgcLower?.value ?? 0 }}
  91. </div>
  92. <div class="unit">MW</div>
  93. </div>
  94. <div
  95. class="data"
  96. @dblclick="dbClicks(allDate[item.id]?.ForecastPower, '预测功率')"
  97. >
  98. <div class="name">预测功率:</div>
  99. <div :class="index < 3 ? 'nums' : 'nums'">
  100. {{ allDate[item.id]?.ForecastPower?.value ?? 0 }}
  101. </div>
  102. <div class="unit">MW</div>
  103. </div>
  104. </div>
  105. <div class="condition">
  106. <div class="status">
  107. <div class="name">{{ allDate[item.id]?.AgcIn?.name }}:</div>
  108. <img
  109. v-if="allDate[item.id]?.AgcIn?.value === 0"
  110. class="statusIcon"
  111. src="@assets/img/controlcenter/daraTrue.png"
  112. />
  113. <img
  114. v-else-if="allDate[item.id]?.AgcIn?.value === 1"
  115. class="statusIcon"
  116. src="@assets/img/controlcenter/dataFalse.png"
  117. />
  118. <div v-else-if="allDate[item.id]?.AgcIn?.value === ''">暂无数据</div>
  119. </div>
  120. <div class="status">
  121. <div class="name">{{ allDate[item.id]?.AgcFar?.name }}:</div>
  122. <img
  123. v-if="allDate[item.id]?.AgcFar?.value === 0"
  124. class="statusIcon"
  125. src="@assets/img/controlcenter/daraTrue.png"
  126. />
  127. <img
  128. v-else-if="allDate[item.id]?.AgcFar?.value === 1"
  129. class="statusIcon"
  130. src="@assets/img/controlcenter/dataFalse.png"
  131. />
  132. <div v-else-if="allDate[item.id]?.AgcFar?.value === ''">暂无数据</div>
  133. </div>
  134. <div class="status">
  135. <div class="name">{{ allDate[item.id]?.SumLock?.name }}:</div>
  136. <img
  137. v-if="allDate[item.id]?.SumLock?.value === 0"
  138. class="statusIcon"
  139. src="@assets/img/controlcenter/daraTrue.png"
  140. />
  141. <img
  142. v-else-if="allDate[item.id]?.SumLock?.value === 1"
  143. class="statusIcon"
  144. src="@assets/img/controlcenter/dataFalse.png"
  145. />
  146. <div v-else-if="allDate[item.id]?.SumLock?.value === ''">
  147. 暂无数据
  148. </div>
  149. </div>
  150. <div class="status">
  151. <div class="name">{{ allDate[item.id]?.SubLock?.name }}:</div>
  152. <img
  153. v-if="allDate[item.id]?.SubLock?.value === 0"
  154. class="statusIcon"
  155. src="@assets/img/controlcenter/daraTrue.png"
  156. />
  157. <img
  158. v-else-if="allDate[item.id]?.SubLock?.value === 1"
  159. class="statusIcon"
  160. src="@assets/img/controlcenter/dataFalse.png"
  161. />
  162. <div v-else-if="allDate[item.id]?.SubLock?.value === ''">
  163. 暂无数据
  164. </div>
  165. </div>
  166. </div>
  167. <div :id="item.id" class="echarts" @dblclick="handleClick(item.id)"></div>
  168. </div>
  169. <Details
  170. @closed="closed()"
  171. v-model="display"
  172. :partsName="partsName"
  173. echartsId="modelEcharts"
  174. :datas="modelDetails"
  175. :calc="this.modelData.calc"
  176. @search-data="search"
  177. @original-data="originalData"
  178. ></Details>
  179. </div>
  180. </template>
  181. <script>
  182. import * as echarts from "echarts";
  183. import Details from "./basicDataDetails.vue";
  184. import api from "@api/stateMonitor/index.js";
  185. export default {
  186. components: {
  187. Details,
  188. },
  189. data() {
  190. return {
  191. display: false,
  192. modelData: {},
  193. partsName: "",
  194. };
  195. },
  196. props: {
  197. allDate: {
  198. type: String,
  199. default: "",
  200. },
  201. allChartDate: {
  202. type: Array,
  203. default: () => {
  204. return [];
  205. },
  206. },
  207. station: {
  208. type: Array,
  209. default: () => {
  210. return [];
  211. },
  212. },
  213. },
  214. updated() {
  215. // this.totleErtcher()
  216. },
  217. mounted() {
  218. },
  219. methods: {
  220. dbClicks(data, partsName, timeValues) {
  221. this.modelData = data;
  222. let date = new Date();
  223. let endTs = timeValues
  224. ? timeValues[1] > date.getTime()
  225. ? date.getTime()
  226. : timeValues[1]
  227. : date.getTime();
  228. let startTs = timeValues ? timeValues[0] : endTs - 28800000;
  229. data.tag &&
  230. api
  231. .getPower({
  232. tagName: data.tag,
  233. startTs: startTs,
  234. endTs: endTs,
  235. interval: 60,
  236. })
  237. .then((res) => {
  238. if (res.data.length > 0) {
  239. this.partsName = partsName;
  240. this.display = true;
  241. this.modelDetails = res.data;
  242. } else {
  243. this.modelDetails = [];
  244. }
  245. });
  246. },
  247. original(data, partsName, timeValues) {
  248. this.modelData = data;
  249. let date = new Date();
  250. let endTs = timeValues
  251. ? timeValues[1] > date.getTime()
  252. ? date.getTime()
  253. : timeValues[1]
  254. : date.getTime();
  255. let startTs = timeValues ? timeValues[0] : endTs - 28800000;
  256. api
  257. .getOriginalPower({
  258. tagName: data.tag,
  259. startTs: startTs,
  260. endTs: endTs,
  261. })
  262. .then((res) => {
  263. if (res.data.length > 0) {
  264. this.partsName = partsName;
  265. this.display = true;
  266. this.modelDetails = res.data;
  267. } else {
  268. this.modelDetails = [];
  269. }
  270. });
  271. },
  272. search(values, interval) {
  273. this.interval = interval;
  274. this.dbClicks(this.modelData, this.partsName, values);
  275. },
  276. originalData(values) {
  277. this.original(this.modelData, this.partsName, values);
  278. },
  279. totleErtcher() {
  280. this.allChartDate.forEach((item) => {
  281. let chartDom = document.getElementById(item.id);
  282. let myChart = echarts.init(chartDom, "#ffffff");
  283. let option;
  284. option = {
  285. tooltip: {
  286. trigger: "axis",
  287. },
  288. legend: {
  289. show: true,
  290. data: item.value.map((t) => {
  291. return t.title;
  292. }),
  293. right: 56,
  294. icon: "circle",
  295. itemWidth: 6,
  296. inactiveColor: "#606769",
  297. textStyle: {
  298. color: "#B3BDC0",
  299. fontSize: 12,
  300. },
  301. },
  302. xAxis: [
  303. {
  304. type: "category",
  305. boundaryGap: false,
  306. axisLabel: {
  307. // interval: 60,
  308. showMinLabel: true,
  309. showMaxLabel: true,
  310. formatter: "{value}",
  311. fontSize: 14,
  312. textStyle: {
  313. color: "#606769",
  314. },
  315. },
  316. axisLine: {
  317. show: false,
  318. },
  319. data: item.value[0].value.map((items) => {
  320. return items.text;
  321. }),
  322. },
  323. ],
  324. yAxis: {
  325. type: "value",
  326. axisLabel: {
  327. formatter: "{value}",
  328. fontSize: 14,
  329. },
  330. axisLine: {
  331. show: false,
  332. },
  333. splitLine: {
  334. show: true,
  335. lineStyle: {
  336. color: "#606769",
  337. type: "dashed",
  338. },
  339. },
  340. },
  341. dataZoom: [
  342. {
  343. show: false,
  344. type: "inside",
  345. start: 0,
  346. end: 100,
  347. },
  348. ],
  349. series: [
  350. {
  351. name: item.value[0].title,
  352. smooth: true,
  353. showSymbol: false,
  354. data: item.value[0].value.map((items) => {
  355. return items.value;
  356. }),
  357. type: "line",
  358. lineStyle: {
  359. normal: {
  360. color: "rgba(75, 85, 174, 1)",
  361. width: 1,
  362. },
  363. },
  364. },
  365. {
  366. name: item.value[1].title,
  367. smooth: true,
  368. showSymbol: false,
  369. data: item.value[1].value.map((items) => {
  370. return items.value;
  371. }),
  372. type: "line",
  373. lineStyle: {
  374. normal: {
  375. color: "rgba(05, 187, 76, 1)",
  376. width: 1,
  377. },
  378. },
  379. },
  380. ],
  381. };
  382. option && myChart.setOption(option);
  383. });
  384. },
  385. handleClick(id) {
  386. this.$emit("handleClick", id);
  387. },
  388. opened() {
  389. },
  390. closed() {
  391. this.detailsDisplay = false;
  392. this.display = false;
  393. },
  394. },
  395. watch: {
  396. allChartDate: {
  397. handler: function (json) {
  398. if (json) {
  399. this.totleErtcher();
  400. }
  401. },
  402. },
  403. },
  404. };
  405. </script>
  406. <style scoped>
  407. .showTitles {
  408. display: flex;
  409. flex-direction: row;
  410. align-items: center;
  411. justify-content: center;
  412. margin-top: -10px;
  413. font-size: 18px;
  414. color: #ffffff;
  415. }
  416. .showContent {
  417. width: 32%;
  418. display: flex;
  419. flex-direction: column;
  420. border: 1px solid rgba(77, 77, 77, 1);
  421. /* background-color: rgba(77, 77, 77, 1); */
  422. margin-right: 10px;
  423. margin-left: 10px;
  424. height: 44vh;
  425. margin-top: 20px;
  426. align-items: center;
  427. }
  428. .showContents {
  429. width: 40%;
  430. display: flex;
  431. flex-direction: column;
  432. border: 1px solid rgba(77, 77, 77, 1);
  433. /* background-color: rgba(77, 77, 77, 1); */
  434. margin-right: 10px;
  435. margin-left: 10px;
  436. height: 43vh;
  437. margin-top: 20px;
  438. align-items: center;
  439. }
  440. .stationName {
  441. font-size: 20px;
  442. width: 400px;
  443. height: 45px;
  444. border: 1px solid rgba(77, 77, 77, 1);
  445. display: flex;
  446. flex-direction: row;
  447. align-items: baseline;
  448. justify-content: center;
  449. color: #ffffff;
  450. background-color: #000000;
  451. margin-top: -15px;
  452. }
  453. .titleName {
  454. margin-top: 10px;
  455. }
  456. .titleNames {
  457. font-size: 12px;
  458. margin-left: 10px;
  459. margin-top: 10px;
  460. }
  461. .body {
  462. background-color: black;
  463. width: 100%;
  464. display: flex;
  465. flex-direction: row;
  466. flex-wrap: wrap;
  467. justify-content: center;
  468. height: 90vh;
  469. overflow-y: auto;
  470. }
  471. .body::-webkit-scrollbar {
  472. /*隐藏滚轮*/
  473. display: none;
  474. }
  475. .echarts {
  476. width: 100%;
  477. height: 500px;
  478. margin-left: 10px;
  479. padding-top: -20px;
  480. }
  481. .dataList {
  482. display: flex;
  483. flex-direction: row;
  484. flex-wrap: wrap;
  485. align-items: center;
  486. padding-top: 27px;
  487. }
  488. .data {
  489. width: 50%;
  490. display: flex;
  491. flex-direction: row;
  492. align-items: center;
  493. margin-bottom: 12px;
  494. justify-content: center;
  495. }
  496. .name {
  497. display: flex;
  498. flex-direction: row-reverse;
  499. font-size: 12px;
  500. color: #ffffff;
  501. }
  502. .num {
  503. margin-left: 59px;
  504. font-size: 16px;
  505. color: #05bb4c;
  506. min-width: 40px;
  507. }
  508. .nums {
  509. margin-left: 29px;
  510. font-size: 16px;
  511. color: #05bb4c;
  512. min-width: 40px;
  513. }
  514. .unit {
  515. font-size: 16px;
  516. color: #ffffff;
  517. margin-left: 15px;
  518. }
  519. .condition {
  520. width: 100%;
  521. display: flex;
  522. flex-direction: row;
  523. align-items: center;
  524. margin-bottom: 20px;
  525. border-bottom: 1px solid #3d3d3d;
  526. padding-bottom: 10px;
  527. }
  528. .status {
  529. width: 25%;
  530. display: flex;
  531. flex-direction: row;
  532. align-items: center;
  533. justify-content: center;
  534. }
  535. .statusIcon {
  536. width: 14px;
  537. height: 14px;
  538. margin-left: 8px;
  539. }
  540. .statusIcons {
  541. width: 14px;
  542. height: 14px;
  543. margin-left: 20px;
  544. }
  545. </style>