趋势图
This commit is contained in:
72
frontend/src/utils/echartMethod.ts
Normal file
72
frontend/src/utils/echartMethod.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
const dataProcessing = (arr: any[]) => {
|
||||||
|
return arr
|
||||||
|
.filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
|
||||||
|
.map(item => (typeof item === 'number' ? item : parseFloat(item)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateValue = (o: number, value: number, num: number, isMin: boolean) => {
|
||||||
|
if (value === 0) {
|
||||||
|
return 0
|
||||||
|
} else if (value > 0 && Math.abs(value) < 1 && isMin == true) {
|
||||||
|
return 0
|
||||||
|
} else if (value > -1 && value < 0 && isMin == false) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let base
|
||||||
|
if (Math.abs(o) >= 100) {
|
||||||
|
base = 100
|
||||||
|
} else if (Math.abs(o) >= 10) {
|
||||||
|
base = 10
|
||||||
|
} else if (Math.abs(o) >= 1) {
|
||||||
|
base = 1
|
||||||
|
} else {
|
||||||
|
const multiple = 1 / 0.1
|
||||||
|
|
||||||
|
base = Math.ceil(Math.abs(o) * multiple) / multiple
|
||||||
|
}
|
||||||
|
|
||||||
|
let calculatedValue
|
||||||
|
if (isMin) {
|
||||||
|
if (value < 0) {
|
||||||
|
calculatedValue = value + num * value
|
||||||
|
} else {
|
||||||
|
calculatedValue = value - num * value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value < 0) {
|
||||||
|
calculatedValue = value - num * value
|
||||||
|
} else {
|
||||||
|
calculatedValue = value + num * value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base === 0.1) {
|
||||||
|
return parseFloat(calculatedValue.toFixed(1))
|
||||||
|
} else if (isMin) {
|
||||||
|
return Math.floor(calculatedValue / base) * base
|
||||||
|
} else {
|
||||||
|
return Math.ceil(calculatedValue / base) * base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理y轴最大最小值
|
||||||
|
export const yMethod = (arr: any) => {
|
||||||
|
const num = 0.2
|
||||||
|
const numList = dataProcessing(arr)
|
||||||
|
let maxValue = 0
|
||||||
|
let minValue = 0
|
||||||
|
let max = 0
|
||||||
|
let min = 0
|
||||||
|
maxValue = Math.max(...numList)
|
||||||
|
minValue = Math.min(...numList)
|
||||||
|
const o = maxValue - minValue == 0 ? maxValue : maxValue - minValue
|
||||||
|
min = calculateValue(o, minValue, num, true)
|
||||||
|
|
||||||
|
max = calculateValue(o, maxValue, num, false)
|
||||||
|
|
||||||
|
return [min, max]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
265
frontend/src/views/home/components/compareDataCheckChart.vue
Normal file
265
frontend/src/views/home/components/compareDataCheckChart.vue
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 历史趋势数据 -->
|
||||||
|
<div class="history_chart">
|
||||||
|
<MyEchart ref="historyChart" :options="echartsData"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { yMethod } from '@/utils/echartMethod'
|
||||||
|
import MyEchart from '@/components/echarts/line/index.vue'
|
||||||
|
import { CheckData } from '@/api/check/interface'
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
tableData: {
|
||||||
|
type: Array as () => CheckData.TableRow[],
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听 tableData 变化并触发 setEchart
|
||||||
|
watch(() => prop.tableData, (newTableData) => {
|
||||||
|
|
||||||
|
console.log("🚀 ~ .then ~ newTableData:", newTableData)
|
||||||
|
// // 更新 chartsList 数据
|
||||||
|
// chartsList.value = newTableData
|
||||||
|
// // 调用 setEchart 更新图表
|
||||||
|
// setEchart()
|
||||||
|
}, {
|
||||||
|
immediate: true, // 立即执行一次
|
||||||
|
deep: true // 深度监听
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const color = [
|
||||||
|
'var(--el-color-primary)',
|
||||||
|
'#07CCCA',
|
||||||
|
'#00BFF5',
|
||||||
|
'#FFBF00',
|
||||||
|
'#77DA63',
|
||||||
|
'#D5FF6B',
|
||||||
|
'#Ff6600',
|
||||||
|
'#FF9100',
|
||||||
|
'#5B6E96',
|
||||||
|
'#66FFCC',
|
||||||
|
'#B3B3B3'
|
||||||
|
]
|
||||||
|
|
||||||
|
const chartsList = ref<any>([])
|
||||||
|
|
||||||
|
const echartsData = ref<any>(null)
|
||||||
|
//初始化趋势图
|
||||||
|
const lineStyle = [{ type: 'solid' }, { type: 'dashed' }, { type: 'dotted' }]
|
||||||
|
|
||||||
|
const setEchart = () => {
|
||||||
|
echartsData.value = {}
|
||||||
|
//icon图标替换legend图例
|
||||||
|
|
||||||
|
// y轴单位数组
|
||||||
|
let unitList: any = []
|
||||||
|
|
||||||
|
let groupedData = chartsList.value.reduce((acc: any, item: any) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.unit
|
||||||
|
} else {
|
||||||
|
key = item.anotherName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
let result = Object.values(groupedData)
|
||||||
|
console.log("🚀 ~ .then ~ result:", result)
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
unitList = result.map((item: any) => {
|
||||||
|
return item[0].unit
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
echartsData.value = {
|
||||||
|
legend: {
|
||||||
|
itemWidth: 20,
|
||||||
|
itemHeight: 20,
|
||||||
|
itemStyle: { opacity: 0 }, //去圆点
|
||||||
|
type: 'scroll', // 开启滚动分页
|
||||||
|
// orient: 'vertical', // 垂直排列
|
||||||
|
top: 5,
|
||||||
|
right: 70
|
||||||
|
// width: 550,
|
||||||
|
// height: 50
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '80px'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
axisPointer: {
|
||||||
|
type: 'cross',
|
||||||
|
label: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
opacity: 0.35,
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||||
|
borderWidth: 0,
|
||||||
|
formatter(params: any) {
|
||||||
|
const xname = params[0].value[0]
|
||||||
|
let str = `${xname}<br>`
|
||||||
|
params.forEach((el: any, index: any) => {
|
||||||
|
let marker = ''
|
||||||
|
|
||||||
|
if (el.value[3] == 'dashed') {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
marker += `<span style="display:inline-block;border: 2px ${el.color} solid;margin-right:5px;width:10px;height:0px;background-color:#ffffff00;"></span>`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
marker = `<span style="display:inline-block;border: 2px ${el.color} ${el.value[3]};margin-right:5px;width:40px;height:0px;background-color:#ffffff00;"></span>`
|
||||||
|
}
|
||||||
|
let unit = el.value[2] ? el.value[2] : ''
|
||||||
|
str += `${marker}${el.seriesName.split('(')[0]}:${el.value[1]}${unit}
|
||||||
|
<br>`
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
},
|
||||||
|
color: ['#DAA520', '#2E8B57', '#A52a2a', ...color],
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: {
|
||||||
|
day: '{MM}-{dd}',
|
||||||
|
month: '{MM}',
|
||||||
|
year: '{yyyy}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [{}],
|
||||||
|
|
||||||
|
options: {
|
||||||
|
series: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
let yData: any = []
|
||||||
|
echartsData.value.yAxis = []
|
||||||
|
let setList = [...new Set(unitList)]
|
||||||
|
|
||||||
|
setList.forEach((item: any, index: any) => {
|
||||||
|
if (index > 2) {
|
||||||
|
echartsData.value.grid.right = (index - 1) * 80
|
||||||
|
}
|
||||||
|
yData.push([])
|
||||||
|
let right = {
|
||||||
|
position: 'right',
|
||||||
|
offset: (index - 1) * 80
|
||||||
|
}
|
||||||
|
echartsData.value.yAxis.push({
|
||||||
|
name: item,
|
||||||
|
yAxisIndex: index,
|
||||||
|
splitNumber: 5,
|
||||||
|
minInterval: 1,
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
...(index > 0 ? right : null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
let ABCName = [
|
||||||
|
...new Set(
|
||||||
|
chartsList.value.map((item: any) => {
|
||||||
|
return item.anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]
|
||||||
|
result.forEach((item: any, index: any) => {
|
||||||
|
let yMethodList: any = []
|
||||||
|
|
||||||
|
let ABCList = Object.values(
|
||||||
|
item.reduce((acc, item) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.anotherName
|
||||||
|
} else {
|
||||||
|
key = item.phase
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
)
|
||||||
|
|
||||||
|
ABCList.forEach((kk: any) => {
|
||||||
|
let colorName = kk[0].phase?.charAt(0).toUpperCase()
|
||||||
|
let lineS = ABCName.findIndex(
|
||||||
|
item =>
|
||||||
|
item ===
|
||||||
|
(kk[0].anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName)
|
||||||
|
)
|
||||||
|
let seriesList: any = []
|
||||||
|
kk.forEach((cc: any) => {
|
||||||
|
if (cc.statisticalData !== null) {
|
||||||
|
yData[setList.indexOf(kk[0].unit)].push(cc.statisticalData?.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
seriesList.push([cc.time, cc.statisticalData?.toFixed(2), cc.unit, lineStyle[lineS].type])
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
echartsData.value.options.series.push({
|
||||||
|
name: kk[0].phase ? kk[0].phase + '相' + kk[0].anotherName : kk[0].anotherName,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
color:
|
||||||
|
colorName == 'A' ? '#DAA520' : colorName == 'B' ? '#2E8B57' : colorName == 'C' ? '#A52a2a' : '',
|
||||||
|
symbol: 'none',
|
||||||
|
data: seriesList,
|
||||||
|
lineStyle: lineStyle[lineS],
|
||||||
|
yAxisIndex: setList.indexOf(kk[0].unit)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// let [min, max] = yMethod(yMethodList)
|
||||||
|
// echartsData.value.yAxis[index].min = min
|
||||||
|
// echartsData.value.yAxis[index].max = max
|
||||||
|
})
|
||||||
|
yData.forEach((item: any, index: any) => {
|
||||||
|
let [min, max] = yMethod(item)
|
||||||
|
echartsData.value.yAxis[index].min = min
|
||||||
|
echartsData.value.yAxis[index].max = max
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ result.forEach ~ echartsData.value:", echartsData.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -160,6 +160,12 @@
|
|||||||
:currentScriptTypeName="currentScriptTypeName"
|
:currentScriptTypeName="currentScriptTypeName"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="历史趋势" name="chartTab">
|
||||||
|
<CompareDataCheckChart
|
||||||
|
v-if="activeTab === 'chartTab'"
|
||||||
|
:tableData="rawTableData.length == 0 ? [] : currentRawTableData"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,6 +178,7 @@ import { dialogBig } from '@/utils/elementBind'
|
|||||||
import { computed, reactive, ref } from 'vue'
|
import { computed, reactive, ref } from 'vue'
|
||||||
import CompareDataCheckResultTable from './compareDataCheckResultTable.vue'
|
import CompareDataCheckResultTable from './compareDataCheckResultTable.vue'
|
||||||
import CompareDataCheckRawDataTable from './compareDataCheckRawDataTable.vue'
|
import CompareDataCheckRawDataTable from './compareDataCheckRawDataTable.vue'
|
||||||
|
import CompareDataCheckChart from './compareDataCheckChart.vue'
|
||||||
import { CheckData } from '@/api/check/interface'
|
import { CheckData } from '@/api/check/interface'
|
||||||
import { useCheckStore } from '@/stores/modules/check'
|
import { useCheckStore } from '@/stores/modules/check'
|
||||||
import { Histogram, Postcard } from '@element-plus/icons-vue'
|
import { Histogram, Postcard } from '@element-plus/icons-vue'
|
||||||
|
|||||||
Reference in New Issue
Block a user