113 lines
4.2 KiB
HTML
113 lines
4.2 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Logic Analyzer</title>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<canvas id="binaryChart" width="500" height="250"></canvas>
|
|
</main>
|
|
<script>
|
|
function drawAllWaveforms(channels_total, samples_total, samples) {
|
|
const canvas = document.getElementById('binaryChart');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
|
const data = [];
|
|
for (let i = 0; i < samples_total; i++) {
|
|
data.push((samples[i] >> 1) & 1);
|
|
}
|
|
|
|
// Настройки отступов
|
|
const leftMargin = 50;
|
|
const rightMargin = 30;
|
|
const topMargin = 30;
|
|
const bottomMargin = 40;
|
|
const graphWidth = canvas.width - leftMargin - rightMargin; // 500 - 50 - 30 = 420
|
|
const graphHeight = canvas.height - topMargin - bottomMargin; // 250 - 30 - 40 = 180
|
|
|
|
// Шаг между точками
|
|
const stepX = graphWidth / (samples_total - 1); // 420 / 9 = 46.67px
|
|
|
|
// Отрисовка осей
|
|
ctx.beginPath();
|
|
// Ось Y (вертикальная)
|
|
ctx.moveTo(leftMargin, topMargin);
|
|
ctx.lineTo(leftMargin, canvas.height - bottomMargin);
|
|
// Ось X (горизонтальная)
|
|
ctx.lineTo(canvas.width - rightMargin, canvas.height - bottomMargin);
|
|
ctx.stroke();
|
|
|
|
// Подписи на оси Y (0 и 1)
|
|
ctx.font = "12px Arial";
|
|
ctx.fillStyle = "black";
|
|
ctx.fillText("1", leftMargin - 20, topMargin + 3);
|
|
ctx.fillText("0", leftMargin - 20, canvas.height - bottomMargin + 3);
|
|
|
|
// Подпись оси Y
|
|
ctx.save();
|
|
ctx.translate(20, canvas.height / 2);
|
|
ctx.rotate(-Math.PI / 2);
|
|
ctx.fillText("Значение", -20, 0);
|
|
ctx.restore();
|
|
|
|
// Рисуем ступенчатый график (бинарный)
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = 'blue';
|
|
ctx.lineWidth = 2;
|
|
|
|
for (let i = 0; i < samples_total; i++) {
|
|
const x = leftMargin + i * stepX;
|
|
// Преобразуем значение (0 или 1) в Y-координату
|
|
// 1 -> верх (topMargin), 0 -> низ (canvas.height - bottomMargin)
|
|
const y = data[i] === 1 ? topMargin : canvas.height - bottomMargin;
|
|
|
|
if (i === 0) {
|
|
ctx.moveTo(x, y);
|
|
} else {
|
|
// Рисуем горизонтальную линию от предыдущей точки
|
|
const prevX = leftMargin + (i - 1) * stepX;
|
|
const prevY = data[i-1] === 1 ? topMargin : canvas.height - bottomMargin;
|
|
ctx.lineTo(prevX + stepX, prevY); // Горизонтальная линия
|
|
ctx.lineTo(x, y); // Вертикальный скачок
|
|
}
|
|
}
|
|
ctx.stroke();
|
|
|
|
ctx.fillStyle = "black";
|
|
ctx.font = "bold 12px Arial";
|
|
ctx.fillText("Время (такты)", canvas.width/2 - 30, canvas.height - 10);
|
|
}
|
|
|
|
function connectWebSocket() {
|
|
ws = new WebSocket('ws://' + window.location.hostname + ':81');
|
|
|
|
ws.onopen = function() {
|
|
console.log('WebSocket connected');
|
|
updateStatus('Подключено');
|
|
};
|
|
|
|
ws.onmessage = function(event) {
|
|
const data = JSON.parse(event.data);
|
|
if (data.type === 'data') {
|
|
drawAllWaveforms(data.channels_total, data.samples_total, data.samples);
|
|
} else if (data.type === 'status') {
|
|
updateStatus(data.message);
|
|
}
|
|
};
|
|
|
|
ws.onclose = function() {
|
|
console.log('WebSocket disconnected');
|
|
updateStatus('Отключено. Переподключение...');
|
|
setTimeout(connectWebSocket, 1000);
|
|
};
|
|
}
|
|
|
|
window.addEventListener('DOMContentLoaded', connectWebSocket);
|
|
</script>
|
|
</body>
|
|
</html>
|