369 lines
8.5 KiB
Vue
369 lines
8.5 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, ref, nextTick, watch } from 'vue';
|
|
import * as echarts from 'echarts/core';
|
|
import { GridComponent, GridComponentOption } from 'echarts/components';
|
|
import {
|
|
BarChart,
|
|
BarSeriesOption,
|
|
PictorialBarChart,
|
|
PictorialBarSeriesOption,
|
|
} from 'echarts/charts';
|
|
import { CanvasRenderer } from 'echarts/renderers';
|
|
import { graphNodeClickID, graphNodeState } from '../../hooks/useTopology';
|
|
import useI18n from '@/hooks/useI18n';
|
|
import { markRaw } from 'vue';
|
|
const { t } = useI18n();
|
|
|
|
echarts.use([GridComponent, BarChart, PictorialBarChart, CanvasRenderer]);
|
|
|
|
type EChartsOption = echarts.ComposeOption<
|
|
GridComponentOption | BarSeriesOption | PictorialBarSeriesOption
|
|
>;
|
|
|
|
/**图DOM节点实例对象 */
|
|
const neResourcesDom = ref<HTMLElement | undefined>(undefined);
|
|
|
|
/**图实例对象 */
|
|
const neResourcesChart = ref<any>(null);
|
|
|
|
// 类别
|
|
const category = ref<any>([
|
|
{
|
|
name: t('views.dashboard.overview.resources.sysDisk'),
|
|
value: 1,
|
|
},
|
|
{
|
|
name: t('views.dashboard.overview.resources.sysMem'),
|
|
value: 1,
|
|
},
|
|
{
|
|
name: t('views.dashboard.overview.resources.sysCpu'),
|
|
value: 1,
|
|
},
|
|
{
|
|
name: t('views.dashboard.overview.resources.neCpu'),
|
|
value: 1,
|
|
},
|
|
]);
|
|
|
|
// 数据总数
|
|
const total = 100;
|
|
|
|
/**图数据 */
|
|
const optionData: EChartsOption = {
|
|
xAxis: {
|
|
max: total,
|
|
splitLine: {
|
|
show: false,
|
|
},
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
axisLabel: {
|
|
show: false,
|
|
},
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
},
|
|
grid: {
|
|
top: '1%', // 设置条形图的边距
|
|
bottom: '12%',
|
|
left: '25%',
|
|
right: '25%',
|
|
},
|
|
yAxis: [
|
|
{
|
|
type: 'category',
|
|
inverse: false,
|
|
data: category.value,
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
axisLabel: {
|
|
show: false,
|
|
},
|
|
},
|
|
],
|
|
series: [
|
|
{
|
|
// 内
|
|
type: 'bar',
|
|
barWidth: 10,
|
|
legendHoverLink: false,
|
|
silent: true,
|
|
itemStyle: {
|
|
color: function (params) {
|
|
// 红色
|
|
if (params.value && +params.value >= 70) {
|
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
{ offset: 0, color: '#fff1f0' },
|
|
{ offset: 0.5, color: '#ffa39e' },
|
|
{ offset: 1, color: '#f5222d' },
|
|
]);
|
|
}
|
|
// 蓝色
|
|
if (params.value && +params.value >= 30) {
|
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
{ offset: 0, color: '#f0f5ff' },
|
|
{ offset: 0.5, color: '#adc6ff' },
|
|
{ offset: 1, color: '#2f54eb' },
|
|
]);
|
|
}
|
|
// 绿色
|
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
{ offset: 0, color: '#f6ffed' },
|
|
{ offset: 0.5, color: '#b7eb8f' },
|
|
{ offset: 1, color: '#52c41a' },
|
|
]);
|
|
},
|
|
},
|
|
label: {
|
|
show: true,
|
|
position: 'left',
|
|
formatter: '{b}: ',
|
|
fontSize: 15,
|
|
color: '#fff',
|
|
},
|
|
data: category.value,
|
|
z: 1,
|
|
animationEasing: 'elasticOut',
|
|
},
|
|
{
|
|
// 分隔
|
|
type: 'pictorialBar',
|
|
itemStyle: {
|
|
color: '#0a3ca0',
|
|
},
|
|
symbolRepeat: 'fixed',
|
|
symbolMargin: 6,
|
|
symbol: 'rect',
|
|
symbolClip: true,
|
|
symbolSize: [1, 12],
|
|
symbolPosition: 'start',
|
|
symbolOffset: [0, -1],
|
|
symbolBoundingData: total,
|
|
data: category.value,
|
|
z: 2,
|
|
animationEasing: 'elasticOut',
|
|
},
|
|
{
|
|
// 外边框
|
|
type: 'pictorialBar',
|
|
symbol: 'rect',
|
|
symbolBoundingData: total,
|
|
itemStyle: {
|
|
color: 'transparent',
|
|
},
|
|
label: {
|
|
formatter: params => {
|
|
var text = `{a| ${params.value}%} `;
|
|
if (params.value && +params.value >= 70) {
|
|
text = `{c| ${params.value}%} `;
|
|
} else if (params.value && +params.value >= 30) {
|
|
text = `{b| ${params.value}%} `;
|
|
}
|
|
return text;
|
|
},
|
|
rich: {
|
|
a: {
|
|
color: '#52c41a', // 绿
|
|
fontSize: 16,
|
|
},
|
|
b: {
|
|
color: '#2f54eb', // 蓝
|
|
fontSize: 16,
|
|
},
|
|
c: {
|
|
color: '#f5222d', // 红
|
|
fontSize: 16,
|
|
},
|
|
f: {
|
|
color: '#ffffff', // 默认
|
|
fontSize: 16,
|
|
},
|
|
},
|
|
position: 'right',
|
|
distance: 0, // 向右偏移位置
|
|
show: true,
|
|
},
|
|
data: category.value,
|
|
z: 0,
|
|
animationEasing: 'elasticOut',
|
|
},
|
|
{
|
|
name: '外框',
|
|
type: 'bar',
|
|
barGap: '-120%', // 设置外框粗细
|
|
data: [total, total, total],
|
|
barWidth: 14,
|
|
itemStyle: {
|
|
color: 'transparent', // 填充色
|
|
borderColor: '#0a3ca0', // 边框色
|
|
borderWidth: 1, // 边框宽度
|
|
borderRadius: 1, //圆角半径
|
|
},
|
|
label: {
|
|
// 标签显示位置
|
|
show: false,
|
|
position: 'top', // insideTop 或者横向的 insideLeft
|
|
},
|
|
z: 0,
|
|
},
|
|
],
|
|
};
|
|
|
|
/**图数据渲染 */
|
|
function handleRanderChart(
|
|
container: HTMLElement | undefined,
|
|
option: EChartsOption
|
|
) {
|
|
if (!container) return;
|
|
neResourcesChart.value = markRaw(echarts.init(container, 'light'));
|
|
option && neResourcesChart.value.setOption(option);
|
|
|
|
// 创建 ResizeObserver 实例
|
|
var observer = new ResizeObserver(entries => {
|
|
if (neResourcesChart.value) {
|
|
neResourcesChart.value.resize();
|
|
}
|
|
});
|
|
// 监听元素大小变化
|
|
observer.observe(container);
|
|
}
|
|
|
|
function fnChangeData(data: any[], itemID: string) {
|
|
let info = data.find((item: any) => item.id === itemID);
|
|
if (!info || !info.neState.online) return;
|
|
// if (!info.neState.online) {
|
|
// info = data.find((item: any) => item.id === itemID);
|
|
// graphNodeClickID.value = itemID;
|
|
// }
|
|
// console.log(info.id);
|
|
// console.log(info.neState.cpu.nfCpuUsage);
|
|
// console.log(info.neState.cpu.sysCpuUsage);
|
|
// console.log(info.neState.mem);
|
|
// console.log(info.neState.disk);
|
|
let sysCpuUsage = 0;
|
|
let nfCpuUsage = 0;
|
|
if (info.neState.cpu) {
|
|
nfCpuUsage = info.neState.cpu.nfCpuUsage;
|
|
const nfCpu = +(info.neState.cpu.nfCpuUsage / 100);
|
|
nfCpuUsage = +nfCpu.toFixed(2);
|
|
if (nfCpuUsage > 100) {
|
|
nfCpuUsage = 100;
|
|
}
|
|
|
|
sysCpuUsage = info.neState.cpu.sysCpuUsage;
|
|
let sysCpu = +(info.neState.cpu.sysCpuUsage / 100);
|
|
sysCpuUsage = +sysCpu.toFixed(2);
|
|
if (sysCpuUsage > 100) {
|
|
sysCpuUsage = 100;
|
|
}
|
|
}
|
|
|
|
let sysMemUsage = 0;
|
|
if (info.neState.mem) {
|
|
const men = info.neState.mem.sysMemUsage;
|
|
sysMemUsage = +(men / 100).toFixed(2);
|
|
if (sysMemUsage > 100) {
|
|
sysMemUsage = 100;
|
|
}
|
|
}
|
|
|
|
let sysDiskUsage = 0;
|
|
if (info.neState.disk && Array.isArray(info.neState.disk.partitionInfo)) {
|
|
let disks: any[] = info.neState.disk.partitionInfo;
|
|
disks = disks.sort((a, b) => +b.used - +a.used);
|
|
if (disks.length > 0) {
|
|
const { total, used } = disks[0];
|
|
sysDiskUsage = +((used / total) * 100).toFixed(2);
|
|
}
|
|
}
|
|
|
|
category.value[0].value = sysDiskUsage;
|
|
category.value[1].value = sysMemUsage;
|
|
category.value[2].value = sysCpuUsage;
|
|
category.value[3].value = nfCpuUsage;
|
|
neResourcesChart.value.setOption({
|
|
series: [
|
|
{
|
|
data: category.value,
|
|
},
|
|
{
|
|
data: category.value,
|
|
},
|
|
{
|
|
data: category.value,
|
|
},
|
|
{
|
|
data: category.value,
|
|
},
|
|
],
|
|
});
|
|
}
|
|
|
|
watch(
|
|
graphNodeState,
|
|
v => {
|
|
fnChangeData(v, graphNodeClickID.value);
|
|
},
|
|
{
|
|
deep: true,
|
|
}
|
|
);
|
|
|
|
watch(graphNodeClickID, v => {
|
|
fnChangeData(graphNodeState.value, v);
|
|
});
|
|
|
|
onMounted(() => {
|
|
// setInterval(function () {
|
|
// var ndata = [
|
|
// {
|
|
// name: '系统内存',
|
|
// value: Math.round(Math.random() * 100),
|
|
// },
|
|
// {
|
|
// name: '系统CPU',
|
|
// value: Math.round(Math.random() * 100),
|
|
// },
|
|
// {
|
|
// name: '网元CPU',
|
|
// value: Math.round(Math.random() * 100),
|
|
// },
|
|
// ];
|
|
// neResourcesChart.value.setOption({
|
|
// series: [
|
|
// {
|
|
// data: ndata,
|
|
// },
|
|
// {
|
|
// data: ndata,
|
|
// },
|
|
// {
|
|
// data: ndata,
|
|
// },
|
|
// ],
|
|
// });
|
|
// }, 2000);
|
|
nextTick(() => {
|
|
handleRanderChart(neResourcesDom.value, optionData);
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="neResourcesDom" class="chart"></div>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
.chart {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|