AIManage/src/views/dashboard/components/ServiceStatus.vue

218 lines
5.4 KiB
Vue

<template>
<div class="service-status">
<div class="sv-chart" >
<div :id="id" :class="className" :style="{ height, width }">
</div>
</div>
<div class="chart-title">内核温度</div>
<div class="chart-bars" v-if="serverInfo">
<div class="chart-bar">
<div class="bar-title">内存</div>
<div class="chart-line">
<div class="chart-line-inner" :style="'width:'+serverInfo.memory_usage*100.0/16.0/1024.0+'%'"></div>
</div>
<div class="bar-title">75%</div>
</div>
<div class="chart-bar">
<div class="bar-title">CPU</div>
<div class="chart-line">
<div class="chart-line-inner" :style="'width:'+serverInfo.cpu_usage+'%'"></div>
</div>
<div class="bar-title">45%</div>
</div>
<div class="chart-bar">
<div class="bar-title">硬盘</div>
<div class="chart-line">
<div class="chart-line-inner" :style="'width:'+serverInfo.storage_usage+'%'"></div>
</div>
<div class="bar-title">65%</div>
</div>
</div>
</div>
</template>
<script lang='ts' setup>
import * as echarts from "echarts";
import LogApi from '@/api/log'
let tempurature=ref<any>(0);
let serverInfo=ref<any>(null);
const props = defineProps({
id: {
type: String,
default: "serviceStatus",
},
className: {
type: String,
default: "",
},
width: {
type: String,
default: "200px",
required: true,
},
height: {
type: String,
default: "200px",
required: true,
}
});
let options = reactive( {
grid: {
left: "20%",
right: "20%",
bottom: "20%",
top: "20%",
containLabel: true,
},
series: [
{
type: 'gauge',
startAngle: 200,
endAngle: -20,
min: 0,
max: 150,
splitNumber: 15,
itemStyle: {
color: '#409eff',
},
progress: {
show: true,
width: 10
},
pointer: {
show: false
},
axisLine: {
lineStyle: {
width: 10
}
},
axisTick: {
distance: -14,
splitNumber: 2,
lineStyle: {
width: 1,
color: '#409eff'
}
},
splitLine: {
distance: -20,
length: 14,
lineStyle: {
width: 1,
color: '#409eff'
}
},
axisLabel: {
distance: -18,
color: '#409eff',
fontSize: 10
},
anchor: {
show: false
},
title: {
show: false
},
detail: {
valueAnimation: true,
width: '60%',
lineHeight: 20,
borderRadius: 8,
offsetCenter: [0, '10%'],
fontSize: 20,
fontWeight: 'bolder',
formatter: '{value} °C',
color: '#409eff'
},
data: [
{
value: tempurature.value
}
]
}
]
});
const loadLog=()=>{
LogApi.serverState().then(d=>{
serverInfo.value=d.data.data
tempurature.value=serverInfo.value.tempurature/10.0;
options.series[0].data[0].value=tempurature.value;
chart.value.setOption(options);
});
}
const chart = ref<any>("");
onMounted(() => {
// 图表初始化
chart.value = markRaw(
echarts.init(document.getElementById(props.id) as HTMLDivElement)
);
chart.value.setOption(options);
// 大小自适应
window.addEventListener("resize", () => {
chart.value.resize();
});
loadLog();
});
onActivated(() => {
if (chart.value) {
chart.value.resize();
}
});
</script>
<style scoped lang='scss'>
.service-status {
position: relative;
.sv-chart {
display: flex;
align-items: center;
justify-content: center;
padding-top: 10px;
}
.chart-title {
text-align: center;
position: absolute;
top: 130px;
width: 100%;
font-size: 12px;
color: #666;
}
.chart-bars {
position: relative;
text-align: center;
top:-30px;
.chart-bar {
display: flex;
padding: 0px 15%;
line-height: 30px;
align-items: center;
.bar-title {
font-size: 12px;
margin: 0px 8px;
}
.chart-line {
height: 8px;
background-color: #ccc;
flex-grow: 1;
border-radius: 4px;
.chart-line-inner {
background-color: var(--el-color-primary);
height: 8px;
border-radius: 4px;
}
}
}
}
}
</style>