index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. <template>
  2. <div
  3. class="dataAnalysisSpaceAna"
  4. :class="!theme ? 'themeDark' : 'themeLight'"
  5. >
  6. <div class="dataAnalysisSpaceAnaMain">
  7. <div class="main_top">
  8. <p class="topPsty">毛容量分析</p>
  9. </div>
  10. <div class="main">
  11. <div class="treeDataMain">
  12. <tree-cop
  13. :data="treeData"
  14. @checkChange="funTreeCheckChange"
  15. :show-checkbox="false"
  16. :height="treeHeight"
  17. :currentNodeKey="currentNodeKey"
  18. @currentChange="funCurrentChange"
  19. @refresh="funGetTree"
  20. >
  21. </tree-cop>
  22. </div>
  23. <div class="excelDataMain">
  24. <excel-cop
  25. :checkIds="excelCheckIds"
  26. :showCheckbox="false"
  27. :data="excelList"
  28. :height="excelHeight"
  29. :theme="theme"
  30. @excelChange="funExcelChange"
  31. @checkChange="funExcelCheckChange"
  32. ></excel-cop>
  33. </div>
  34. <div class="tableDataMain">
  35. <div :style="{ height: tableHeight }">
  36. <div style="height: 49%">
  37. <el-icon
  38. :style="!theme ? 'color: #fff' : ''"
  39. class="chartIcon"
  40. size="18"
  41. @click="
  42. funActCop(
  43. { xAxis: barxAxis, yAxis: baryAxis, series: barSeries },
  44. 'barChartCop'
  45. )
  46. "
  47. >
  48. <ZoomIn />
  49. </el-icon>
  50. <bar-chart-cop
  51. width="100%"
  52. height="100%"
  53. :subtext="`${windName} 平均风速 ${avgSpeed}`"
  54. :theme="theme"
  55. :echartsTheme="echartsTheme"
  56. :xAxis="barxAxis"
  57. :yAxis="baryAxis"
  58. :series="barSeries"
  59. ></bar-chart-cop>
  60. </div>
  61. <div style="height: 49%">
  62. <el-icon
  63. :style="!theme ? 'color: #fff' : ''"
  64. class="chartIcon"
  65. size="18"
  66. @click="
  67. funActCop(
  68. { xAxis: linexAxis, yAxis: lineyAxis, series: lineSeries },
  69. 'lineChartCop'
  70. )
  71. "
  72. >
  73. <ZoomIn />
  74. </el-icon>
  75. <bar-chart-cop
  76. width="100%"
  77. height="100%"
  78. :subtext="`${windName} 平均毛容量系数 ${avgMrxs}`"
  79. :theme="theme"
  80. :echartsTheme="echartsTheme"
  81. :xAxis="linexAxis"
  82. :yAxis="lineyAxis"
  83. :series="lineSeries"
  84. ></bar-chart-cop>
  85. </div>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. <el-dialog
  91. custom-class="windLifeDialog"
  92. draggable
  93. width="80%"
  94. v-model="dialog"
  95. :title="actDiaTitle"
  96. >
  97. <el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
  98. <el-form-item label="" class="!mb-0">
  99. <el-select
  100. v-model="queryForm.checkIds"
  101. style="width: 120px"
  102. clearable
  103. @clear="checkAll = false"
  104. collapse-tags
  105. multiple
  106. >
  107. <el-option
  108. label="全选"
  109. :class="{ selected: checkAll }"
  110. @click="funCheckAll"
  111. ></el-option>
  112. <el-option
  113. v-for="item in chartExcelList"
  114. :key="item.id"
  115. :value="item.id"
  116. :label="item.name"
  117. >
  118. </el-option>
  119. </el-select>
  120. </el-form-item>
  121. <el-form-item class="!mb-0">
  122. <submit-btn desc="查询" @click="funDiaSubmit"></submit-btn>
  123. <submit-btn desc="导出" @click="funDiaExport"></submit-btn>
  124. </el-form-item>
  125. </el-form>
  126. <div v-loading="exportLoading">
  127. <el-row
  128. ref="diaPanelRef"
  129. style="height: 650px; overflow-y: auto; over-x: hidden"
  130. >
  131. <el-col
  132. :span="actCopList.length > 1 ? 12 : 24"
  133. v-for="item in actCopList"
  134. :key="item.id"
  135. style="height: 650px"
  136. >
  137. <component
  138. :is="item.actCop"
  139. width="100%"
  140. height="100%"
  141. :xAxis="item.xAxis"
  142. :subtext="item.subtext"
  143. :title="item.title"
  144. :series="item.series"
  145. :isDiaAlone="actCopList.length === 1"
  146. @dblclick="funDbClick(item)"
  147. :yAxis="item.yAxis"
  148. :dataset="item.dataset"
  149. :brush="item.isBrush"
  150. :theme="theme"
  151. :echartsTheme="echartsTheme"
  152. @getSelected="funChartSelect"
  153. ></component>
  154. </el-col>
  155. </el-row>
  156. </div>
  157. </el-dialog>
  158. </div>
  159. </template>
  160. <script setup name="rateAnalysis">
  161. import excelCop from "@/components/generatingCapacityComponent/excel.vue";
  162. import treeCop from "@/components/generatingCapacityComponent/tree.vue";
  163. import barChartCop from "./components/barChart.vue";
  164. import {
  165. onMounted,
  166. ref,
  167. onActivated,
  168. shallowRef,
  169. reactive,
  170. nextTick,
  171. watch,
  172. } from "vue";
  173. import { useStore } from "vuex";
  174. import httpRequest from "@/utils/request.js";
  175. import tools from "@tools/htmlToPdf.js";
  176. import jsonData from "./components/data.json";
  177. /**配置参数 */
  178. const treeHeight = ref(window.innerHeight - 116 + "px"); //tree高度
  179. const excelHeight = ref(window.innerHeight - 116 + "px"); //excel高度
  180. const tableHeight = ref(window.innerHeight - 116 + "px");
  181. /**excel 开始 */
  182. const excelCheckIds = ref([]);
  183. const excelList = ref([]);
  184. /** 额定功率 */
  185. const powerproduction = ref("");
  186. const currentNodeKey = ref("");
  187. //点击excel项时
  188. const funExcelChange = async (obj) => {
  189. excelCheckIds.value = [obj.id]; //当为单选展示风机图表时
  190. chartExcelList.value = excelList.value.map((o) => {
  191. return {
  192. ...o,
  193. name: o.name.split("_")[0],
  194. };
  195. }); // 选中excel当前项时, excel列表赋值给dialog 下拉框
  196. queryForm.checkIds = excelList.value.map((o) => o.id);
  197. checkAll.value = true;
  198. funSubmit();
  199. };
  200. const funExcelCheckChange = ({ checkArr, data }) => {
  201. excelCheckIds.value = checkArr;
  202. };
  203. /**tree 开始 */
  204. const treeData = ref([]);
  205. const actTreeNode = ref(null);
  206. const funRepeatMap = (arr) => {
  207. return arr.map((o) => {
  208. if (o.children) {
  209. const findIndex = o.children.findIndex((p) => !!p.type);
  210. if (findIndex !== -1) {
  211. o.childs = o.children;
  212. o.children = [];
  213. if (!actTreeNode.value) {
  214. actTreeNode.value = o;
  215. }
  216. }
  217. }
  218. return {
  219. ...o,
  220. children: o.children.length ? funRepeatMap(o.children) : [],
  221. };
  222. });
  223. };
  224. const funGetTree = async () => {
  225. const res = await httpRequest.get("/power/process/tree");
  226. actTreeNode.value = null;
  227. excelList.value = [];
  228. treeData.value = funRepeatMap(res.data);
  229. if (actTreeNode.value) {
  230. currentNodeKey.value = actTreeNode.value?.id || "";
  231. funCurrentChange({
  232. current: actTreeNode.value,
  233. currentNode: null,
  234. });
  235. funExcelChange({
  236. id: actTreeNode.value.childs[0].id,
  237. });
  238. }
  239. };
  240. const funTreeCheckChange = ({
  241. current,
  242. checkedNodes,
  243. checkedKeys,
  244. halfCheckedNodes,
  245. halfCheckedKeys,
  246. }) => {
  247. //tree change -> excel change
  248. funCurrentChange({
  249. current,
  250. currentNode: "",
  251. });
  252. const checkIds = [];
  253. if (checkedNodes.length) {
  254. for (const node of checkedNodes) {
  255. if (node.childs && node.childs.length) {
  256. for (const child of node.childs) {
  257. checkIds.push(child.id);
  258. }
  259. }
  260. }
  261. }
  262. excelCheckIds.value = checkIds;
  263. };
  264. const funCurrentChange = ({ current, currentNode }) => {
  265. if (current.childs) {
  266. excelList.value = current.childs.map((o) => {
  267. return {
  268. id: o.id,
  269. interval: o.interval,
  270. path: o.path,
  271. prepareid: o.prepareid,
  272. station: o.station,
  273. time: o.time,
  274. type: o.type,
  275. windturbine: o.windturbine,
  276. name: o.path.substring(
  277. o.path.indexOf(o.station + "_") + (o.station + "_").length
  278. ),
  279. };
  280. });
  281. if (excelList.value.length > 0) {
  282. funExcelChange(excelList.value[0]);
  283. }
  284. } else {
  285. excelList.value = [];
  286. }
  287. };
  288. /**chart */
  289. let chartId = 1;
  290. const powerproductionNum = ref(0);
  291. const avgSpeed = ref("");
  292. const avgMrxs = ref("");
  293. const windName = ref("");
  294. /**submit */
  295. const funSubmit = async () => {
  296. const tempRes = await httpRequest.get("/wind/avg/speed", {
  297. params: {
  298. ids: excelCheckIds.value.join(","),
  299. },
  300. });
  301. if (tempRes.code === 200) {
  302. if (tempRes.data.length) {
  303. for (const chart of tempRes.data) {
  304. chart.currentData.sort((a, b) => {
  305. return new Date(a.time).getTime() - new Date(b.time).getTime();
  306. });
  307. chart.preData.sort((a, b) => {
  308. return new Date(a.time).getTime() - new Date(b.time).getTime();
  309. });
  310. let xAxisData = [],
  311. barData1 = [],
  312. barData2 = [],
  313. lineData1 = [],
  314. lineData2 = [];
  315. let avgSpeedSum = 0,
  316. avgMrxsSum = 0;
  317. chart.currentData.forEach((current) => {
  318. xAxisData.push(current.time);
  319. barData1.push(current.avgspeed);
  320. avgSpeedSum += current.avgspeed;
  321. avgMrxsSum += current.mrxs;
  322. lineData1.push((current.mrxs * 100).toFixed(2));
  323. });
  324. chart.preData.forEach((current) => {
  325. xAxisData.push(current.time);
  326. barData2.push(current.avgspeed);
  327. lineData2.push((current.mrxs * 100).toFixed(2));
  328. });
  329. avgSpeed.value = (avgSpeedSum / barData1.length).toFixed(2) + " m/s";
  330. avgMrxs.value =
  331. ((avgMrxsSum / lineData1.length) * 100).toFixed(2) + " %";
  332. // windName.value = chart.wtId
  333. windName.value = chart.code;
  334. barxAxis.data = xAxisData;
  335. linexAxis.data = xAxisData;
  336. barSeries[0].data = barData1;
  337. barSeries[1].data = barData2;
  338. chartId++;
  339. lineSeries[0].data = lineData1;
  340. lineSeries[1].data = lineData2;
  341. chartId++;
  342. }
  343. }
  344. }
  345. };
  346. /**lineChart */
  347. const linexAxis = reactive({
  348. type: "category",
  349. name: "日",
  350. data: [],
  351. splitLine: {
  352. show: false,
  353. },
  354. axisTick: {
  355. show: true,
  356. },
  357. axisLine: {
  358. onZero: false,
  359. },
  360. });
  361. const lineyAxis = reactive({
  362. type: "value",
  363. name: "%",
  364. splitLine: {
  365. show: false,
  366. },
  367. axisTick: {
  368. show: true,
  369. },
  370. axisLine: {
  371. onZero: false,
  372. },
  373. });
  374. const lineSeries = reactive([
  375. {
  376. name: "最新",
  377. type: "line",
  378. data: [],
  379. symbol: "line", //设定为实心点
  380. symbolSize: 0, //设定实心点的大小
  381. markLine: {
  382. symbol: "none",
  383. label: {
  384. show: true,
  385. },
  386. lineStyle: {
  387. color: "#F72C5B",
  388. },
  389. data: [],
  390. },
  391. },
  392. {
  393. name: "历史",
  394. type: "line",
  395. data: [],
  396. symbol: "line", //设定为实心点
  397. symbolSize: 0, //设定实心点的大小
  398. markLine: {
  399. symbol: "none",
  400. label: {
  401. show: false,
  402. },
  403. lineStyle: {
  404. color: "#F72C5B",
  405. },
  406. data: [],
  407. },
  408. },
  409. ]);
  410. // 圈选散点触发函数
  411. const funChartSelect = async (batch) => {
  412. const wDataArr = [];
  413. const yDataArr = [];
  414. let scatterls = [];
  415. let dataSetObj = [];
  416. wtData.value = [];
  417. if (batch.length && actCopList.value[0].dataset) {
  418. scatterls = batch[0].selected[1].dataIndex;
  419. if (scatterls.length) {
  420. dataSetObj = JSON.parse(actCopList.value[0].dataset);
  421. if (scatterls.length) {
  422. for (const scatterIndex of scatterls) {
  423. wDataArr.push(dataSetObj[0].source[scatterIndex].k);
  424. }
  425. }
  426. const wtRes = await httpRequest.get("/power/fitting/filter", {
  427. params: {
  428. yk: yDataArr.join(","),
  429. wk: wDataArr.join(","),
  430. },
  431. });
  432. if (wtRes.code === 200) {
  433. let id = 1;
  434. const tempArr = []; //用于以风机id 聚合dataArr
  435. if (wtRes.data.length) {
  436. for (const data of wtRes.data) {
  437. if (tempArr.length) {
  438. const findIndex = tempArr.findIndex((o) => o.wtId === data.wtId);
  439. if (findIndex !== -1) {
  440. if (!tempArr[findIndex].children) {
  441. tempArr[findIndex].children = [];
  442. }
  443. tempArr[findIndex].children.push({
  444. ...data,
  445. id: id,
  446. filter: data.filter === 0 ? "是" : "否",
  447. });
  448. id++;
  449. } else {
  450. tempArr.push({
  451. ...data,
  452. id: id,
  453. filter: data.filter === 0 ? "是" : "否",
  454. });
  455. id++;
  456. }
  457. } else {
  458. tempArr.push({
  459. ...data,
  460. id: id,
  461. filter: data.filter === 0 ? "是" : "否",
  462. });
  463. id++;
  464. }
  465. }
  466. wtDialog.value = true;
  467. nextTick(() => {
  468. wtTab.value = "table";
  469. wtData.value = tempArr;
  470. });
  471. }
  472. }
  473. }
  474. }
  475. };
  476. /**barChart */
  477. const barxAxis = reactive({
  478. type: "category",
  479. name: "日",
  480. data: [],
  481. splitLine: {
  482. show: false,
  483. },
  484. axisTick: {
  485. show: true,
  486. },
  487. axisLine: {
  488. onZero: false,
  489. },
  490. });
  491. const baryAxis = reactive({
  492. type: "value",
  493. name: "m/s",
  494. splitLine: {
  495. show: false,
  496. },
  497. axisTick: {
  498. show: true,
  499. },
  500. axisLine: {
  501. onZero: false,
  502. },
  503. });
  504. const barSeries = reactive([
  505. {
  506. name: "机舱风速(最近)",
  507. type: "line",
  508. symbol: "line", //设定为实心点
  509. symbolSize: 0, //设定实心点的大小
  510. data: [],
  511. markLine: {
  512. symbol: "none",
  513. label: {
  514. show: true,
  515. },
  516. lineStyle: {
  517. color: "#F72C5B",
  518. },
  519. data: [],
  520. },
  521. },
  522. {
  523. name: "机舱风速(历史)",
  524. type: "line",
  525. symbol: "line", //设定为实心点
  526. symbolSize: 0, //设定实心点的大小
  527. data: [],
  528. markLine: {
  529. symbol: "none",
  530. label: {
  531. show: false,
  532. },
  533. lineStyle: {
  534. color: "#F72C5B",
  535. },
  536. data: [],
  537. },
  538. },
  539. ]);
  540. /**dialog 数据 */
  541. const wtDialog = ref(false);
  542. const wtData = ref([]);
  543. const wtTab = ref("table");
  544. /**dialog */
  545. const dialog = ref(false);
  546. const actChartName = ref("");
  547. const actDiaTitle = ref("");
  548. const diaPanelRef = ref();
  549. const exportLoading = ref(false);
  550. const actCopList = ref([
  551. // {
  552. // xAxis: [],
  553. // subtext: '',
  554. // title: '',
  555. // isRadar: false,
  556. // series: [],
  557. // yAxis: [],
  558. // dataset: []
  559. // }
  560. ]);
  561. // 作为actCopList的备份 在actCopList赋值多个时 同时赋值, 在dialog弹出时清空. 作用: 在actCopList变化时, 重新赋值原始数据
  562. const actCopListBak = ref([]);
  563. const checkAll = ref(true);
  564. const queryForm = reactive({
  565. checkIds: [],
  566. });
  567. const funCheckAll = () => {
  568. checkAll.value = !checkAll.value;
  569. if (checkAll.value) {
  570. queryForm.checkIds = chartExcelList.value.map((o) => o.id);
  571. } else {
  572. queryForm.checkIds = [];
  573. }
  574. };
  575. const chartExcelList = ref([]); //dialog 下拉项
  576. const funActCop = (obj, type) => {
  577. switch (type) {
  578. case "barChartCop":
  579. actChartName.value = "barChartCop";
  580. obj.actCop = shallowRef(barChartCop);
  581. actDiaTitle.value = "风速";
  582. break;
  583. case "lineChartCop":
  584. actChartName.value = "lineChartCop";
  585. obj.actCop = shallowRef(barChartCop);
  586. actDiaTitle.value = "毛容量系数";
  587. break;
  588. // case 'CurrentScatterChartCop':
  589. // actChartName.value = 'CurrentScatterChartCop'
  590. // obj.actCop = shallowRef(CurrentScatte // console.log(res)rChartCop)
  591. // actDiaTitle.value = '静态偏航对风分析图'
  592. // break
  593. }
  594. obj.isBrush = false;
  595. obj.id = chartId;
  596. chartId++;
  597. dialog.value = true;
  598. actCopListBak.value = [];
  599. nextTick(() => {
  600. actCopList.value = [obj];
  601. });
  602. };
  603. const funDiaSubmit = async () => {
  604. let url = "";
  605. switch (actChartName.value) {
  606. case "barChartCop":
  607. url = "/wind/avg/speed";
  608. break;
  609. case "lineChartCop":
  610. url = "/wind/avg/speed";
  611. break;
  612. // case 'CurrentScatterChartCop':
  613. // url = '' //暂无接口
  614. // break
  615. }
  616. if (url) {
  617. const res = await httpRequest.get(url, {
  618. params: {
  619. ids: queryForm.checkIds.join(","),
  620. mode: 0,
  621. },
  622. });
  623. if (res.code === 200) {
  624. actCopList.value = [];
  625. actCopListBak.value = []; //清空备份
  626. if (res.data.length) {
  627. for (const chart of res.data) {
  628. chart.currentData.sort((a, b) => {
  629. return new Date(a.time).getTime() - new Date(b.time).getTime();
  630. });
  631. chart.preData.sort((a, b) => {
  632. return new Date(a.time).getTime() - new Date(b.time).getTime();
  633. });
  634. const xAxisData = [],
  635. barData1 = [],
  636. barData2 = [],
  637. lineData1 = [],
  638. lineData2 = [];
  639. let avgSpeedSum = 0,
  640. avgMrxsSum = 0;
  641. let avgSpeedDesc = "",
  642. avgMrxsDesc = "";
  643. for (const current of chart.currentData) {
  644. xAxisData.push(current.time);
  645. barData1.push(current.avgspeed);
  646. avgSpeedSum += current.avgspeed;
  647. avgMrxsSum += current.mrxs;
  648. lineData1.push((current.mrxs * 100).toFixed(2));
  649. }
  650. for (const current of chart.preData) {
  651. barData2.push(current.avgspeed);
  652. lineData2.push((current.mrxs * 100).toFixed(2));
  653. }
  654. avgSpeedDesc = (avgSpeedSum / barData1.length).toFixed(2) + " m/s";
  655. avgMrxsDesc =
  656. ((avgMrxsSum / lineData1.length) * 100).toFixed(2) + " %";
  657. if (actChartName.value === "barChartCop") {
  658. actCopList.value.push({
  659. id: chartId,
  660. isBrush: false,
  661. actCop: shallowRef(barChartCop),
  662. // title: chart.windturbine,
  663. subtext: `${chart.wtId} 平均风速 ${avgSpeedDesc}`,
  664. xAxis: {
  665. ...barxAxis,
  666. data: xAxisData,
  667. },
  668. yAxis: baryAxis,
  669. series: [
  670. {
  671. ...barSeries[0],
  672. data: barData1,
  673. },
  674. {
  675. ...barSeries[1],
  676. data: barData2,
  677. },
  678. ],
  679. });
  680. chartId++;
  681. }
  682. if (actChartName.value === "lineChartCop") {
  683. actCopList.value.push({
  684. id: chartId,
  685. isBrush: false,
  686. actCop: shallowRef(barChartCop),
  687. // title: chart.windturbine,
  688. subtext: `${chart.wtId} 平均毛容量系数 ${avgMrxsDesc}`,
  689. xAxis: {
  690. ...linexAxis,
  691. data: xAxisData,
  692. },
  693. yAxis: lineyAxis,
  694. series: [
  695. {
  696. ...lineSeries[0],
  697. data: lineData1,
  698. },
  699. {
  700. ...lineSeries[1],
  701. data: lineData2,
  702. },
  703. ],
  704. });
  705. chartId++;
  706. }
  707. }
  708. actCopListBak.value = actCopList.value;
  709. }
  710. }
  711. }
  712. };
  713. const funDiaExport = () => {
  714. exportLoading.value = true;
  715. tools.scrollToPDF(diaPanelRef.value, actDiaTitle.value, () => {
  716. exportLoading.value = false;
  717. });
  718. };
  719. const funDbClick = (obj) => {
  720. if (actCopListBak.value.length > 1) {
  721. //判断大于1时, 才有双击放大功能
  722. if (actCopList.value.length === 1) {
  723. actCopList.value = actCopListBak.value;
  724. } else {
  725. actCopList.value = [obj];
  726. }
  727. }
  728. };
  729. /**created */
  730. // funGetTree()
  731. const theme = ref(null);
  732. const echartsTheme = ref("");
  733. const store = useStore();
  734. watch(
  735. () => store.state.theme,
  736. (newVal, oldVal) => {
  737. theme.value = newVal;
  738. echartsTheme.value = !newVal ? "dark" : "";
  739. funGetTree();
  740. },
  741. {
  742. deep: true,
  743. }
  744. );
  745. const initPageData = () => {
  746. actTreeNode.value = null;
  747. excelList.value = [];
  748. treeData.value = funRepeatMap(JSON.parse(JSON.stringify(jsonData.treeData)));
  749. if (actTreeNode.value) {
  750. currentNodeKey.value = actTreeNode.value?.id || "";
  751. if (actTreeNode.value.childs) {
  752. excelList.value = actTreeNode.value.childs.map((o) => {
  753. return {
  754. id: o.id,
  755. interval: o.interval,
  756. path: o.path,
  757. prepareid: o.prepareid,
  758. station: o.station,
  759. time: o.time,
  760. type: o.type,
  761. windturbine: o.windturbine,
  762. isCheck: false,
  763. name: o.path.substring(
  764. o.path.indexOf(o.station + "_") + (o.station + "_").length
  765. ),
  766. };
  767. });
  768. } else {
  769. excelList.value = [];
  770. }
  771. const obj = {
  772. id: actTreeNode.value.childs[0].id,
  773. };
  774. excelCheckIds.value = [obj.id]; //当为单选展示风机图表时
  775. chartExcelList.value = excelList.value.map((o) => {
  776. return {
  777. ...o,
  778. name: o.name.split("_")[0],
  779. };
  780. }); // 选中excel当前项时, excel列表赋值给dialog 下拉框
  781. queryForm.checkIds = excelList.value.map((o) => o.id);
  782. checkAll.value = true;
  783. for (const chart of jsonData.speedData) {
  784. chart.currentData.sort((a, b) => {
  785. return new Date(a.time).getTime() - new Date(b.time).getTime();
  786. });
  787. chart.preData.sort((a, b) => {
  788. return new Date(a.time).getTime() - new Date(b.time).getTime();
  789. });
  790. let xAxisData = [],
  791. barData1 = [],
  792. barData2 = [],
  793. lineData1 = [],
  794. lineData2 = [];
  795. let avgSpeedSum = 0,
  796. avgMrxsSum = 0;
  797. chart.currentData.forEach((current) => {
  798. xAxisData.push(current.time);
  799. barData1.push(current.avgspeed);
  800. avgSpeedSum += current.avgspeed;
  801. avgMrxsSum += current.mrxs;
  802. lineData1.push((current.mrxs * 100).toFixed(2));
  803. });
  804. chart.preData.forEach((current) => {
  805. xAxisData.push(current.time);
  806. barData2.push(current.avgspeed);
  807. lineData2.push((current.mrxs * 100).toFixed(2));
  808. });
  809. avgSpeed.value = (avgSpeedSum / barData1.length).toFixed(2) + " m/s";
  810. avgMrxs.value =
  811. ((avgMrxsSum / lineData1.length) * 100).toFixed(2) + " %";
  812. // windName.value = chart.wtId
  813. windName.value = chart.code;
  814. barxAxis.data = xAxisData;
  815. linexAxis.data = xAxisData;
  816. barSeries[0].data = barData1;
  817. barSeries[1].data = barData2;
  818. chartId++;
  819. lineSeries[0].data = lineData1;
  820. lineSeries[1].data = lineData2;
  821. chartId++;
  822. }
  823. }
  824. };
  825. /**activated */
  826. onMounted(() => {
  827. //test
  828. // funSubmit()
  829. //
  830. initPageData();
  831. funGetTree();
  832. theme.value = store.state.theme;
  833. echartsTheme.value = !theme.value ? "dark" : "";
  834. tableHeight.value = window.innerHeight - 116 + "px";
  835. excelHeight.value = window.innerHeight - 116 + "px";
  836. treeHeight.value = window.innerHeight - 116 + "px";
  837. window.addEventListener("resize", () => {
  838. tableHeight.value = window.innerHeight - 116 + "px";
  839. excelHeight.value = window.innerHeight - 116 + "px";
  840. treeHeight.value = window.innerHeight - 116 + "px";
  841. });
  842. });
  843. onActivated(() => {
  844. // funGetTree()
  845. });
  846. </script>
  847. <style lang="less" scoped>
  848. .dataAnalysisSpaceAna {
  849. height: 100%;
  850. .dataAnalysisSpaceAnaMain {
  851. height: 100%;
  852. .main_top {
  853. height: 40px;
  854. display: flex;
  855. align-items: center;
  856. .topPsty {
  857. position: relative;
  858. top: 5px;
  859. padding: 7px 20px;
  860. font-size: 12px;
  861. font-weight: 600;
  862. margin-left: 10px;
  863. border-radius: 3px;
  864. }
  865. }
  866. .main {
  867. display: flex;
  868. width: 100%;
  869. .treeDataMain,
  870. .excelDataMain,
  871. .tableDataMain {
  872. border-radius: 10px;
  873. }
  874. .treeDataMain {
  875. margin-right: 10px;
  876. padding: 10px 0 10px 10px;
  877. width: calc(19% - 20px);
  878. }
  879. .excelDataMain {
  880. margin-right: 10px;
  881. padding: 10px 0 10px 10px;
  882. width: calc(15% - 20px);
  883. }
  884. .tableDataMain {
  885. padding: 10px;
  886. width: calc(66% - 20px);
  887. position: relative;
  888. .chartIcon {
  889. cursor: pointer;
  890. }
  891. .butten_com {
  892. position: absolute;
  893. right: 20px;
  894. z-index: 111111;
  895. }
  896. }
  897. }
  898. }
  899. }
  900. .themeDark {
  901. .dataAnalysisSpaceAnaMain {
  902. .main_top {
  903. .topPsty {
  904. color: #1c99ff;
  905. background: #1e2126;
  906. }
  907. }
  908. .main {
  909. background: #13171e;
  910. .treeDataMain {
  911. background: transparent;
  912. }
  913. .excelDataMain {
  914. background: #313233;
  915. }
  916. .tableDataMain {
  917. margin-top: 5px;
  918. background: #212223;
  919. }
  920. }
  921. }
  922. }
  923. .themeLight {
  924. padding: 0;
  925. .dataAnalysisSpaceAnaMain {
  926. .main_top {
  927. .topPsty {
  928. color: #2778ff;
  929. background: #ffffff;
  930. }
  931. }
  932. .main {
  933. background: #e6e8f2;
  934. .treeDataMain {
  935. background: transparent;
  936. }
  937. .excelDataMain {
  938. background: #f4f6fb;
  939. }
  940. .tableDataMain {
  941. background: #fff;
  942. margin-top: 5px;
  943. }
  944. }
  945. }
  946. }
  947. </style>