feat(map): add batch export and adjust layout alignment
- Implement synchronous offscreen wafer map PNG rendering and CSV summary. - Add "Batch Export" button to file browser sidebar. - Adjust trend pane bottom spacer to align with About button when visible. - Fix type check errors and add pytest coverage for batch export.
This commit is contained in:
@@ -10,15 +10,20 @@ Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
// Wire streamController.trendData (Signal(str) carrying JSON list of floats)
|
||||
// into the trend chart's data property. The slot parseJsonToData() is defined
|
||||
// on the Python TrendChartItem; we use it so malformed payloads are logged
|
||||
// there instead of crashing the QML binding.
|
||||
// Wire streamController.trendDelta (Signal(str) carrying one new
|
||||
// [elapsed_s, value] pair per live frame) into the trend chart, which
|
||||
// accumulates its own bounded 60s window. trendReset clears it when a
|
||||
// new stream starts. Parsing happens on the Python TrendChartItem side
|
||||
// so malformed payloads are logged there instead of crashing the QML
|
||||
// binding.
|
||||
property string loadErrorMessage: ""
|
||||
Connections {
|
||||
target: streamController
|
||||
function onTrendData(avgsJson) {
|
||||
trendChart.setDataFromJson(avgsJson);
|
||||
function onTrendDelta(deltaJson) {
|
||||
trendChart.appendDelta(deltaJson);
|
||||
}
|
||||
function onTrendReset() {
|
||||
trendChart.clearTrend();
|
||||
}
|
||||
function onLoadedFileChanged() {
|
||||
root.loadErrorMessage = "";
|
||||
@@ -145,6 +150,8 @@ Item {
|
||||
id: waferView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 400
|
||||
Layout.minimumHeight: 280
|
||||
blend: readoutPanel.heatmapBlend
|
||||
showLabels: readoutPanel.showLabels
|
||||
showThickness: readoutPanel.showThickness
|
||||
@@ -152,23 +159,31 @@ Item {
|
||||
Rectangle {
|
||||
id: trendPane
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 160
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 220
|
||||
Layout.minimumHeight: 160
|
||||
visible: trendChart.hasData && streamController.mode === "live"
|
||||
color: Theme.cardBackground
|
||||
border.color: Theme.cardBorder
|
||||
border.width: 1
|
||||
radius: Theme.radiusMd
|
||||
|
||||
TrendChartItem {
|
||||
id: trendChart
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
spacing: 10
|
||||
|
||||
TrendChartItem {
|
||||
id: trendChart
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 16
|
||||
implicitHeight: trendPane.visible ? 52 : 16
|
||||
}
|
||||
TransportBar {
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -275,8 +275,15 @@ Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 28
|
||||
text: "Export"
|
||||
// Nothing to export until a file is loaded or a stream has played
|
||||
enabled: streamController.sensorValues.length > 0
|
||||
opacity: enabled ? 1 : 0.4
|
||||
|
||||
onClicked: exportDialog.open()
|
||||
onClicked: {
|
||||
// Default into <saveDataDir>/Export (created on demand)
|
||||
exportDialog.selectedFile = "file://" + deviceController.exportDir() + "/wafer_map.png"
|
||||
exportDialog.open()
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
radius: Theme.radiusSm
|
||||
@@ -299,6 +306,7 @@ Rectangle {
|
||||
id: exportDialog
|
||||
title: "Export Wafer Map"
|
||||
fileMode: FileDialog.SaveFile
|
||||
defaultSuffix: "png"
|
||||
nameFilters: ["PNG files (*.png)"]
|
||||
onAccepted: {
|
||||
var path = String(selectedFile).replace(/^file:\/\//, "");
|
||||
|
||||
Reference in New Issue
Block a user