bitmin / index.html
Gaslighttheghost's picture
undefined - Initial Deployment
c7b1baa verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Magrav-Bitcoin Mining Control System</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.gauge-container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 50%;
}
.gauge {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.alert-flash {
animation: flash 2s infinite;
}
@keyframes flash {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.chart-container {
position: relative;
height: 300px;
width: 100%;
}
.system-status {
transition: all 0.3s ease;
}
.emergency-active {
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
</style>
</head>
<body class="bg-gray-900 text-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-8">
<div>
<h1 class="text-3xl md:text-4xl font-bold mb-2">
<i class="fas fa-bolt text-yellow-400 mr-2"></i>
Magrav-Bitcoin Mining Control System
</h1>
<p class="text-gray-400">Experimental Power Integration Monitoring</p>
</div>
<div class="mt-4 md:mt-0 flex items-center">
<div id="systemStatus" class="system-status px-4 py-2 rounded-full flex items-center
bg-gray-800 border border-gray-700">
<span class="w-3 h-3 rounded-full bg-red-500 mr-2"></span>
<span>System Offline</span>
</div>
</div>
</div>
<!-- System Stats -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Magrav Output -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">
<i class="fas fa-atom text-red-400 mr-2"></i>
Magrav Output
</h3>
<span class="text-xs bg-gray-700 px-2 py-1 rounded">Experimental</span>
</div>
<div class="flex items-end justify-between">
<div>
<div class="text-3xl font-bold text-red-400" id="magravOutput">0</div>
<div class="text-gray-400 text-sm">Watts</div>
</div>
<div class="gauge-container">
<canvas id="magravGauge" class="gauge"></canvas>
</div>
</div>
</div>
<!-- Battery Status -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">
<i class="fas fa-battery-three-quarters text-green-400 mr-2"></i>
Battery Status
</h3>
<span class="text-xs bg-gray-700 px-2 py-1 rounded">48V LiFePO4</span>
</div>
<div class="flex items-end justify-between">
<div>
<div class="text-3xl font-bold text-green-400" id="batteryCapacity">0</div>
<div class="text-gray-400 text-sm" id="batteryVoltage">0.0V</div>
</div>
<div class="gauge-container">
<canvas id="batteryGauge" class="gauge"></canvas>
</div>
</div>
</div>
<!-- DC Output -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">
<i class="fas fa-plug text-blue-400 mr-2"></i>
DC Output
</h3>
<span class="text-xs bg-gray-700 px-2 py-1 rounded">12V Target</span>
</div>
<div class="flex items-end justify-between">
<div>
<div class="text-3xl font-bold text-blue-400" id="dcVoltage">0.00</div>
<div class="text-gray-400 text-sm">Volts</div>
</div>
<div class="gauge-container">
<canvas id="voltageGauge" class="gauge"></canvas>
</div>
</div>
</div>
<!-- Mining Power -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">
<i class="fas fa-microchip text-orange-400 mr-2"></i>
Mining Power
</h3>
<span class="text-xs bg-gray-700 px-2 py-1 rounded">500W Test Rig</span>
</div>
<div class="flex items-end justify-between">
<div>
<div class="text-3xl font-bold text-orange-400" id="minerPower">0</div>
<div class="text-gray-400 text-sm" id="gridPower">Grid: 0W</div>
</div>
<div class="gauge-container">
<canvas id="minerGauge" class="gauge"></canvas>
</div>
</div>
</div>
</div>
<!-- Control Panel -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700 mb-8">
<h3 class="text-xl font-semibold mb-6">
<i class="fas fa-sliders-h text-gray-400 mr-2"></i>
System Controls
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<!-- System Toggle -->
<button id="systemToggle"
class="px-6 py-3 rounded-lg font-semibold bg-gray-700 hover:bg-gray-600 text-white transition-colors flex items-center justify-center">
<i class="fas fa-power-off mr-2"></i>
Power ON
</button>
<!-- Mining Toggle -->
<button id="miningToggle" disabled
class="px-6 py-3 rounded-lg font-semibold bg-gray-700 text-gray-400 transition-colors flex items-center justify-center cursor-not-allowed">
<i class="fas fa-digging mr-2"></i>
Mining OFF
</button>
<!-- Emergency Stop -->
<button id="emergencyStop"
class="px-6 py-3 rounded-lg font-semibold bg-red-600 hover:bg-red-700 text-white transition-colors flex items-center justify-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Emergency Stop
</button>
<!-- Reset System -->
<button id="resetSystem" disabled
class="px-6 py-3 rounded-lg font-semibold bg-blue-600 text-blue-200 transition-colors flex items-center justify-center cursor-not-allowed">
<i class="fas fa-sync-alt mr-2"></i>
Reset System
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Power Flow Chart -->
<div class="bg-gray-900 rounded-lg p-4 border border-gray-700">
<h4 class="text-lg font-semibold mb-4">
<i class="fas fa-exchange-alt text-purple-400 mr-2"></i>
Power Flow
</h4>
<div class="chart-container">
<canvas id="powerFlowChart"></canvas>
</div>
</div>
<!-- System Health Chart -->
<div class="bg-gray-900 rounded-lg p-4 border border-gray-700">
<h4 class="text-lg font-semibold mb-4">
<i class="fas fa-heartbeat text-green-400 mr-2"></i>
System Health
</h4>
<div class="chart-container">
<canvas id="healthChart"></canvas>
</div>
</div>
</div>
</div>
<!-- Alerts and Statistics -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Alerts Panel -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<h3 class="text-xl font-semibold mb-4 flex items-center">
<i class="fas fa-exclamation-circle text-yellow-400 mr-2"></i>
System Alerts
</h3>
<div class="space-y-2 max-h-64 overflow-y-auto pr-2" id="alertsContainer">
<div class="p-3 rounded-lg bg-gray-900 border-l-4 border-gray-500">
<div class="flex justify-between items-start">
<span class="text-sm">System initialized and ready</span>
<span class="text-xs text-gray-400">Just now</span>
</div>
</div>
</div>
</div>
<!-- Statistics Panel -->
<div class="bg-gray-800 rounded-xl p-6 border border-gray-700">
<h3 class="text-xl font-semibold mb-4 flex items-center">
<i class="fas fa-chart-line text-blue-400 mr-2"></i>
Experiment Statistics
</h3>
<div class="space-y-4 mb-6">
<div class="flex justify-between items-center">
<span class="text-gray-300">
<i class="fas fa-bolt text-yellow-400 mr-2"></i>
Total Energy from Magrav:
</span>
<span class="font-semibold text-green-400" id="totalEnergy">0.000 kWh</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-300">
<i class="fas fa-dollar-sign text-green-400 mr-2"></i>
Theoretical Cost Savings:
</span>
<span class="font-semibold text-green-400" id="costSavings">$0.00</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-300">
<i class="fas fa-tachometer-alt text-blue-400 mr-2"></i>
System Efficiency:
</span>
<span class="font-semibold text-blue-400" id="systemEfficiency">0%</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-300">
<i class="fas fa-plug text-orange-400 mr-2"></i>
Grid Dependence:
</span>
<span class="font-semibold text-orange-400" id="gridDependence">0%</span>
</div>
</div>
<div class="p-4 bg-yellow-900 rounded-lg border border-yellow-700">
<h4 class="font-semibold text-yellow-300 mb-2 flex items-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Experimental Notice
</h4>
<p class="text-sm text-yellow-200">
This system is for research purposes only. Real-world performance may vary significantly from simulated results.
Always follow proper electrical safety procedures when working with experimental power systems.
</p>
</div>
</div>
</div>
</div>
<script>
// System Configuration
const CONFIG = {
MAGRAV_MAX_OUTPUT: 2000, // 2kW claimed max
BATTERY_NOMINAL_VOLTAGE: 48.0,
BATTERY_CAPACITY: 10000, // 10kWh
DC_VOLTAGE_TARGET: 12.0,
DC_VOLTAGE_TOLERANCE: 0.6, // ±5%
MINER_POWER_RATING: 500, // 500W GPU rig
GRID_RATE: 0.12, // $0.12/kWh
SAFETY_THRESHOLDS: {
OVERVOLTAGE: 12.6,
UNDERVOLTAGE: 11.4,
OVERTEMPERATURE: 75
}
};
// System State
let systemState = {
systemEnabled: false,
emergencyStop: false,
miningEnabled: false,
magravOutput: 0,
batteryVoltage: 44.0,
batteryCapacity: 20,
dcVoltage: 0,
minerPower: 0,
gridPower: 0
};
// Performance Data
let performanceData = [];
let alerts = [];
let totalEnergy = 0;
let costSavings = 0;
let updateInterval;
let alertId = 0;
// DOM Elements
const systemStatusEl = document.getElementById('systemStatus');
const systemToggleBtn = document.getElementById('systemToggle');
const miningToggleBtn = document.getElementById('miningToggle');
const emergencyStopBtn = document.getElementById('emergencyStop');
const resetSystemBtn = document.getElementById('resetSystem');
const alertsContainer = document.getElementById('alertsContainer');
// Gauge Charts
const magravGauge = createGauge('magravGauge', 'Magrav Output', 'W', 0, CONFIG.MAGRAV_MAX_OUTPUT, 'red');
const batteryGauge = createGauge('batteryGauge', 'Battery', '%', 0, 100, 'green');
const voltageGauge = createGauge('voltageGauge', 'DC Voltage', 'V', 10, 14, 'blue');
const minerGauge = createGauge('minerGauge', 'Miner Power', 'W', 0, CONFIG.MINER_POWER_RATING, 'orange');
// Line Charts
const powerFlowChart = createLineChart('powerFlowChart', ['Magrav Output', 'Miner Power', 'Grid Power'], ['#EF4444', '#F97316', '#3B82F6']);
const healthChart = createLineChart('healthChart', ['Battery %', 'DC Voltage'], ['#10B981', '#8B5CF6']);
// Initialize system
updateUI();
addAlert('info', 'System initialized and ready');
// Event Listeners
systemToggleBtn.addEventListener('click', toggleSystem);
miningToggleBtn.addEventListener('click', toggleMining);
emergencyStopBtn.addEventListener('click', emergencyStop);
resetSystemBtn.addEventListener('click', resetSystem);
// System Functions
function toggleSystem() {
if (systemState.emergencyStop) return;
systemState.systemEnabled = !systemState.systemEnabled;
systemState.miningEnabled = false;
if (systemState.systemEnabled) {
startSystem();
addAlert('info', 'System powered ON');
} else {
stopSystem();
addAlert('info', 'System powered OFF');
}
updateUI();
}
function toggleMining() {
if (systemState.dcVoltage < CONFIG.SAFETY_THRESHOLDS.UNDERVOLTAGE) {
addAlert('error', 'Cannot enable mining - DC voltage too low');
return;
}
systemState.miningEnabled = !systemState.miningEnabled;
if (systemState.miningEnabled) {
addAlert('info', 'Mining enabled');
} else {
addAlert('info', 'Mining disabled');
}
updateUI();
}
function emergencyStop() {
systemState.emergencyStop = true;
systemState.systemEnabled = false;
systemState.miningEnabled = false;
clearInterval(updateInterval);
addAlert('error', 'EMERGENCY STOP ACTIVATED');
updateUI();
}
function resetSystem() {
systemState.emergencyStop = false;
addAlert('info', 'System reset completed');
updateUI();
}
function startSystem() {
// Initialize performance data
performanceData = [];
// Start update loop
updateInterval = setInterval(updateSystem, 1000);
}
function stopSystem() {
clearInterval(updateInterval);
}
function updateSystem() {
if (systemState.emergencyStop) return;
// Simulate Magrav output
systemState.magravOutput = simulateMagravOutput();
// Calculate mining power
systemState.minerPower = calculateMinerPower();
// Update battery state
const batteryState = updateBatteryState(systemState.magravOutput, systemState.minerPower);
systemState.batteryCapacity = batteryState.capacity;
systemState.batteryVoltage = batteryState.voltage;
// Calculate DC output
systemState.dcVoltage = calculateDCOutput(systemState.batteryVoltage, systemState.minerPower);
// Calculate grid power
systemState.gridPower = Math.max(0, systemState.minerPower - systemState.magravOutput);
// Update totals
totalEnergy += systemState.magravOutput / 3600000; // Convert to kWh
costSavings += (systemState.magravOutput * CONFIG.GRID_RATE) / 3600000;
// Add data point
const dataPoint = {
timestamp: new Date().toLocaleTimeString(),
magravOutput: systemState.magravOutput,
minerPower: systemState.minerPower,
batteryCapacity: systemState.batteryCapacity,
dcVoltage: systemState.dcVoltage,
gridPower: systemState.gridPower
};
performanceData.push(dataPoint);
if (performanceData.length > 15) {
performanceData.shift();
}
// Check safety conditions
checkSafetyConditions();
// Update UI
updateUI();
}
function simulateMagravOutput() {
if (!systemState.systemEnabled) return 0;
// Simulate erratic/experimental behavior
const baseOutput = CONFIG.MAGRAV_MAX_OUTPUT * 0.3; // 30% of claimed
const variation = Math.sin(Date.now() / 10000) * 200;
const noise = (Math.random() - 0.5) * 300;
return Math.max(0, baseOutput + variation + noise);
}
function updateBatteryState(magravInput, minerLoad) {
const currentCapacity = systemState.batteryCapacity;
const chargeRate = magravInput / CONFIG.BATTERY_CAPACITY * 100;
const dischargeRate = minerLoad / CONFIG.BATTERY_CAPACITY * 100;
const netChange = chargeRate - dischargeRate;
const newCapacity = Math.max(0, Math.min(100, currentCapacity + netChange * 0.1));
const voltage = 44.0 + (newCapacity / 100) * 8.0; // 44V to 52V range
return { capacity: newCapacity, voltage };
}
function calculateDCOutput(batteryVoltage, load) {
if (batteryVoltage < 44.0) return 0; // Undervoltage cutoff
const efficiency = 0.95; // 95% efficiency
const regulation = CONFIG.DC_VOLTAGE_TARGET;
const loadEffect = load > 400 ? -0.1 : 0; // Voltage drop under heavy load
return regulation + loadEffect;
}
function calculateMinerPower() {
if (!systemState.miningEnabled || systemState.dcVoltage < CONFIG.SAFETY_THRESHOLDS.UNDERVOLTAGE) {
return 0;
}
const basePower = CONFIG.MINER_POWER_RATING;
const voltageEffect = (systemState.dcVoltage - 12.0) / 12.0 * 50;
return basePower + voltageEffect;
}
function checkSafetyConditions() {
const { dcVoltage, batteryVoltage } = systemState;
if (dcVoltage > CONFIG.SAFETY_THRESHOLDS.OVERVOLTAGE) {
addAlert('error', 'DC Overvoltage detected! System shutdown initiated.');
systemState.emergencyStop = true;
systemState.miningEnabled = false;
systemState.systemEnabled = false;
stopSystem();
return false;
}
if (dcVoltage < CONFIG.SAFETY_THRESHOLDS.UNDERVOLTAGE && systemState.miningEnabled) {
addAlert('warning', 'DC Undervoltage - Mining disabled for protection.');
systemState.miningEnabled = false;
}
if (batteryVoltage < 44.0) {
addAlert('warning', 'Battery critically low - System protection activated.');
systemState.miningEnabled = false;
}
return true;
}
function addAlert(type, message) {
const alert = {
id: alertId++,
type,
message,
timestamp: new Date().toLocaleTimeString()
};
alerts.unshift(alert);
if (alerts.length > 10) {
alerts.pop();
}
// Create alert element
const alertEl = document.createElement('div');
alertEl.className = `p-3 rounded-lg border-l-4 mb-2 ${
type === 'error' ? 'bg-red-900 border-red-500' :
type === 'warning' ? 'bg-yellow-900 border-yellow-500' :
'bg-blue-900 border-blue-500'
}`;
alertEl.innerHTML = `
<div class="flex justify-between items-start">
<span class="text-sm">${message}</span>
<span class="text-xs text-gray-400">${alert.timestamp}</span>
</div>
`;
alertsContainer.insertBefore(alertEl, alertsContainer.firstChild);
// Flash alert
if (type === 'error') {
alertEl.classList.add('alert-flash');
}
}
function updateUI() {
// Update status display
if (systemState.emergencyStop) {
systemStatusEl.innerHTML = `
<span class="w-3 h-3 rounded-full bg-red-500 mr-2 animate-pulse"></span>
<span>EMERGENCY STOP</span>
`;
systemStatusEl.classList.add('emergency-active');
} else if (systemState.systemEnabled) {
systemStatusEl.innerHTML = `
<span class="w-3 h-3 rounded-full bg-green-500 mr-2"></span>
<span>System Online</span>
`;
systemStatusEl.classList.remove('emergency-active');
} else {
systemStatusEl.innerHTML = `
<span class="w-3 h-3 rounded-full bg-red-500 mr-2"></span>
<span>System Offline</span>
`;
systemStatusEl.classList.remove('emergency-active');
}
// Update control buttons
systemToggleBtn.innerHTML = `
<i class="fas fa-power-off mr-2"></i>
${systemState.systemEnabled ? 'Power OFF' : 'Power ON'}
`;
systemToggleBtn.className = systemState.systemEnabled ?
'px-6 py-3 rounded-lg font-semibold bg-green-600 hover:bg-green-700 text-white transition-colors flex items-center justify-center' :
'px-6 py-3 rounded-lg font-semibold bg-gray-700 hover:bg-gray-600 text-white transition-colors flex items-center justify-center';
miningToggleBtn.disabled = !systemState.systemEnabled || systemState.emergencyStop;
miningToggleBtn.innerHTML = `
<i class="fas fa-digging mr-2"></i>
${systemState.miningEnabled ? 'Mining OFF' : 'Mining ON'}
`;
miningToggleBtn.className = systemState.miningEnabled ?
'px-6 py-3 rounded-lg font-semibold bg-orange-600 hover:bg-orange-700 text-white transition-colors flex items-center justify-center' :
'px-6 py-3 rounded-lg font-semibold bg-gray-700 hover:bg-gray-600 text-white transition-colors flex items-center justify-center';
if (miningToggleBtn.disabled) {
miningToggleBtn.className = 'px-6 py-3 rounded-lg font-semibold bg-gray-700 text-gray-400 transition-colors flex items-center justify-center cursor-not-allowed';
}
resetSystemBtn.disabled = !systemState.emergencyStop;
if (resetSystemBtn.disabled) {
resetSystemBtn.className = 'px-6 py-3 rounded-lg font-semibold bg-blue-600 text-blue-200 transition-colors flex items-center justify-center cursor-not-allowed';
} else {
resetSystemBtn.className = 'px-6 py-3 rounded-lg font-semibold bg-blue-600 hover:bg-blue-700 text-white transition-colors flex items-center justify-center';
}
// Update numeric displays
document.getElementById('magravOutput').textContent = systemState.magravOutput.toFixed(1);
document.getElementById('batteryCapacity').textContent = systemState.batteryCapacity.toFixed(1);
document.getElementById('batteryVoltage').textContent = systemState.batteryVoltage.toFixed(1) + 'V';
document.getElementById('dcVoltage').textContent = systemState.dcVoltage.toFixed(2);
document.getElementById('minerPower').textContent = systemState.minerPower.toFixed(1);
document.getElementById('gridPower').textContent = `Grid: ${systemState.gridPower.toFixed(1)}W`;
// Update statistics
document.getElementById('totalEnergy').textContent = totalEnergy.toFixed(3) + ' kWh';
document.getElementById('costSavings').textContent = '$' + costSavings.toFixed(2);
const efficiency = systemState.magravOutput > 0 ?
((systemState.minerPower / systemState.magravOutput) * 100).toFixed(1) : 0;
document.getElementById('systemEfficiency').textContent = efficiency + '%';
const gridDependence = systemState.minerPower > 0 ?
((systemState.gridPower / systemState.minerPower) * 100).toFixed(1) : 0;
document.getElementById('gridDependence').textContent = gridDependence + '%';
// Update gauges
updateGauge(magravGauge, systemState.magravOutput);
updateGauge(batteryGauge, systemState.batteryCapacity);
updateGauge(voltageGauge, systemState.dcVoltage);
updateGauge(minerGauge, systemState.minerPower);
// Update line charts
updateLineChart(powerFlowChart, performanceData, ['magravOutput', 'minerPower', 'gridPower']);
updateLineChart(healthChart, performanceData, ['batteryCapacity', 'dcVoltage']);
}
// Chart Functions
function createGauge(canvasId, label, unit, min, max, color) {
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
return {
ctx,
label,
unit,
min,
max,
color,
value: 0
};
}
function updateGauge(gauge, value) {
const { ctx, label, unit, min, max, color } = gauge;
const width = ctx.canvas.width;
const height = ctx.canvas.height;
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Draw gauge background
ctx.beginPath();
ctx.arc(width / 2, height / 2, Math.min(width, height) / 2 - 10, 0.75 * Math.PI, 2.25 * Math.PI);
ctx.lineWidth = 20;
ctx.strokeStyle = '#374151';
ctx.stroke();
// Calculate angle for value
const normalizedValue = Math.min(Math.max(value, min), max);
const angle = 0.75 * Math.PI + (1.5 * Math.PI * (normalizedValue - min) / (max - min));
// Draw gauge value
ctx.beginPath();
ctx.arc(width / 2, height / 2, Math.min(width, height) / 2 - 10, 0.75 * Math.PI, angle);
ctx.lineWidth = 20;
ctx.strokeStyle = color;
ctx.stroke();
// Draw gauge center
ctx.fillStyle = '#1F2937';
ctx.beginPath();
ctx.arc(width / 2, height / 2, Math.min(width, height) / 2 - 30, 0, 2 * Math.PI);
ctx.fill();
// Draw value text
ctx.fillStyle = '#F3F4F6';
ctx.font = 'bold ' + (Math.min(width, height) / 5) + 'px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(normalizedValue.toFixed(1), width / 2, height / 2);
// Draw unit text
ctx.fillStyle = '#9CA3AF';
ctx.font = (Math.min(width, height) / 8) + 'px Arial';
ctx.fillText(unit, width / 2, height / 2 + (Math.min(width, height) / 6));
}
function createLineChart(canvasId, datasets, colors) {
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
return new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: datasets.map((label, i) => ({
label,
data: [],
borderColor: colors[i],
backgroundColor: colors[i] + '20',
borderWidth: 2,
tension: 0.3,
fill: true
}))
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
grid: {
color: '#374151'
},
ticks: {
color: '#9CA3AF'
}
},
y: {
grid: {
color: '#374151'
},
ticks: {
color: '#9CA3AF'
}
}
},
plugins: {
legend: {
labels: {
color: '#F3F4F6'
}
}
},
interaction: {
intersect: false,
mode: 'index'
}
}
});
}
function updateLineChart(chart, data, fields) {
chart.data.labels = data.map(item => item.timestamp);
fields.forEach((field, i) => {
chart.data.datasets[i].data = data.map(item => item[field]);
});
chart.update();
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Gaslighttheghost/bitmin" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>