import QtQuick import QtQuick.Controls import QtQuick.Layouts import ISC import ISC.Wafer // ===== Run Chart ===== // Zoomable whole-run multi-sensor chart (C# parity: PopupChartForm.cs). // Lives in the Graph tab. Mouse wheel zooms around the cursor, drag pans; // the strip below shows the aggregate min/max/avg over the *visible* range // (not the whole run), matching PopupChartForm's recalc_stats. Cursor/ // playhead tracking is out of scope — see specs/plans/2026-07-10-popup-chart.md // and docs/adr/0004-graphquickitem-viewport-for-replay-chart.md. Item { id: root property alias sensorNames: chart.sensorNames property alias seriesData: chart.seriesData property alias title: chart.title ColumnLayout { anchors.fill: parent spacing: 8 Item { Layout.fillWidth: true Layout.fillHeight: true GraphQuickItem { id: chart anchors.fill: parent showMinMaxMarkers: true xLabel: "Measurement Interval" yLabel: "Temperature (°C)" } MouseArea { id: interaction anchors.fill: parent acceptedButtons: Qt.LeftButton property real lastX: 0 onWheel: function(wheel) { var frac = Math.max(0, Math.min(1, wheel.x / width)); var factor = wheel.angleDelta.y > 0 ? 0.8 : 1.25; chart.zoomAtFraction(frac, factor); wheel.accepted = true; } onPressed: function(mouse) { lastX = mouse.x; } onPositionChanged: function(mouse) { if (pressed && width > 0) { chart.panByFraction(-(mouse.x - lastX) / width); lastX = mouse.x; } } } } // ── Min/Max/Avg readout strip + Reset Zoom ───────────────────── RowLayout { Layout.fillWidth: true spacing: 16 Label { text: "Min:" color: Theme.sensorLow font.family: Theme.uiFontFamily font.pixelSize: Theme.fontSm font.weight: Font.Medium } Label { text: chart.viewMin.toFixed(2) + (chart.viewMinSensor ? " (" + chart.viewMinSensor + ")" : "") color: Theme.headingColor font.family: Theme.codeFontFamily font.pixelSize: Theme.fontSm } Label { text: "Max:" color: Theme.sensorHigh font.family: Theme.uiFontFamily font.pixelSize: Theme.fontSm font.weight: Font.Medium } Label { text: chart.viewMax.toFixed(2) + (chart.viewMaxSensor ? " (" + chart.viewMaxSensor + ")" : "") color: Theme.headingColor font.family: Theme.codeFontFamily font.pixelSize: Theme.fontSm } Label { text: "Avg:" color: Theme.sideMutedText font.family: Theme.uiFontFamily font.pixelSize: Theme.fontSm font.weight: Font.Medium } Label { text: chart.viewAvg.toFixed(2) color: Theme.headingColor font.family: Theme.codeFontFamily font.pixelSize: Theme.fontSm } Item { Layout.fillWidth: true } Button { id: resetZoomBtn implicitHeight: 32 hoverEnabled: true text: "Reset Zoom" font.family: Theme.uiFontFamily font.pixelSize: Theme.fontSm font.weight: Font.Medium background: Rectangle { radius: Theme.radiusSm color: resetZoomBtn.pressed ? Theme.transportButtonHover : Theme.transportButtonBg border.color: Theme.sideBorder border.width: 1 } contentItem: Text { text: resetZoomBtn.text color: Theme.headingColor font: resetZoomBtn.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } onClicked: chart.resetZoom() } } } }