Browse Source

2022-11-17 update

1. 调整excel 及 tree组件的样式效果
2. 新增散点图表的框选功能 并展示表格
3. 调整散点图表的散点数据结构
4. 新增数据准备阶段时, websocket获取数据进度展示
5. 调整布局的gutter宽度
moccus 2 years ago
parent
commit
30de4f8bc7

+ 2 - 6
src/api/config.js

@@ -1,10 +1,6 @@
 const config = {
-    // baseURL: 'http://192.168.2.12:8075', // 本地后端服务实际地址
-    baseURL: 'http://192.168.10.4:9002', // 宁夏华为云后端服务实际地址
-    // baseURL: 'http://192.168.1.18:8075', // 宁夏ylt后端服务实际地址
-    // baseURL: 'http://192.168.2.205:8075', // 河北后端服务实际地址
-    // baseURL: 'http://10.0.118.75:8075', // 和风后端服务实际地址
-    // baseURL: 'http://15.147.0.228:8075', // 巴音后端服务实际地址
+    baseURL: 'http://192.168.10.4:9002',
+    socketURL: 'ws://192.168.10.4:9002'
 }
 
 export default config;

+ 5 - 5
src/components/excel.vue

@@ -30,15 +30,15 @@ const funCheckChange = (checkArr) => {
 		:style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
 		<el-empty v-if="!props.data.length" description="暂无数据" />
 		<el-checkbox-group size="small" v-model="excelCheckIds" v-if="props.showCheckbox" @change="funCheckChange">
-			<el-checkbox :class="{'bg-[rgb(236,245,255)]': currentId === item.id}" size="small" class="!mr-0" :label="item.id" v-for="item in props.data" :key="item.name">
-				<span class="mb-[6px] cursor-pointer text-[12px] leading-[10px] inline-flex items-end"
-					@click.stop="funExcelChange(item)"><el-icon class="mr-[4px]"><Document /></el-icon>{{ item.name }}</span>
+			<el-checkbox :class="{'bg-[rgb(236,245,255)]': currentId === item.id}" size="small" class="!mr-0 mb-[6px]" :label="item.id" v-for="item in props.data" :key="item.name">
+				<span class="whitespace-nowrap cursor-pointer text-[12px] align-middle inline-flex items-center"
+					@click.stop="funExcelChange(item)"><el-icon class="mr-[4px] !text-[rgb(71,179,71)]"><Document /></el-icon>{{ item.name }}</span>
 			</el-checkbox>
 		</el-checkbox-group>
 		<div v-else>
 			<div
-				class="text-[#606266] pl-[8px] w-[96%] cursor-pointer leading-[10px] inline-flex items-center h-[24px] text-[12px]"
-				v-for="item in props.data" :key="item.name" :class="{'bg-[rgb(236,245,255)]': currentId === item.id}" @click="funExcelChange(item)"><el-icon class="mr-[4px]"><Document /></el-icon>{{ item.name }}</div>
+				class="whitespace-nowrap text-[#606266] px-[8px] w-full cursor-pointer leading-[10px] inline-flex items-center h-[24px] text-[12px]"
+				v-for="item in props.data" :key="item.name" :class="{'bg-[rgb(236,245,255)]': currentId === item.id}" @click="funExcelChange(item)"><el-icon class="mr-[4px] !text-[rgb(71,179,71)]"><Document /></el-icon>{{ item.name }}</div>
 		</div>
 	</div>
 </template>

+ 5 - 5
src/components/tree.vue

@@ -9,17 +9,17 @@
 			highlight-current :props="defaultProps" :current-node-key="''" @check="funCheckChange"
 			:expand-on-click-node="false" @node-click="funCurrentChange" :filter-node-method="funTreeFilter">
 			<template #default="{ node, data }">
-				<p v-if="node.level == 1" class="flex justify-between items-center text-[12px]"
+				<p v-if="node.level === 1" class="flex justify-between items-center text-[12px]"
 					:class="[props.showCheckbox ? 'w-[84%]' : 'w-[90%]']">
 					<span>{{ node.label }}</span>
-					<el-icon title="刷新" @click.stop="emits('refresh')">
+					<el-icon class="!text-[rgb(64,158,255)]" title="刷新" @click.stop="emits('refresh')">
 						<RefreshRight />
 					</el-icon>
 				</p>
 				<el-dropdown ref="dropdown1" v-else size="small" trigger="contextmenu" @command="funCommand"
 					style="margin-right: 30px">
 					<span class="el-dropdown-link text-[12px] flex items-center">
-						<el-icon class="mr-[4px]">
+						<el-icon class="mr-[4px] !text-[#E6A23C]">
 							<Folder v-if="!node.expanded || (node.isLeaf && !node.isCurrent)" />
 							<FolderOpened v-else />
 						</el-icon>
@@ -27,9 +27,9 @@
 					</span>
 					<template #dropdown>
 						<el-dropdown-menu>
-							<el-dropdown-item v-if="data.childs && data.childs.length" :command="{ type: 'export', data, node }">导出
+							<el-dropdown-item class="text-[#409EFF]" v-if="data.childs && data.childs.length" :command="{ type: 'export', data, node }">导出
 							</el-dropdown-item>
-							<el-dropdown-item :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
+							<el-dropdown-item class="text-[#F56C6C]" :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
 						</el-dropdown-menu>
 					</template>
 				</el-dropdown>

+ 20 - 7
src/pages/dataFilter/combine/components/current-scatter-chart.vue

@@ -39,6 +39,10 @@ export default {
         return [];
       },
     },
+    dataSet: {
+      type: String,
+      default: ''
+    },
     // 图表核心数据
     seriesData: {
       type: Array,
@@ -141,19 +145,18 @@ export default {
           formatter(params) {
             return params.name
               ? `${params.seriesName}<br />风速:${params.name}m/s<br />功率:${params.value}kW`
-              : `${params.seriesName}<br />风速:${params.data[0]}m/s<br />功率:${params.data[1]}kW`;
+              : `${params.seriesName}<br />风速:${params.value.s}m/s<br />功率:${params.value.p}kW`;
           },
         },
         brush: {
-          brushLink: 'all',
-          yAxisIndex: 'all',
-          xAxisIndex: 'all',
+          seriesIndex: [2,3],
+          yAxisIndex: 0,
           transformable: true,
           throttleType: "debounce",
           throttleDelay: 600,
           removeOnClick: true,
           brushType: "polygon",
-          brushMode: "single",
+          brushMode: "multiple",
           brushStyle: {
             borderWidth: 1,
             color: "rgba(255,36,36,0.2)",
@@ -241,6 +244,7 @@ export default {
           min: 0,
         }],
         animation: false,
+        dataset: that.dataSet.length? JSON.parse(that.dataSet) : [],
         //数据-data是最终要显示的数据
         series: that.seriesData,
       };
@@ -263,10 +267,19 @@ export default {
           // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
           key: "brush",
           brushOption: {
-            // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
+            seriesIndex: [2,3],
+            yAxisIndex: 0,
+            transformable: true,
+            throttleType: "debounce",
+            throttleDelay: 600,
+            removeOnClick: true,
             brushType: "polygon",
-            // 参见 brush 组件的 brushMode。如果不设置,则取 brush 组件的 brushMode 设置。
             brushMode: "multiple",
+            brushStyle: {
+              borderWidth: 1,
+              color: "rgba(255,36,36,0.2)",
+              borderColor: "#ff2424",
+            },
           },
         });
       }

+ 1 - 1
src/pages/dataFilter/combine/components/table.vue

@@ -23,7 +23,7 @@ const funExport = () => {
 const tableRef = ref('')
 const tableHeight =  computed(() => {
   console.log(tableRef.value.offsetHeight)
-  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 42 : 661
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 661
 })
 </script>
 <template>

+ 123 - 37
src/pages/dataFilter/combine/index.vue

@@ -33,11 +33,11 @@ const funExcelChange = async (obj: any) => { //点击excel项时
 	let chartResponse = null
 	tableLoading.value = true
 	if (obj.type === 'process') {
-		res = await request.get('/power/process/show', {params: { id: obj.id }})
+		res = await request.get('/power/process/show', { params: { id: obj.id } })
 	} else if (obj.type === 'fitting') {
 		activeTab.value = '2'
-		res = await request.get('/power/fitting/show', {params: { id: obj.id }})
-		chartResponse = await request.get('/power/fitting/curve', {params: { id: obj.id }})
+		res = await request.get('/power/fitting/show', { params: { id: obj.id } })
+		chartResponse = await request.get('/power/fitting/curve', { params: { id: obj.id } })
 	}
 	tableColumn.value = res.data.title.map(o => {
 		return {
@@ -51,9 +51,16 @@ const funExcelChange = async (obj: any) => { //点击excel项时
 
 	if (chartResponse) {
 		chartRes = chartResponse.data
+		dataSet.value = JSON.stringify([
+			{
+				source: chartRes.scatterls
+			},
+			{
+				source: chartRes.scatterhs
+			}
+		])
 		seriesData.value = [
 			{
-				id: 1,
 				name: "实际功率",
 				type: "line",
 				symbol: "line", //设定为实心点
@@ -62,16 +69,15 @@ const funExcelChange = async (obj: any) => { //点击excel项时
 				data: chartRes.sjgl,
 				itemStyle: {
 					normal: {
-						color: "#05bb4c",
+						color: "rgb(158,138,103)",
 						lineStyle: {
-							color: "#05bb4c",
+							color: "rgb(158,138,103)",
 						},
 					},
 				},
 				xAxisIndex: 0,
 			},
 			{
-				id: 2,
 				name: "保证功率",
 				type: "line",
 				symbol: "line", //设定为实心点
@@ -89,21 +95,22 @@ const funExcelChange = async (obj: any) => { //点击excel项时
 				xAxisIndex: 0,
 			},
 			{
-				id: 3,
-        type: 'scatter',
+				type: 'effectScatter',
+				showEffectOn: "emphasis",
 				name: '无用点',
-        data: chartRes.scatterls,
-        // dimensions: ['x', 'y'],
-        symbolSize: 5,
-				encode:{
-					x: [0],
-					y: [1]
+				// data: chartRes.scatterls,
+				symbolSize: 5,
+				datasetIndex: 0,
+				encode: {
+					x: 's',
+					y: 'p'
 				},
-        large: true,
-        largeThreshold: 500,
+				animation: false,
+				// large: true,
+				// largeThreshold: 500,
 				xAxisIndex: 0,
 				yAxisIndex: 0,
-      },
+			},
 			// {
 			// 	name: "无用点",
 			// 	type: "effectScatter",
@@ -114,21 +121,30 @@ const funExcelChange = async (obj: any) => { //点击excel项时
 			// 	yAxisIndex: 0,
 			// },
 			{
-				id: 4,
-        type: 'scatter',
+				type: 'effectScatter',
+				showEffectOn: "emphasis",
 				name: '有用点',
-        data: chartRes.scatterhs,
-        // dimensions: ['x', 'y'],
-        symbolSize: 5,
-				encode:{
-					x: [0],
-					y: [1]
+				// data: chartRes.scatterhs,
+				symbolSize: 5,
+				datasetIndex: 1,
+				animation: false,
+				encode: {
+					x: 's',
+					y: 'p'
+				},
+				itemStyle: {
+					normal: {
+						color: "#05bb4c",
+						lineStyle: {
+							color: "#05bb4c",
+						},
+					},
 				},
-        large: true,
-        largeThreshold: 500,
+				// large: true,
+				// largeThreshold: 500,
 				xAxisIndex: 0,
 				yAxisIndex: 0,
-      },
+			},
 
 			// {
 			// 	name: "有用点",
@@ -201,7 +217,7 @@ const funCurrentChange = ({ current, currentNode }) => {
 				time: o.time,
 				type: o.type,
 				windturbine: o.windturbine,
-				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station+'_').length)
+				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
 			}
 		})
 	} else {
@@ -241,7 +257,7 @@ const funProcessCurrentChange = ({ current, currentNode }) => {
 				time: o.time,
 				type: o.type,
 				windturbine: o.windturbine,
-				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station+'_').length)
+				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
 			}
 		})
 	} else {
@@ -266,7 +282,7 @@ const funSubmit = async (query) => {
 		...query,
 		ids: excelCheckIds.value.join(',')
 	}
-	const res = await request.get('/power/fitting/data', {params: params})
+	const res = await request.get('/power/fitting/data', { params: params })
 	if (res.code === 200) {
 		ElMessage.success(res.msg)
 		funGetProcessTree()
@@ -275,9 +291,60 @@ const funSubmit = async (query) => {
 /**chart Data */
 const xAxisData = ref([])
 const seriesData = ref([])
-const funChartSelect = (selected) => {
-	console.log(selected)
+const dataSet = ref('')
+const funChartSelect = (batch) => {
+	wtTab.value = 'table'
+	console.log(batch)
+	const dataArr = []
+	const tempArr = [] //用于以风机id 聚合dataArr
+	let scatterls = []
+	let scatterhs = []
+	let dataSetObj = []
+	let id = 1
+	wtData.value = []
+	wtDialog.value = false
+	if (batch?.length && dataSet.value) {
+		scatterls = batch[0].selected[2].dataIndex
+		scatterhs = batch[0].selected[3].dataIndex
+		if (scatterls?.length || scatterhs?.length) {
+			dataSetObj = JSON.parse(dataSet.value)
+			if (scatterls?.length) {
+				for (const scatterIndex of scatterls) {
+					dataArr.push({...dataSetObj[0].source[scatterIndex], u: '否'})  // s p w u  w: '风机'
+				}
+			}
+			if (scatterhs?.length) {
+				for (const scatterIndex of scatterhs) {
+					dataArr.push({...dataSetObj[1].source[scatterIndex], u: '是'})
+				}
+			}
+			for(const data of dataArr){
+				if(tempArr.length){
+					const findIndex = tempArr.findIndex(o => o.w === data.w)
+					if(findIndex !== -1){
+						if(!tempArr[findIndex].children){
+							tempArr[findIndex].children = []
+						}
+						tempArr[findIndex].children.push({...data, id: id})
+						id++
+					}else{
+						tempArr.push({...data, id: id})
+						id++
+					}
+				}else{
+					tempArr.push({...data, id: id})
+					id++
+				}
+			}
+			wtData.value = tempArr
+			wtDialog.value = true
+		}
+	}
 }
+/**dialog 数据 */
+const wtDialog = ref(false)
+const wtData = ref([])
+const wtTab = ref('table')
 /**tab  */
 const activeTab = ref('1')
 /**created */
@@ -287,7 +354,25 @@ funGetProcessTree()
 <template>
 	<div class="bg-white pb-[10px]">
 		<search-cop @submit="funSubmit"></search-cop>
-		<el-row :gutter="20">
+		<el-dialog v-model="wtDialog" title="风机功率点位">
+			<el-tabs v-model="wtTab">
+				<el-tab-pane label="表格数据" name="table">
+					<el-table :data="wtData" row-key="id" :max-height="550">
+						<el-table-column property="w" align="center" label="风机" />
+						<el-table-column property="s" sortable align="center" label="风速(m/s)" />
+						<el-table-column property="p" sortable align="center" label="功率(kw)" />
+						<el-table-column property="u" 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>
+		<el-row :gutter="10">
 			<el-col :span="5">
 				<tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="true" :height="treeHeight"
 					@currentChange="funCurrentChange" @refresh="funGetTree"></tree-cop>
@@ -309,10 +394,11 @@ funGetProcessTree()
 						</el-tab-pane>
 						<table-cop v-show="activeTab === '1'" :data="tableData" :loading="tableLoading" :column="tableColumn"
 							:height="tableHeight" :tableId="tableShowId" :tableName="tableName"></table-cop>
-						<div v-show="activeTab === '2'" :style="{ height: typeof tableHeight === 'string' ? tableHeight: tableHeight + 'px' }" class="p-[10px]">
+						<div v-show="activeTab === '2'"
+							:style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }" class="p-[10px]">
 							<CurrentScatterChart width="100%" height="100%" chartTitle="风速功率曲线图" :xAxisData="xAxisData"
 								:yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData" :showLegend="true"
-								:brushSelected="true" @getSelected="funChartSelect" />
+								:brushSelected="true" :dataSet="dataSet" @getSelected="funChartSelect" />
 						</div>
 					</el-tabs>
 				</div>

+ 1 - 6
src/pages/dataFilter/prepare/components/search.vue

@@ -1,7 +1,6 @@
 <script lang="ts" setup name="search">
 import { onMounted, reactive, ref } from 'vue'
 import request from '@/api/axios.js'
-import { ElMessage } from 'element-plus';
 
 const queryForm = reactive({
 	station: '',
@@ -55,11 +54,7 @@ const funSubmit = async () => {
 			query.interval = 900
 			break;
 	}
-	const res = await request.get('/power/prepare/data', {params: query})
-	if (res.code === 200) {
-		ElMessage.success(res.msg)
-		emits('submit')
-	}
+	emits('submit', query)
 }
 /**created */
 funGetStation()

+ 1 - 1
src/pages/dataFilter/prepare/components/table.vue

@@ -22,7 +22,7 @@ const funExport = () => {
 const tableRef = ref('')
 const tableHeight =  computed(() => {
   console.log(tableRef.value.offsetHeight)
-  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 42 : 661
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 661
 })
 </script>
 <template>

+ 33 - 5
src/pages/dataFilter/prepare/index.vue

@@ -3,6 +3,7 @@ import searchCop from './components/search.vue'
 import excelCop from '@/components/excel.vue'
 import treeCop from '@/components/tree.vue'
 import tableCop from './components/table.vue'
+import { ElMessage } from 'element-plus';
 import { onMounted, ref } from 'vue'
 import request from "@/api/axios.js"
 import config from '@/api/config.js'
@@ -78,14 +79,40 @@ const funExport = async () => {
 	a.download = ''
 	a.click()
 }
-/**table 结束 */
+/**submit */
+const progress = ref(0)
+const funWebSocket = () => {
+	const webSocket = new WebSocket(`${config.socketURL}/ws/powerfitting/admin`)
+	webSocket.onerror = () => setTimeout(() => { funWebSocket() }, 2000)
+
+	webSocket.onmessage = (event) => {
+		console.log(event)
+		const message = JSON.parse(event.data)
+		if (message.code === 200) {
+			progress.value = Number(message.data) * 100
+			if (progress.value === 100) {
+				ElMessage.success('数据加载完成')
+				funGetTree()
+				progress.value = 0
+			}
+		}
+	}
+}
+const funSubmit = async (params) => {
+	const res = await request.get('/power/prepare/data', { params: params })
+	if (res.code === 200) {
+		ElMessage.success(res.msg)
+
+	}
+}
 /**created */
 funGetTree()
+funWebSocket()
 </script>
 <template>
-	<div class="bg-white">
-		<search-cop @submit="funGetTree"></search-cop>
-		<el-row :gutter="20">
+	<div class="bg-white pb-[10px] relative">
+		<search-cop @submit="funSubmit"></search-cop>
+		<el-row :gutter="10">
 			<el-col :span="5">
 				<tree-cop :data="treeData" :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree">
 				</tree-cop>
@@ -100,6 +127,7 @@ funGetTree()
 				</div>
 			</el-col>
 		</el-row>
-		<!-- <el-progress :percentage="50" class="mt-[5px] mb-[2px]" :indeterminate="false" color="rgb(19,206,102)" :stroke-width="4" :show-text="false" /> -->
+		<el-progress :percentage="progress" class="!absolute top-0 right-0 left-0" :indeterminate="false" color="rgb(19,206,102)"
+			:stroke-width="4" :show-text="false" />
 	</div>
 </template>

+ 1 - 1
src/pages/dataFilter/process/components/table.vue

@@ -22,7 +22,7 @@ const funExport = () => {
 const tableRef = ref('')
 const tableHeight =  computed(() => {
   console.log(tableRef.value.offsetHeight)
-  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 42 : 661
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 661
 })
 </script>
 <template>

+ 1 - 1
src/pages/dataFilter/process/index.vue

@@ -156,7 +156,7 @@ funGetProcessTree()
 <template>
 	<div class="bg-white pb-[10px]">
 		<search-cop @submit="funSubmit"></search-cop>
-		<el-row :gutter="20">
+		<el-row :gutter="10">
 			<el-col :span="5">
 				<tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="true" :height="treeHeight"
 					@currentChange="funCurrentChange" @refresh="funGetTree"></tree-cop>