805 lines
28 KiB
JavaScript
805 lines
28 KiB
JavaScript
class SystemInfo extends HTMLElement {
|
||
constructor() {
|
||
super();
|
||
this.attachShadow({ mode: 'open' });
|
||
this.charts = [];
|
||
this.chartOptions = [
|
||
'内存使用率',
|
||
'磁盘使用率',
|
||
'网络带宽'
|
||
];
|
||
|
||
// 动态添加CPU核心选项
|
||
this.cpuCoreCount = 8; // 默认值,后续会从系统获取
|
||
for (let i = 0; i < this.cpuCoreCount; i++) {
|
||
this.chartOptions.push(`CPU${i}使用率`);
|
||
}
|
||
|
||
// 每个图表的默认选择
|
||
this.chartSelections = [
|
||
'CPU0使用率',
|
||
'CPU1使用率',
|
||
'内存使用率',
|
||
'网络带宽'
|
||
];
|
||
|
||
// 存储历史数据
|
||
this.historyData = {};
|
||
this.chartOptions.forEach(option => {
|
||
this.historyData[option] = Array(60).fill(0);
|
||
});
|
||
|
||
// 为上传带宽单独存储数据
|
||
this.historyData['上传带宽'] = Array(60).fill(0);
|
||
this.historyData['下载带宽'] = Array(60).fill(0);
|
||
|
||
// 初始化状态
|
||
this.chartsInitialized = false;
|
||
this.setupInProgress = false;
|
||
this.chartJsLoaded = false;
|
||
this.domInitialized = false;
|
||
this.isActive = false; // 添加活动状态标记
|
||
}
|
||
|
||
connectedCallback() {
|
||
this.isActive = true; // 组件连接到DOM时设置为活动状态
|
||
this.render();
|
||
|
||
// 创建一个MutationObserver来监听shadowRoot内容变化
|
||
this.observer = new MutationObserver(this.onDomChange.bind(this));
|
||
this.observer.observe(this.shadowRoot, { childList: true, subtree: true });
|
||
|
||
// 立即尝试初始化事件监听器
|
||
setTimeout(() => this.setupEventListeners(), 0);
|
||
|
||
// 获取系统信息
|
||
this.fetchSystemInfo();
|
||
|
||
// 加载Chart.js
|
||
this.loadChartJs();
|
||
|
||
// 设置定时刷新
|
||
this.refreshInterval = setInterval(() => {
|
||
if (!this.isActive) return; // 非活动状态时不执行更新
|
||
|
||
this.fetchSystemInfo();
|
||
|
||
// 图表初始化后才更新
|
||
if (this.chartsInitialized) {
|
||
this.updateCharts();
|
||
}
|
||
}, 2000);
|
||
}
|
||
|
||
disconnectedCallback() {
|
||
this.isActive = false; // 组件断开连接时设置为非活动状态
|
||
|
||
if (this.refreshInterval) {
|
||
clearInterval(this.refreshInterval);
|
||
this.refreshInterval = null;
|
||
}
|
||
|
||
if (this.observer) {
|
||
this.observer.disconnect();
|
||
}
|
||
|
||
this.cleanupCharts();
|
||
}
|
||
|
||
// 清理所有图表
|
||
cleanupCharts() {
|
||
// 销毁图表
|
||
if (this.charts) {
|
||
this.charts.forEach((chart, index) => {
|
||
if (chart) {
|
||
try {
|
||
chart.destroy();
|
||
} catch (e) {
|
||
console.error(`销毁图表${index}失败:`, e);
|
||
}
|
||
this.charts[index] = null;
|
||
}
|
||
});
|
||
}
|
||
this.chartsInitialized = false;
|
||
}
|
||
|
||
// 重新激活组件的方法(当标签页重新被选中时调用)
|
||
reactivate() {
|
||
if (this.isActive) return; // 如果已经是活动状态,不重复处理
|
||
|
||
this.isActive = true;
|
||
|
||
// 重置图表状态
|
||
this.cleanupCharts();
|
||
this.domInitialized = false;
|
||
|
||
// 重新设置刷新定时器
|
||
if (!this.refreshInterval) {
|
||
this.refreshInterval = setInterval(() => {
|
||
if (!this.isActive) return;
|
||
|
||
this.fetchSystemInfo();
|
||
|
||
if (this.chartsInitialized) {
|
||
this.updateCharts();
|
||
}
|
||
}, 2000);
|
||
}
|
||
|
||
// 重新初始化图表
|
||
setTimeout(() => {
|
||
if (this.chartJsLoaded) {
|
||
// 确保DOM已初始化
|
||
const canvasElements = this.shadowRoot.querySelectorAll('canvas');
|
||
if (canvasElements.length === 4) {
|
||
this.domInitialized = true;
|
||
this.initializeCharts();
|
||
} else {
|
||
// 如果DOM还没准备好,等待DOM变化
|
||
this.observer = new MutationObserver(this.onDomChange.bind(this));
|
||
this.observer.observe(this.shadowRoot, { childList: true, subtree: true });
|
||
}
|
||
} else {
|
||
// 如果Chart.js还没加载,重新加载
|
||
this.loadChartJs();
|
||
}
|
||
}, 300);
|
||
}
|
||
|
||
// 监听DOM变化
|
||
onDomChange(mutations) {
|
||
if (this.domInitialized) return;
|
||
|
||
// 检查canvas元素是否已添加到DOM
|
||
const canvasElements = this.shadowRoot.querySelectorAll('canvas');
|
||
if (canvasElements.length === 4) {
|
||
this.domInitialized = true;
|
||
|
||
// 如果Chart.js已加载,初始化图表
|
||
if (this.chartJsLoaded) {
|
||
this.initializeCharts();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 加载Chart.js
|
||
loadChartJs() {
|
||
if (typeof Chart !== 'undefined') {
|
||
this.chartJsLoaded = true;
|
||
|
||
// 如果DOM已准备就绪,初始化图表
|
||
if (this.domInitialized) {
|
||
this.initializeCharts();
|
||
}
|
||
return;
|
||
}
|
||
|
||
const script = document.createElement('script');
|
||
script.src = './chart.min.js';
|
||
|
||
script.onload = () => {
|
||
this.chartJsLoaded = true;
|
||
|
||
// 如果DOM已准备就绪,初始化图表
|
||
if (this.domInitialized) {
|
||
this.initializeCharts();
|
||
}
|
||
};
|
||
|
||
script.onerror = () => {
|
||
const cdnScript = document.createElement('script');
|
||
cdnScript.src = 'https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js';
|
||
|
||
cdnScript.onload = () => {
|
||
this.chartJsLoaded = true;
|
||
|
||
// 如果DOM已准备就绪,初始化图表
|
||
if (this.domInitialized) {
|
||
this.initializeCharts();
|
||
}
|
||
};
|
||
|
||
document.head.appendChild(cdnScript);
|
||
};
|
||
|
||
document.head.appendChild(script);
|
||
}
|
||
|
||
render() {
|
||
// 提前生成图表选项HTML字符串
|
||
const options0 = this.generateChartOptions(0);
|
||
const options1 = this.generateChartOptions(1);
|
||
const options2 = this.generateChartOptions(2);
|
||
const options3 = this.generateChartOptions(3);
|
||
|
||
this.shadowRoot.innerHTML = `
|
||
<style>
|
||
:host {
|
||
display: block;
|
||
height: 100%;
|
||
overflow: auto;
|
||
padding: 16px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.system-info-container {
|
||
background-color: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
padding: 16px;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.info-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
}
|
||
|
||
.info-title {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.system-overview {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 16px;
|
||
margin-bottom: 24px;
|
||
background-color: #f5f5f5;
|
||
border-radius: 6px;
|
||
padding: 16px;
|
||
}
|
||
|
||
.overview-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.overview-label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.overview-value {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.overview-subvalue {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
.charts-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
grid-template-rows: repeat(2, 1fr);
|
||
gap: 16px;
|
||
flex-grow: 1;
|
||
min-height: 400px;
|
||
}
|
||
|
||
.chart-card {
|
||
background-color: #f5f5f5;
|
||
border-radius: 6px;
|
||
padding: 16px;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 200px;
|
||
}
|
||
|
||
.chart-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.chart-title {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.chart-select {
|
||
padding: 4px;
|
||
border-radius: 4px;
|
||
border: 1px solid #ccc;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.chart-container {
|
||
flex-grow: 1;
|
||
position: relative;
|
||
min-height: 150px;
|
||
}
|
||
|
||
canvas {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
position: absolute;
|
||
}
|
||
</style>
|
||
<div class="system-info-container">
|
||
<div class="info-header">
|
||
<div class="info-title">系统信息</div>
|
||
</div>
|
||
|
||
<div class="system-overview">
|
||
<div class="overview-item">
|
||
<div class="overview-label">操作系统</div>
|
||
<div class="overview-value" id="os-info">Loading...</div>
|
||
<div class="overview-subvalue" id="kernel-info">Loading...</div>
|
||
</div>
|
||
<div class="overview-item">
|
||
<div class="overview-label">CPU核心数</div>
|
||
<div class="overview-value" id="cpu-cores">Loading...</div>
|
||
</div>
|
||
<div class="overview-item">
|
||
<div class="overview-label">IP地址</div>
|
||
<div class="overview-value" id="ip-address">Loading...</div>
|
||
</div>
|
||
<div class="overview-item">
|
||
<div class="overview-label">已隔离CPU核心号</div>
|
||
<div class="overview-value" id="isolated-cores">Loading...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="charts-container">
|
||
<div class="chart-card">
|
||
<div class="chart-header">
|
||
<div class="chart-title">监控图表 1</div>
|
||
<select class="chart-select" data-chart-index="0">
|
||
${options0}
|
||
</select>
|
||
</div>
|
||
<div class="chart-container">
|
||
<canvas id="chart0"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chart-card">
|
||
<div class="chart-header">
|
||
<div class="chart-title">监控图表 2</div>
|
||
<select class="chart-select" data-chart-index="1">
|
||
${options1}
|
||
</select>
|
||
</div>
|
||
<div class="chart-container">
|
||
<canvas id="chart1"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chart-card">
|
||
<div class="chart-header">
|
||
<div class="chart-title">监控图表 3</div>
|
||
<select class="chart-select" data-chart-index="2">
|
||
${options2}
|
||
</select>
|
||
</div>
|
||
<div class="chart-container">
|
||
<canvas id="chart2"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chart-card">
|
||
<div class="chart-header">
|
||
<div class="chart-title">监控图表 4</div>
|
||
<select class="chart-select" data-chart-index="3">
|
||
${options3}
|
||
</select>
|
||
</div>
|
||
<div class="chart-container">
|
||
<canvas id="chart3"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
setupEventListeners() {
|
||
// 设置图表选择监听器
|
||
const selects = this.shadowRoot.querySelectorAll('.chart-select');
|
||
if (selects.length !== 4) {
|
||
setTimeout(() => this.setupEventListeners(), 100);
|
||
return;
|
||
}
|
||
|
||
selects.forEach(select => {
|
||
select.addEventListener('change', (e) => {
|
||
const chartIndex = parseInt(e.target.getAttribute('data-chart-index'));
|
||
const newMetric = e.target.value;
|
||
const oldMetric = this.chartSelections[chartIndex];
|
||
|
||
// 更新选择
|
||
this.chartSelections[chartIndex] = newMetric;
|
||
|
||
// 如果图表已初始化,重新创建图表而不是更新
|
||
if (this.charts[chartIndex]) {
|
||
this.recreateChart(chartIndex);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 初始化所有图表
|
||
initializeCharts() {
|
||
if (this.setupInProgress || this.chartsInitialized) {
|
||
return;
|
||
}
|
||
|
||
this.setupInProgress = true;
|
||
|
||
try {
|
||
for (let i = 0; i < 4; i++) {
|
||
this.createChart(i);
|
||
}
|
||
|
||
this.chartsInitialized = true;
|
||
} catch (error) {
|
||
console.error('图表初始化失败:', error);
|
||
} finally {
|
||
this.setupInProgress = false;
|
||
}
|
||
}
|
||
|
||
// 创建单个图表
|
||
createChart(index) {
|
||
const canvas = this.shadowRoot.getElementById(`chart${index}`);
|
||
if (!canvas) {
|
||
throw new Error(`找不到图表${index}的canvas元素`);
|
||
}
|
||
|
||
// 确保canves宽高被设置
|
||
canvas.style.width = '100%';
|
||
canvas.style.height = '100%';
|
||
|
||
const ctx = canvas.getContext('2d');
|
||
if (!ctx) {
|
||
throw new Error(`无法获取图表${index}的2D上下文`);
|
||
}
|
||
|
||
// 获取指标和数据
|
||
const metric = this.chartSelections[index];
|
||
const data = [...(this.historyData[metric] || Array(60).fill(0))];
|
||
|
||
// 针对不同指标设置不同的y轴配置和数据集
|
||
const yAxisConfig = this.getYAxisConfig(metric);
|
||
let datasets = [];
|
||
|
||
if (metric === '网络带宽') {
|
||
// 网络带宽显示两条线:上传和下载
|
||
datasets = [
|
||
{
|
||
label: '下载带宽',
|
||
data: [...this.historyData['下载带宽']],
|
||
borderColor: '#4CAF50', // 绿色
|
||
borderWidth: 2,
|
||
fill: false,
|
||
tension: 0.4,
|
||
pointRadius: 0, // 去掉点
|
||
pointHoverRadius: 0 // 去掉悬停点
|
||
},
|
||
{
|
||
label: '上传带宽',
|
||
data: [...this.historyData['上传带宽']],
|
||
borderColor: '#F44336', // 红色
|
||
borderWidth: 2,
|
||
fill: false,
|
||
tension: 0.4,
|
||
pointRadius: 0, // 去掉点
|
||
pointHoverRadius: 0 // 去掉悬停点
|
||
}
|
||
];
|
||
} else {
|
||
// 其他指标只显示一条线
|
||
datasets = [
|
||
{
|
||
label: metric,
|
||
data: data,
|
||
borderColor: this.getChartColor(metric),
|
||
borderWidth: 2,
|
||
fill: false,
|
||
tension: 0.4,
|
||
pointRadius: 0, // 去掉点
|
||
pointHoverRadius: 0 // 去掉悬停点
|
||
}
|
||
];
|
||
}
|
||
|
||
// 创建图表
|
||
this.charts[index] = new Chart(ctx, {
|
||
type: 'line',
|
||
data: {
|
||
labels: Array(60).fill(''),
|
||
datasets: datasets
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
animation: {
|
||
duration: 0 // 关闭动画提高性能
|
||
},
|
||
elements: {
|
||
point: {
|
||
radius: 0 // 全局去掉点
|
||
},
|
||
line: {
|
||
tension: 0.4 // 平滑曲线
|
||
}
|
||
},
|
||
scales: {
|
||
y: yAxisConfig,
|
||
x: {
|
||
display: false
|
||
}
|
||
},
|
||
plugins: {
|
||
legend: {
|
||
display: metric === '网络带宽', // 只在网络带宽图表显示图例
|
||
position: 'top',
|
||
labels: {
|
||
boxWidth: 12,
|
||
font: {
|
||
size: 10
|
||
}
|
||
}
|
||
},
|
||
tooltip: {
|
||
mode: 'index',
|
||
intersect: false,
|
||
callbacks: {
|
||
label: function(context) {
|
||
const value = context.raw;
|
||
// 为网络带宽添加单位
|
||
if (metric === '网络带宽' ||
|
||
context.dataset.label === '上传带宽' ||
|
||
context.dataset.label === '下载带宽') {
|
||
return `${value} Mbps`;
|
||
}
|
||
// 为其他指标添加百分比单位
|
||
return `${value}%`;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// 根据指标类型获取y轴配置
|
||
getYAxisConfig(metric) {
|
||
// 网络带宽使用Mbps单位,其他使用百分比
|
||
if (metric === '网络带宽') {
|
||
return {
|
||
beginAtZero: true,
|
||
// 自动计算最大值,但最少为1
|
||
suggestedMax: 1,
|
||
title: {
|
||
display: true,
|
||
text: 'Mbps'
|
||
}
|
||
};
|
||
} else {
|
||
return {
|
||
beginAtZero: true,
|
||
max: 100,
|
||
title: {
|
||
display: true,
|
||
text: '%'
|
||
}
|
||
};
|
||
}
|
||
}
|
||
|
||
// 根据指标类型获取图表颜色
|
||
getChartColor(metric) {
|
||
if (metric === '下载带宽') {
|
||
return '#4CAF50'; // 绿色
|
||
} else if (metric === '上传带宽') {
|
||
return '#F44336'; // 红色
|
||
} else if (metric === '内存使用率') {
|
||
return '#2196F3'; // 蓝色
|
||
} else if (metric === '磁盘使用率') {
|
||
return '#FF9800'; // 橙色
|
||
} else if (metric.includes('CPU')) {
|
||
// CPU使用率显示紫色色调
|
||
return '#9C27B0';
|
||
}
|
||
|
||
// 默认颜色
|
||
const colors = [
|
||
'#4285F4', // 蓝色
|
||
'#EA4335', // 红色
|
||
'#34A853', // 绿色
|
||
'#FBBC05' // 黄色
|
||
];
|
||
|
||
// 为不同的指标分配不同的默认颜色
|
||
const hash = metric.split('').reduce((hash, char) => {
|
||
return char.charCodeAt(0) + ((hash << 5) - hash);
|
||
}, 0);
|
||
|
||
return colors[Math.abs(hash) % colors.length];
|
||
}
|
||
|
||
// 更新单个图表
|
||
updateChart(index) {
|
||
try {
|
||
if (!this.charts[index]) {
|
||
return;
|
||
}
|
||
|
||
const metric = this.chartSelections[index];
|
||
if (!this.historyData[metric] && metric !== '网络带宽') {
|
||
return;
|
||
}
|
||
|
||
if (metric === '网络带宽') {
|
||
// 获取上传和下载数据
|
||
const downloadData = [...this.historyData['下载带宽']];
|
||
const uploadData = [...this.historyData['上传带宽']];
|
||
|
||
// 找出最大值来设置Y轴
|
||
const maxDownload = Math.max(...downloadData);
|
||
const maxUpload = Math.max(...uploadData);
|
||
const maxValue = Math.max(maxDownload, maxUpload);
|
||
|
||
// 网络带宽图表根据数据自动调整y轴刻度
|
||
if (this.charts[index].options.scales.y) {
|
||
// 根据当前最大值动态设置y轴,但至少为1
|
||
const suggestedMax = Math.max(maxValue * 1.2, 1);
|
||
this.charts[index].options.scales.y.suggestedMax = suggestedMax;
|
||
}
|
||
|
||
// 更新两个数据集
|
||
this.charts[index].data.datasets[0].data = downloadData;
|
||
this.charts[index].data.datasets[1].data = uploadData;
|
||
} else {
|
||
// 其他指标只有一个数据集
|
||
const currentData = [...this.historyData[metric]];
|
||
this.charts[index].data.datasets[0].data = currentData;
|
||
}
|
||
|
||
this.charts[index].update();
|
||
} catch (error) {
|
||
console.error(`更新图表${index}失败:`, error);
|
||
}
|
||
}
|
||
|
||
// 更新所有图表
|
||
updateCharts() {
|
||
if (!this.chartsInitialized) {
|
||
return;
|
||
}
|
||
|
||
for (let i = 0; i < 4; i++) {
|
||
this.updateChart(i);
|
||
}
|
||
}
|
||
|
||
// 重新创建单个图表
|
||
recreateChart(index) {
|
||
try {
|
||
// 销毁现有图表
|
||
if (this.charts[index]) {
|
||
this.charts[index].destroy();
|
||
this.charts[index] = null;
|
||
}
|
||
|
||
// 重新创建
|
||
this.createChart(index);
|
||
|
||
} catch (error) {
|
||
console.error(`重新创建图表${index}失败:`, error);
|
||
}
|
||
}
|
||
|
||
// 获取系统信息
|
||
async fetchSystemInfo() {
|
||
try {
|
||
const response = await fetch('/api/system-info');
|
||
if (!response.ok) {
|
||
throw new Error(`获取系统信息失败: ${response.status}`);
|
||
}
|
||
const data = await response.json();
|
||
|
||
// 更新系统概览
|
||
const osInfo = this.shadowRoot.getElementById('os-info');
|
||
const kernelInfo = this.shadowRoot.getElementById('kernel-info');
|
||
const cpuCores = this.shadowRoot.getElementById('cpu-cores');
|
||
const ipAddress = this.shadowRoot.getElementById('ip-address');
|
||
const isolatedCores = this.shadowRoot.getElementById('isolated-cores');
|
||
|
||
if (osInfo) osInfo.textContent = data.os;
|
||
if (kernelInfo) kernelInfo.textContent = data.kernel || '';
|
||
if (cpuCores) cpuCores.textContent = data.cpuCores;
|
||
if (ipAddress) ipAddress.textContent = data.ipAddress;
|
||
if (isolatedCores) isolatedCores.textContent = data.isolatedCores.join(',') || '无';
|
||
|
||
// 更新CPU核心数并重新生成选项
|
||
if (this.cpuCoreCount !== data.cpuCores) {
|
||
this.cpuCoreCount = data.cpuCores;
|
||
this.updateCpuOptions();
|
||
}
|
||
|
||
// 更新历史数据
|
||
for (const [key, value] of Object.entries(data.metrics)) {
|
||
if (this.historyData[key]) {
|
||
this.historyData[key].shift();
|
||
this.historyData[key].push(value);
|
||
}
|
||
}
|
||
|
||
// 如果图表已初始化,则更新图表
|
||
if (this.chartsInitialized) {
|
||
this.updateCharts();
|
||
}
|
||
} catch (error) {
|
||
console.error('获取系统信息失败:', error);
|
||
}
|
||
}
|
||
|
||
// 更新CPU选项
|
||
updateCpuOptions() {
|
||
// 清除旧的CPU选项
|
||
this.chartOptions = this.chartOptions.filter(opt => !opt.startsWith('CPU'));
|
||
|
||
// 添加新的CPU选项
|
||
for (let i = 0; i < this.cpuCoreCount; i++) {
|
||
const option = `CPU${i}使用率`;
|
||
this.chartOptions.push(option);
|
||
|
||
// 确保历史数据中有此项
|
||
if (!this.historyData[option]) {
|
||
this.historyData[option] = Array(60).fill(0);
|
||
}
|
||
}
|
||
|
||
// 更新图表选择下拉框
|
||
const selects = this.shadowRoot.querySelectorAll('.chart-select');
|
||
if (selects.length === 4) {
|
||
selects.forEach((select, index) => {
|
||
// 保存当前选择
|
||
const currentValue = this.chartSelections[index];
|
||
|
||
// 更新选项
|
||
select.innerHTML = this.generateChartOptions(index);
|
||
|
||
// 如果当前选择的值不在新选项中,则更新为第一个选项
|
||
if (!this.chartOptions.includes(currentValue)) {
|
||
this.chartSelections[index] = this.chartOptions[0];
|
||
if (this.charts[index]) {
|
||
this.recreateChart(index);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// 生成图表选项HTML
|
||
generateChartOptions(chartIndex) {
|
||
let html = '';
|
||
this.chartOptions.forEach(option => {
|
||
const selected = option === this.chartSelections[chartIndex] ? 'selected' : '';
|
||
html += `<option value="${option}" ${selected}>${option}</option>`;
|
||
});
|
||
return html;
|
||
}
|
||
}
|
||
|
||
customElements.define('system-info', SystemInfo);
|