rax-medical/src/views/remote-manage/chart-line.vue

225 lines
4.9 KiB
Vue
Raw Normal View History

2023-11-10 17:45:10 +08:00
<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>