2026-04-17 09:15:58 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<el-card class="dip-chart-card" shadow="never">
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
|
<div class="card-header-main">
|
|
|
|
|
|
<div class="card-title">耐受图</div>
|
|
|
|
|
|
<div class="card-subtitle">
|
|
|
|
|
|
{{ selectedMappingText }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
plain
|
|
|
|
|
|
:loading="curveLoading"
|
|
|
|
|
|
class="draw-curve-button"
|
|
|
|
|
|
@click="drawCharacteristicCurve"
|
|
|
|
|
|
>
|
|
|
|
|
|
绘制特性曲线
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="chart-wrapper">
|
|
|
|
|
|
<MyEchart :options="chartOptions"/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
|
import {computed, ref, watch} from 'vue'
|
|
|
|
|
|
import {ElMessage} from 'element-plus'
|
|
|
|
|
|
import MyEchart from '@/components/echarts/line/index.vue'
|
|
|
|
|
|
import {getFreqConverterSCurve} from '@/api/device/freqConverter'
|
|
|
|
|
|
|
|
|
|
|
|
type ChartPointStatus = 'pass' | 'fail'
|
|
|
|
|
|
|
|
|
|
|
|
interface ChartPoint {
|
|
|
|
|
|
duration: number;
|
|
|
|
|
|
residualVoltage: number;
|
|
|
|
|
|
status: ChartPointStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface NormalizedTolerantPoint {
|
|
|
|
|
|
duration: number;
|
|
|
|
|
|
residualVoltage: number;
|
|
|
|
|
|
tolerant: number | null;
|
|
|
|
|
|
status: ChartPointStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
|
|
selectedMapping?: Record<string, any> | null;
|
|
|
|
|
|
webMsgSend?: any;
|
|
|
|
|
|
resultData?: any;
|
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
|
|
const STATUS_COLOR_MAP: Record<ChartPointStatus, string> = {
|
|
|
|
|
|
pass: '#1d4ed8',
|
|
|
|
|
|
fail: '#111111'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const chartPoints = ref<ChartPoint[]>([])
|
|
|
|
|
|
const characteristicCurveData = ref<Array<[number, number]>>([])
|
|
|
|
|
|
const curveLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
const selectedMappingText = computed(() => {
|
|
|
|
|
|
if (!props.selectedMapping) {
|
|
|
|
|
|
return '未选择变频器'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return `变频器:${props.selectedMapping.freqConverterName || '-'}`
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeTolerantValue = (value: unknown) => {
|
|
|
|
|
|
if (value === undefined || value === null || value === '') {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const result = Number(value)
|
|
|
|
|
|
if ([0, 1, 2].includes(result)) {
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeDuration = (source: Record<string, any>) => {
|
|
|
|
|
|
return toNumber(
|
|
|
|
|
|
source.durationMs !== undefined && source.durationMs !== null
|
|
|
|
|
|
? Number(source.durationMs) / 1000
|
|
|
|
|
|
: source.duration ??
|
|
|
|
|
|
source.x ??
|
|
|
|
|
|
source.dipDuration ??
|
|
|
|
|
|
source.retainTime ??
|
|
|
|
|
|
source.durationValue
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeResidualVoltageValue = (source: Record<string, any>) => {
|
|
|
|
|
|
return toNumber(
|
|
|
|
|
|
source.residualVoltage ??
|
|
|
|
|
|
source.y ??
|
|
|
|
|
|
source.residual ??
|
|
|
|
|
|
source.voltage ??
|
|
|
|
|
|
source.residual_value
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeCurveData = (source: unknown) => {
|
|
|
|
|
|
if (!Array.isArray(source)) {
|
|
|
|
|
|
return [] as Array<[number, number]>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return source
|
|
|
|
|
|
.map(item => {
|
|
|
|
|
|
if (Array.isArray(item) && item.length >= 2) {
|
|
|
|
|
|
const duration = Number(item[0])
|
|
|
|
|
|
const residualVoltage = Number(item[1])
|
|
|
|
|
|
if (Number.isFinite(duration) && Number.isFinite(residualVoltage)) {
|
|
|
|
|
|
return [duration, residualVoltage] as [number, number]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (item && typeof item === 'object') {
|
|
|
|
|
|
const record = item as Record<string, any>
|
|
|
|
|
|
const tolerant = normalizeTolerantValue(record.tolerant)
|
|
|
|
|
|
if (tolerant !== null && tolerant !== 2) {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const duration = normalizeDuration(record)
|
|
|
|
|
|
const residualVoltage = normalizeResidualVoltageValue(record)
|
|
|
|
|
|
if (duration !== null && residualVoltage !== null) {
|
|
|
|
|
|
return [duration, residualVoltage] as [number, number]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
|
})
|
|
|
|
|
|
.filter((item): item is [number, number] => !!item)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const extractCurveData = (payload: any) => {
|
|
|
|
|
|
if (!payload) {
|
|
|
|
|
|
return [] as Array<[number, number]>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const candidates = [
|
|
|
|
|
|
payload,
|
|
|
|
|
|
payload?.data,
|
|
|
|
|
|
payload?.data?.records,
|
|
|
|
|
|
payload?.data?.points,
|
|
|
|
|
|
payload?.points,
|
|
|
|
|
|
payload?.records,
|
|
|
|
|
|
payload?.list
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
for (const candidate of candidates) {
|
|
|
|
|
|
const normalized = normalizeCurveData(candidate)
|
|
|
|
|
|
if (normalized.length) {
|
|
|
|
|
|
return normalized
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return [] as Array<[number, number]>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const drawCharacteristicCurve = async () => {
|
|
|
|
|
|
const freqConverterId = props.selectedMapping?.freqConverterId
|
|
|
|
|
|
if (!freqConverterId) {
|
|
|
|
|
|
ElMessage.warning('未获取到变频器ID')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
curveLoading.value = true
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const result = await getFreqConverterSCurve({
|
|
|
|
|
|
converterId: freqConverterId
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const normalizedCurveData = extractCurveData(result)
|
|
|
|
|
|
|
|
|
|
|
|
if (!normalizedCurveData.length) {
|
|
|
|
|
|
characteristicCurveData.value = []
|
|
|
|
|
|
ElMessage.warning('未获取到特性曲线数据')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
characteristicCurveData.value = normalizedCurveData
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('绘制特性曲线失败:', error)
|
|
|
|
|
|
characteristicCurveData.value = []
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
curveLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const chartOptions = computed(() => {
|
|
|
|
|
|
const maxDuration = 2
|
|
|
|
|
|
// const maxDuration = Math.max(
|
|
|
|
|
|
// 2,
|
|
|
|
|
|
// ...chartPoints.value.map(item => item.duration).filter(item => Number.isFinite(item)),
|
|
|
|
|
|
// ...characteristicCurveData.value.map(item => item[0]).filter(item => Number.isFinite(item))
|
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: {
|
|
|
|
|
|
text: ''
|
|
|
|
|
|
},
|
|
|
|
|
|
grid: {
|
|
|
|
|
|
top: 30,
|
|
|
|
|
|
left: 48,
|
|
|
|
|
|
right: 22,
|
|
|
|
|
|
bottom: 52
|
|
|
|
|
|
},
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'item',
|
|
|
|
|
|
formatter(params: any) {
|
|
|
|
|
|
if (params.seriesType === 'line') {
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const [duration, residualVoltage, statusText] = params.value
|
|
|
|
|
|
return [
|
|
|
|
|
|
`持续时间: ${duration} s`,
|
|
|
|
|
|
`残余电压: ${residualVoltage} %`,
|
|
|
|
|
|
`状态: ${statusText}`
|
|
|
|
|
|
].join('<br/>')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
legend: {
|
|
|
|
|
|
top: 0,
|
|
|
|
|
|
right: 0,
|
|
|
|
|
|
data: ['特性测试曲线']
|
|
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
2026-04-22 19:32:28 +08:00
|
|
|
|
type: 'log',
|
2026-04-17 09:15:58 +08:00
|
|
|
|
name: '持续时间(s)',
|
|
|
|
|
|
nameLocation: 'middle',
|
|
|
|
|
|
nameGap: 34,
|
2026-04-22 19:32:28 +08:00
|
|
|
|
min: 0.01,
|
|
|
|
|
|
max: 60,
|
|
|
|
|
|
logBase: 10,
|
2026-04-17 09:15:58 +08:00
|
|
|
|
minorTick: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
splitNumber: 10
|
|
|
|
|
|
},
|
|
|
|
|
|
minorSplitLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
color: '#e8edf6'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
color: '#cfd8e6'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
|
|
|
|
|
formatter(value: number) {
|
|
|
|
|
|
return value.toFixed(2)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: 'value',
|
|
|
|
|
|
name: '暂降幅值',
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
max: 100,
|
|
|
|
|
|
interval: 10,
|
|
|
|
|
|
minorTick: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
splitNumber: 2
|
|
|
|
|
|
},
|
|
|
|
|
|
minorSplitLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
color: '#e8edf6'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
color: '#cfd8e6'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
|
|
|
|
|
formatter(value: number) {
|
|
|
|
|
|
return `${value}%`
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
dataZoom: [],
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '特性测试曲线',
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
smooth: true,
|
|
|
|
|
|
showSymbol: true,
|
|
|
|
|
|
symbolSize: 7,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
color: '#ff2a2a',
|
|
|
|
|
|
width: 3
|
|
|
|
|
|
},
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: '#ff2a2a'
|
|
|
|
|
|
},
|
|
|
|
|
|
data: characteristicCurveData.value
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '暂降点',
|
|
|
|
|
|
type: 'scatter',
|
|
|
|
|
|
symbolSize: 10,
|
|
|
|
|
|
data: chartPoints.value.map(item => ({
|
|
|
|
|
|
value: [item.duration, item.residualVoltage, getStatusText(item.status)],
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: STATUS_COLOR_MAP[item.status]
|
|
|
|
|
|
}
|
|
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
options: {
|
|
|
|
|
|
animation: false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const toNumber = (value: unknown) => {
|
|
|
|
|
|
const result = Number(value)
|
|
|
|
|
|
return Number.isFinite(result) ? result : null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeStatus = (value: unknown): ChartPointStatus => {
|
|
|
|
|
|
const rawValue = `${value ?? ''}`.trim().toLowerCase()
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
value === 0 ||
|
|
|
|
|
|
rawValue === '0' ||
|
|
|
|
|
|
rawValue === 'false' ||
|
|
|
|
|
|
rawValue === 'fail' ||
|
|
|
|
|
|
rawValue === 'failed' ||
|
|
|
|
|
|
rawValue.includes('不耐受')
|
|
|
|
|
|
) {
|
|
|
|
|
|
return 'fail'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 'pass'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizeTolerantPoint = (source: Record<string, any>): NormalizedTolerantPoint | null => {
|
|
|
|
|
|
const duration = normalizeDuration(source)
|
|
|
|
|
|
const residualVoltage = normalizeResidualVoltageValue(source)
|
|
|
|
|
|
|
|
|
|
|
|
if (duration === null || residualVoltage === null) {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (duration <= 0 || residualVoltage < 0 || residualVoltage > 100) {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const tolerant = normalizeTolerantValue(
|
|
|
|
|
|
source.tolerant ??
|
|
|
|
|
|
source.endure ??
|
|
|
|
|
|
source.isEndure ??
|
|
|
|
|
|
source.tolerable ??
|
|
|
|
|
|
source.isTolerable ??
|
|
|
|
|
|
source.status ??
|
|
|
|
|
|
source.pointStatus ??
|
|
|
|
|
|
source.result ??
|
|
|
|
|
|
source.state
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
duration,
|
|
|
|
|
|
residualVoltage,
|
|
|
|
|
|
tolerant,
|
|
|
|
|
|
status:
|
|
|
|
|
|
tolerant === 0
|
|
|
|
|
|
? 'fail'
|
|
|
|
|
|
: tolerant === 1
|
|
|
|
|
|
? 'pass'
|
|
|
|
|
|
: normalizeStatus(
|
|
|
|
|
|
source.tolerant ??
|
|
|
|
|
|
source.endure ??
|
|
|
|
|
|
source.isEndure ??
|
|
|
|
|
|
source.tolerable ??
|
|
|
|
|
|
source.isTolerable ??
|
|
|
|
|
|
source.status ??
|
|
|
|
|
|
source.pointStatus ??
|
|
|
|
|
|
source.result ??
|
|
|
|
|
|
source.state
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const getStatusText = (status: ChartPointStatus) => {
|
|
|
|
|
|
if (status === 'fail') {
|
|
|
|
|
|
return '不耐受'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return '耐受'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const normalizePoint = (source: Record<string, any>): ChartPoint | null => {
|
|
|
|
|
|
const point = normalizeTolerantPoint(source)
|
|
|
|
|
|
if (!point || point.tolerant === 2) {
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
duration: point.duration,
|
|
|
|
|
|
residualVoltage: point.residualVoltage,
|
|
|
|
|
|
status: point.status
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const extractCharacteristicCurvePoints = (payload: any) => {
|
|
|
|
|
|
const result: Array<[number, number]> = []
|
|
|
|
|
|
const seen = new Set<string>()
|
|
|
|
|
|
const rootPayload = payload?.data && typeof payload.data === 'object' ? payload.data : payload
|
|
|
|
|
|
|
|
|
|
|
|
const walk = (node: any) => {
|
|
|
|
|
|
if (!node) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(node)) {
|
|
|
|
|
|
node.forEach(item => walk(item))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof node !== 'object') {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const point = normalizeTolerantPoint(node)
|
|
|
|
|
|
if (point?.tolerant === 2) {
|
|
|
|
|
|
const key = `${point.duration}|${point.residualVoltage}`
|
|
|
|
|
|
if (!seen.has(key)) {
|
|
|
|
|
|
seen.add(key)
|
|
|
|
|
|
result.push([point.duration, point.residualVoltage])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Object.values(node).forEach(item => {
|
|
|
|
|
|
if (item && typeof item === 'object') {
|
|
|
|
|
|
walk(item)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
walk(rootPayload)
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const extractPoints = (payload: any) => {
|
|
|
|
|
|
const result: ChartPoint[] = []
|
|
|
|
|
|
const seen = new Set<string>()
|
|
|
|
|
|
const rootPayload = payload?.data && typeof payload.data === 'object' ? payload.data : payload
|
|
|
|
|
|
|
|
|
|
|
|
const walk = (node: any) => {
|
|
|
|
|
|
if (!node) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(node)) {
|
|
|
|
|
|
node.forEach(item => walk(item))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof node !== 'object') {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const point = normalizePoint(node)
|
|
|
|
|
|
if (point) {
|
|
|
|
|
|
const key = `${point.duration}|${point.residualVoltage}`
|
|
|
|
|
|
if (!seen.has(key)) {
|
|
|
|
|
|
seen.add(key)
|
|
|
|
|
|
result.push(point)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Object.values(node).forEach(item => {
|
|
|
|
|
|
if (item && typeof item === 'object') {
|
|
|
|
|
|
walk(item)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
walk(rootPayload)
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.webMsgSend,
|
|
|
|
|
|
newValue => {
|
|
|
|
|
|
if (!newValue) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const nextPoints = extractPoints(newValue)
|
|
|
|
|
|
if (!nextPoints.length) {
|
|
|
|
|
|
const nextCurvePoints = extractCharacteristicCurvePoints(newValue)
|
|
|
|
|
|
if (nextCurvePoints.length) {
|
|
|
|
|
|
characteristicCurveData.value = nextCurvePoints
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const existingPointMap = new Map(
|
|
|
|
|
|
chartPoints.value.map(item => [`${item.duration}|${item.residualVoltage}`, item] as const)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
nextPoints.forEach(item => {
|
|
|
|
|
|
const key = `${item.duration}|${item.residualVoltage}`
|
|
|
|
|
|
existingPointMap.set(key, item)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
chartPoints.value = Array.from(existingPointMap.values())
|
|
|
|
|
|
|
|
|
|
|
|
const nextCurvePoints = extractCharacteristicCurvePoints(newValue)
|
|
|
|
|
|
if (nextCurvePoints.length) {
|
|
|
|
|
|
characteristicCurveData.value = nextCurvePoints
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{deep: true}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.resultData,
|
|
|
|
|
|
newValue => {
|
|
|
|
|
|
if (!newValue) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
chartPoints.value = extractPoints(newValue)
|
|
|
|
|
|
const nextCurvePoints = extractCharacteristicCurvePoints(newValue)
|
|
|
|
|
|
if (nextCurvePoints.length) {
|
|
|
|
|
|
characteristicCurveData.value = nextCurvePoints
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{deep: true, immediate: true}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.selectedMapping,
|
|
|
|
|
|
() => {
|
|
|
|
|
|
chartPoints.value = []
|
|
|
|
|
|
characteristicCurveData.value = []
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.dip-chart-card {
|
|
|
|
|
|
border: 1px solid var(--el-border-color-light);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.dip-chart-card .el-card__header) {
|
|
|
|
|
|
padding: 10px 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.dip-chart-card .el-card__body) {
|
|
|
|
|
|
padding: 10px 14px 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-header-main {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-subtitle {
|
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: var(--el-text-color-secondary);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.draw-curve-button {
|
|
|
|
|
|
margin-top: -2px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chart-wrapper {
|
|
|
|
|
|
height: 400px;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|