index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. <script setup name="prepare">
  2. import excelCop from '@/components/excel.vue'
  3. import treeCop from '@/components/tree.vue'
  4. import barChartCop from './components/barChart.vue'
  5. import lineChartCop from './components/lineChart.vue'
  6. import SubmitBtn from '@/components/SubmitBtn.vue'
  7. import { shallowRef, ref, nextTick, onActivated, onMounted, reactive } from 'vue'
  8. import request from '@/api/axios.js'
  9. import tools from '@tools/htmlToPdf.js'
  10. import { ElMessage } from 'element-plus'
  11. import util from "@tools/util";
  12. import CurrentScatterChart from './components/current-scatter-chart.vue'
  13. /**配置参数 */
  14. const treeHeight = ref(window.innerHeight - 150 + 'px') //tree高度
  15. const excelHeight = ref(window.innerHeight - 150 + 'px') //excel高度
  16. const tableHeight = ref(window.innerHeight - 204 + 'px')
  17. /** 额定功率 */
  18. const powerproduction = ref("")
  19. /**excel 开始 */
  20. const excelCheckboxShow = ref(false)
  21. const excelCheckIds = ref([])
  22. const excelList = ref([])
  23. const funExcelChange = async (obj) => { //点击excel项时
  24. /**次代码供温度功率曲线分析使用 */
  25. excelCheckIds.value = [obj.id] //当为单选展示风机图表时
  26. chartExcelList.value = excelList.value.map(o=> {
  27. return {
  28. ...o,
  29. name: o.windturbine
  30. }
  31. }) // 选中excel当前项时, excel列表赋值给dialog 下拉框
  32. queryForm.checkIds = excelList.value.map(o => o.id)
  33. checkAll.value = true
  34. funSubmit()
  35. /**---------------------------- */
  36. activeTab.value = '1'
  37. isChartArea.value = false
  38. let chartRes = {
  39. scatterhs: [[]],
  40. scatterls: [[]],
  41. sjgl: [[]],
  42. llgl: [[]],
  43. cpz: [[]]
  44. }
  45. let chartResponse = null
  46. if (obj.type === 'fitting') {
  47. chartResponse = await request.get('/temperature/curve/analysis', { params: { id: obj.id, p: 1 } })
  48. }
  49. if (chartResponse && chartResponse.code === 200) {
  50. chartRes = chartResponse.data
  51. markDot.pcl5 = chartRes.obj.pc5ratio
  52. markDot.pcl10 = chartRes.obj.pc10ratio
  53. markDot.pcl12 = chartRes.obj.pc12ratio
  54. markDot.pcl25 = chartRes.obj.pc25ratio
  55. avgObj.title = chartRes.obj.path.substring(chartRes.obj.path.indexOf(chartRes.obj.station + '_') + (chartRes.obj.station + '_').length).split('_')[0];
  56. avgObj.cpavg = Number(chartRes.obj.cpavg).toFixed(2)
  57. avgObj.frequency = Number(chartRes.obj.frequency).toFixed(2)
  58. avgObj.pcratio = Number(chartRes.obj.pcratio).toFixed(2)
  59. // dataSet.value = JSON.stringify([
  60. // {
  61. // source: chartRes.scatter
  62. // },
  63. // ])
  64. const color = ["#1C99FF", "#FF8700", "#3D54BE", "#fa8c16", "#1DA0D7", "#DD5044"]
  65. seriesData.value = [
  66. {
  67. name: "拟合功率",
  68. type: "line",
  69. symbol: "line", //设定为实心点
  70. symbolSize: 0, //设定实心点的大小
  71. smooth: true, //这个是把线变成曲线
  72. data: chartRes.sjgl,
  73. xAxisIndex: 0,
  74. },
  75. {
  76. name: "保证功率",
  77. type: "line",
  78. symbol: "line", //设定为实心点
  79. symbolSize: 0, //设定实心点的大小
  80. smooth: true, //这个是把线变成曲线
  81. data: chartRes.llgl,
  82. xAxisIndex: 0,
  83. },
  84. {
  85. type: 'effectScatter',
  86. showEffectOn: "emphasis",
  87. rippleEffect: {
  88. scale: 1
  89. },
  90. name: '数据散点',
  91. // symbolSize: (data) => {
  92. // return data.s ? data.s > 10 ? 10 : data.s : 4
  93. // },
  94. // datasetIndex: 1,
  95. // encode: {
  96. // x: 'x',
  97. // y: 'y'
  98. // },
  99. data: chartRes.scatter,
  100. xAxisIndex: 0,
  101. yAxisIndex: 0,
  102. },
  103. ]
  104. }
  105. }
  106. const funExcelCheckChange = ({ checkArr, data }) => {
  107. excelCheckIds.value = checkArr
  108. }
  109. /**prepare tree 开始 */
  110. const treeData = ref([])
  111. const actTreeNode = ref(null) //当前激活的treeNode
  112. const funRepeatMap = (arr) => {
  113. return arr.map(o => {
  114. if (o.children) {
  115. const findIndex = o.children.findIndex(p => !!p.type)
  116. if (findIndex !== -1) {
  117. o.childs = o.children
  118. o.children = []
  119. if(!actTreeNode.value){ //判断当且仅有process获取tree时 赋值
  120. actTreeNode.value = o
  121. }
  122. }
  123. }
  124. return {
  125. ...o,
  126. children: o.children ? funRepeatMap(o.children) : []
  127. }
  128. })
  129. }
  130. const funCurrentChange = ({ current, currentNode }) => {
  131. excelCheckboxShow.value = true
  132. if (current.childs) {
  133. excelList.value = current.childs.map(o => {
  134. return {
  135. id: o.id,
  136. interval: o.interval,
  137. path: o.path,
  138. prepareid: o.prepareid,
  139. station: o.station,
  140. time: o.time,
  141. type: o.type,
  142. windturbine: o.windturbine,
  143. name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
  144. }
  145. })
  146. } else {
  147. excelList.value = []
  148. }
  149. }
  150. /**process tree 开始 */
  151. const processTreeData = ref([])
  152. const funGetProcessTree = async () => { //flag控制是否获取tree的第一项 true为可获取
  153. actTreeNode.value = null
  154. const res = await request.get("/power/fitting/tree")
  155. excelList.value = []
  156. processTreeData.value = funRepeatMap(res.data) //flag控制对actTreeNode赋值
  157. if(actTreeNode.value){
  158. funProcessCurrentChange({current: actTreeNode.value, currentNode: null})
  159. const child = actTreeNode.value.childs[0]
  160. const obj = {
  161. id: child.id,
  162. interval: child.interval,
  163. path: child.path,
  164. prepareid: child.prepareid,
  165. station: child.station,
  166. time: child.time,
  167. type: child.type,
  168. windturbine: child.windturbine,
  169. name: child.path.substring(child.path.indexOf(child.station + '_') + (child.station + '_').length)
  170. }
  171. funExcelChange(obj)
  172. }
  173. }
  174. const funProcessCurrentChange = ({ current, currentNode }) => {
  175. if (current.childs) {
  176. excelList.value = current.childs.map(o => {
  177. return {
  178. id: o.id,
  179. interval: o.interval,
  180. path: o.path,
  181. prepareid: o.prepareid,
  182. station: o.station,
  183. time: o.time,
  184. type: o.type,
  185. windturbine: o.windturbine,
  186. name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
  187. }
  188. })
  189. } else {
  190. excelList.value = []
  191. }
  192. }
  193. /**chart */
  194. let chartId = 1
  195. const powerproductionNum = ref(0)
  196. /**search 开始 */
  197. const funSubmit = async () => {
  198. const tempRes = await request.get('/temperature/rated/power', {
  199. params: {
  200. ids: excelCheckIds.value.join(','),
  201. }
  202. })
  203. if (tempRes.code === 200) {
  204. if (tempRes.data?.length) {
  205. for (const chart of tempRes.data) {
  206. powerproduction.value = `(额定功率=${chart.power.powerproduction}kW)`
  207. powerproductionNum.value = chart.power.powerproduction
  208. barxAxis.data = Object.keys(chart.res1)
  209. barSeries[0].data = Object.values(chart.res1)
  210. barSeries[0].markLine.data = [{
  211. yAxis: 0,
  212. }]
  213. chartId++
  214. lineSeries.value = [
  215. {
  216. type: 'effectScatter',
  217. showEffectOn: "emphasis",
  218. rippleEffect: {
  219. scale: 1
  220. },
  221. legendHoverLink: false,
  222. name: '',
  223. symbolSize: 5,
  224. data: chart.res2,
  225. yAxisIndex: 0,
  226. markLine: {
  227. symbol: 'none',
  228. label: {
  229. show: false,
  230. },
  231. lineStyle: {
  232. color: '#F72C5B'
  233. },
  234. data: [{
  235. yAxis: powerproductionNum.value,
  236. }]
  237. }
  238. }
  239. ]
  240. chartId++
  241. }
  242. }
  243. }
  244. }
  245. /**lineChart */
  246. const linexAxis = reactive({
  247. type: 'value',
  248. name: '°C',
  249. splitLine: {
  250. show: false
  251. },
  252. axisTick: {
  253. show: true
  254. },
  255. axisLine: {
  256. onZero: false
  257. }
  258. })
  259. const lineyAxis = reactive([
  260. {
  261. type: 'value',
  262. name: 'kW',
  263. splitLine: {
  264. show: false
  265. },
  266. axisTick: {
  267. show: true
  268. },
  269. axisLine: {
  270. onZero: false
  271. }
  272. }
  273. ])
  274. const lineSeries = ref([])
  275. const lineDataSet = reactive([
  276. {
  277. source: []
  278. }
  279. ])
  280. // 圈选散点触发函数
  281. const funChartSelect = async (batch) => {
  282. const wDataArr = []
  283. const yDataArr = []
  284. let scatterls = []
  285. let dataSetObj = []
  286. wtData.value = []
  287. if (batch?.length && actCopList.value[0]?.dataset) {
  288. scatterls = batch[0].selected[1].dataIndex
  289. if (scatterls?.length) {
  290. dataSetObj = JSON.parse(actCopList.value[0].dataset)
  291. if (scatterls?.length) {
  292. for (const scatterIndex of scatterls) {
  293. wDataArr.push(dataSetObj[0].source[scatterIndex].k)
  294. }
  295. }
  296. const wtRes = await request.get('/power/fitting/filter', { params: { yk: yDataArr.join(','), wk: wDataArr.join(',') } })
  297. if (wtRes.code === 200) {
  298. let id = 1
  299. const tempArr = [] //用于以风机id 聚合dataArr
  300. if (wtRes.data?.length) {
  301. for (const data of wtRes.data) {
  302. if (tempArr.length) {
  303. const findIndex = tempArr.findIndex(o => o.wtId === data.wtId)
  304. if (findIndex !== -1) {
  305. if (!tempArr[findIndex].children) {
  306. tempArr[findIndex].children = []
  307. }
  308. tempArr[findIndex].children.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  309. id++
  310. } else {
  311. tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  312. id++
  313. }
  314. } else {
  315. tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  316. id++
  317. }
  318. }
  319. wtDialog.value = true
  320. nextTick(() => {
  321. wtTab.value = 'table'
  322. wtData.value = tempArr
  323. })
  324. }
  325. }
  326. }
  327. }
  328. }
  329. /**barChart */
  330. const barxAxis = reactive({
  331. type: 'category',
  332. name: '℃',
  333. data: [],
  334. splitLine: {
  335. show: false
  336. },
  337. axisTick: {
  338. show: true
  339. },
  340. axisLine: {
  341. onZero: false
  342. }
  343. })
  344. const baryAxis = reactive({
  345. type: 'value',
  346. name: 'kW',
  347. splitLine: {
  348. show: false
  349. },
  350. axisTick: {
  351. show: true
  352. },
  353. axisLine: {
  354. onZero: false
  355. }
  356. })
  357. const barSeries = reactive([{
  358. name: "",
  359. type: "bar",
  360. data: [],
  361. markLine: {
  362. symbol: 'none',
  363. label: {
  364. show: false,
  365. },
  366. lineStyle: {
  367. color: '#F72C5B'
  368. },
  369. data: []
  370. }
  371. }])
  372. /**chart Data */
  373. const avgObj = reactive({ //平均cpz等
  374. title: '',
  375. cpavg: '',
  376. frequency: '',
  377. pcratio: ''
  378. })
  379. const markDot = reactive({ //3-5 point点等
  380. pcl5: null,
  381. pcl10: null,
  382. pcl12: null,
  383. pcl25: null
  384. })
  385. const xAxisData = ref([])
  386. const chartRef = ref() //chart 的ref
  387. const seriesData = ref([])
  388. const isChartArea = ref(false) // 用来控制图表是否区域划分
  389. const dataSet = ref('')
  390. const funhotChartSelect = async (batch) => {
  391. const wDataArr = []
  392. const yDataArr = []
  393. let scatterls = []
  394. let scatterhs = []
  395. let dataSetObj = []
  396. wtData.value = []
  397. if (batch?.length && dataSet.value) {
  398. scatterls = batch[0].selected[2].dataIndex
  399. scatterhs = batch[0].selected[3].dataIndex
  400. if (scatterls?.length || scatterhs?.length) {
  401. dataSetObj = JSON.parse(dataSet.value)
  402. if (scatterls?.length) {
  403. for (const scatterIndex of scatterls) {
  404. wDataArr.push(dataSetObj[0].source[scatterIndex].k)
  405. }
  406. }
  407. if (scatterhs?.length) {
  408. for (const scatterIndex of scatterhs) {
  409. yDataArr.push(dataSetObj[1].source[scatterIndex].k)
  410. }
  411. }
  412. const wtRes = await request.get('/power/fitting/filter', { params: { yk: yDataArr.join(','), wk: wDataArr.join(',') } })
  413. if (wtRes.code === 200) {
  414. let id = 1
  415. const tempArr = [] //用于以风机id 聚合dataArr
  416. if (wtRes.data?.length) {
  417. for (const data of wtRes.data) {
  418. if (tempArr.length) {
  419. const findIndex = tempArr.findIndex(o => o.wtId === data.wtId)
  420. if (findIndex !== -1) {
  421. if (!tempArr[findIndex].children) {
  422. tempArr[findIndex].children = []
  423. }
  424. tempArr[findIndex].children.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  425. id++
  426. } else {
  427. tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  428. id++
  429. }
  430. } else {
  431. tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
  432. id++
  433. }
  434. }
  435. wtDialog.value = true
  436. nextTick(() => {
  437. wtTab.value = 'table'
  438. wtData.value = tempArr
  439. })
  440. }
  441. }
  442. }
  443. }
  444. }
  445. const funChartArea = () => {
  446. if (seriesData.value?.length) {
  447. if (!isChartArea.value) {
  448. // 请求一下
  449. seriesData.value[0] = {
  450. ...seriesData.value[0],
  451. markLine: {
  452. symbol: 'none',
  453. label: {
  454. show: false
  455. },
  456. lineStyle: {
  457. color: 'rgba(96,174,255, 1)'
  458. },
  459. data: [
  460. {
  461. xAxis: 3,
  462. valueIndex: 0,
  463. },
  464. {
  465. xAxis: 5,
  466. valueIndex: 0
  467. },
  468. {
  469. xAxis: 10,
  470. valueIndex: 0
  471. },
  472. {
  473. xAxis: 12,
  474. valueIndex: 0
  475. },
  476. {
  477. xAxis: 25,
  478. valueIndex: 0
  479. },
  480. ]
  481. },
  482. markArea: {
  483. label: {
  484. fontSize: util.vh(12),
  485. },
  486. itemStyle: {
  487. color: 'rgba(236,245,255, 0)'
  488. },
  489. emphasis: {
  490. itemStyle: {
  491. color: 'rgba(96,174,255, 0.5)'
  492. }
  493. },
  494. data: [
  495. [
  496. {
  497. name: `3~5m 偏差率: ${markDot.pcl5}%`,
  498. xAxis: 3,
  499. },
  500. {
  501. xAxis: 5,
  502. }
  503. ],
  504. [
  505. {
  506. name: `5~10m 偏差率: ${markDot.pcl10}%`,
  507. xAxis: 5,
  508. },
  509. {
  510. xAxis: 10,
  511. }
  512. ],
  513. [
  514. {
  515. name: `10~12m 偏差率: ${markDot.pcl12}%`,
  516. xAxis: 10,
  517. },
  518. {
  519. xAxis: 12,
  520. }
  521. ],
  522. [
  523. {
  524. name: `12~25m 偏差率: ${markDot.pcl25}%`,
  525. xAxis: 12,
  526. },
  527. {
  528. xAxis: 25,
  529. }
  530. ],
  531. ]
  532. },
  533. }
  534. isChartArea.value = true
  535. } else {
  536. seriesData.value[0] = {
  537. ...seriesData.value[0],
  538. markLine: null,
  539. markArea: null,
  540. }
  541. isChartArea.value = false
  542. }
  543. }
  544. }
  545. /**dialog 数据 */
  546. const wtDialog = ref(false)
  547. const wtData = ref([])
  548. const wtTab = ref('table')
  549. /**dialog */
  550. const dialog = ref(false)
  551. const actChartName = ref('')
  552. const actDiaTitle = ref('')
  553. const diaPanelRef = ref()
  554. const exportLoading = ref(false)
  555. const actCopList = ref([
  556. // {
  557. // xAxis: [],
  558. // subtext: '',
  559. // title: '',
  560. // isRadar: false,
  561. // series: [],
  562. // yAxis: [],
  563. // dataset: []
  564. // }
  565. ])
  566. // 作为actCopList的备份 在actCopList赋值多个时 同时赋值, 在dialog弹出时清空. 作用: 在actCopList变化时, 重新赋值原始数据
  567. const actCopListBak = ref([])
  568. const checkAll = ref(true)
  569. const queryForm = reactive({
  570. checkIds: []
  571. })
  572. const funCheckAll = () => {
  573. checkAll.value = !checkAll.value
  574. if(checkAll.value){
  575. queryForm.checkIds = chartExcelList.value.map(o => o.id)
  576. }else{
  577. queryForm.checkIds = []
  578. }
  579. }
  580. const chartExcelList = ref([]) //dialog 下拉项
  581. const funActCop = (obj, type) => {
  582. switch(type){
  583. case 'barChartCop':
  584. actChartName.value = 'barChartCop'
  585. obj.actCop = shallowRef(barChartCop)
  586. actDiaTitle.value = '平均功率-额定功率'
  587. break
  588. case 'lineChartCop':
  589. actChartName.value = 'lineChartCop'
  590. obj.actCop = shallowRef(lineChartCop)
  591. actDiaTitle.value = '额定功率温度分析'
  592. break
  593. // case 'CurrentScatterChartCop':
  594. // actChartName.value = 'CurrentScatterChartCop'
  595. // obj.actCop = shallowRef(CurrentScatte // console.log(res)rChartCop)
  596. // actDiaTitle.value = '静态偏航对风分析图'
  597. // break
  598. }
  599. obj.isBrush = false
  600. obj.id = chartId
  601. chartId ++
  602. dialog.value = true
  603. actCopListBak.value = []
  604. nextTick(() => {
  605. actCopList.value = [obj]
  606. })
  607. }
  608. const funDiaSubmit = async () => {
  609. let url = ''
  610. switch(actChartName.value){
  611. case 'barChartCop':
  612. url = '/temperature/rated/power'
  613. break
  614. case 'lineChartCop':
  615. url = '/temperature/rated/power'
  616. break
  617. // case 'CurrentScatterChartCop':
  618. // url = '' //暂无接口
  619. // break
  620. }
  621. if(url){
  622. const res = await request.get(url, {
  623. params: {
  624. ids: queryForm.checkIds.join(','),
  625. mode: 0
  626. }
  627. })
  628. if(res.code===200){
  629. actCopList.value = []
  630. actCopListBak.value = [] //清空备份
  631. if(res.data?.length){
  632. for(const chart of res.data){
  633. if(actChartName.value==='barChartCop'){
  634. actCopList.value.push({
  635. id: chartId,
  636. isBrush: false,
  637. actCop: shallowRef(barChartCop),
  638. title: chart.wt,
  639. subtext: `平均功率-额定功率(额定功率=${chart.power.powerproduction}kW)`,
  640. xAxis: {
  641. ...barxAxis,
  642. data: Object.keys(chart.res1)
  643. },
  644. yAxis: baryAxis,
  645. series: [{
  646. name: "",
  647. type: "bar",
  648. data: Object.values(chart.res1),
  649. markLine: {
  650. symbol: 'none',
  651. label: {
  652. show: false,
  653. },
  654. lineStyle: {
  655. color: '#F72C5B'
  656. },
  657. data: [{
  658. yAxis: 0,
  659. }]
  660. }
  661. }]
  662. })
  663. chartId++
  664. }
  665. if(actChartName.value === 'lineChartCop'){
  666. actCopList.value.push({
  667. id: chartId,
  668. isBrush: false,
  669. actCop: shallowRef(lineChartCop),
  670. title: chart.wt,
  671. subtext: `额定功率温度分析(额定功率=${chart.power.powerproduction}kW)`,
  672. xAxis: linexAxis,
  673. yAxis: lineyAxis,
  674. dataset: lineDataSet,
  675. series: [
  676. {
  677. type: 'effectScatter',
  678. showEffectOn: "emphasis",
  679. rippleEffect: {
  680. scale: 1
  681. },
  682. legendHoverLink: false,
  683. name: '',
  684. symbolSize: 5,
  685. data: chart.res2,
  686. yAxisIndex: 0,
  687. markLine: {
  688. symbol: 'none',
  689. label: {
  690. show: false,
  691. },
  692. lineStyle: {
  693. color: '#F72C5B'
  694. },
  695. data: [{
  696. yAxis: chart.power.powerproduction,
  697. }]
  698. }
  699. }
  700. ]
  701. })
  702. chartId++
  703. }
  704. }
  705. actCopListBak.value = actCopList.value
  706. }
  707. }
  708. }
  709. }
  710. const funDiaExport = () => {
  711. exportLoading.value = true
  712. tools.scrollToPDF(diaPanelRef.value, actDiaTitle.value, () => {
  713. exportLoading.value = false
  714. })
  715. }
  716. const funDbClick = (obj) => {
  717. if(actCopListBak.value.length > 1){ //判断大于1时, 才有双击放大功能
  718. if(actCopList.value.length === 1){
  719. actCopList.value = actCopListBak.value
  720. }else{
  721. actCopList.value = [obj]
  722. }
  723. }
  724. }
  725. /**tab */
  726. const activeTab = ref('1')
  727. /**created */
  728. // funGetProcessTree()
  729. /**mounted */
  730. onMounted(() => {
  731. tableHeight.value = window.innerHeight - 204 + 'px'
  732. excelHeight.value =(window.innerHeight - 150) + 'px'
  733. treeHeight.value = (window.innerHeight - 150) + 'px'
  734. window.addEventListener('resize', () => {
  735. tableHeight.value = window.innerHeight - 204 + 'px'
  736. excelHeight.value = (window.innerHeight - 150) + 'px'
  737. treeHeight.value = (window.innerHeight - 150) + 'px'
  738. })
  739. /**test */
  740. // funExcelChange({
  741. // id: 1,
  742. // name: 'excel',
  743. // type: 'fitting',
  744. // })
  745. })
  746. /**activated */
  747. onActivated(() => {
  748. funGetProcessTree()
  749. })
  750. </script>
  751. <template>
  752. <div class="bg-white py-[10px] px-[10px]">
  753. <!-- <search-cop class="mb-[20px] shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
  754. </search-cop> -->
  755. <el-dialog draggable width="80%" v-model="dialog" :title="actDiaTitle">
  756. <el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
  757. <el-form-item label="" class="!mb-0">
  758. <el-select v-model="queryForm.checkIds" clearable @clear="checkAll = false" collapse-tags multiple>
  759. <el-option label="全选" :class="{'selected': checkAll}" @click="funCheckAll"></el-option>
  760. <el-option v-for="item in chartExcelList" :key="item.id" :value="item.id" :label="item.name"></el-option>
  761. </el-select>
  762. </el-form-item>
  763. <el-form-item class="!mb-0">
  764. <submit-btn desc="查询" @click="funDiaSubmit"></submit-btn>
  765. <submit-btn desc="导出" @click="funDiaExport"></submit-btn>
  766. </el-form-item>
  767. </el-form>
  768. <div v-loading="exportLoading">
  769. <div ref="diaPanelRef" class="flex flex-wrap justify-center items-center h-[650px] overflow-y-auto overflow-x-hidden">
  770. <component :is="item.actCop" :width="actCopList.length > 1 ? '50%' : '100%'" height="100%" v-for="item in actCopList"
  771. :key="item.id" :xAxis="item.xAxis" :subtext="item.subtext" :title="item.title"
  772. :series="item.series" :isDiaAlone="(actCopList.length === 1)" @dblclick="funDbClick(item)" :yAxis="item.yAxis" :dataset="item.dataset" :brush="item.isBrush" @getSelected="funChartSelect"></component>
  773. </div>
  774. </div>
  775. </el-dialog>
  776. <el-dialog v-model="wtDialog" draggable title="风机功率点位">
  777. <el-tabs v-model="wtTab">
  778. <el-tab-pane label="数据" name="table">
  779. <el-table :data="wtData" row-key="id" :max-height="550">
  780. <el-table-column property="wtId" align="center" label="风机" />
  781. <el-table-column property="time" sortable :width="160" align="center" label="时间" />
  782. <el-table-column property="speed" sortable align="center" label="风速(m/s)" />
  783. <el-table-column property="power" sortable align="center" label="功率(kW)" />
  784. <el-table-column property="rr" sortable align="center" label="转速" />
  785. <el-table-column property="filter" sortable align="center" label="是否有用点" />
  786. </el-table>
  787. </el-tab-pane>
  788. <el-tab-pane label="故障" name="problem" disabled>
  789. </el-tab-pane>
  790. <el-tab-pane label="预警" name="warning" disabled>
  791. </el-tab-pane>
  792. </el-tabs>
  793. </el-dialog>
  794. <div class="relative shadow rounded-[6px] shadow-blue-500 px-[10px] pt-[20px] pb-[10px]">
  795. <div class="text-[14px] absolute top-[-7px] text-[#838383] left-[20px]">数据展示</div>
  796. <el-row :gutter="10">
  797. <el-col :span="5">
  798. <tree-cop :data="processTreeData" :height="treeHeight"
  799. @currentChange="funProcessCurrentChange" @refresh="funGetProcessTree"></tree-cop>
  800. </el-col>
  801. <el-col :span="3">
  802. <excel-cop :data="excelList" :height="excelHeight" @excelChange="funExcelChange">
  803. </excel-cop>
  804. </el-col>
  805. <el-col :span="16">
  806. <div class="px-[10px] shadow rounded-[6px] shadow-blue-500 ">
  807. <!-- <SubmitBtn class="absolute right-[16px] top-[6px] z-10" desc="区域划分" v-if="activeTab === '2' && excelType === 'fitting'" @click="funChartArea"></SubmitBtn> -->
  808. <el-tabs v-model="activeTab">
  809. <el-tab-pane label="温度与功率" name="1">
  810. </el-tab-pane>
  811. <el-tab-pane label="温度曲线" name="2">
  812. </el-tab-pane>
  813. <div v-show="activeTab === '1'" :style="{ height: tableHeight }"
  814. class="flex flex-wrap justify-center items-center overflow-x-hidden overflow-y-auto ">
  815. <div class="mb-[10px] w-[100%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
  816. <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
  817. @click="funActCop({xAxis:barxAxis, yAxis:baryAxis, series: barSeries}, 'barChartCop')">
  818. <ZoomIn />
  819. </el-icon>
  820. <bar-chart-cop width="100%" height="100%" :subtext="`平均功率-额定功率 ${powerproduction}`" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
  821. </div>
  822. <div class="w-[100%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
  823. <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
  824. @click="funActCop({xAxis:linexAxis, yAxis:lineyAxis, series: lineSeries}, 'lineChartCop')">
  825. <ZoomIn />
  826. </el-icon>
  827. <line-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis" :yAxis="lineyAxis"
  828. :series="lineSeries" :subtext="`额定功率温度分析 ${powerproduction}`" :dataset="lineDataSet"></line-chart-cop>
  829. </div>
  830. </div>
  831. <div v-if="activeTab === '2'"
  832. :style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }"
  833. class="p-[10px]">
  834. <CurrentScatterChart ref="chartRef" width="100%" :height="`calc( ${tableHeight} - 20px )`" :chartTitle="avgObj.title+ '&nbsp;&nbsp;' +'平均Cp值:'+avgObj.cpavg+'; 静风频率:'+avgObj.frequency+'%; 曲线偏差率:'+avgObj.pcratio+'%'"
  835. :xAxisData="xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData"
  836. :showLegend="true" :brushSelected="false" :dataSet="dataSet" @getSelected="funhotChartSelect" />
  837. </div>
  838. </el-tabs>
  839. </div>
  840. </el-col>
  841. </el-row>
  842. </div>
  843. </div>
  844. </template>