mirror of
https://gitee.com/xiongmao1988/rax-medical.git
synced 2026-06-14 20:21:47 +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 './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>
|