Browse Source

2023-03-03 update

1. 调整hotAnalysis  合并 tempAnalysis 代码 . 并注释调temp的路由
2. tree组件增加dropdownMenu控制
3. combine页 增加右键保存功能
moccus 2 years ago
parent
commit
7769b184ec

+ 44 - 3
src/components/tree.vue

@@ -27,9 +27,10 @@
 					</span>
 					<template #dropdown>
 						<el-dropdown-menu>
-							<el-dropdown-item class="text-[#409EFF]" v-if="data.childs && data.childs.length" :command="{ type: 'export', data, node }">导出
+							<el-dropdown-item class="text-[#409EFF]" v-if="props.dropdownMenu.includes('save')" :command="{ type: 'save', data, node }">保存</el-dropdown-item>
+							<el-dropdown-item class="text-[#409EFF]" v-if="data.childs && data.childs.length && props.dropdownMenu.includes('export')" :command="{ type: 'export', data, node }">导出
 							</el-dropdown-item>
-							<el-dropdown-item class="text-[#F56C6C]" :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
+							<el-dropdown-item class="text-[#F56C6C]" v-if="props.dropdownMenu.includes('delete')" :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
 						</el-dropdown-menu>
 					</template>
 				</el-dropdown>
@@ -65,12 +66,17 @@ const props = withDefaults(
 		height?: number | string;
 		showCheckbox?: boolean;
 		type?: string;
+		dropdownMenu?: string[]
 	}>(),
 	{
 		data: () => [],
 		height: 400,
 		showCheckbox: false,
-		type: 'wind'
+		type: 'wind',
+		dropdownMenu: () => [
+			'export',
+			'delete',
+		]
 	}
 );
 
@@ -104,6 +110,41 @@ const funCheckChange = (
 //右键时, command菜单
 const funCommand = async ({ type, data, node }) => {
 	switch (type) {
+		case 'save': 
+			/**该保存功能目前暂用于风电场, combine页 */
+			if(props.type !== 'wind'){
+				return false
+			}
+			ElMessageBox.confirm("确认保存当前节点的拟合功率?", "保存", {
+				confirmButtonText: "确认",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(async () => {
+				let saveArr = [];
+				const repeatArr = (arr, saveArr) => {
+					for (const unit of arr) {
+						if (unit.childs?.length) {
+							saveArr.push(...unit.childs.map((o) => o.id));
+						} else if (unit.children?.length) {
+							repeatArr(unit.children, saveArr);
+						}
+					}
+				};
+				if (data.childs?.length) {
+					saveArr = data.childs.map((o) => o.id);
+				} else if (data.children?.length) {
+					repeatArr(data.children, saveArr);
+				}
+				let res = {code: 500}
+				res = await request.get("/power/fitting/curve/save", {
+					params: { ids: saveArr.join(",") },
+				}); //删除当前节点
+				
+				if (res.code === 200) {
+					ElMessage.success(res.msg);
+				}
+			});
+			break;
 		case "export":
 			ElMessageBox.confirm("确认导出当前节点的所有数据?", "导出", {
 				confirmButtonText: "确认",

+ 1 - 1
src/pages/dataAnalysis/combine/index.vue

@@ -526,7 +526,7 @@ onActivated(() => {
 				<el-col :span="5">
 					<tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="true" :height="treeHeight"
 						@currentChange="funCurrentChange" @refresh="funGetTree"></tree-cop>
-					<tree-cop class="mt-[10px]" :data="processTreeData" :height="treeHeight"
+					<tree-cop class="mt-[10px]" :dropdownMenu="['export','delete','save']" :data="processTreeData" :height="treeHeight"
 						@currentChange="funProcessCurrentChange" @refresh="funGetProcessTree"></tree-cop>
 				</el-col>
 				<el-col :span="3">

+ 397 - 0
src/pages/dataAnalysis/hotAnalysis/components/barChart.json

@@ -0,0 +1,397 @@
+
+{
+	"color": [
+			"#db60c8",
+			"#c12e34",
+			"#e6b600d9",
+			"#0098d9",
+			"#465a83",
+			"#005eaa",
+			"#cda819",
+			"#32a487"
+	],
+	"backgroundColor": "rgba(0,0,0,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#000"
+			},
+			"subtextStyle": {
+					"color": "#000"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			},
+			"barMaxWidth": 50
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#c12e34",
+					"color0": "#2b821d",
+					"borderColor": "#c12e34",
+					"borderColor0": "#2b821d",
+					"borderWidth": 1
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": 1,
+					"color": "#aaaaaa"
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#c12e34",
+					"#e6b600",
+					"#0098d9",
+					"#50ec39",
+					"#005eaa",
+					"#339ca8",
+					"#cda819",
+					"#32a487"
+			],
+			"label": {
+					"color": "#eeeeee"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": false,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#06467c"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#4187c2"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#838383B3B3B3"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#005eaa",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#005eaa",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#005eaa",
+					"borderColor": "#005eaa",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#005eaa",
+					"borderColor": "#316bc2"
+			},
+			"label": {
+					"color": "#005eaa"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#005eaa"
+					},
+					"controlStyle": {
+							"color": "#005eaa",
+							"borderColor": "#005eaa",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#005eaa"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#1790cf",
+					"#a2d4e6"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(47,69,84,0)",
+			"dataBackgroundColor": "rgba(47,69,84,0.3)",
+			"fillerColor": "rgba(167,183,204,0.4)",
+			"handleColor": "#a7b7cc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#838383B3B3B3"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#eeeeee"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#eeeeee"
+					}
+			}
+	}
+}

+ 199 - 0
src/pages/dataAnalysis/hotAnalysis/components/barChart.vue

@@ -0,0 +1,199 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './barChart.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import {useStore} from 'vuex'
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"rgb(50,93,171)",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				trigger: "axis",
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const store = useStore()
+const collapse = computed({
+	get(){
+		return store.state.collapse
+	},
+	set(val){}
+})
+watch(collapse, (val) => {
+	if(chartIns.value){
+		setTimeout(() => {
+			chartIns.value?.resize()
+		},300)
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 200 - 0
src/pages/dataAnalysis/hotAnalysis/components/lineChart.vue

@@ -0,0 +1,200 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './../rateAnalysis.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import {useStore} from 'vuex'
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"#325dab",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				axisPointer: {
+            type: "cross",
+          },
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const store = useStore()
+const collapse = computed({
+	get(){
+		return store.state.collapse
+	},
+	set(val){}
+})
+watch(collapse, (val) => {
+	if(chartIns.value){
+		setTimeout(() => {
+			chartIns.value?.resize()
+		},300)
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 425 - 102
src/pages/dataAnalysis/hotAnalysis/index.vue

@@ -1,34 +1,41 @@
 <script setup name="prepare">
-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 barChartCop from './components/barChart.vue'
+import lineChartCop from './components/lineChart.vue'
 import SubmitBtn from '@/components/SubmitBtn.vue'
-import { ref, nextTick, onActivated, onMounted, reactive } from 'vue'
+import { shallowRef, ref, nextTick, onActivated, onMounted, reactive } from 'vue'
 import request from '@/api/axios.js'
+import tools from '@tools/htmlToPdf.js'
 import { ElMessage } from 'element-plus'
 import util from "@tools/util";
 import CurrentScatterChart from './components/current-scatter-chart.vue'
-// import dotRes from '@/data/dot.json'
-// import tableRes from '@/data/table.json'
-// import areaDataRes from '@/data/areaData.json'
 /**配置参数 */
 const treeHeight = ref(window.innerHeight - 150 + 'px') //tree高度
 const excelHeight = ref(window.innerHeight - 150 + 'px') //excel高度
 const tableHeight = ref(window.innerHeight - 204 + 'px')
+/** 额定功率 */
+const powerproduction = ref("")
 /**excel 开始 */
 const excelCheckboxShow = ref(false)
-const excelType = ref('')
 const excelCheckIds = ref([])
 const excelList = ref([])
 const funExcelChange = async (obj) => { //点击excel项时
+	/**次代码供温度功率曲线分析使用 */
+	excelCheckIds.value = [obj.id] //当为单选展示风机图表时
+	chartExcelList.value = excelList.value.map(o=> {
+		return {
+			...o,
+			name: o.windturbine
+		}
+	})  // 选中excel当前项时, excel列表赋值给dialog 下拉框
+	queryForm.checkIds = excelList.value.map(o => o.id)
+	checkAll.value = true
+	funSubmit()
+	/**---------------------------- */
 	activeTab.value = '1'
 	isChartArea.value = false
-	tableShowId.value = obj.id
-	tableName.value = obj.name
-	excelType.value = obj.type // 接收excel的type 用于控制右侧tab展示
 
-	let res = null
 	let chartRes = {
 		scatterhs: [[]],
 		scatterls: [[]],
@@ -37,29 +44,9 @@ const funExcelChange = async (obj) => { //点击excel项时
 		cpz: [[]]
 	}
 	let chartResponse = null
-	tableLoading.value = true
-	if (obj.type === 'process') {
-		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 } })
-		// res = tableRes
-		// chartResponse = dotRes
+	if (obj.type === 'fitting') {
 		chartResponse = await request.get('/temperature/curve/analysis', { params: { id: obj.id, p: 1 } })
 	}
-	if(res.code === 200){
-		tableColumn.value = res.data.title.map(o => {
-			return {
-				prop: o.key,
-				width: o.des==='时间'? 100: 80,
-				label: o.des,
-			}
-		})
-		tableData.value = res.data.data
-		tableLoading.value = false
-	}else{
-		tableLoading.value = false
-	}
 
 	if (chartResponse && chartResponse.code === 200) {
 		chartRes = chartResponse.data
@@ -118,37 +105,30 @@ const funExcelChange = async (obj) => { //点击excel项时
 		]
 	}
 }
-const funExcelCheckChange = ({ checkArr, data }) => {   //bug 
+const funExcelCheckChange = ({ checkArr, data }) => {
 	excelCheckIds.value = checkArr
 }
-/**excel fitData */
-const excelFitList = ref([])
 /**prepare tree 开始 */
 const treeData = ref([])
 const actTreeNode = ref(null) //当前激活的treeNode
-const funRepeatMap = (arr, type='prepare') => {
+const funRepeatMap = (arr) => {
 	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 === 'process'){ //判断当且仅有process获取tree时 赋值
+				if(!actTreeNode.value){ //判断当且仅有process获取tree时 赋值
 					actTreeNode.value = o
 				}
 			}
 		}
 		return {
 			...o,
-			children: o.children ? funRepeatMap(o.children, type) : []
+			children: o.children ? funRepeatMap(o.children) : []
 		}
 	})
 }
-const funGetTree = async () => {
-	const res = await request.get("/power/process/tree")
-	treeData.value = funRepeatMap(res.data)
-	excelList.value = []
-}
 const funCurrentChange = ({ current, currentNode }) => {
 	excelCheckboxShow.value = true
 	if (current.childs) {
@@ -169,28 +149,14 @@ const funCurrentChange = ({ current, currentNode }) => {
 		excelList.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)
-				}
-			}
-		}
-	}
-	excelCheckIds.value = checkIds
-}
 
 /**process tree 开始 */
 const processTreeData = ref([])
-const funGetProcessTree = async (flag = true) => { //flag控制是否获取tree的第一项 true为可获取
+const funGetProcessTree = async () => { //flag控制是否获取tree的第一项 true为可获取
 	actTreeNode.value = null
 	const res = await request.get("/power/fitting/tree")
-	excelFitList.value = []
-	processTreeData.value = funRepeatMap(res.data, flag? 'process' : 'prepare') //flag控制对actTreeNode赋值
+	excelList.value = []
+	processTreeData.value = funRepeatMap(res.data) //flag控制对actTreeNode赋值
 	if(actTreeNode.value){
 		funProcessCurrentChange({current: actTreeNode.value, currentNode: null})
 		const child = actTreeNode.value.childs[0]
@@ -210,7 +176,7 @@ const funGetProcessTree = async (flag = true) => { //flag控制是否获取tree
 }
 const funProcessCurrentChange = ({ current, currentNode }) => {
 	if (current.childs) {
-		excelFitList.value = current.childs.map(o => {
+		excelList.value = current.childs.map(o => {
 			return {
 				id: o.id,
 				interval: o.interval,
@@ -224,41 +190,189 @@ const funProcessCurrentChange = ({ current, currentNode }) => {
 			}
 		})
 	} else {
-		excelFitList.value = []
+		excelList.value = []
 	}
 }
 
-/**table 开始 */
-const tableShowId = ref('')
-const tableColumn = ref([])
-const tableLoading = ref(false)
-const tableName = ref('')
-const tableData = ref([])
-/**table 结束 */
+/**chart */
+let chartId = 1
+const powerproductionNum = ref(0)
 /**search 开始 */
-const funSubmit = async (query) => {
-	if (!excelCheckIds.value.length) {
-		ElMessage.error('请勾选要预处理的项')
-		return false
+const funSubmit = async () => {
+	const tempRes = await request.get('/temperature/rated/power', {
+		params: {
+			ids: excelCheckIds.value.join(','),
+		}
+	})
+	if (tempRes.code === 200) {
+		if (tempRes.data?.length) {
+			for (const chart of tempRes.data) {
+				powerproduction.value = `(额定功率=${chart.power.powerproduction}kW)` 
+				powerproductionNum.value = chart.power.powerproduction
+				barxAxis.data = Object.keys(chart.res1)
+				barSeries[0].data = Object.values(chart.res1)
+				barSeries[0].markLine.data = [{
+					yAxis: 0,
+				}]
+				chartId++
+				lineSeries.value = [
+					{
+						type: 'effectScatter',
+						showEffectOn: "emphasis",
+						rippleEffect: {
+							scale: 1
+						},
+						legendHoverLink: false,
+						name: '',
+						symbolSize: 5,
+						data: chart.res2,
+						yAxisIndex: 0,
+						markLine: {
+							symbol: 'none',
+							label: {
+								show: false,
+							},
+							lineStyle: {
+								color: '#F72C5B'
+							},
+							data: [{
+								yAxis: powerproductionNum.value,
+							}]
+						}
+					}
+				]
+				chartId++
+			}
+		}
+	}
+}
+/**lineChart */
+const linexAxis = reactive({
+	type: 'value',
+	name: '°C',
+	splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	},
+	axisLine: {
+		onZero: false
 	}
-	const params = {
-		...query,
-		ids: excelCheckIds.value.join(',')
+})
+const lineyAxis = reactive([
+	{
+		type: 'value',
+		name: 'kW',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	},
+	axisLine: {
+		onZero: false
 	}
-	const res = await request.get('/power/fitting/data', { params: params })
-	if (res.code === 200) {
-		ElMessage.success(res.msg)
-		funGetProcessTree(false) //阻止获取tree第一项数据及图表
-		const excelInfo = res.data
-
-		/**拟合完成后 显示右侧图表及数据 */
-		funExcelChange({
-			id: excelInfo.id,
-			name: excelInfo.path.substring(excelInfo.path.indexOf(excelInfo.station + '_') + (excelInfo.station + '_').length),
-			type: 'fitting'
-		})
+	}
+])
+const lineSeries = ref([])
+const lineDataSet = reactive([
+	{
+		source: []
+	}
+])
+// 圈选散点触发函数
+const funChartSelect = async (batch) => {
+	const wDataArr = []
+	const yDataArr = []
+	let scatterls = []
+	let dataSetObj = []
+	wtData.value = []
+	if (batch?.length && actCopList.value[0]?.dataset) {
+		scatterls = batch[0].selected[1].dataIndex
+		if (scatterls?.length) {
+			dataSetObj = JSON.parse(actCopList.value[0].dataset)
+			if (scatterls?.length) {
+				for (const scatterIndex of scatterls) {
+					wDataArr.push(dataSetObj[0].source[scatterIndex].k)
+				}
+			}
+			const wtRes = await request.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
+					})
+				}
+			}
+		}
 	}
 }
+/**barChart */
+const barxAxis = reactive({
+	type: 'category',
+	name: '℃',
+	data: [],
+	splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	},
+	axisLine: {
+		onZero: false
+	}
+})
+const baryAxis = reactive({
+		type: 'value',
+		name: 'kW',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	},
+	axisLine: {
+		onZero: false
+	}
+})
+const barSeries = reactive([{
+	name: "",
+	type: "bar",
+	data: [],
+	markLine: {
+		symbol: 'none',
+		label: {
+			show: false,
+		},
+		lineStyle: {
+			color: '#F72C5B'
+		},
+		data: []
+	}
+}])
 /**chart Data */
 const avgObj = reactive({ //平均cpz等
 	title: '',
@@ -277,7 +391,7 @@ const chartRef = ref() //chart 的ref
 const seriesData = ref([])
 const isChartArea = ref(false) // 用来控制图表是否区域划分
 const dataSet = ref('')
-const funChartSelect = async (batch) => {
+const funhotChartSelect = async (batch) => {
 	const wDataArr = []
 	const yDataArr = []
 	let scatterls = []
@@ -436,10 +550,187 @@ const funChartArea = () => {
 const wtDialog = ref(false)
 const wtData = ref([])
 const wtTab = ref('table')
+/**dialog */
+const dialog = 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 = chartExcelList.value.map(o => o.id)
+	}else{
+		queryForm.checkIds = []
+	}
+}
+const chartExcelList = ref([]) //dialog 下拉项
+const funActCop = (obj, type) => {
+	switch(type){
+		case 'barChartCop':
+			actChartName.value = 'barChartCop'
+			obj.actCop = shallowRef(barChartCop)
+			actDiaTitle.value = '平均功率-额定功率'
+			break
+		case 'lineChartCop':
+			actChartName.value = 'lineChartCop'
+			obj.actCop = shallowRef(lineChartCop)
+			actDiaTitle.value = '额定功率温度分析'
+			break
+		// case 'CurrentScatterChartCop':
+		// 	actChartName.value = 'CurrentScatterChartCop'
+		// 	obj.actCop = shallowRef(CurrentScatte		console.log(res)rChartCop)
+		// 	actDiaTitle.value = '静态偏航对风分析图'
+		// 	break
+	}
+	obj.isBrush = false
+	obj.id = chartId
+	chartId ++
+	dialog.value = true
+	actCopListBak.value = []
+	nextTick(() => {
+		actCopList.value = [obj]
+	})
+}
+const funDiaSubmit = async () => {
+	let url = ''
+	switch(actChartName.value){
+		case 'barChartCop':
+			url = '/temperature/rated/power'
+			break
+		case 'lineChartCop':
+			url = '/temperature/rated/power'
+			break
+		// case 'CurrentScatterChartCop':
+		// 	url = '' //暂无接口
+		// 	break
+	}
+	if(url){
+		const res = await request.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==='barChartCop'){
+						actCopList.value.push({
+							id: chartId,
+							isBrush: false,
+							actCop: shallowRef(barChartCop),
+							title: chart.wt,
+							subtext: `平均功率-额定功率(额定功率=${chart.power.powerproduction}kW)`,
+							xAxis: {
+								...barxAxis,
+								data: Object.keys(chart.res1)
+							},
+							yAxis: baryAxis,
+							series: [{
+								name: "",
+								type: "bar", 
+								data: Object.values(chart.res1),
+								markLine: {
+									symbol: 'none',
+									label: {
+										show: false,
+									},
+									lineStyle: {
+										color: '#F72C5B'
+									},
+									data: [{
+										yAxis: 0,
+									}]
+								}
+							}]
+						})
+						chartId++
+					}
+					if(actChartName.value === 'lineChartCop'){
+						actCopList.value.push({
+							id: chartId,
+							isBrush: false,
+							actCop: shallowRef(lineChartCop),
+							title: chart.wt,
+							subtext: `额定功率温度分析(额定功率=${chart.power.powerproduction}kW)`,
+							xAxis: linexAxis,
+							yAxis: lineyAxis,
+							dataset: lineDataSet,
+							series: [
+								{
+									type: 'effectScatter',
+									showEffectOn: "emphasis",
+									rippleEffect: {
+										scale: 1
+									},
+									legendHoverLink: false,
+									name: '',
+									symbolSize: 5,
+									data: chart.res2,
+									yAxisIndex: 0,
+									markLine: {
+										symbol: 'none',
+										label: {
+											show: false,
+										},
+										lineStyle: {
+											color: '#F72C5B'
+										},
+										data: [{
+											yAxis: chart.power.powerproduction,
+										}]
+									}
+								}
+							]
+
+						})
+						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]
+		}
+	}
+}
 /**tab  */
 const activeTab = ref('1')
 /**created */
-// funGetTree()
 // funGetProcessTree()
 /**mounted */
 onMounted(() => {
@@ -460,7 +751,6 @@ onMounted(() => {
 })
 /**activated */
 onActivated(() => {
-	// funGetTree()
 	funGetProcessTree()
 })
 </script>
@@ -468,6 +758,27 @@ onActivated(() => {
 	<div class="bg-white py-[10px] px-[10px]">
 		<!-- <search-cop class="mb-[20px]  shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
 		</search-cop> -->
+		<el-dialog draggable width="80%" v-model="dialog" :title="actDiaTitle">
+			<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 chartExcelList" :key="item.id" :value="item.id" :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 ref="diaPanelRef" class="flex flex-wrap justify-center items-center h-[650px] overflow-y-auto overflow-x-hidden">
+					<component :is="item.actCop" :width="actCopList.length > 1 ? '50%' : '100%'" height="100%" v-for="item in actCopList"
+						:key="item.id" :xAxis="item.xAxis" :subtext="item.subtext" :title="item.title"
+						:series="item.series" :isDiaAlone="(actCopList.length === 1)" @dblclick="funDbClick(item)" :yAxis="item.yAxis" :dataset="item.dataset" :brush="item.isBrush" @getSelected="funChartSelect"></component>
+				</div>
+			</div>
+		</el-dialog>
 		<el-dialog v-model="wtDialog" draggable title="风机功率点位">
 			<el-tabs v-model="wtTab">
 				<el-tab-pane label="数据" name="table">
@@ -492,33 +803,45 @@ onActivated(() => {
 			<div class="text-[14px] absolute top-[-7px] text-[#838383] left-[20px]">数据展示</div>
 			<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> -->
 					<tree-cop :data="processTreeData" :height="treeHeight"
 						@currentChange="funProcessCurrentChange" @refresh="funGetProcessTree"></tree-cop>
 				</el-col>
 				<el-col :span="3">
-					<!-- <excel-cop :checkIds="excelCheckIds" :showCheckbox="excelCheckboxShow" :data="excelList" :height="excelHeight"
-						@excelChange="funExcelChange" @checkChange="funExcelCheckChange"></excel-cop> -->
-					<excel-cop :data="excelFitList" :height="excelHeight" @excelChange="funExcelChange">
+					<excel-cop :data="excelList" :height="excelHeight" @excelChange="funExcelChange">
 					</excel-cop>
 				</el-col>
 				<el-col :span="16">
 					<div class="px-[10px] shadow rounded-[6px] shadow-blue-500 ">
 						<!-- <SubmitBtn class="absolute right-[16px] top-[6px] z-10" desc="区域划分" v-if="activeTab === '2' && excelType === 'fitting'" @click="funChartArea"></SubmitBtn> -->
 						<el-tabs v-model="activeTab">
-							<el-tab-pane label="表格数据" name="1">
+							<el-tab-pane label="温度与功率" name="1">
 							</el-tab-pane>
-							<el-tab-pane label="图表展示" name="2" v-if="excelType === 'fitting'">
+							<el-tab-pane label="温度曲线" name="2">
 							</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'"
+							<div v-show="activeTab === '1'" :style="{ height: tableHeight }"
+								class="flex flex-wrap justify-center items-center overflow-x-hidden overflow-y-auto ">
+								<div class="mb-[10px] w-[100%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
+									<el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+										@click="funActCop({xAxis:barxAxis, yAxis:baryAxis, series: barSeries}, 'barChartCop')">
+										<ZoomIn />
+									</el-icon>
+									<bar-chart-cop width="100%" height="100%" :subtext="`平均功率-额定功率 ${powerproduction}`" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+								</div>
+								<div class="w-[100%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
+									<el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+										@click="funActCop({xAxis:linexAxis, yAxis:lineyAxis, series: lineSeries}, 'lineChartCop')">
+										<ZoomIn />
+									</el-icon>
+									<line-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis" :yAxis="lineyAxis"
+										:series="lineSeries" :subtext="`额定功率温度分析 ${powerproduction}`" :dataset="lineDataSet"></line-chart-cop>
+								</div>
+							</div>
+							<div v-if="activeTab === '2'"
 								:style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }"
 								class="p-[10px]">
 								<CurrentScatterChart ref="chartRef" width="100%" :height="`calc( ${tableHeight} - 20px )`" :chartTitle="avgObj.title+ '&nbsp;&nbsp;' +'平均Cp值:'+avgObj.cpavg+'; 静风频率:'+avgObj.frequency+'%; 曲线偏差率:'+avgObj.pcratio+'%'"
 									:xAxisData="xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData"
-									:showLegend="true" :brushSelected="false" :dataSet="dataSet" @getSelected="funChartSelect" />
+									:showLegend="true" :brushSelected="false" :dataSet="dataSet" @getSelected="funhotChartSelect" />
 							</div>
 						</el-tabs>
 					</div>

+ 393 - 0
src/pages/dataAnalysis/hotAnalysis/rateAnalysis.json

@@ -0,0 +1,393 @@
+
+{
+	"color": [
+			"#3fb1e3",
+			"#6be6c1",
+			"#626c91",
+			"#a0a7e6",
+			"#c4ebad",
+			"#96dee8"
+	],
+	"backgroundColor": "rgba(252,252,252,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#000"
+			},
+			"subtextStyle": {
+					"color": "#000"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "2"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": true
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "3"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			}
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#e6a0d2",
+					"color0": "transparent",
+					"borderColor": "#e6a0d2",
+					"borderColor0": "#3fb1e3",
+					"borderWidth": "2"
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": "1",
+					"color": "#cccccc"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#3fb1e3",
+					"#6be6c1",
+					"#626c91",
+					"#a0a7e6",
+					"#c4ebad",
+					"#96dee8"
+			],
+			"label": {
+					"color": "#ffffff"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#838383"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383",
+					"fontSize": 10
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#838383"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#999999"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#666666"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#626c91",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#626c91",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#626c91",
+					"borderColor": "#626c91",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#3fb1e3",
+					"borderColor": "#3fb1e3"
+			},
+			"label": {
+					"color": "#626c91"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#626c91"
+					},
+					"controlStyle": {
+							"color": "#626c91",
+							"borderColor": "#626c91",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#626c91"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#2a99c9",
+					"#afe8ff"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(255,255,255,0)",
+			"dataBackgroundColor": "rgba(222,222,222,1)",
+			"fillerColor": "rgba(114,230,212,0.25)",
+			"handleColor": "#cccccc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#ffffff"
+					}
+			}
+	}
+}

+ 5 - 1
src/pages/dataAnalysis/lineAnalysis/components/barChart.vue

@@ -16,6 +16,10 @@ const props = defineProps({
 		type: Array,
 		required: false
 	},
+	colors: {
+		type: Array,
+		default: () => []
+	},
 	series: {
 		type: Array,
 		required: true
@@ -54,7 +58,7 @@ const props = defineProps({
 const option = computed({
 	get() {
 		return {
-			color:[
+			color: props.colors.length? props.colors: [
 				"rgb(50,93,171)",
 				"rgb(222,132,82)",
 				"rgb(105,188,80)",

+ 65 - 8
src/pages/dataAnalysis/lineAnalysis/index.vue

@@ -250,6 +250,7 @@ const funChartArea = () => {
 }
 const funTimeArea = async () => {
 	if(seriesData.value?.length){
+		activeTab.value = '1'
 		//获取数据
 		const res = await request.get('/power/fitting/time',{params: {ids: excelCheckIds.value.join(',')}})
 		console.log(res)
@@ -281,10 +282,34 @@ const funTimeArea = async () => {
 				stack: 'a',
 				data: [],
 			}]
+			barUnWorkSeries.value = [{
+				name: "3~5m风速",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "5~10m风速",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "10~12m风速",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "12~25m风速",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			}]
 			for(const wtObj of res.data){
 				barxAxis.data.push(wtObj.wtId)
-				for(const timeKey in wtObj.time){
-					barSeries.value[timeKey].data.push((wtObj.time[timeKey]/60).toFixed(0))
+				for(const timeKey in wtObj.time1){
+					barSeries.value[timeKey].data.push((wtObj.time1[timeKey]/60).toFixed(0))
+				}
+				for(const time2Key in wtObj.time2){
+					barUnWorkSeries.value[time2Key].data.push((wtObj.time2[time2Key]/60).toFixed(0))
 				}
 			}
 			tmDialog.value = true
@@ -294,6 +319,7 @@ const funTimeArea = async () => {
 /**dialog 数据 */
 const wtDialog = ref(false)
 const wtData = ref([])
+const activeTab = ref('1')
 /**tmdialog 数据 */
 const tmDialog = ref(false)
 const barxAxis = reactive({
@@ -317,27 +343,48 @@ const baryAxis = ref({
 	}
 })
 const barSeries = ref([{
-	name: "3~5m功率",
+	name: "不运行",
 	type: "bar",
 	stack: 'a',
 	data: [],
 },{
-	name: "5~10m功率",
+	name: "3~5m风速",
 	type: "bar",
 	stack: 'a',
 	data: [],
 },{
-	name: "10~12m功率",
+	name: "5~10m风速",
 	type: "bar",
 	stack: 'a',
 	data: [],
 },{
-	name: "12~25m全功率",
+	name: "10~12m风速",
 	type: "bar",
 	stack: 'a',
 	data: [],
 },{
-	name: "不运行",
+	name: "12~25m风速",
+	type: "bar",
+	stack: 'a',
+	data: [],
+}])
+const barUnWorkSeries = ref([{
+	name: "3~5m风速",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "5~10m风速",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "10~12m风速",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "12~25m风速",
 	type: "bar",
 	stack: 'a',
 	data: [],
@@ -370,7 +417,17 @@ onActivated(() => {
 <template>
   <div class="bg-white py-[10px] px-[10px] s-dialog-body">
 		<el-dialog draggable width="1000px" v-model="tmDialog" title="时间占比">
-			<bar-chart-cop height="700px" width="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+			<el-tabs v-model="activeTab">
+				<el-tab-pane label="运行时间" name="1">
+				</el-tab-pane>
+				<el-tab-pane label="不运行时间" name="2"></el-tab-pane>
+				<div  v-if="activeTab === '1'">
+					<bar-chart-cop height="700px" width="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+				</div>
+				<div v-if="activeTab === '2'">
+					<bar-chart-cop height="700px" :colors='["rgb(222,132,82)","rgb(105,188,80)","rgb(197,78,82)","rgb(129,114,181)"]' width="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barUnWorkSeries"></bar-chart-cop>
+				</div>
+			</el-tabs>
 		</el-dialog>
     <el-dialog draggable v-model="wtDialog" title="曲线偏差率">
 			<el-table :data="wtData" row-key="id" :max-height="550">

+ 14 - 14
src/router/index.js

@@ -115,25 +115,25 @@ const routes = [{
                     path: '/dataAnalysis/hotAnalysis',
                     name: 'dataAnalysisthotAnalysis',
                     meta: {
-                        title: '温度曲线分析',
+                        title: '温度与功率分析',
                     },
                     component: () =>
                         import(
                             '../pages/dataAnalysis/hotAnalysis/index.vue'
                         ),
                 },
-                {
-                    icon: 'el-icon-s-home',
-                    path: '/dataAnalysis/tempAnalysis',
-                    name: 'dataAnalysistempAnalysis',
-                    meta: {
-                        title: '温度与功率曲线分析',
-                    },
-                    component: () =>
-                        import(
-                            '../pages/dataAnalysis/tempAnalysis/index.vue'
-                        ),
-                },
+                // {
+                //     icon: 'el-icon-s-home',
+                //     path: '/dataAnalysis/tempAnalysis',
+                //     name: 'dataAnalysistempAnalysis',
+                //     meta: {
+                //         title: '温度与功率曲线分析',
+                //     },
+                //     component: () =>
+                //         import(
+                //             '../pages/dataAnalysis/tempAnalysis/index.vue'
+                //         ),
+                // },
                 {
                     icon: 'el-icon-s-home',
                     path: '/dataAnalysis/agcAnalysis',
@@ -151,7 +151,7 @@ const routes = [{
                     path: '/dataAnalysis/windAnalysis',
                     name: 'dataAnalysisWindAnalysis',
                     meta: {
-                        title: '风机绩效榜',
+                        title: '损失电量分析',
                     },
                     component: () =>
                         import(