feat: redesign StatusTab UI with bento-grid layout and add CSV metadata editing capabilities
This commit is contained in:
@@ -24,11 +24,20 @@ Item {
|
||||
|
||||
function waferTypeForFile(path) {
|
||||
if (!path) return ""
|
||||
// A file registered as a master carries that slot's family — this is
|
||||
// the only way a live recording gets a family (its filename/metadata
|
||||
// don't encode one reliably).
|
||||
for (var fam in settingsModel.masters)
|
||||
if (settingsModel.masters[fam] === path) return fam.toUpperCase()
|
||||
var rows = file_browser.files
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
if (rows[i].fileName === path) return (rows[i].waferType || "").toUpperCase()
|
||||
if (rows[i].fileName === path) {
|
||||
if (rows[i].isRecording) return (rows[i].masterType || "").toUpperCase()
|
||||
return (rows[i].waferType || "").toUpperCase()
|
||||
}
|
||||
}
|
||||
var base = path.split("/").pop()
|
||||
if (base.toLowerCase().indexOf("live_") === 0) return ""
|
||||
return base ? base.charAt(0).toUpperCase() : ""
|
||||
}
|
||||
|
||||
@@ -37,6 +46,19 @@ Item {
|
||||
// simply won't exist under this key).
|
||||
readonly property string runBWaferType: root.waferTypeForFile(root.compareFileB)
|
||||
readonly property string masterFileForRunB: root.runBWaferType !== "" ? (settingsModel.masters[root.runBWaferType] || "") : ""
|
||||
readonly property string runAWaferType: root.useMasterFile ? root.runBWaferType : root.waferTypeForFile(root.compareFileA)
|
||||
// Family gate: both runs must resolve to the same wafer family. An empty
|
||||
// family means an unassigned live recording — comparable only after it is
|
||||
// registered as a master file (Settings → Master Files).
|
||||
readonly property string familyGateError: {
|
||||
var fileA = root.useMasterFile ? root.masterFileForRunB : root.compareFileA
|
||||
if (fileA === "" || root.compareFileB === "") return ""
|
||||
if (root.runAWaferType === "" || root.runBWaferType === "")
|
||||
return "Recording has no wafer family — register it as a master file (Settings → Master Files)"
|
||||
if (root.runAWaferType !== root.runBWaferType)
|
||||
return "Wafer family mismatch: " + root.runAWaferType + " vs " + root.runBWaferType
|
||||
return ""
|
||||
}
|
||||
property real warpingDistance: -1
|
||||
property int frameOffset: 0
|
||||
property real frameOffsetSeconds: 0
|
||||
@@ -609,7 +631,15 @@ Item {
|
||||
readonly property real padTop: 24
|
||||
readonly property real padBottom: 36
|
||||
|
||||
function drawGrid(ctx, minV, maxV, dataLen) {
|
||||
// Nice tick step (1/2/5 × 10^k) — same scheme as TrendChartItem,
|
||||
// so labels land on round numbers instead of raw data min/max.
|
||||
function niceStep(rawStep) {
|
||||
var mag = Math.pow(10, Math.floor(Math.log10(rawStep)))
|
||||
return [1, 2, 5, 10].map(function (s) { return s * mag })
|
||||
.find(function (s) { return s >= rawStep })
|
||||
}
|
||||
|
||||
function drawGrid(ctx, minV, maxV, yStep, dataLen) {
|
||||
var plotW = width - padLeft - padRight
|
||||
var plotH = height - padTop - padBottom
|
||||
var range = (maxV - minV) || 1
|
||||
@@ -620,7 +650,8 @@ Item {
|
||||
ctx.font = "10px " + Theme.uiFontFamily
|
||||
ctx.textAlign = "right"
|
||||
|
||||
var ySteps = 5
|
||||
var ySteps = Math.max(1, Math.round(range / yStep))
|
||||
var yDec = Math.max(0, -Math.floor(Math.log10(yStep)))
|
||||
for (var yi = 0; yi <= ySteps; yi++) {
|
||||
var yFrac = yi / ySteps
|
||||
var yPx = padTop + plotH * yFrac
|
||||
@@ -631,16 +662,17 @@ Item {
|
||||
ctx.lineTo(padLeft + plotW, yPx)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.fillText(yVal.toFixed(1), padLeft - 6, yPx + 3)
|
||||
ctx.fillText(yVal.toFixed(yDec), padLeft - 6, yPx + 3)
|
||||
}
|
||||
|
||||
ctx.textAlign = "center"
|
||||
var xSteps = Math.min(5, dataLen - 1)
|
||||
for (var xi = 0; xi <= xSteps; xi++) {
|
||||
var xFrac = xi / xSteps
|
||||
var xPx = padLeft + plotW * xFrac
|
||||
var xIdx = Math.round(xFrac * (dataLen - 1))
|
||||
ctx.fillText(xIdx.toString(), xPx, height - 20)
|
||||
var xMax = dataLen - 1
|
||||
if (xMax > 0) {
|
||||
var xStep = niceStep(xMax / 5 || 1)
|
||||
for (var xIdx = 0; xIdx <= xMax; xIdx += xStep) {
|
||||
var xPx = padLeft + (xIdx / xMax) * plotW
|
||||
ctx.fillText(xIdx.toString(), xPx, height - 20)
|
||||
}
|
||||
}
|
||||
|
||||
ctx.save()
|
||||
@@ -700,9 +732,13 @@ Item {
|
||||
var padding = (maxV - minV) * 0.05
|
||||
minV -= padding
|
||||
maxV += padding
|
||||
// Snap bounds to nice-step multiples -> stable round-number axis
|
||||
var yStep = niceStep((maxV - minV) / 5 || 1)
|
||||
minV = Math.floor(minV / yStep) * yStep
|
||||
maxV = Math.ceil(maxV / yStep) * yStep
|
||||
var range = (maxV - minV) || 1
|
||||
|
||||
drawGrid(ctx, minV, maxV, root.seriesLen)
|
||||
drawGrid(ctx, minV, maxV, yStep, root.seriesLen)
|
||||
drawSeries(ctx, root.trendDataA, minV, range, Theme.primaryAccent, root.seriesLen)
|
||||
drawSeries(ctx, root.trendDataB, minV, range, Theme.themeSkill, root.seriesLen)
|
||||
drawScrubMarker(ctx)
|
||||
|
||||
Reference in New Issue
Block a user