mirror of
https://gitee.com/xiongmao1988/rax-medical.git
synced 2026-06-14 18:01:45 +08:00
225 lines
4.9 KiB
Vue
225 lines
4.9 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 '@/utils/date-util';
|
||
|
||
const chartDom = ref();
|
||
|
||
interface Props {
|
||
names: string[];
|
||
chartData: any[];
|
||
}
|
||
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
names: () => ['BIS', 'HR'],
|
||
chartData: () => [] as any[],
|
||
});
|
||
|
||
// const emit = defineEmits(['updateData']);
|
||
|
||
let chart: any;
|
||
const names = props.names; // 类型名称
|
||
const color = ['#00AAB7', '#C77000'];
|
||
let legendData = [] as any[];
|
||
let xData = [] as any[]; // x时间轴
|
||
let series = [] as any[];
|
||
|
||
|
||
// 更新图表
|
||
function updateChart(ary: number[], time?: string) {
|
||
xData.shift();
|
||
xData.push(dateFormater('HH:mm:ss', time));
|
||
// const values: number[] = [];
|
||
series.forEach((item, index) => {
|
||
item.data.shift();
|
||
item.data.push(ary[index]);
|
||
// values.push(item.data[item.data.length - 1]);
|
||
});
|
||
// emit('updateData', [values]); // 传值
|
||
chart.setOption({
|
||
xAxis: {
|
||
data: xData,
|
||
},
|
||
series,
|
||
});
|
||
}
|
||
// 格式化数据
|
||
function formatterData() {
|
||
legendData = [];
|
||
xData = [];
|
||
series = [];
|
||
for (let i = 0; i < 10; 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',
|
||
smooth: true,
|
||
data: [] as number[],
|
||
};
|
||
for (let i = 0; i < 10; i++) {
|
||
if (props.chartData[i]) obj.data.push(props.chartData[i][item]);
|
||
else obj.data.unshift(0);
|
||
}
|
||
legendData.push({
|
||
name: item,
|
||
textStyle: { color: color[index] },
|
||
});
|
||
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();
|
||
formatterData();
|
||
const option : any = {
|
||
color,
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
formatter: (params: any) => {
|
||
let str = '';
|
||
str += params[0].axisValue;
|
||
str += '<br>';
|
||
names.forEach((item, index) => {
|
||
str += params[index].marker;
|
||
str += params[index].seriesName + ' ';
|
||
switch (item) {
|
||
case 'BIS':
|
||
str += `脑电双频指数<麻醉深度>:${params[index].value}`;
|
||
break;
|
||
case 'HR':
|
||
str += `心率:${params[index].value} 次/分`;
|
||
break;
|
||
case 'SBP':
|
||
str += `收缩压:${params[index].value} mmHg`;
|
||
break;
|
||
case 'DBP':
|
||
str += `舒张压:${params[index].value} mmHg`;
|
||
break;
|
||
case 'SPO2':
|
||
str += `体温:${params[index].value}`;
|
||
break;
|
||
case 'TEMP':
|
||
str += `氧饱和度:${params[index].value}`;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
str += index === 0 ? '<br>' : '';
|
||
});
|
||
return str;
|
||
},
|
||
},
|
||
legend: {
|
||
type: 'plain',
|
||
show: true,
|
||
top: 0,
|
||
right: 15,
|
||
itemGap: 30,
|
||
itemWidth: 20,
|
||
itemHeight: 3,
|
||
icon: 'rect',
|
||
textStyle: {
|
||
fontSize: 16,
|
||
fontWeight: 600,
|
||
lineHeight: 30,
|
||
},
|
||
formatter: (params: string) => {
|
||
const index = names.findIndex((item) => item === params);
|
||
let str = params + ' ';
|
||
switch (params) {
|
||
case 'BIS':
|
||
str += `${series[index].data[series[index].data.length - 1]}`;
|
||
break;
|
||
case 'HR':
|
||
str += `${series[index].data[series[index].data.length - 1]} 次/分`;
|
||
break;
|
||
case 'SBP':
|
||
str += `${series[index].data[series[index].data.length - 1]} mmHg`;
|
||
break;
|
||
case 'DBP':
|
||
str += `${series[index].data[series[index].data.length - 1]} mmHg`;
|
||
break;
|
||
case 'SPO2':
|
||
str += `${series[index].data[series[index].data.length - 1]}`;
|
||
break;
|
||
case 'TEMP':
|
||
str += `${series[index].data[series[index].data.length - 1]}`;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return str;
|
||
},
|
||
data: legendData,
|
||
},
|
||
grid: {
|
||
left: 5,
|
||
right: 25,
|
||
bottom: 5,
|
||
top: 40,
|
||
containLabel: true,
|
||
},
|
||
xAxis: {
|
||
show: true,
|
||
type: 'category',
|
||
boundaryGap: false,
|
||
data: xData,
|
||
axisLine: { lineStyle: { color: '#006080' } }
|
||
},
|
||
yAxis: {
|
||
show: true,
|
||
type: 'value',
|
||
axisLabel: {
|
||
formatter: `{value} ${names[0] === 'BIS' ? '次/分' : names[0] === 'SBP' ? 'mmHg' : ''}`
|
||
},
|
||
axisLine: { show: true, lineStyle: { color: '#006080' } },
|
||
splitLine: { lineStyle: { color: '#C0C4CC', width: 1, type: 'dashed' } },
|
||
},
|
||
series,
|
||
};
|
||
if(names[0] !== 'BIS') {
|
||
option.yAxis.max = (value: any) => value.max + 20;
|
||
}
|
||
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;
|
||
}
|
||
</style>
|