supervised.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <template>
  2. <div class="decision-page-1">
  3. <div class="query mg-b-8">
  4. <div class="query-items">
  5. <div class="query-item">
  6. <div class="lable">算法类型:</div>
  7. <div class="search-input">
  8. <el-select
  9. v-model="chooseAlgorithm"
  10. @change="algorithmChange(chooseAlgorithm)"
  11. clearable
  12. placeholder="请选择"
  13. popper-class="select"
  14. >
  15. <el-option
  16. v-for="item in algorithm"
  17. :key="item.name"
  18. :value="item.name"
  19. :label="item.name"
  20. >
  21. </el-option>
  22. </el-select>
  23. </div>
  24. </div>
  25. <!-- <div v-for="(item, index) in chooseAlgorithm.parameters" :key="index">
  26. {{ item.name }}:
  27. <input
  28. v-model="item.value"
  29. type="number"
  30. @focus="inputChange(item)"
  31. @blur="inputChange(item)"
  32. />
  33. </div> -->
  34. </div>
  35. </div>
  36. <div class="actions mg-b-8">
  37. <button class="btn" @click="TypeClick('sjfl')">数据分类</button>
  38. <button class="btn" @click="TypeClick('mxjl')">模型记录</button>
  39. <button class="btn" @click="TypeClick('jcjl')">检测记录</button>
  40. <!-- <button class="btn" @click="handleTraining()">检测记录</button> -->
  41. </div>
  42. <el-row :type="'flex'" class="content">
  43. <el-col :span="16" class="pd-l-8">
  44. <panel :title="'训练记录'" :showLine="false">
  45. <div class="dataTitle">
  46. <div class="chooses">
  47. <el-date-picker
  48. class="picker"
  49. @change="changes"
  50. v-model="timeValue"
  51. type="datetimerange"
  52. range-separator="至"
  53. start-placeholder="开始日期"
  54. end-placeholder="结束日期"
  55. >
  56. </el-date-picker>
  57. <div class="contents">
  58. 风电场:
  59. <el-select
  60. v-model="selectValue"
  61. @change="search()"
  62. clearable
  63. placeholder="请选择"
  64. popper-class="select"
  65. style="width: 170px; margin-left: 20px"
  66. >
  67. <el-option
  68. v-for="item in options"
  69. :key="item.value"
  70. :value="item.value"
  71. :label="item.label"
  72. />
  73. </el-select>
  74. </div>
  75. <div class="contents">
  76. 机型:
  77. <el-select
  78. v-model="selectMoudle"
  79. @change="selectSearch()"
  80. clearable
  81. placeholder="全部"
  82. popper-class="select"
  83. style="width: 120px; margin-left: 20px"
  84. >
  85. <el-option
  86. v-for="item in moudleList"
  87. :key="item.value"
  88. :value="item.value"
  89. :label="item.label"
  90. />
  91. </el-select>
  92. </div>
  93. </div>
  94. <button class="btn" @click="getFaultList">查询</button>
  95. </div>
  96. <div class="bodys" v-if="dataList.length > 0">
  97. <div v-for="(item, index) in dataList" :key="index">
  98. <div class="faultTitle">{{ item.name }}:</div>
  99. <div class="fault">
  100. <div
  101. class="faultBlock"
  102. v-for="(val, indexs) in item.children"
  103. :key="indexs"
  104. >
  105. <div class="left">
  106. <div>{{ val.stationcn }}</div>
  107. <div>{{ val.windturbineid }}</div>
  108. <div>{{ val.model }}</div>
  109. <div style="font-size: 14px">{{ val.starttime }}</div>
  110. </div>
  111. <div class="right">
  112. <img class="imgs" src="./img/generator.png" alt="" />
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. <div v-else class="none">暂无数据</div>
  119. </panel>
  120. </el-col>
  121. <el-col :span="8" class="pd-l-8">
  122. <panel :title="'演示过程图'" :showLine="false">
  123. <div class="results" v-if="showTraining">
  124. <div class="progressTitle">
  125. <div v-if="!trainingFlag">数据获取中...</div>
  126. <div v-if="trainingFlag && width < 100">训练中...</div>
  127. <div v-if="trainingFlag && width === 100">训练完成</div>
  128. <div class="progressNum">
  129. 当前进度:{{ width >= 0 ? width : 0 }}%
  130. </div>
  131. </div>
  132. <div class="box">
  133. <div class="progress" :style="`width:${width}%;`"></div>
  134. <div class="line"></div>
  135. <div class="unprogress" :style="`width:${100 - width}%;`"></div>
  136. </div>
  137. </div>
  138. <LineChart v-if="lossList" id="loss" :dataList="lossList"></LineChart>
  139. <LineChart
  140. v-if="accuracyList"
  141. id="accuracy"
  142. :dataList="accuracyList"
  143. ></LineChart>
  144. <BarChart
  145. v-if="barList.length > 0"
  146. id="bar"
  147. :baseLine="ceshiList?.BaseLine"
  148. @click="showDetials"
  149. :barList="barList"
  150. ></BarChart>
  151. </panel>
  152. </el-col>
  153. </el-row>
  154. <SuperviseDataClassify
  155. ref="dataClass"
  156. @click-training="handleClick"
  157. @handleInterval="intervals"
  158. v-model="display"
  159. :allData="allData"
  160. :chooseAlgorithm="chooseAlgorithm"
  161. ></SuperviseDataClassify>
  162. <Records
  163. @results="recordResults"
  164. supervisedFlag="true"
  165. :recordList="showBarList"
  166. :accuracyList="accuracyList"
  167. v-model="recordsDisplay"
  168. ></Records>
  169. <ChartDetails
  170. v-model="detialsDisplay"
  171. :barList="ceshiList?.bar"
  172. :baseLine="ceshiList?.BaseLine"
  173. ></ChartDetails>
  174. <DetectionRecord
  175. v-model="detectionDisplay"
  176. :allData="allData"
  177. ></DetectionRecord>
  178. </div>
  179. </template>
  180. <script>
  181. import Panel from "../../components/coms/panel/panel.vue";
  182. import LineChart from "./components/lineChart.vue";
  183. import BarChart from "./components/barChart.vue";
  184. import SuperviseDataClassify from "./components/superviseDataClassify.vue";
  185. import Records from "./components/records.vue";
  186. import ChartDetails from "./components/chartDetails.vue";
  187. import DetectionRecord from "./components/detectionRecord.vue";
  188. export default {
  189. components: {
  190. Panel,
  191. LineChart,
  192. BarChart,
  193. SuperviseDataClassify,
  194. Records,
  195. ChartDetails,
  196. DetectionRecord,
  197. },
  198. created() {
  199. if (this.timeValue.length === 0) {
  200. let date = new Date();
  201. this.timeValue[0] = date.getTime() - 86400000;
  202. this.timeValue[1] = date.getTime();
  203. }
  204. let select = this.options.filter(
  205. (item) => item.value === this.selectValue
  206. )[0];
  207. this.selectMoudle = select.station[0].lable;
  208. this.moudleList = select.station;
  209. this.getfaultLables();
  210. },
  211. data() {
  212. return {
  213. dataList: [],
  214. faultLists: [],
  215. lossList: {},
  216. accuracyList: {},
  217. barList: [],
  218. algorithm: [], //算法
  219. chooseAlgorithm: "",
  220. timeValue: [],
  221. showBarList: [],
  222. moudleList: [],
  223. allData: [],
  224. ceshiList: [],
  225. detectionDisplay: false,
  226. showTraining: false,
  227. trainingFlag: false,
  228. lastTraining: false,
  229. display: false,
  230. recordsDisplay: false,
  231. detialsDisplay: false,
  232. width: 60,
  233. selectValue: "NSS_FDC",
  234. selectMoudle: "UP82",
  235. options: [
  236. {
  237. value: "NSS_FDC",
  238. label: "牛首山风电场",
  239. station: [
  240. {
  241. lable: "UP82",
  242. value: "UP82",
  243. },
  244. ],
  245. },
  246. {
  247. value: "MHS_FDC",
  248. label: "麻黄山风电场",
  249. station: [
  250. {
  251. lable: "UP77",
  252. value: "UP77",
  253. },
  254. {
  255. lable: "UP105-2000-S",
  256. value: "UP105-2000-S",
  257. },
  258. ],
  259. },
  260. {
  261. value: "QS_FDC",
  262. label: "青山风电场",
  263. station: [
  264. {
  265. lable: "CCWE-1500",
  266. value: "CCWE-1500",
  267. },
  268. {
  269. lable: "UP105-2000-S",
  270. value: "UP105-2000-S",
  271. },
  272. ],
  273. },
  274. {
  275. value: "SBQ_FDC",
  276. label: "石板泉风电场",
  277. station: [
  278. {
  279. lable: "UP82",
  280. value: "UP82",
  281. },
  282. {
  283. lable: "UP97",
  284. value: "UP97",
  285. },
  286. {
  287. lable: "UP105-2000-S",
  288. value: "UP105-2000-S",
  289. },
  290. ],
  291. },
  292. {
  293. value: "XS_FDC",
  294. label: "香山风电场",
  295. station: [
  296. {
  297. lable: "UP97",
  298. value: "UP97",
  299. },
  300. {
  301. lable: "UP105-2000-S",
  302. value: "UP105-2000-S",
  303. },
  304. ],
  305. },
  306. ],
  307. };
  308. },
  309. mounted() {
  310. let dataList = JSON.parse(
  311. '{"ducumentName":"NNS-1637028563000","loss":[1.0882383584976196,1.067789912223816,1.0520573854446411,1.0380222797393799,1.0230460166931152,1.0070627927780151,0.9899255037307739,0.9736341238021851,0.9547672271728516,0.9341660737991333,0.9082227945327759,0.8833365440368652,0.8581799268722534,0.8310791254043579,0.8011142611503601,0.7700659036636353,0.7383494973182678,0.7076452970504761,0.6731187105178833,0.6390867829322815],"accuracy":[0.3047619163990021,0.37142857909202576,0.3619047701358795,0.3619047701358795,0.380952388048172,0.5809524059295654,0.6571428775787354,0.6571428775787354,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6761904954910278,0.6952381134033203,0.7333333492279053,0.7428571581840515],"val_loss":[1.0914311408996582,1.0727100372314453,1.0579898357391357,1.0469794273376465,1.0305122137069702,1.012723684310913,0.9997329115867615,0.9839586615562439,0.9610583782196045,0.9339884519577026,0.9096081256866455,0.8876619338989258,0.862886905670166,0.8299474120140076,0.793283998966217,0.7597811222076416,0.7229973673820496,0.6826366782188416,0.6449647545814514,0.6126752495765686],"val_accuracy":[0.2666666805744171,0.2666666805744171,0.2666666805744171,0.2666666805744171,0.4000000059604645,0.644444465637207,0.644444465637207,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.6666666865348816,0.7333333492279053,0.7555555701255798,0.7333333492279053],"bar":[{"name":"邮箱温度","value":0.3},{"name":"风速","value":0.25},{"name":"变桨","value":0.25},{"name":"有高","value":0.2}]}'
  312. );
  313. this.ceshiList = dataList;
  314. this.lossList.loss = dataList.loss;
  315. this.lossList.val_loss = dataList.val_loss;
  316. this.accuracyList.accuracy = dataList.accuracy;
  317. this.accuracyList.val_accuracy = dataList.val_accuracy;
  318. this.barList = dataList.bar;
  319. this.getFaultList();
  320. this.getType();
  321. },
  322. methods: {
  323. getfaultLables() {
  324. let that = this;
  325. this.API.requestData({
  326. method: "GET",
  327. subUrl: "http://192.168.1.18:9002/know/fault/type/all",
  328. success(res) {
  329. if (res) {
  330. console.log(444444444);
  331. that.faultLists = res.data;
  332. }
  333. },
  334. });
  335. },
  336. getType() {
  337. let that = this;
  338. this.API.requestData({
  339. method: "GET",
  340. baseURL: "http://192.168.10.18:8080/",
  341. subUrl: "api/coordinate/algorithm",
  342. data: {
  343. type: 1,
  344. },
  345. success(res) {
  346. if (res) {
  347. that.algorithm = res;
  348. that.value1 = res[0];
  349. that.chooseAlgorithm = res[0].name;
  350. }
  351. },
  352. });
  353. },
  354. TypeClick(btnType) {
  355. if (btnType === "sjfl") {
  356. this.display = true;
  357. } else if (btnType === "mxjl") {
  358. this.showBarList.push(this.ceshiList);
  359. this.recordsDisplay = true;
  360. } else if (btnType === "jcjl") {
  361. this.detectionDisplay = true;
  362. }
  363. },
  364. selectSearch() {
  365. this.allData.forEach((item) => {
  366. if (item.modelId.indexOf(this.selectMoudle) != -1) {
  367. this.dataList.push(item);
  368. }
  369. });
  370. },
  371. search() {
  372. let select = this.options.filter(
  373. (item) => item.value === this.selectValue
  374. )[0];
  375. this.selectMoudle = select.station[0].lable;
  376. this.moudleList = select.station;
  377. },
  378. showDetials() {
  379. this.detialsDisplay = true;
  380. },
  381. getFaultList() {
  382. this.dataList = [];
  383. let that = this;
  384. this.API.requestData({
  385. method: "GET",
  386. subUrl: "http://192.168.1.18:9002/case/fault/list",
  387. data: {
  388. station: this.selectValue,
  389. model: this.selectMoudle,
  390. st: new Date(this.timeValue[0]).formatDate("yyyy-MM-dd hh:mm:ss"),
  391. et: new Date(this.timeValue[1]).formatDate("yyyy-MM-dd hh:mm:ss"),
  392. },
  393. success(res) {
  394. if (res) {
  395. console.log(333333333);
  396. that.allData = res.data;
  397. res.data.forEach((item) => {
  398. let array = that.dataList.filter(
  399. (val) => val.code === item.faultcode
  400. );
  401. item.stationcn = that.options.filter(
  402. (items) => items.value === item.stationen
  403. )[0]?.label;
  404. if (array.length > 0) {
  405. array[0].children.push(item);
  406. } else {
  407. let obj = {
  408. name: that.faultLists.filter(
  409. (items) => items.faultcode === item.faultcode
  410. )[0]?.faulttype,
  411. code: item.faultcode,
  412. children: [],
  413. };
  414. obj.children.push(item);
  415. that.dataList.push(obj);
  416. }
  417. });
  418. }
  419. },
  420. });
  421. },
  422. handleClick() {
  423. this.lastTraining = false;
  424. this.barList = [];
  425. this.handleTraining();
  426. },
  427. handleTraining() {
  428. let that = this;
  429. that.resultList = [];
  430. this.API.requestData({
  431. method: "GET",
  432. baseURL: "http://192.168.10.18:8080/",
  433. subUrl: "api/supervised/",
  434. success(res) {
  435. if (res.value.length > 0) {
  436. let arr = JSON.parse(res.value);
  437. that.ceshiList = arr;
  438. that.lossList.loss = arr.loss;
  439. that.lossList.val_loss = arr.val_loss;
  440. that.accuracyList.accuracy = arr.accuracy;
  441. that.accuracyList.val_accuracy = arr.val_accuracy;
  442. if (arr.bar) {
  443. arr.bar = JSON.parse(arr.bar);
  444. arr.bar?.sort(that.Compare("value"));
  445. that.barList = arr.bar?.slice(0, 5);
  446. }
  447. }
  448. },
  449. });
  450. this.API.requestData({
  451. method: "GET",
  452. baseURL: "http://192.168.10.18:8080/",
  453. subUrl: "api/supervised/progress",
  454. success(res) {
  455. that.showTraining = true;
  456. if (res) {
  457. that.trainingFlag = res.value === -1 ? false : true;
  458. that.width = res.value === -1 ? 0 : (res.value * 100).toFixed(2);
  459. if (that.width < 100) {
  460. setTimeout(() => {
  461. that.handleTraining();
  462. }, 1000);
  463. } else {
  464. if (!that.lastTraining) {
  465. that.lastTraining = true;
  466. that.handleTraining();
  467. }
  468. }
  469. }
  470. },
  471. });
  472. },
  473. handleClose() {
  474. this.barList = this.ceshiList.bar.slice(0, 5);
  475. },
  476. algorithmChange(val) {
  477. this.chooseAlgorithm = this.algorithm.filter(
  478. (item) => item.name === val
  479. )[0].name;
  480. },
  481. // clear() {
  482. // this.chooseAlgorithm = '';
  483. // },
  484. Compare(property) {
  485. return function (a, b) {
  486. var value1 = a[property];
  487. var value2 = b[property];
  488. return value2 - value1;
  489. };
  490. },
  491. },
  492. };
  493. </script>
  494. <style lang="less" scoped>
  495. .dataTitle {
  496. display: flex;
  497. flex-direction: row;
  498. align-items: center;
  499. justify-content: space-between;
  500. margin-bottom: 20px;
  501. margin-top: 10px;
  502. .chooses {
  503. display: flex;
  504. flex-direction: row;
  505. align-items: center;
  506. }
  507. .timeInput {
  508. width: 30px;
  509. }
  510. .contents {
  511. display: flex;
  512. flex-direction: row;
  513. align-items: center;
  514. margin-left: 30px;
  515. }
  516. }
  517. .faultTitle {
  518. font-size: 18px;
  519. margin-bottom: 20px;
  520. }
  521. .fault {
  522. display: flex;
  523. flex-direction: row;
  524. align-items: center;
  525. flex-wrap: wrap;
  526. .faultBlock {
  527. width: 220px;
  528. height: 90px;
  529. border: 1px solid #05bb4c;
  530. display: flex;
  531. flex-direction: row;
  532. align-items: center;
  533. justify-content: space-between;
  534. margin-right: 20px;
  535. margin-bottom: 20px;
  536. .left {
  537. line-height: 19px;
  538. margin-left: 10px;
  539. font-size: 16px;
  540. }
  541. .right {
  542. display: flex;
  543. align-items: center;
  544. justify-content: center;
  545. height: 100%;
  546. border-left: 1px solid #05bb4c;
  547. .imgs {
  548. margin: 0px 10px;
  549. width: 40px;
  550. height: 40px;
  551. }
  552. }
  553. }
  554. }
  555. .bodys {
  556. display: flex;
  557. flex-direction: column;
  558. overflow-y: auto;
  559. height: 75vh;
  560. }
  561. .none {
  562. width: 100%;
  563. display: flex;
  564. justify-content: center;
  565. margin-top: 150px;
  566. color: #999999;
  567. }
  568. .results {
  569. margin-left: 35px;
  570. }
  571. .box {
  572. width: 80%;
  573. margin-top: 20px;
  574. height: 20px;
  575. display: flex;
  576. align-items: center;
  577. .progress {
  578. background: linear-gradient(to right, #0d692c, #6df0a0);
  579. height: 16px;
  580. z-index: 1;
  581. }
  582. .line {
  583. width: 1px;
  584. height: 70px;
  585. z-index: 2;
  586. background: linear-gradient(
  587. to bottom,
  588. rgba(158, 151, 151, 0) 0%,
  589. rgba(0, 0, 0, 0) 10%,
  590. rgba(255, 255, 255, 0.3) 20%,
  591. rgba(255, 255, 255, 0.6) 30%,
  592. rgba(255, 255, 255, 0.8) 40%,
  593. rgba(255, 255, 255, 1) 50%,
  594. rgba(255, 255, 255, 0.8) 60%,
  595. rgba(255, 255, 255, 0.6) 70%,
  596. rgba(255, 255, 255, 0.3) 80%,
  597. rgba(0, 0, 0, 0) 90%,
  598. rgba(0, 0, 0, 0) 100%
  599. );
  600. transition: width 0.2s linear;
  601. }
  602. .unprogress {
  603. background: linear-gradient(to right, #41acec, #003e7a);
  604. height: 16px;
  605. z-index: 1;
  606. }
  607. }
  608. </style>