rax-medical/src/views/remote-manage/chart-ecg.vue
2023-11-10 17:45:10 +08:00

198 lines
4.3 KiB
Vue

<template>
<div class="chart-dom-box">
<div ref="chartDom" style="width: 100%; height: 100%"></div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import * as echarts from 'echarts';
import { dateFormater } from './date-util';
const chartDom = ref();
interface Props {
names?: string[];
chartData: any[];
}
const props = withDefaults(defineProps<Props>(), {
names: () => ['CH1', 'CH2'],
chartData: () => [] as any[],
});
// const emit = defineEmits(['updateData']);
let chart: any;
const names = props.names; // 类型名称
const color = ['#00AAB7', '#C77000'];
let xData = [] as any[]; // x时间轴
let series = [] as any[];
// 更新图表
function updateChart(num: number, time?: string) {
xData.shift();
xData.push(dateFormater('HH:mm:ss', time));
// const values = [] as number[];
series.forEach((item, index) => {
item.data.shift();
// item.data.push(index === 0 ? num - 0.2 : index === 2 ? num + 0.2 : num);
// item.data.push(index === 0 ? -Math.floor(Math.random() * 50 + 40) : Math.floor(Math.random() * 50 + 40));
item.data.push(Math.floor(Math.random() * 160 + -80));
// values.push(item.data[item.data.length - 1]);
});
// emit('updateData', values); // 传值
chart.setOption({
xAxis: {
data: xData,
},
series,
});
}
// 格式化数据
function formatterData() {
xData = [];
series = [];
for (let i = 0; i < 50; i++) {
if (props.chartData[i]) xData.push(dateFormater('HH:mm:ss', props.chartData[i].Time || props.chartData[i].TIME));
else xData.unshift(0);
}
names.forEach((item, index) => {
const obj = {
name: item,
type: 'line',
symbol: 'none',
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{
offset: 0,
color: 'rgba(40,94,125,0)',
},
{
offset: 0.3,
color: color[index],
},
{
offset: 0.5,
color: color[index],
},
{
offset: 0.7,
color: color[index],
},
{
offset: 1,
color: 'rgba(40,94,125,0)',
},
]),
width: 1,
},
data: [] as number[],
};
for (let i = 0; i < 50; i++) {
if (props.chartData[i]) {
const num = props.chartData[i].ST;
// obj.data.push(index === 0 ? num - 0.2 : index === 2 ? num + 0.2 : num);
// obj.data.push(index === 0 ? -Math.floor(Math.random() * 50 + 40) : Math.floor(Math.random() * 50 + 40));
obj.data.push(Math.floor(Math.random() * 160 + -80));
} else obj.data.unshift(0);
}
series.push(obj);
});
}
// 渲染图表 父组件调用
function chartSet() {
formatterData();
if (chart) chart.setOption({
xAxis: {
data: xData,
},
series,
});
}
// 图表初始化
function chartInit() {
chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
const option = {
color: color,
tooltip: {
trigger: 'axis',
formatter: (params: any) => {
let str = params[0].axisValue;
str += `<br>`;
names.forEach((item, index) => {
str += params[index].marker;
str += params[index].seriesName + ' ';
str += `${params[index].value} HZ`;
str += index === 0 ? '<br>' : '';
});
return str;
},
},
grid: {
left: 1,
right: 20,
bottom: 5,
top: 20,
containLabel: true,
},
xAxis: {
show: true,
type: 'category',
boundaryGap: false,
axisLine: { show: false, lineStyle: { color: '#006080' } },
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: true, lineStyle: { color: '#D4E8F0', width: 1, type: 'solid' } },
data: xData,
},
yAxis: {
show: true,
type: 'value',
min: function (value: any) {
return value.min - 40
},
max: function (value: any) {
return value.max + 40
},
axisLabel: {
formatter: `{value} HZ`
},
axisLine: { show: false, lineStyle: { color: '#006080' } },
splitLine: { lineStyle: { color: '#D4E8F0', width: 1, type: 'solid' } },
},
series,
};
chart.setOption(option);
chart.resize();
window.addEventListener('resize', () => {
chart.resize();
});
}
onMounted(() => {
chartInit();
});
defineExpose({
updateChart,
chartSet
});
</script>
<style lang="scss" scoped>
.chart-dom-box {
position: relative;
.chart-rate {
position: absolute;
top: 5px;
left: 30px;
color: #285e7d;
font-size: 16px;
line-height: 30px;
font-weight: 600;
}
}
</style>