e6875f0b4b
- 13-service async plugin framework - Textual TUI with CLI fallback - Plugin hot-reload + permission system - Web management panel (aiohttp) - Bridge-based inter-module communication - 10 regression tests Fixes applied: - PBKDF2-SHA256 auth (was plain SHA256) - Auth bypass removed (was allow-all on fail) - Bare excepts replaced with logged errors - CatFramework/DreamSu -> SenSu naming unified - ServiceManager: health checks + startup_order - Env var credentials (SENSU_ADMIN_PASSWORD etc)
52 lines
1.5 KiB
JavaScript
52 lines
1.5 KiB
JavaScript
class MiniChart {
|
|
constructor(canvasId, color = '#7aa2f7') {
|
|
this.canvas = document.getElementById(canvasId);
|
|
this.ctx = this.canvas.getContext('2d');
|
|
this.color = color;
|
|
this.data = new Array(60).fill(0); // 60秒历史
|
|
this.maxVal = 100;
|
|
|
|
this.resize();
|
|
window.addEventListener('resize', () => this.resize());
|
|
}
|
|
|
|
resize() {
|
|
const rect = this.canvas.parentElement.getBoundingClientRect();
|
|
this.canvas.width = rect.width - 24;
|
|
this.canvas.height = 60;
|
|
this.draw();
|
|
}
|
|
|
|
update(val) {
|
|
this.data.push(val);
|
|
if(this.data.length > 60) this.data.shift();
|
|
this.maxVal = Math.max(...this.data, 100);
|
|
this.draw();
|
|
}
|
|
|
|
draw() {
|
|
if(!this.ctx) return;
|
|
const { width, height } = this.canvas;
|
|
this.ctx.clearRect(0, 0, width, height);
|
|
|
|
this.ctx.strokeStyle = this.color;
|
|
this.ctx.lineWidth = 2;
|
|
this.ctx.beginPath();
|
|
|
|
this.data.forEach((v, i) => {
|
|
const x = (i / 59) * width;
|
|
const y = height - (v / this.maxVal) * (height - 10);
|
|
if(i === 0) this.ctx.moveTo(x, y);
|
|
else this.ctx.lineTo(x, y);
|
|
});
|
|
this.ctx.stroke();
|
|
|
|
// 填充渐变
|
|
this.ctx.lineTo(width, height);
|
|
this.ctx.lineTo(0, height);
|
|
this.ctx.fillStyle = this.color + '20';
|
|
this.ctx.fill();
|
|
}
|
|
}
|
|
window.MiniChart = MiniChart;
|