diff --git a/frontend/components/analysis/analysis-view.tsx b/frontend/components/analysis/analysis-view.tsx
index a502141..f0325f6 100644
--- a/frontend/components/analysis/analysis-view.tsx
+++ b/frontend/components/analysis/analysis-view.tsx
@@ -8,7 +8,6 @@ import { Area, AreaChart } from "@/components/charts/area-chart";
import { Bar } from "@/components/charts/bar";
import { BarChart } from "@/components/charts/bar-chart";
import { BarXAxis } from "@/components/charts/bar-x-axis";
-import { BarYAxis } from "@/components/charts/bar-y-axis";
import { Grid } from "@/components/charts/grid";
import { ChartTooltip } from "@/components/charts/tooltip";
import { XAxis } from "@/components/charts/x-axis";
@@ -196,7 +195,8 @@ export function AnalysisView() {
-
+ {/* One tick per month so every point is labelled. */}
+
@@ -207,8 +207,9 @@ export function AnalysisView() {
+ {/* Vertical bars: weekdays live on the x-axis only. (A BarYAxis
+ here printed the categories down the left, overflowing the card.) */}
-
diff --git a/frontend/components/analysis/live-hospital-chart.tsx b/frontend/components/analysis/live-hospital-chart.tsx
index fc6ca9d..804d99c 100644
--- a/frontend/components/analysis/live-hospital-chart.tsx
+++ b/frontend/components/analysis/live-hospital-chart.tsx
@@ -1,6 +1,8 @@
"use client";
+import { Pause, Play } from "lucide-react";
import { useEffect, useRef, useState } from "react";
+import { useTranslation } from "react-i18next";
import {
LiveLineChart,
@@ -9,24 +11,34 @@ import {
import { LiveLine } from "@/components/charts/live-line";
import { LiveYAxis } from "@/components/charts/live-y-axis";
import { ChartTooltip } from "@/components/charts/tooltip";
+import { Button } from "@/components/ui/button";
// temetro has no real-time telemetry feed yet, so the "Live" panel simulates a
// hospital signal (patients currently in the building) as a bounded random walk
// that updates once a second. Swap `tick()` for a WebSocket/poll when a real
// feed exists — the chart contract (append { time, value }) stays the same.
+//
+// The simulation (a 1s interval + an rAF animation loop) only runs while the
+// clinician has explicitly toggled it on, so the Analysis page stays idle by
+// default instead of animating in the background.
const BASELINE = 48;
const MIN = 24;
const MAX = 90;
const WINDOW_SECONDS = 30;
export function LiveHospitalChart() {
+ const { t } = useTranslation();
+ const [live, setLive] = useState(false);
const [data, setData] = useState([]);
const [value, setValue] = useState(BASELINE);
const valueRef = useRef(BASELINE);
useEffect(() => {
- // Seed a short history so the line is drawn immediately on mount.
+ if (!live) return;
+ // Seed a short history so the line is drawn immediately on start.
const now = Date.now() / 1000;
+ valueRef.current = BASELINE;
+ setValue(BASELINE);
setData(
Array.from({ length: WINDOW_SECONDS }, (_, i) => ({
time: now - (WINDOW_SECONDS - i),
@@ -45,23 +57,60 @@ export function LiveHospitalChart() {
]);
}, 1000);
return () => clearInterval(id);
- }, []);
+ }, [live]);
return (
-
);
}
diff --git a/frontend/lib/i18n/locales/en/translation.json b/frontend/lib/i18n/locales/en/translation.json
index 9938031..e2b748d 100644
--- a/frontend/lib/i18n/locales/en/translation.json
+++ b/frontend/lib/i18n/locales/en/translation.json
@@ -556,7 +556,10 @@
"live": {
"title": "Live",
"subtitle": "Patients currently in the building, updating in real time.",
- "label": "In the building now"
+ "label": "In the building now",
+ "start": "Go live",
+ "pause": "Pause",
+ "idle": "Live stream paused — press Go live to start."
},
"patientVolume": {
"title": "Patient volume",