Problem
Selecting a tree node shows each child sensor as its own separate tile/plot. To answer "which child was hottest over the last hour" — which process used the most CPU, which NIC moved the most data, which disk was busiest — the operator has to open each child sensor one by one and eyeball its chart. There is no node-level combined view.
(Dashboards already support multi-line panels, but you must add each sensor to a panel by hand. This is the zero-config, node-driven version.)
Proposal — v1 (this issue)
On a tree node, add a "Chart" tab that overlays every comparable child sensor's history as one multi-line time chart over the operator-chosen window (last hour / 3h / day / custom).
Scope for v1:
- Same-unit nodes only — all children share a sensor type + unit. Real examples on a live agent:
Top CPU processes (all %), Network per-interface throughput (all MB/s). Mixed-unit nodes (e.g. Disks monitoring: %, MB/s, GB) are out of scope here (see v3).
- Read-only, derived entirely from stored history — never writes or changes sensor state.
- One line per child. Children with no data in the window are omitted (not zero-filled). Sparse series are drawn with gaps, not interpolated — top-N folders (
Top CPU processes) report a process only while it is in the top-10 at ≥1%, so most lines are intermittent by design; a short UI note should explain this.
- No view when there are < 2 comparable children (fall back to the normal node panel) — e.g. a host with a single disk has nothing to overlay.
Implementation notes (verified anchors)
- Children of a node:
TreeViewModel.GetAllNodeSensors(Guid) (already wrapped by HomeController.GetNodeSensors) returns all descendant sensor ids.
- History read: same path
SensorHistoryController.ChartHistory uses (GetSensorHistoryRequest). Precedent for one request → many series is the Grafana datasource query (QueryHistoryRequest.Targets[]). Add a node-level batch endpoint (node id + window + optional unit-group) that fans out over GetAllNodeSensors and returns the full series set in one call.
- Client render: Plotly.js 2.28.0 is already bundled and used by
Views/Home/Sensor/History/_SensorGraphTabContent.cshtml — reuse it for the overlay.
- UI surface: new tab in the node panel —
HomeController.SelectNode → Views/Home/_NodeDataPanel.cshtml.
Out of scope (tracked separately, later)
- v2 — Ranking: fold the same series into a sorted "top consumers" leaderboard (total / average / peak) as a second tab on the same data.
- v3: mixed-unit nodes (one chart/group per unit), scope toggle (direct children vs flattened subtree), per-type aggregation strategies (rate/counter delta, enum/bool availability = % uptime / downtime / flaps).
Acceptance (v1)
- Select
Top CPU processes → Chart tab → last hour → one chart with a line per process.
- Select
Network → one line per interface (MB/s).
- Node with < 2 comparable children → no Chart tab.
- Selecting a period re-queries and redraws; children with no data in the window are absent, not zeroed.
Feature doc
aicontext/features/site/node-children-view/feature.md (companion docs PR) — full behavior, invariants, and the v1/v2/v3 progression.
Problem
Selecting a tree node shows each child sensor as its own separate tile/plot. To answer "which child was hottest over the last hour" — which process used the most CPU, which NIC moved the most data, which disk was busiest — the operator has to open each child sensor one by one and eyeball its chart. There is no node-level combined view.
(Dashboards already support multi-line panels, but you must add each sensor to a panel by hand. This is the zero-config, node-driven version.)
Proposal — v1 (this issue)
On a tree node, add a "Chart" tab that overlays every comparable child sensor's history as one multi-line time chart over the operator-chosen window (last hour / 3h / day / custom).
Scope for v1:
Top CPU processes(all%),Networkper-interface throughput (allMB/s). Mixed-unit nodes (e.g.Disks monitoring:%,MB/s,GB) are out of scope here (see v3).Top CPU processes) report a process only while it is in the top-10 at ≥1%, so most lines are intermittent by design; a short UI note should explain this.Implementation notes (verified anchors)
TreeViewModel.GetAllNodeSensors(Guid)(already wrapped byHomeController.GetNodeSensors) returns all descendant sensor ids.SensorHistoryController.ChartHistoryuses (GetSensorHistoryRequest). Precedent for one request → many series is the Grafana datasourcequery(QueryHistoryRequest.Targets[]). Add a node-level batch endpoint (node id + window + optional unit-group) that fans out overGetAllNodeSensorsand returns the full series set in one call.Views/Home/Sensor/History/_SensorGraphTabContent.cshtml— reuse it for the overlay.HomeController.SelectNode→Views/Home/_NodeDataPanel.cshtml.Out of scope (tracked separately, later)
Acceptance (v1)
Top CPU processes→ Chart tab → last hour → one chart with a line per process.Network→ one line per interface (MB/s).Feature doc
aicontext/features/site/node-children-view/feature.md(companion docs PR) — full behavior, invariants, and the v1/v2/v3 progression.