|
|
|
@ -1,408 +0,0 @@
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<div class="tire2-container">
|
|
|
|
|
|
|
|
<el-card class="tree-card" shadow="never" v-loading="loading">
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
|
|
|
<span class="header-title">批次列表</span>
|
|
|
|
|
|
|
|
<el-input v-model="searchText" placeholder="筛选" size="small" clearable style="width: 110px" />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<el-tree
|
|
|
|
|
|
|
|
ref="treeRef"
|
|
|
|
|
|
|
|
:data="treeData"
|
|
|
|
|
|
|
|
:props="treeProps"
|
|
|
|
|
|
|
|
node-key="id"
|
|
|
|
|
|
|
|
default-expand-all
|
|
|
|
|
|
|
|
:expand-on-click-node="false"
|
|
|
|
|
|
|
|
highlight-current
|
|
|
|
|
|
|
|
:filter-node-method="filterTreeNode"
|
|
|
|
|
|
|
|
@node-click="handleNodeClick"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<template #default="{ node, data }">
|
|
|
|
|
|
|
|
<span class="custom-tree-node">
|
|
|
|
|
|
|
|
<el-icon v-if="!data.children"><Document /></el-icon>
|
|
|
|
|
|
|
|
<el-icon v-else><Folder /></el-icon>
|
|
|
|
|
|
|
|
<span class="label-text">{{ node.label }}</span>
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-tree>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="content-area">
|
|
|
|
|
|
|
|
<div class="main-area">
|
|
|
|
|
|
|
|
<div class="top-section">
|
|
|
|
|
|
|
|
<el-card class="production-card" shadow="never" v-loading="loading">
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
|
|
<div class="blue-header"><span class="header-title">生产信息</span></div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<el-descriptions :column="1" border size="small" class="desc">
|
|
|
|
|
|
|
|
<el-descriptions-item label="成型号">{{ productionInfo.greenTyreNo }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化号"><span class="highlight">{{ productionInfo.tyreNo }}</span></el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="成型时间">{{ productionInfo.moldingTime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="成型机台">{{ productionInfo.moldingMachine }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="主手">{{ productionInfo.moldingOperator }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="成型班次">{{ productionInfo.moldingShift }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="成型班组">{{ productionInfo.moldingTeam }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化开始时间">{{ productionInfo.curingStartTime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化结束时间">{{ productionInfo.curingEndTime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化操作人">{{ productionInfo.curingOperator }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化班次">{{ productionInfo.curingShift }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="硫化班组">{{ productionInfo.curingTeam }}</el-descriptions-item>
|
|
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-card class="quality-card" shadow="never" v-loading="loading">
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
|
|
<div class="blue-header"><span class="header-title">质检信息</span></div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<el-descriptions :column="1" border size="small" class="desc">
|
|
|
|
|
|
|
|
<el-descriptions-item label="最终品级">{{ qualityInfo.finalGrade }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="外观品级">{{ qualityInfo.faceGrade }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="外观质检人">{{ qualityInfo.faceOper }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="外观质检时间">{{ qualityInfo.faceDatetime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="X光品级">{{ qualityInfo.xrayGrade }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="X光质检人">{{ qualityInfo.xrayOper }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="X光质检时间">{{ qualityInfo.xrayDatetime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="动平衡品级">{{ qualityInfo.dbGrade }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="动平衡质检人">{{ qualityInfo.dbOper }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="动平衡质检时间">{{ qualityInfo.dbDatetime }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="均匀性品级">{{ qualityInfo.ufGrade }}</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item label="均匀性质检人">{{ qualityInfo.ufOper }}</el-descriptions-item>
|
|
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-card class="process-card" shadow="never" v-loading="loading">
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
|
|
<div class="blue-header"><span class="header-title">工艺</span></div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<div class="empty-block">
|
|
|
|
|
|
|
|
<el-empty description="暂无工艺数据(可接 GREEN_TYRENO_PARAMS_TRACE.plc_tech_json)" :image-size="88" />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="curve-area" :class="{ collapsed: curveCollapsed }">
|
|
|
|
|
|
|
|
<div class="curve-toggle" @click="toggleCurve">
|
|
|
|
|
|
|
|
<span class="toggle-text">曲线信息</span>
|
|
|
|
|
|
|
|
<el-icon class="toggle-icon" :class="{ rotated: !curveCollapsed }"><ArrowRight /></el-icon>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-card class="curve-card" shadow="never" v-show="!curveCollapsed">
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
|
|
|
<div class="blue-header">
|
|
|
|
|
|
|
|
<span class="header-title">曲线信息</span>
|
|
|
|
|
|
|
|
<div class="legend-group">
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #ff4d4f"></i>温度</span>
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #40a9ff"></i>功率</span>
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #36cfc9"></i>能量</span>
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #95de64"></i>压力</span>
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #f7d13d"></i>转速</span>
|
|
|
|
|
|
|
|
<span class="legend-item"><i class="legend-dot" style="background: #ffa07a"></i>上顶栓</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-button size="small" text type="primary" style="color: #fff" @click="toggleCurve">收起</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<div ref="chartRef" class="chart-container"></div>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts" name="MixTraceTire2">
|
|
|
|
|
|
|
|
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
|
|
|
|
|
import { ArrowRight, Document, Folder } from '@element-plus/icons-vue';
|
|
|
|
|
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
|
|
|
import tireData from './data/tire2.json';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const source = tireData as any;
|
|
|
|
|
|
|
|
const treeProps = { children: 'children', label: 'label' };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const searchText = ref('');
|
|
|
|
|
|
|
|
const loading = ref(false);
|
|
|
|
|
|
|
|
const curveCollapsed = ref(true);
|
|
|
|
|
|
|
|
const treeData = ref<any[]>(source.treeData || []);
|
|
|
|
|
|
|
|
const productionInfo = ref(source.productionInfo || {});
|
|
|
|
|
|
|
|
const qualityInfo = ref(source.qualityInfo || {});
|
|
|
|
|
|
|
|
const curveDataSource = ref(source.curveData || {});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const treeRef = ref();
|
|
|
|
|
|
|
|
const chartRef = ref<HTMLDivElement>();
|
|
|
|
|
|
|
|
let chartInstance: echarts.ECharts | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const filterTreeNode = (value: string, data: any) => {
|
|
|
|
|
|
|
|
if (!value) return true;
|
|
|
|
|
|
|
|
return String(data.label || '').toLowerCase().includes(value.toLowerCase());
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const initChart = () => {
|
|
|
|
|
|
|
|
if (!chartRef.value) return;
|
|
|
|
|
|
|
|
const cd = curveDataSource.value || {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
|
|
chartInstance.dispose();
|
|
|
|
|
|
|
|
chartInstance = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chartInstance = echarts.init(chartRef.value);
|
|
|
|
|
|
|
|
chartInstance.setOption({
|
|
|
|
|
|
|
|
grid: { left: '5%', right: '5%', top: '10%', bottom: '10%', containLabel: true },
|
|
|
|
|
|
|
|
tooltip: { trigger: 'axis' },
|
|
|
|
|
|
|
|
xAxis: { type: 'category', data: cd.mixingTime || [], boundaryGap: false, name: '时间(s)' },
|
|
|
|
|
|
|
|
yAxis: [
|
|
|
|
|
|
|
|
{ type: 'value', name: '温度(℃)', position: 'left', axisLine: { show: true } },
|
|
|
|
|
|
|
|
{ type: 'value', name: '其他参数', position: 'right', axisLine: { show: true } }
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
|
|
|
{ name: '温度', type: 'line', yAxisIndex: 0, data: cd.temperature || [], smooth: true, itemStyle: { color: '#ff4d4f' } },
|
|
|
|
|
|
|
|
{ name: '功率', type: 'line', yAxisIndex: 1, data: cd.power || [], smooth: true, itemStyle: { color: '#40a9ff' } },
|
|
|
|
|
|
|
|
{ name: '能量', type: 'line', yAxisIndex: 1, data: cd.energy || [], smooth: true, itemStyle: { color: '#36cfc9' } },
|
|
|
|
|
|
|
|
{ name: '压力', type: 'line', yAxisIndex: 1, data: cd.pressure || [], smooth: true, itemStyle: { color: '#95de64' } },
|
|
|
|
|
|
|
|
{ name: '转速', type: 'line', yAxisIndex: 1, data: cd.speed || [], smooth: true, itemStyle: { color: '#f7d13d' } },
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
name: '上顶栓',
|
|
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
|
|
yAxisIndex: 1,
|
|
|
|
|
|
|
|
data: cd.position || [],
|
|
|
|
|
|
|
|
smooth: false,
|
|
|
|
|
|
|
|
lineStyle: { type: 'dashed' },
|
|
|
|
|
|
|
|
itemStyle: { color: '#ffa07a' }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const resizeChart = () => {
|
|
|
|
|
|
|
|
chartInstance?.resize();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const renderChartWithDelay = () => {
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
initChart();
|
|
|
|
|
|
|
|
resizeChart();
|
|
|
|
|
|
|
|
}, 180);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const toggleCurve = () => {
|
|
|
|
|
|
|
|
curveCollapsed.value = !curveCollapsed.value;
|
|
|
|
|
|
|
|
if (!curveCollapsed.value) {
|
|
|
|
|
|
|
|
renderChartWithDelay();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleNodeClick = (nodeData: any) => {
|
|
|
|
|
|
|
|
ElMessage.info(`当前节点: ${nodeData?.label || '-'}`);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(searchText, (value) => {
|
|
|
|
|
|
|
|
treeRef.value?.filter(value);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
|
|
loading.value = true;
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
|
|
const defaultKey = treeData.value?.[0]?.id;
|
|
|
|
|
|
|
|
if (defaultKey && treeRef.value) {
|
|
|
|
|
|
|
|
treeRef.value.setCurrentKey(defaultKey);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, 120);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('resize', resizeChart);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
|
|
window.removeEventListener('resize', resizeChart);
|
|
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
|
|
chartInstance.dispose();
|
|
|
|
|
|
|
|
chartInstance = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
|
|
.tire2-container {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
|
|
height: calc(100vh - 90px);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tree-card {
|
|
|
|
|
|
|
|
width: 300px;
|
|
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.el-card__header) {
|
|
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.card-header {
|
|
|
|
|
|
|
|
background-color: #2f6ea5;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
padding: 10px 14px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
.header-title {
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.custom-tree-node {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.label-text {
|
|
|
|
|
|
|
|
margin-left: 6px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.content-area {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.main-area {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.top-section {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
|
|
.production-card {
|
|
|
|
|
|
|
|
flex: 0 0 420px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.quality-card {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.blue-header {
|
|
|
|
|
|
|
|
background-color: #2f6ea5;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
padding: 10px 14px;
|
|
|
|
|
|
|
|
margin: -20px -20px 16px -20px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
.header-title {
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.desc {
|
|
|
|
|
|
|
|
:deep(.el-descriptions__label) {
|
|
|
|
|
|
|
|
width: 108px;
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
background: #fafafa;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.highlight {
|
|
|
|
|
|
|
|
color: #eab308;
|
|
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.process-card {
|
|
|
|
|
|
|
|
.empty-block {
|
|
|
|
|
|
|
|
min-height: 190px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.curve-area {
|
|
|
|
|
|
|
|
flex: 0 0 50%;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
transition: flex-basis 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.collapsed {
|
|
|
|
|
|
|
|
flex-basis: 30px;
|
|
|
|
|
|
|
|
width: 30px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.curve-toggle {
|
|
|
|
|
|
|
|
width: 30px;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
background-color: #2f6ea5;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
|
|
.toggle-text {
|
|
|
|
|
|
|
|
writing-mode: vertical-rl;
|
|
|
|
|
|
|
|
letter-spacing: 3px;
|
|
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.toggle-icon {
|
|
|
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
|
|
|
transition: transform 0.3s ease;
|
|
|
|
|
|
|
|
&.rotated {
|
|
|
|
|
|
|
|
transform: rotate(180deg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.curve-card {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
:deep(.el-card__header) {
|
|
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-card__body) {
|
|
|
|
|
|
|
|
height: calc(100% - 48px);
|
|
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.legend-group {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
|
|
flex-wrap: nowrap;
|
|
|
|
|
|
|
|
.legend-item {
|
|
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.legend-dot {
|
|
|
|
|
|
|
|
width: 8px;
|
|
|
|
|
|
|
|
height: 8px;
|
|
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.chart-container {
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
min-height: 300px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|