Files
go-service/cmd/server/web/js/chart.js

151 lines
4.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// chart.js
export function drawChart(canvas, history) {
if (!canvas || !history?.length) return;
const rect = canvas.getBoundingClientRect();
const displayHeight = rect.height || 200;
const displayWidth = rect.width || 800;
canvas.width = displayWidth;
canvas.height = displayHeight;
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
// ===== ОТСТУПЫ =====
const padLeft = 45;
const padRight = 15;
const padTop = 10;
const padBottom = 25;
const plotW = w - padLeft - padRight;
const plotH = h - padTop - padBottom;
// ===== ФОН =====
ctx.fillStyle = "#0a0f0a";
ctx.fillRect(0, 0, w, h);
// ===== СЕТКА =====
const maxVal = 63;
const gridLines = 4;
ctx.strokeStyle = "#0d2a0d";
ctx.lineWidth = 0.5;
ctx.setLineDash([4, 4]);
for (let i = 0; i <= gridLines; i++) {
const val = (maxVal / gridLines) * i;
const y = padTop + plotH - (val / maxVal) * plotH;
ctx.beginPath();
ctx.moveTo(padLeft, y);
ctx.lineTo(w - padRight, y);
ctx.stroke();
ctx.fillStyle = "#00ff88";
ctx.font = "11px monospace";
ctx.textAlign = "right";
ctx.fillText(Math.round(val), padLeft - 8, y + 4);
}
ctx.setLineDash([]);
// ===== ПОДПИСЬ ОСИ Y =====
ctx.fillStyle = "#00ff88";
ctx.font = "bold 11px monospace";
ctx.save();
ctx.translate(12, padTop + plotH / 2);
ctx.rotate(-Math.PI / 2);
ctx.textAlign = "center";
ctx.fillText("ЗНАЧЕНИЕ", 0, 0);
ctx.restore();
// ===== ПОДПИСЬ ОСИ X =====
ctx.textAlign = "center";
ctx.fillText("БУФЕР ПРИНЯТЫХ ДАННЫХ", padLeft + plotW / 2, h - 4);
// ===== СИГНАЛ =====
const hasSignal = history.some(v => v > 0);
if (!hasSignal) {
ctx.fillStyle = "#ff4444";
ctx.font = "14px monospace";
ctx.textAlign = "center";
ctx.fillText("Ожидание сигнала...", w / 2, h / 2);
return;
}
// Прореживание если точек больше чем пикселей
let plotData = history;
if (history.length > plotW) {
const step = history.length / plotW;
plotData = [];
for (let i = 0; i < plotW; i++) {
const idx = Math.floor(i * step);
plotData.push(history[idx]);
}
}
ctx.strokeStyle = "#e6852d";
ctx.lineWidth = 1.5;
ctx.shadowColor = "#e6852d";
ctx.shadowBlur = 3;
ctx.beginPath();
const stepX = plotW / Math.max(plotData.length - 1, 1);
for (let i = 0; i < plotData.length; i++) {
const x = padLeft + i * stepX;
const y = padTop + plotH - (plotData[i] / maxVal) * plotH;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
ctx.shadowBlur = 0;
// ===== ПОСЛЕДНЯЯ ТОЧКА + ЗНАЧЕНИЕ =====
if (history.length > 0) {
const lastVal = history[history.length - 1];
const lastX = padLeft + (plotData.length - 1) * stepX;
const lastY = padTop + plotH - (lastVal / maxVal) * plotH;
// Кружок
ctx.fillStyle = "#c46b1f";
ctx.beginPath();
ctx.arc(lastX, lastY, 4, 0, Math.PI * 2);
ctx.fill();
// Значение последней точки
const labelText = `${lastVal}`;
const labelWidth = ctx.measureText(labelText).width;
// Фон для читаемости
ctx.fillStyle = "rgba(0,0,0,0.8)";
ctx.fillRect(lastX - labelWidth / 2 - 4, lastY - 22, labelWidth + 8, 18);
// Текст по центру над точкой
ctx.fillStyle = "#00ff88";
ctx.font = "bold 12px monospace";
ctx.textAlign = "center";
ctx.fillText(labelText, lastX, lastY - 8);
// Статистика в углу
const peak = Math.max(...history);
const min = Math.min(...history);
ctx.fillStyle = "rgba(0,0,0,0.7)";
ctx.fillRect(w - 120, padTop, 110, 42);
ctx.fillStyle = "#00ff88";
ctx.font = "10px monospace";
ctx.textAlign = "left";
ctx.fillText(`Пик: ${peak}`, w - 110, padTop + 14);
ctx.fillText(`Мин: ${min}`, w - 110, padTop + 28);
ctx.fillText(`Точек: ${history.length}`, w - 110, padTop + 42);
}
}