fault-diagnosis.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. <template>
  2. <div class="fault-diagnosis-pop-up-window">
  3. <div class="white font-md">查询条件</div>
  4. <div class="query left mg-b-8">
  5. <div class="query-items">
  6. <div class="query-item">
  7. <div class="lable">风机:</div>
  8. <div class="search-input">
  9. <el-input v-model="value1" placeholder="SG01_53" class="placeholder-left" />
  10. </div>
  11. </div>
  12. <div class="query-item">
  13. <div class="lable">部件类型:</div>
  14. <div class="search-input">
  15. <el-select class="placeholder-left" v-model="value2" placeholder="风机" popper-class="select">
  16. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
  17. </el-select>
  18. </div>
  19. </div>
  20. <div class="query-item">
  21. <div class="lable">测点类型:</div>
  22. <div class="search-input">
  23. <el-select class="placeholder-left" v-model="value3" placeholder="所有测点" popper-class="select">
  24. <el-option v-for="item in pointype" :key="item.value" :label="item.label" :value="item.value"></el-option>
  25. </el-select>
  26. </div>
  27. </div>
  28. </div>
  29. <div class="query-actions">
  30. <button class="btn green" @click="onClickSelect">重新选择</button>
  31. </div>
  32. </div>
  33. <div class="white font-md mg-t-16">
  34. <div>测点选择</div>
  35. <div class="check-item">
  36. <el-checkbox-group v-model="checkValue" text-color="#05bb4c" fill="#05bb4c" :max="5" @change="check">
  37. <template v-for="(items, i) in checkList" :key="i">
  38. <template v-for="(item, j) in items" :key="j">
  39. <el-checkbox class="cb-item" :label="item.uniformcode+'$'+item.name"> {{item.name}},值:{{item.value}}</el-checkbox>
  40. </template>
  41. <br>
  42. </template>
  43. </el-checkbox-group>
  44. </div>
  45. </div>
  46. <div class="time-axis-box">
  47. <div class="time-axis-icon mg-r-16" @click="startAnimate">
  48. <i :class="timeAxisIcon" class="green"></i>
  49. </div>
  50. <div class="time-axis-progress-box">
  51. <div class="time-axis-progress" :style="'width: '+timeAxisProgress+'%;'"></div>
  52. <div class="time-axis-progress-scale" v-for="index of 20" :key="index"></div>
  53. </div>
  54. </div>
  55. <div class="white font-md mg-t-16">风机故障回溯</div>
  56. <div class="fdp-sub-title font-sm">国电电力宁夏新能源集控系统</div>
  57. <multiple-y-line-chart ref="chart" class="fdp-chart" height="32.407vh" :yAxises="yAxis" :list="lineData" :showLegend="true" />
  58. </div>
  59. </template>
  60. <script>
  61. import MultipleYLineChart from "@com/chart/line/multiple-y-line-chart.vue";
  62. export default {
  63. components: {MultipleYLineChart},
  64. props:{
  65. data: String,
  66. },
  67. data() {
  68. return {
  69. yAxis: [
  70. {
  71. name: '机舱震动x方向',
  72. min: -0.01,
  73. max: 0,
  74. unit: "",
  75. position: "left",
  76. },
  77. {
  78. name: '机舱震动y方向',
  79. min: -0.01,
  80. max: 0,
  81. unit: "",
  82. position: "right",
  83. },
  84. {
  85. name: '机舱震动最大偏移值',
  86. min: 0,
  87. max: 1,
  88. unit: "",
  89. position: "left",
  90. },
  91. {
  92. name: '风速1',
  93. min: 0,
  94. max: 10,
  95. unit: "",
  96. position: "right",
  97. },
  98. {
  99. name: '风速2',
  100. min: 0,
  101. max: 10,
  102. unit: "",
  103. position: "left",
  104. },
  105. ],
  106. lineData: [
  107. {
  108. title: "机舱震动x方向",
  109. yAxisIndex: 0,
  110. value: [
  111. {
  112. text: "-0.003",
  113. value: -0.003,
  114. },
  115. {
  116. text: "-0.002",
  117. value: -0.002,
  118. },
  119. {
  120. text: "-0.003",
  121. value: -0.006,
  122. },
  123. {
  124. text: "-0.003",
  125. value: -0.003,
  126. },
  127. {
  128. text: "-0.002",
  129. value: -0.002,
  130. },
  131. {
  132. text: "-0.003",
  133. value: -0.006,
  134. },
  135. {
  136. text: "-0.003",
  137. value: -0.003,
  138. },
  139. {
  140. text: "-0.002",
  141. value: -0.002,
  142. },
  143. {
  144. text: "-0.003",
  145. value: -0.006,
  146. },
  147. ],
  148. },
  149. {
  150. title: "机舱震动y方向",
  151. yAxisIndex: 1,
  152. value: [
  153. {
  154. text: "-0.01",
  155. value: -0.01,
  156. },
  157. {
  158. text: "-0.005",
  159. value: -0.005,
  160. },
  161. {
  162. text: "-0.008",
  163. value: -0.008,
  164. },
  165. {
  166. text: "-0.01",
  167. value: -0.01,
  168. },
  169. {
  170. text: "-0.005",
  171. value: -0.005,
  172. },
  173. {
  174. text: "-0.008",
  175. value: -0.008,
  176. },
  177. {
  178. text: "-0.01",
  179. value: -0.01,
  180. },
  181. {
  182. text: "-0.005",
  183. value: -0.005,
  184. },
  185. {
  186. text: "-0.008",
  187. value: -0.008,
  188. },
  189. ],
  190. },
  191. {
  192. title: "机舱震动最大偏移值",
  193. yAxisIndex: 2,
  194. value: [
  195. {
  196. text: "1",
  197. value: 1,
  198. },
  199. {
  200. text: "0.05",
  201. value: 0.05,
  202. },
  203. {
  204. text: "0.5",
  205. value: 0.5,
  206. },
  207. {
  208. text: "1",
  209. value: 1,
  210. },
  211. {
  212. text: "0.05",
  213. value: 0.05,
  214. },
  215. {
  216. text: "0.5",
  217. value: 0.5,
  218. },
  219. {
  220. text: "1",
  221. value: 1,
  222. },
  223. {
  224. text: "0.05",
  225. value: 0.05,
  226. },
  227. {
  228. text: "0.5",
  229. value: 0.5,
  230. },
  231. ],
  232. },
  233. {
  234. title: "风速1",
  235. yAxisIndex: 3,
  236. value: [
  237. {
  238. text: "1",
  239. value: 1,
  240. },
  241. {
  242. text: "5",
  243. value: 5,
  244. },
  245. {
  246. text: "3",
  247. value: 1,
  248. },
  249. {
  250. text: "1",
  251. value: 1,
  252. },
  253. {
  254. text: "5",
  255. value: 5,
  256. },
  257. {
  258. text: "3",
  259. value: 1,
  260. },
  261. {
  262. text: "1",
  263. value: 1,
  264. },
  265. {
  266. text: "5",
  267. value: 5,
  268. },
  269. {
  270. text: "3",
  271. value: 1,
  272. },
  273. ],
  274. },
  275. {
  276. title: "风速2",
  277. yAxisIndex: 4,
  278. value: [
  279. {
  280. text: "1",
  281. value: 1,
  282. },
  283. {
  284. text: "2",
  285. value: 2,
  286. },
  287. {
  288. text: "3",
  289. value: 1,
  290. },
  291. {
  292. text: "1",
  293. value: 1,
  294. },
  295. {
  296. text: "2",
  297. value: 2,
  298. },
  299. {
  300. text: "3",
  301. value: 1,
  302. },
  303. {
  304. text: "1",
  305. value: 1,
  306. },
  307. {
  308. text: "2",
  309. value: 2,
  310. },
  311. {
  312. text: "3",
  313. value: 1,
  314. },
  315. ],
  316. },
  317. ],
  318. options: [
  319. {
  320. value: "0",
  321. label: "风机",
  322. },
  323. {
  324. value: "1",
  325. label: "齿轮箱",
  326. },
  327. {
  328. value: "2",
  329. label: "发电机",
  330. },
  331. {
  332. value: "3",
  333. label: "变桨",
  334. }
  335. ],
  336. pointype: [
  337. {
  338. value: "0",
  339. label: "所有测点",
  340. },
  341. {
  342. value: "1",
  343. label: "遥测测点",
  344. },
  345. {
  346. value: "2",
  347. label: "遥信测点",
  348. },
  349. ],
  350. value1: "",
  351. value2: "",
  352. value3: "",
  353. checkList: [],
  354. checkValue: [],
  355. timeAxisIcon: "el-icon-video-play", // el-icon-video-play el-icon-video-pause
  356. timeAxisProgress: 0,
  357. timeAxisAnimate: false,
  358. animationFrameId: null,
  359. start: 0,
  360. end: 10,
  361. temp: null,
  362. temp1: null,
  363. animationTime: 100, // 每次变化数据的大致时间间隔(具体会根据当前页面是否可见、CPU的负荷情况等上下浮动14~18ms)
  364. animationData: {}, // 回显的数组
  365. animationDataIndex: -1,
  366. maxlength: 0,
  367. };
  368. },
  369. created(){},
  370. mounted() {
  371. this.value1 = this.data.windTurbineId
  372. this.value2 = this.options[0].value
  373. this.value3 = this.pointype[0].value
  374. this.requestPoint()
  375. },
  376. // 函数
  377. methods: {
  378. // 重新选择按钮
  379. onClickSelect(){
  380. this.requestPoint()
  381. },
  382. requestPoint(){
  383. let that = this;
  384. that.API.requestData({
  385. method: "POST",
  386. subUrl: "/fault/queryPointVos",
  387. data: {
  388. wtId: that.value1,
  389. bjtype: that.value2,
  390. cdtype: that.value3
  391. },
  392. success(res) {
  393. if(res.code == 200){
  394. let points = "";
  395. let data = res.data;
  396. that.checkList = [];
  397. // 将数据分成4个一组
  398. var chunk = 4;
  399. for(var i = 0, j = data.length; i < j ;i+=chunk) {
  400. that.checkList.push(data.slice(i,i + chunk))
  401. }
  402. data.forEach(item => {points += item.uniformcode + ","})
  403. // 默认选择前5个
  404. if (that.checkList.length >= 2){
  405. that.checkValue = [
  406. that.checkList[0][0].uniformcode + "$" + that.checkList[0][0].name,
  407. that.checkList[0][1].uniformcode + "$" + that.checkList[0][1].name,
  408. that.checkList[0][2].uniformcode + "$" + that.checkList[0][2].name,
  409. that.checkList[0][3].uniformcode + "$" + that.checkList[0][3].name,
  410. that.checkList[1][0].uniformcode + "$" + that.checkList[1][0].name]
  411. }else {
  412. data.forEach(item => {
  413. that.checkValue.push(item.uniformcode + "$" + item.name)
  414. })
  415. }
  416. that.requestValue(points);
  417. }
  418. },
  419. });
  420. },
  421. requestValue(points){
  422. let that = this;
  423. that.API.requestData({
  424. method: "POST",
  425. subUrl: "/fault/getFaultPlayback",
  426. timeout: 8000,
  427. data: {
  428. wtId: that.value1,
  429. pointids: points,
  430. stopTime: new Date(that.data.stopTime).formatDate("yyyy-MM-dd hh:mm:ss")
  431. },
  432. success(res) {
  433. if(res.code == 200) {
  434. that.animationData = [];
  435. let data = res.data.datas
  436. // 取出最长的一个数值
  437. that.checkList.forEach((items) => {
  438. for (var i = 0; i < items.length; i++){
  439. items[i].value = data[items[i].uniformcode][0]
  440. if (items[i].uniformcode.length > that.maxlength){
  441. that.maxlength = data[items[i].uniformcode].length;
  442. }
  443. }
  444. })
  445. that.animationData = data;
  446. }
  447. that.initEchart();
  448. },
  449. });
  450. },
  451. startAnimate: function () {
  452. if (this.timeAxisAnimate) {
  453. this.timeAxisIcon = "el-icon-video-play";
  454. if (this.animationFrameId) {
  455. window.cancelAnimationFrame(this.animationFrameId);
  456. }
  457. } else {
  458. this.timeAxisIcon = "el-icon-video-pause";
  459. this.animationFrameId = window.requestAnimationFrame(this.timeAxisAnimation);
  460. }
  461. this.timeAxisAnimate = !this.timeAxisAnimate;
  462. },
  463. endAnimate: function () {
  464. this.timeAxisProgress = 0;
  465. this.timeAxisIcon = "el-icon-video-play";
  466. this.timeAxisAnimate = false;
  467. this.start = 0;
  468. this.end = 10;
  469. this.$refs.chart.datazoom(this.start, this.end);
  470. if (this.animationFrameId) {
  471. window.cancelAnimationFrame(this.animationFrameId);
  472. }
  473. this.animationFrameId = null;
  474. this.animationDataIndex = -1;
  475. },
  476. timeAxisAnimation: function () {
  477. if (this.timeAxisAnimate) {
  478. this.maxlength <= 100 ? this.maxlength = 100 : this.maxlength
  479. const step = this.maxlength / 100;
  480. this.timeAxisProgress += step;
  481. this.animationDataIndex += 1;
  482. if (this.animationDataIndex < this.maxlength) {
  483. this.checkList.forEach(items => {
  484. items.forEach(item => {
  485. if (this.animationDataIndex < this.animationData[item.uniformcode].length)
  486. item.value = this.animationData[item.uniformcode][this.animationDataIndex]
  487. })
  488. })
  489. }
  490. this.start += step;
  491. this.end += step;
  492. this.$refs.chart.datazoom(this.start, this.end);
  493. if (this.timeAxisProgress < 100) {
  494. setTimeout(() => {
  495. this.animationFrameId = window.requestAnimationFrame(this.timeAxisAnimation);
  496. }, this.animationTime);
  497. } else {
  498. this.endAnimate();
  499. }
  500. }
  501. },
  502. check: function () {
  503. this.initEchart();
  504. if (this.temp) {
  505. this.lineData.splice(4, 0, this.temp);
  506. this.yAxis.splice(4, 0, this.temp1);
  507. this.temp = null;
  508. this.temp1 = null;
  509. } else {
  510. this.temp = this.lineData[4];
  511. this.temp1 = this.yAxis[4];
  512. this.lineData.splice(4, 1);
  513. this.yAxis.splice(4, 1);
  514. }
  515. this.$refs.chart.reload();
  516. },
  517. initEchart(){
  518. this.yAxis = [];
  519. this.lineData = [];
  520. this.checkValue.forEach((item, index) => {
  521. let uniformcode = item.substring(0, item.indexOf("$"));
  522. let name = item.substring(item.indexOf("$") + 1);
  523. let obj = {
  524. name: name,
  525. unit: "",
  526. }
  527. if (index%2 == 0)
  528. obj.position = "left";
  529. else
  530. obj.position = "right";
  531. this.yAxis.push(obj);
  532. let data = {
  533. title: name,
  534. yAxisIndex: index
  535. }
  536. let value = [];
  537. this.animationData[uniformcode].forEach(ele => {
  538. let obj = {
  539. text: String(ele),
  540. value: ele
  541. }
  542. value.push(obj)
  543. })
  544. data.value = value
  545. this.lineData.push(data);
  546. })
  547. },
  548. },
  549. watch: {
  550. data(value){
  551. this.value1 = value.windTurbineId
  552. this.checkList = []
  553. }
  554. }
  555. };
  556. </script>
  557. <style lang="less">
  558. .fault-diagnosis-pop-up-window {
  559. width: 100%;
  560. .time-axis-box {
  561. margin: 16px auto;
  562. display: flex;
  563. width: 256px;
  564. .time-axis-icon {
  565. font-size: 30px;
  566. line-height: 1;
  567. cursor: pointer;
  568. }
  569. .time-axis-progress-box {
  570. width: 200px;
  571. height: 30px;
  572. display: flex;
  573. position: relative;
  574. .time-axis-progress {
  575. position: absolute;
  576. height: 100%;
  577. left: 0;
  578. top: 0;
  579. background: fade(@green, 60);
  580. transition: all .1s;
  581. }
  582. .time-axis-progress-scale {
  583. width: 10px;
  584. height: 100%;
  585. border: 1px solid @green;
  586. +.time-axis-progress-scale {
  587. border-left: none;
  588. }
  589. }
  590. }
  591. }
  592. .fdp-sub-title {
  593. color: #a8b2b5;
  594. margin: 2px 0 16px 0;
  595. }
  596. .cb-item {
  597. margin-top: 12px;
  598. width: 240px;
  599. }
  600. .fdp-chart {
  601. width: 100%;
  602. height: 32.407vh;
  603. }
  604. }
  605. </style>