Make the live graph scale with the window

Three things pinned it small. The container was a fixed h-64, so the graph stayed
256px tall on any display; the page was capped at max-w-7xl, so a large window only
added empty margins; and the graph shared a two-column row, so it never got more than
half the available width.

The container is now h-[clamp(18rem,45vh,52rem)], the page cap is 2600px, and the
graph panel spans its row. Measured: 525x360 to 1142x360 at 1280x800, and 988x648 to
2468x648 at 3440x1440.

Chart.js needed help despite being configured responsive with maintainAspectRatio
false. It had latched onto a stale size -- the canvas sat at width:0px, height:288px
while its container had grown to 988x648. A ResizeObserver on the container fixed
growth but not shrinking, because passing explicit dimensions to resize() left the
canvas 988px wide inside a 435px container, overflowing it. Calling resize() with no
arguments lets Chart.js measure the container itself, and the canvas is absolutely
positioned within the relative container so it cannot force it wider.

Verified from 1100x700 to 3440x1440: the canvas matches its container exactly at every
size, growing and shrinking, with no horizontal page overflow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
drjones
2026-09-07 14:52:23 -07:00
parent 4a38cd68b3
commit 2b00ab4e12
2 changed files with 45 additions and 6 deletions

View File

@@ -1101,3 +1101,37 @@ document.addEventListener('DOMContentLoaded', () => {
fetchEngineConfig();
setInterval(fetchEngineConfig, 120000);
});
// ---------------------------------------------------------------- chart sizing
// Chart.js is configured responsive with maintainAspectRatio:false, so it should track
// its container on its own. In practice it latched onto a stale size -- the canvas sat
// at width:0px, height:288px (the old fixed h-64) while its container had grown to
// 988x648 on a large window. An explicit observer makes the chart follow the container
// whatever the window does.
function watchChartSize() {
const canvas = document.getElementById('oc-chart');
if (!canvas || !canvas.parentElement) return;
const container = canvas.parentElement;
const resize = () => {
if (typeof ocChart === 'undefined' || !ocChart) return;
// No explicit dimensions: with responsive + maintainAspectRatio:false, Chart.js
// measures the container itself. Passing width/height instead made the canvas grow
// but never shrink -- it ended up 988px wide inside a 435px container, overflowing
// it, which is also why the canvas is absolutely positioned now.
ocChart.resize();
};
if (typeof ResizeObserver !== 'undefined') {
new ResizeObserver(resize).observe(container);
}
window.addEventListener('resize', resize);
// Run once after layout settles, in case the chart was built before the container had
// a width (which is how it ended up at 0 in the first place).
requestAnimationFrame(resize);
setTimeout(resize, 300);
}
document.addEventListener('DOMContentLoaded', () => setTimeout(watchChartSize, 200));

View File

@@ -5,6 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HYPERSWAP // Dual-Engine Model Orchestrator & Live Telemetry</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
// The CDN build has no breakpoint above 2xl, so a very wide window kept a
// two-column layout with increasingly stretched panels.
tailwind.config = { theme: { extend: { screens: { '3xl': '2000px' } } } };
</script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<link rel="stylesheet" href="/static/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
@@ -13,7 +18,7 @@
<!-- TOP HEADER -->
<header class="border-b border-slate-800 bg-slate-900/80 backdrop-blur sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3 flex flex-wrap items-center justify-between gap-4">
<div class="max-w-[2600px] mx-auto px-4 sm:px-6 lg:px-8 py-3 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-cyan-500 via-indigo-500 to-purple-500 flex items-center justify-center shadow-lg shadow-cyan-500/20">
<i class="fa-solid fa-bolt-lightning text-white text-lg"></i>
@@ -60,7 +65,7 @@
</header>
<!-- MAIN CONTAINER -->
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
<main class="max-w-[2600px] mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
<!-- HERO MEMORY GAUGES -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
@@ -431,7 +436,7 @@
</div>
<!-- OVERCLOCK CONTROL PANEL -->
<div class="bg-slate-900/80 border border-fuchsia-900/50 rounded-2xl p-5 space-y-4 shadow-lg shadow-fuchsia-950/30">
<div class="lg:col-span-2 bg-slate-900/80 border border-fuchsia-900/50 rounded-2xl p-5 space-y-4 shadow-lg shadow-fuchsia-950/30">
<div class="flex flex-wrap items-center justify-between gap-3 pb-3 border-b border-slate-800">
<div class="flex items-center space-x-2">
<div class="p-2 rounded-lg bg-fuchsia-950/80 border border-fuchsia-800 text-fuchsia-400">
@@ -599,8 +604,8 @@
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-fuchsia-400 inline-block"></span>RAM Cache GB</span>
</div>
</div>
<div class="relative h-64">
<canvas id="oc-chart"></canvas>
<div class="relative h-[clamp(18rem,45vh,52rem)]">
<canvas id="oc-chart" class="absolute inset-0 !w-full !h-full"></canvas>
</div>
</div>
@@ -672,7 +677,7 @@
</div>
<!-- ============ NEXT-LEVEL PANELS: governor / residency / analytics / autotune ============ -->
<div class="grid grid-cols-1 xl:grid-cols-2 gap-5 mt-5">
<div class="grid grid-cols-1 xl:grid-cols-2 3xl:grid-cols-3 gap-5 mt-5">
<!-- System health: makes a silently-broken dependency loud -->