<template> <div class="dataAnalysisPosAnal" :class="!theme ? 'themeDark' : 'themeLight'"> <div class="dataAnalysisPosAnalMain"> <p>微观选址分析</p> <div class="main"> <div class="treeDataMain"> <tree-cop ref="treeCopRef" :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="false" :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree"></tree-cop> </div> <div class="excelDataMain"> <excel-cop :checkIds="excelCheckIds" :showCheckbox="excelCheckboxShow" :data="excelList" :height="excelHeight" @excelChange="funExcelChange" @checkChange="funExcelCheckChange"> </excel-cop> </div> <div class="tableDataMain"> <div class="shadow rounded-[6px] shadow-blue-500 overflow-hidden"> <div :style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px', overflow: 'hidden', }"> <posChart @mapDone="funMapDone" @rightClick="funRightClick" :height="tableHeight" :windList="windList" :ids="excelCheckIds" v-if="showOnlineMap" /> <!-- v-if="showOnlineMap" --> <kMap :parentId="treeId" :ids="excelCheckIds" @mapDone="funMapDone" @rightClick="funRightClick" v-else /> </div> </div> </div> </div> </div> <el-dialog draggable width="80%" top="10px" v-model="dbRateDialog" :title="actDiaTitle" modal-class="rightMenuDialog"> <el-form class="whitespace-nowrap" :inline="true" :model="queryForm"> <el-form-item label="" class="!mb-0"> <el-select v-model="queryForm.checkIds" clearable @clear="checkAll = false" collapse-tags multiple> <el-option label="全选" :class="{ selected: checkAll }" @click="funCheckAll"></el-option> <el-option v-for="item in windList" :key="item.processId" :value="item.processId" :label="item.name"></el-option> </el-select> </el-form-item> <el-form-item class="!mb-0"> <submit-btn desc="查询" @click="funDiaSubmit"></submit-btn> <submit-btn desc="导出" @click="funDiaExport"></submit-btn> </el-form-item> </el-form> <div v-loading="exportLoading"> <div style="height: 600px" class="flex flex-wrap justify-center items-center overflow-y-auto overflow-x-hidden" ref="diaPanelRef"> <component :is="item.actCop" :width="`${100 / (actCopList.length || 1)}%`" height="100%" v-for="item in actCopList" :key="item.id" :xAxis="item.xAxis" :subtext="item.subtext" :isRadar="item.isRadar" :title="item.title" :series="item.series" :isDiaAlone="actCopList.length === 1" @dblclick="funDbClick(item)" :yAxis="item.yAxis" :dataset="item.dataset" :brush="item.isBrush"></component> </div> </div> </el-dialog> <el-dialog custom-class="windLifeDialog" title="对风偏差分析" draggable width="90%" top="25px" v-model="rateDialog"> <el-row :style="{ height: '793px' }"> <el-col :span="12" v-for="(item, index) in chartData" :key="item.id" style="height: 45%"> <el-icon :style="!theme ? 'color: #fff' : ''" size="18" @click="funActCop(item, 'chartCop' + (index + 1))"> <ZoomIn /> </el-icon> <chart-cop class="" height="100%" width="100%" :xAxis="item.xAxis" :isRadar="item.isRadar" :theme="theme" :echartsTheme="echartsTheme" :subtext="item.subtext" :title="item.title" :series="item.series"> </chart-cop> </el-col> <el-col :span="12" v-if="!!lineSeries.length" style="height: 50%"> <el-icon :style="!theme ? 'color: #fff' : ''" size="18" @click="funActCop({ xAxis: linexAxis, yAxis: lineyAxis, series: lineSeries, dataset: lineDataSet }, 'lineChartCop')"> <ZoomIn /> </el-icon> <line-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis" :yAxis="lineyAxis" :theme="theme" :echartsTheme="echartsTheme" :series="lineSeries" subtext="对风偏差分析图" :dataset="lineDataSet"></line-chart-cop> </el-col> <el-col :span="12" v-if="!!lineSeries.length" style="height: 50%"> <el-icon :style="!theme ? 'color: #fff' : ''" size="18" @click="funActCop({ xAxis: scatterxData, yAxis: scatteryData, series: scatterSeries }, 'scatterSingleChartCop')"> <ZoomIn /> </el-icon> <scatter-single-chart-cop class="" height="95%" width="100%" :xAxis="scatterxData" :theme="theme" :echartsTheme="echartsTheme" :yAxis="scatteryData" :series="scatterSeries" subtext="静态偏航对风分析图"> </scatter-single-chart-cop> </el-col> </el-row> </el-dialog> <el-dialog custom-class="windLifeDialog" title="功率曲线拟合" draggable width="90%" top="25px" modal-class="rightMenuDialog" v-model="combineDialog"> <combineChart width="100%" height="600px" :chartTitle=" avgObj.title + ' ' + '平均Cp值:' + avgObj.cpavg + '; 静风频率:' + avgObj.frequency + '%; 曲线偏差率:' + avgObj.pcratio + '%' " :xAxisData="combine.xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="combine.seriesData" :theme="theme" :echartsTheme="echartsTheme" :showLegend="true" :brushSelected="!combine.isChartArea" :dataSet="combine.dataSet" @getSelected="funCombineChartSelect"></combineChart> </el-dialog> <!-- 功率曲线拟合的圈选功能 --> <el-dialog v-model="wtDialog" draggable title="风机功率点位"> <el-tabs v-model="wtTab"> <el-tab-pane label="数据" name="table"> <el-table :data="wtData" default-expand-all row-key="id" :max-height="550"> <el-table-column property="wtId" align="center" label="风机" /> <el-table-column property="time" sortable :width="160" align="center" label="时间" /> <el-table-column property="speed" sortable align="center" label="风速(m/s)" /> <el-table-column property="power" sortable align="center" label="功率(kW)" /> <el-table-column property="rr" sortable align="center" label="转速" /> <el-table-column property="filter" sortable align="center" label="是否有用点" /> </el-table> </el-tab-pane> <el-tab-pane label="故障" name="problem" disabled> </el-tab-pane> <el-tab-pane label="预警" name="warning" disabled> </el-tab-pane> </el-tabs> </el-dialog> </div> </template> <script setup name="prepare"> import excelCop from '@/components/generatingCapacityComponent/excel.vue' import treeCop from '@/components/generatingCapacityComponent/tree.vue' import { ref, nextTick, onActivated, shallowRef, onMounted, reactive, watch, } from "vue"; import { useRouter } from "vue-router"; import { useStore } from "vuex"; import { ElMessage } from "element-plus"; import tools from "@tools/htmlToPdf.js"; import posChart from "./components/posChart.vue"; /**combine */ import combineChart from "../combine/components/current-scatter-chart.vue"; /**rateAnalysis */ import chartCop from "../rateAnalysis/components/chart.vue"; import lineChartCop from "../rateAnalysis/components/lineChart.vue"; import scatterSingleChartCop from "../rateAnalysis/components/scatterSingleChart.vue"; import kMap from "@/components/generatingCapacityComponent/kMap/index.vue"; import httpRequest from '@/utils/request.js' const router = useRouter(); /**配置参数 */ const treeHeight = ref(window.innerHeight - 170 + "px"); //tree高度 const excelHeight = ref(window.innerHeight - 170 + "px"); //excel高度 const tableHeight = ref(window.innerHeight - 170 + "px"); /**excel 开始 */ const excelCheckboxShow = ref(false); const excelCheckIds = ref([]); const excelList = ref([]); const store = useStore(); const showOnlineMap = ref(true); watch( () => router.currentRoute.value, (newValue, oldValue) => { // if (newValue.path === "/dataAnalysis/posAnalysis") { if (newValue.path.indexOf("/dataAnalysis/posAnalysis") > -1) { if (newValue.query.onlineMap) { showOnlineMap.value = newValue.query.onlineMap === "1" ? true : false; } } }, { immediate: true } ); const funExcelChange = async (obj) => { //点击excel项时 return false; }; const funExcelCheckChange = ({ checkArr, data }) => { //bug excelCheckIds.value = checkArr; funSubmit(); }; /**prepare tree 开始 */ const treeData = ref([]); const treeCopRef = ref(); //treeCop ref const actTreeNode = ref(null); //当前激活的treeNode const funRepeatMap = (arr, type = "fitting") => { return arr.map((o) => { if (o.children) { const findIndex = o.children.findIndex((p) => !!p.type); if (findIndex !== -1) { o.childs = o.children; o.children = []; if (!actTreeNode.value && type === "fitting") { //判断当且仅有process获取tree时 赋值 actTreeNode.value = o; } } } return { ...o, children: o.children ? funRepeatMap(o.children, type) : [], }; }); }; const funGetTree = async () => { actTreeNode.value = null; const res = await httpRequest.get("/power/fitting/tree"); treeData.value = funRepeatMap(res.data); excelList.value = []; if (actTreeNode.value) { funCurrentChange({ current: actTreeNode.value, currentNode: null }); if (treeCopRef.value) { treeCopRef.value.$refs.tree.setCheckedKeys([actTreeNode.value.id]); excelCheckIds.value = actTreeNode.value.childs.map((o) => o.id); funSubmit(); } } }; const treeId = ref(""); const funCurrentChange = ({ current, currentNode }) => { excelCheckboxShow.value = true; if (current.childs) { excelList.value = current.childs.map((o) => { return { id: o.id, interval: o.interval, path: o.path, prepareid: o.prepareid, station: o.station, time: o.time, type: o.type, windturbine: o.windturbine, name: o.path.substring( o.path.indexOf(o.station + "_") + (o.station + "_").length ), }; }); excelCheckIds.value = current.childs.map((o) => o.id); treeId.value = current.id || ""; funSubmit(); } else { excelList.value = []; excelCheckIds.value = []; windList.value = []; } }; const funTreeCheckChange = ({ current, checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys, }) => { //tree change -> excel change // funCurrentChange({ current, currentNode: '' }) // const checkIds = [] // if (checkedNodes.length) { // for (const node of checkedNodes) { // if (node.childs && node.childs.length) { // for (const child of node.childs) { // checkIds.push(child.id) // } // } // } // }else{ // windList.value = [] // } // excelCheckIds.value = checkIds // funSubmit() }; /**search 开始 */ const funSubmit = async () => { // if (!excelCheckIds.value.length) { // ElMessage.error('请勾选要执行的项') // return false // } const params = { ids: excelCheckIds.value.join(","), }; const res = await httpRequest.get("/base/location", { params: params }); let windList = []; res.data.forEach((ele) => { if (ele.longitude && ele.latitude) { windList.push(ele); } }); windList.value = windList; }; /**posChart */ const windList = ref([]); const funRightClick = ({ menuIndex, current }) => { console.log({ menuIndex, current }); switch (menuIndex) { case 0: funCombineGet(current); break; case 1: funRateSubmit(current); queryForm.checkIds = windList.value.map((o) => o.processId); break; } }; /**combine-chart */ const combineDialog = ref(false); const avgObj = reactive({ //平均cpz等 title: "", cpavg: "", frequency: "", pcratio: "", }); const markDot = reactive({ //3-5 point点等 pcl5: null, pcl10: null, pcl12: null, pcl25: null, }); const combine = reactive({ xAxisData: [], seriesData: [], dataSet: "", isChartArea: false, }); const wtDialog = ref(false); const wtData = ref([]); const wtTab = ref("table"); const funCombineChartSelect = async (batch) => { const wDataArr = []; const yDataArr = []; let scatterls = []; let scatterhs = []; let dataSetObj = []; wtData.value = []; if (batch.length && combine.dataSet) { scatterls = batch[0].selected[2].dataIndex; scatterhs = batch[0].selected[3].dataIndex; if (scatterls.length || scatterhs.length) { dataSetObj = JSON.parse(combine.dataSet); if (scatterls.length) { for (const scatterIndex of scatterls) { wDataArr.push(dataSetObj[0].source[scatterIndex].k); } } if (scatterhs.length) { for (const scatterIndex of scatterhs) { yDataArr.push(dataSetObj[1].source[scatterIndex].k); } } const wtRes = await httpRequest.get("/power/fitting/filter", { params: { yk: yDataArr.join(","), wk: wDataArr.join(",") }, }); if (wtRes.code === 200) { let id = 1; const tempArr = []; //用于以风机id 聚合dataArr if (wtRes.data.length) { for (const data of wtRes.data) { if (tempArr.length) { const findIndex = tempArr.findIndex((o) => o.wtId === data.wtId); if (findIndex !== -1) { if (!tempArr[findIndex].children) { tempArr[findIndex].children = []; } tempArr[findIndex].children.push({ ...data, id: id, filter: data.filter === 0 ? "是" : "否", }); id++; } else { tempArr.push({ ...data, id: id, filter: data.filter === 0 ? "是" : "否", }); id++; } } else { tempArr.push({ ...data, id: id, filter: data.filter === 0 ? "是" : "否", }); id++; } } wtDialog.value = true; nextTick(() => { wtTab.value = "table"; wtData.value = tempArr; }); } } } } }; const funCombineGet = async (obj) => { //点击excel项时 combine.isChartArea = false; let res = null; let chartRes = { scatterhs: [ [] ], scatterls: [ [] ], sjgl: [ [] ], llgl: [ [] ], cpz: [ [] ], }; const chartResponse = await httpRequest.get("/power/fitting/curve", { params: { id: obj.fittingId, p: 1 }, }); if (chartResponse && chartResponse.code === 200) { combineDialog.value = true; nextTick(() => { chartRes = chartResponse.data; markDot.pcl5 = chartRes.obj.pc5ratio; markDot.pcl10 = chartRes.obj.pc10ratio; markDot.pcl12 = chartRes.obj.pc12ratio; markDot.pcl25 = chartRes.obj.pc25ratio; avgObj.title = chartRes.obj.path .substring( chartRes.obj.path.indexOf(chartRes.obj.station + "_") + (chartRes.obj.station + "_").length ) .split("_")[0]; avgObj.cpavg = Number(chartRes.obj.cpavg).toFixed(2); avgObj.frequency = Number(chartRes.obj.frequency).toFixed(2); avgObj.pcratio = Number(chartRes.obj.pcratio).toFixed(2); combine.dataSet = JSON.stringify([{ source: chartRes.wyd, // source: chartRes.scatterls }, { source: chartRes.yyd, // source: chartRes.scatterhs }, ]); const color = [ "#1C99FF", "#FF8700", "#3D54BE", "#fa8c16", "#1DA0D7", "#DD5044", ]; combine.seriesData = [{ name: "拟合功率", type: "line", symbol: "line", //设定为实心点 symbolSize: 0, //设定实心点的大小 smooth: true, //这个是把线变成曲线 data: chartRes.sjgl, xAxisIndex: 0, }, { name: "保证功率", type: "line", symbol: "line", //设定为实心点 symbolSize: 0, //设定实心点的大小 smooth: true, //这个是把线变成曲线 data: chartRes.llgl, xAxisIndex: 0, }, { type: "effectScatter", showEffectOn: "emphasis", rippleEffect: { scale: 1, }, name: "无用点", symbolSize: (data) => { return data.s ? (data.s > 10 ? 10 : data.s) : 4; }, datasetIndex: 0, encode: { x: "x", y: "y", }, xAxisIndex: 0, yAxisIndex: 0, }, { type: "effectScatter", showEffectOn: "emphasis", rippleEffect: { scale: 1, }, name: "有用点", symbolSize: (data) => { return data.s ? (data.s > 10 ? 10 : data.s) : 4; }, datasetIndex: 1, encode: { x: "x", y: "y", }, xAxisIndex: 0, yAxisIndex: 0, }, { name: "Cp值", type: "line", symbol: "line", //设定为实心点 symbolSize: 0, //设定实心点的大小 smooth: true, //这个是把线变成曲线 data: chartRes.cpz, xAxisIndex: 0, yAxisIndex: 1, }, ]; }); } }; /**rateAnalysis chart */ const funText = (index) => { let str = ""; switch (index) { case 0: str = "0-2.5"; break; case 1: str = "2.5-5"; break; case 2: str = "5-7.5"; break; case 3: str = "7.5-10"; break; case 4: str = "10-12.5"; break; case 5: str = "12.5-15"; break; case 6: str = "15-17.5"; break; case 7: str = "17.5-20"; break; case 8: str = "20-22.5"; break; case 9: str = "22.5-25"; break; case 10: str = "25-inf"; break; } return str; }; const scatterxData = ref([{ type: "category", name: "度", data: new Array(61).fill(-30).map((o, index) => Number(o + index)), boundaryGap: false, splitLine: { show: true, }, axisLine: { show: true, }, }, ]); const scatteryData = ref([{ type: "category", data: [5, 6, 7, 8, 9, 10], axisLine: { show: false, }, name: "m/s", splitLine: { show: false, }, }, ]); const scatterSeries = ref([{ name: "对风偏航", type: "scatter", symbolSize: function (val) { return val[2]; }, data: [], markLine: { symbol: "none", label: { show: false, }, lineStyle: { color: "#F72C5B", width: "3", }, data: [{ // yAxis: powerproductionNum.value, }, ], }, animationDelay: function (idx) { return idx * 5; }, }, ]); const chartData = ref([]); //roses的chartList let chartId = 1; /**submit */ const funRateSubmit = async (obj) => { const rosesRes = await httpRequest.get("/wind/roses", { params: { ids: obj.processId, mode: 0, }, }); const lineRes = await httpRequest.get("/wind/deviation/ratio", { params: { ids: obj.processId, mode: 0, }, }); if (rosesRes.code === 200) { debugger if (rosesRes.data.length) { rateDialog.value = true; nextTick(() => { chartData.value = []; for (const chart of rosesRes.data) { chartData.value.push({ id: chartId, title: "", subtext: "风速风向玫瑰图", xAxis: { type: "category", boundaryGap: false, data: [ "N", "", "N-E", "", "E", "", "S-E", "", "S", "", "S-W", "", "W", "", "W-N", "", ], splitLine: { show: true, }, }, isRadar: false, series: chart.roses.length ? chart.roses.map((o, index) => { return { type: "bar", data: o, coordinateSystem: "polar", name: funText(index), stack: "a", emphasis: { focus: "series", }, }; }) : [], }); chartId++; chartData.value.push({ id: chartId, title: "", subtext: "风速风向频次玫瑰图", isRadar: true, xAxis: { type: "category", boundaryGap: false, data: [ "N", "", "N-E", "", "E", "", "S-E", "", "S", "", "S-W", "", "W", "", "W-N", "", ], splitLine: { show: true, }, }, series: chart.count.length ? [ ...chart.count.map((o, index) => { return { type: "bar", data: o, coordinateSystem: "polar", name: funText(index), stack: "a", emphasis: { focus: "series", }, }; }), { type: "radar", // coordinateSystem: 'polar', tooltip: { trigger: "item", }, // smooth: true, // areaStyle: {}, name: "对风", data: [{ value: chart.radar, }, ], }, ] : [], }); chartId++; scatterSeries.value[0].data = chart.frequency.data.length ? chart.frequency.data.map((item) => { return [item[1] + "", item[0] + "", (item[2] * 15).toFixed(1)]; }) : []; scatterSeries.value[0].markLine.data = [{ xAxis: `${chart.frequency.avg}`, name: `平均偏航:${chart.frequency.avg}度`, }, ]; } }); } } if (lineRes.code === 200) { if (lineRes.data.length) { lineDataSet.value[0].source = lineRes.data[0].scatter.map((o) => { return [o.x + "", o.y]; }); lineSeries.value = [{ name: "对风频次", type: "line", symbol: "line", //设定为实心点 symbolSize: 0, //设定实心点的大小 smooth: true, //这个是把线变成曲线 data: lineRes.data[0].count, yAxisIndex: 1, }, { type: "effectScatter", showEffectOn: "emphasis", rippleEffect: { scale: 1, }, legendHoverLink: false, name: "数据散点", symbolSize: 5, datasetIndex: 0, encode: { x: "x", y: "y", }, yAxisIndex: 0, }, ]; } } }; /**lineChart */ const linexAxis = ref({ type: "category", data: new Array(101) .fill(-50) .map((o, index) => Number((o + index).toFixed(1))), splitLine: { show: false, }, axisTick: { show: true, }, }); const lineyAxis = ref([{ type: "value", name: "m/s", splitLine: { show: false, }, axisTick: { show: true, }, }, { type: "value", name: "频次", splitLine: { show: false, }, axisTick: { show: true, }, }, ]); const lineSeries = ref([]); const lineDataSet = ref([{ source: [], }, ]); /** rate dialog */ const rateDialog = ref(false); const dbRateDialog = ref(false); const actChartName = ref(""); const actDiaTitle = ref(""); const diaPanelRef = ref(); const exportLoading = ref(false); const actCopList = ref([ // { // xAxis: [], // subtext: '', // title: '', // isRadar: false, // series: [], // yAxis: [], // dataset: [] // } ]); // 作为actCopList的备份 在actCopList赋值多个时 同时赋值, 在dialog弹出时清空. 作用: 在actCopList变化时, 重新赋值原始数据 const actCopListBak = ref([]); const checkAll = ref(true); const queryForm = reactive({ checkIds: [], }); const funCheckAll = () => { checkAll.value = !checkAll.value; if (checkAll.value) { queryForm.checkIds = windList.value.map((o) => o.processId); } else { queryForm.checkIds = []; } }; const funActCop = (obj, type) => { switch (type) { case "chartCop1": actChartName.value = "chartCop1"; obj.actCop = shallowRef(chartCop); actDiaTitle.value = "风速风向玫瑰图"; break; case "chartCop2": actChartName.value = "chartCop2"; obj.actCop = shallowRef(chartCop); actDiaTitle.value = "风速风向频次玫瑰图"; break; case "lineChartCop": actChartName.value = "lineChartCop"; obj.actCop = shallowRef(lineChartCop); actDiaTitle.value = "对风偏差分析图"; break; case "scatterSingleChartCop": actChartName.value = "scatterSingleChartCop"; obj.actCop = shallowRef(scatterSingleChartCop); actDiaTitle.value = "静态偏航对风分析图"; break; } obj.isBrush = type === "lineChartCop" ? false : false; obj.id = chartId; chartId++; dbRateDialog.value = true; actCopListBak.value = []; nextTick(() => { actCopList.value = [obj]; }); }; const funDiaSubmit = async () => { let url = ""; switch (actChartName.value) { case "chartCop1": url = "/wind/roses"; break; case "chartCop2": url = "/wind/roses"; break; case "lineChartCop": url = "/wind/deviation/ratio"; break; case "scatterSingleChartCop": url = "/wind/roses"; break; } if (url) { const res = await httpRequest.get(url, { params: { ids: queryForm.checkIds.join(","), mode: 0, }, }); if (res.code === 200) { actCopList.value = []; actCopListBak.value = []; //清空备份 if (res.data.length) { for (const chart of res.data) { if (actChartName.value === "chartCop1") { actCopList.value.push({ id: chartId, isBrush: false, actCop: shallowRef(chartCop), title: chart.wt, subtext: "风速风向玫瑰图", xAxis: { type: "category", boundaryGap: false, data: [ "N", "", "N-E", "", "E", "", "S-E", "", "S", "", "S-W", "", "W", "", "W-N", "", ], splitLine: { show: true, }, }, isRadar: false, series: chart.roses.length ? chart.roses.map((o, index) => { return { type: "bar", data: o, coordinateSystem: "polar", name: funText(index), stack: "a", emphasis: { focus: "series", }, }; }) : [], }); chartId++; } if (actChartName.value === "chartCop2") { actCopList.value.push({ id: chartId, isBrush: false, actCop: shallowRef(chartCop), title: chart.wt, subtext: "风速风向频次玫瑰图", xAxis: { type: "category", boundaryGap: false, data: [ "N", "", "N-E", "", "E", "", "S-E", "", "S", "", "S-W", "", "W", "", "W-N", "", ], splitLine: { show: true, }, }, isRadar: true, series: chart.count.length ? [ ...chart.count.map((o, index) => { return { type: "bar", data: o, coordinateSystem: "polar", name: funText(index), stack: "a", emphasis: { focus: "series", }, }; }), { type: "radar", // coordinateSystem: 'polar', tooltip: { trigger: "item", }, // smooth: true, // areaStyle: {}, name: "对风", data: [{ value: chart.radar, }, ], }, ] : [], }); chartId++; } if (actChartName.value === "lineChartCop") { actCopList.value.push({ id: chartId, isBrush: false, actCop: shallowRef(lineChartCop), title: chart.wtId, subtext: "对风偏差分析图", xAxis: linexAxis.value, yAxis: lineyAxis.value, dataset: [{ source: chart.scatter.map((o) => { return [o.x + "", o.y]; }), }, ], isRadar: false, series: [{ name: "对风频次", type: "line", symbol: "line", //设定为实心点 symbolSize: 0, //设定实心点的大小 smooth: true, //这个是把线变成曲线 data: chart.count, yAxisIndex: 1, }, { type: "effectScatter", showEffectOn: "emphasis", rippleEffect: { scale: 1, }, legendHoverLink: false, name: "数据散点", symbolSize: 5, datasetIndex: 0, encode: { x: "x", y: "y", }, yAxisIndex: 0, }, ], }); chartId++; } if (actChartName.value === "scatterSingleChartCop") { actCopList.value.push({ id: chartId, isBrush: false, actCop: shallowRef(scatterSingleChartCop), title: chart.wt, subtext: "静态偏航对风分析图", xAxis: scatterxData.value, yAxis: scatteryData.value, isRadar: false, series: [{ name: "对风偏航", type: "scatter", symbolSize: function (val) { return val[2]; }, markLine: { symbol: "none", label: { show: false, }, lineStyle: { color: "#F72C5B", width: "3", }, data: [{ name: `平均偏航:${chart.frequency.avg}度`, xAxis: `${chart.frequency.avg}`, }, ], }, data: chart.frequency.data.length ? chart.frequency.data.map((item) => { return [ item[1] + "", item[0] + "", (item[2] * 15).toFixed(1), ]; }) : [], animationDelay: function (idx) { return idx * 5; }, }, ], }); chartId++; } } actCopListBak.value = actCopList.value; } } } }; const funDiaExport = () => { exportLoading.value = true; tools.scrollToPDF(diaPanelRef.value, actDiaTitle.value, () => { exportLoading.value = false; }); }; const funDbClick = (obj) => { if (actCopListBak.value.length > 1) { //判断大于1时, 才有双击放大功能 if (actCopList.value.length === 1) { actCopList.value = actCopListBak.value; } else { actCopList.value = [obj]; } } }; const theme = ref(null) const echartsTheme = ref('') watch(() => store.state.theme, (newVal, oldVal) => { theme.value = newVal echartsTheme.value = !newVal ? 'dark' : '' funGetTree() }, { deep: true }) /**mounted */ onMounted(() => { funGetTree(); theme.value = store.state.theme echartsTheme.value = !theme.value ? 'dark' : '' tableHeight.value = window.innerHeight - 170 + "px"; excelHeight.value = window.innerHeight - 170 + "px"; treeHeight.value = window.innerHeight - 170 + "px"; window.addEventListener("resize", () => { tableHeight.value = window.innerHeight - 170 + "px"; excelHeight.value = window.innerHeight - 170 + "px"; treeHeight.value = window.innerHeight - 170 + "px"; }); /**test */ // funExcelChange({ // id: 1, // name: 'excel', // type: 'fitting', // }) }); /**activated */ // onActivated(() => { // funGetTree() // }) const funMapDone = (mapStatus) => { if (mapStatus) { funGetTree(); } }; </script> <style lang="less" scoped> .dataAnalysisPosAnal { padding: 20px; p { font-size: 16px; margin-left: 20px; margin-bottom: 10px; } .main { display: flex; justify-content: space-between; // width: calc(100% - 40px); width: 100%; .treeDataMain, .excelDataMain, .tableDataMain { padding: 10px; border-radius: 10px; } .treeDataMain { width: calc(20% - 20px); } .excelDataMain { width: calc(13% - 20px); .excelDataMain_top { height: 49%; padding: 5px 0; } .excelDataMain_bot { padding: 5px 0; } } .tableDataMain { width: calc(66% - 20px); position: relative; .butten_com { position: absolute; right: 20px; z-index: 111111; } } } } .rightMenuDialog { .el-overlay-dialog { overflow: hidden; } } .themeDark { p { color: #fff; } .treeDataMain, .excelDataMain, .tableDataMain { background: #161f1e; } } .themeLight { padding: 0; p { color: #000; } .treeDataMain, .excelDataMain, .tableDataMain { background: #edeffb; } .dataAnalysisPosAnalMain { padding: 20px 0; border-radius: 10px; background: #fff; } } </style>