You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.1 KiB
Vue

<template>
<div :class="className" :style="{ width, height }" ref="chartContainer" />
</template>
<script>
import { defineComponent, onMounted, onUnmounted, ref } from 'vue';
import * as echarts from 'echarts';
import { getOutputLog3 } from '~/src/service/api/produre/workRecords/index';
const COLORS = [
'#53D7F7', '#FF7D00', '#7CFFB2', '#FF6699', '#9966FF',
'#FF9933', '#33CCFF', '#FF3366', '#66CC99', '#CC99FF'
];
export default defineComponent({
props: {
year: null,
className: {
type: String,
default: 'chart',
required: true
},
width: {
type: String,
default: '400px',
validate: value => /^\d+px$/.test(value)
},
height: {
type: String,
default: '230px',
validate: value => /^\d+px$/.test(value)
},
realData: {
type: Object,
default: () => ({})
}
},
setup(props, { emit }) {
const chartContainer = ref(null);
let myChart = null;
const initChart = () => {
if (!chartContainer.value) return;
myChart = echarts.init(chartContainer.value);
updateChartOptions();
};
const updateChartOptions = () => {
const options = {
grid: {
left: '4%',
right: '18%',
bottom: '4%',
top: '13%',
containLabel: true
},
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(10, 43, 113, 0.9)',
borderColor: 'rgba(143, 225, 252, 0.9)',
padding: 10,
axisPointer: { show: false },
textStyle: { color: '#fff', fontSize: 14 },
formatter: (params) => {
const batch = params.data.batchNumber;
const percent = (Math.min(params.value / 70 * 100, 100)).toFixed(2) + '%';
const status = params.value >= 65 && params.value <= 75 ? '正常' : '异常';
return `
<div style="font-weight: bold; margin-bottom: 5px;">批次: ${batch}</div>
<div> 机台: ${params.seriesName}</div>
<div> 转速: ${params.value}转/秒</div>
<div><span style="color: ${params.color}">●</span>质量状态: <span style="color: ${status === '正常' ? '#00ff00' : '#ff0000'}">(${status})</span></div>
`;
}
},
xAxis: {
show: true,
data: ['', '', '', '', '', '', '', '', '', '', ''],
axisLine: { show: true, lineStyle: { color: 'rgba(30, 78, 123, 1)', width: 2 } },
axisTick: { show: false },
axisLabel: { show: true, rotate: 45, color: '#fff', fontSize: 14 }
},
yAxis: [{
name: '转速/秒',
nameTextStyle: { color: '#fff', fontSize: 15 },
type: 'value',
splitLine: { show: false },
axisTick: { show: false },
axisLine: { show: true, lineStyle: { color: 'rgba(30, 78, 123, 1)' } },
axisLabel: { show: true, color: '#fff', fontSize: 14 }
}],
legend: {
show: true,
type: 'scroll',
orient: 'horizontal',
right: '5%',
top: '5%',
textStyle: { color: '#fff', fontSize: 14 },
pageIconColor: '#fff',
pageTextStyle: { color: '#fff' }
},
series: []
};
const fetchAndUpdateData = async () => {
try {
const { data } = await getOutputLog3();
options.series = data.map((line, index) => ({
name: line.name,
type: 'line',
barWidth: 15,
showSymbol: true,
symbolSize: 10,
symbol: 'circle',
lineStyle: { color: COLORS[index % COLORS.length], width: 2 },
itemStyle: {
color: COLORS[index % COLORS.length],
borderColor: COLORS[index % COLORS.length],
borderWidth: 2
},
data: line.data.map((value, idx) => ({
value,
itemStyle: { color: value >= 65 && value <= 75 ? '#00ff00' : '#ff0000' },
batchNumber: line.batchNumber && line.batchNumber[idx] || '未知批次',
id: line.ids && line.ids[idx] || ''
})),
label: { show: false },
markLine: {
silent: true,
data: [{
name: '标准值70',
yAxis: 70,
label: {
show: index === 0,
formatter: '标准值70\n(65-75)',
color: '#fff',
position: 'end',
distance: 1,
fontSize: 12, // 调整为合适的字体大小
borderRadius: 3,
padding: [2, 4]
},
lineStyle: { color: 'red', type: 'dashed', width: 3 },
symbol: ['none', 'none']
}]
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[{ offset: 0, color: echarts.color.modifyAlpha(COLORS[index % COLORS.length], 0.1) }],
false
),
shadowColor: echarts.color.modifyAlpha(COLORS[index % COLORS.length], 0.1),
shadowBlur: 12
}
}
}));
myChart.setOption(options);
myChart.resize();
emit('endLoading', 3);
// 添加点击事件监听
addPointClickEvent();
} catch (error) {
console.error('数据获取失败:', error);
}
};
fetchAndUpdateData();
};
// 添加数据点点击事件处理
const addPointClickEvent = () => {
if (myChart) {
// 移除之前的点击事件监听器,防止重复添加
myChart.off('click');
// 添加新的点击事件监听器
myChart.on('click', (params) => {
console.log("params", params)
if (params.componentType === 'series') {
// 点击的是数据点
const seriesName = params.seriesName; // 生产线名称
const value = params.value; // 转速值
const batchNumber = params.data.batchNumber; // 批次号
const id = params.data.id; // 批次号
console.log(`点击了 ${seriesName} 的数据点`);
console.log(`批次: ${batchNumber}, 转速: ${value} 转/秒`);
console.log(`id: ${id}, 转速: ${value} 转/秒`);
// 触发自定义事件,通知父组件
emit('pointClick', {
id
});
}
});
}
};
onMounted(() => {
initChart();
// 初始加载后添加点击事件
addPointClickEvent();
});
onUnmounted(() => {
if (myChart) {
// 移除事件监听器并销毁图表
myChart.off('click');
myChart.dispose();
myChart = null;
}
});
return { chartContainer };
}
});
</script>
<style scoped>
.chart {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>