Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019A9CSrh9rfM5WwqKtg8BSE
This commit is contained in:
@@ -84,16 +84,18 @@ function csvExport() {
|
||||
const toleranceMinus = this.hasNumber(nominal) && this.hasNumber(subtask.ltl)
|
||||
? nominal - subtask.ltl : null;
|
||||
|
||||
// #118: quota non misurata (value null) -> NaN nel valore e nella deviazione; le tolleranze nulle restano vuote
|
||||
const notMeasured = m.value === null || m.value === undefined;
|
||||
const row = [
|
||||
m.id || '',
|
||||
m.subtask_id || '',
|
||||
this.escapeCsvValue(subtask.description || ''),
|
||||
this.formatNumber(m.value),
|
||||
notMeasured ? 'NaN' : this.formatNumber(m.value),
|
||||
this.escapeCsvValue(subtask.unit || 'mm'),
|
||||
this.formatNumber(nominal),
|
||||
this.formatNumber(tolerancePlus),
|
||||
this.formatNumber(toleranceMinus),
|
||||
this.formatNumber(m.deviation),
|
||||
notMeasured ? 'NaN' : this.formatNumber(m.deviation),
|
||||
m.pass_fail || '',
|
||||
this.escapeCsvValue(m.lot_number || ''),
|
||||
this.escapeCsvValue(m.serial_number || ''),
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
// la scrive e avvisa il componente visionRecipe con l'evento 'dxf-recipe-saved'.
|
||||
// Uso: x-data="dxfRecipeWizard(task.id, csrfFn, msgs)". Dipende da Alpine.js e station_calibration.js.
|
||||
function dxfRecipeWizard(taskId, csrf, msgs) {
|
||||
// Colori overlay per ruolo, uguali a vision_execute.js (reference, roi, found)
|
||||
const ROLE_COLORS = { reference: '#2563eb', found: '#16a34a', roi: '#f59e0b' };
|
||||
// #121: i colori per ruolo stanno in VisionOverlay (vision_overlay.js)
|
||||
const VALUE_UNITS = { 'dxf.points_in_pct': '%', 'dxf.distance_avg': 'mm', 'dxf.distance_min': 'mm', 'dxf.distance_max': 'mm' }; // #104
|
||||
const VALUE_KEYS = ['dxf.points_in_pct', 'dxf.distance_avg', 'dxf.distance_min', 'dxf.distance_max'];
|
||||
|
||||
@@ -466,6 +465,7 @@ function dxfRecipeWizard(taskId, csrf, msgs) {
|
||||
let cx = 0, cy = 0;
|
||||
if (vp) { cx = (vp.scrollLeft + vp.clientWidth / 2) / old; cy = (vp.scrollTop + vp.clientHeight / 2) / old; }
|
||||
this.zoom = z;
|
||||
this.drawOverlay(); // #121: ridisegno al nuovo zoom
|
||||
if (vp) this.$nextTick(() => { vp.scrollLeft = cx * z - vp.clientWidth / 2; vp.scrollTop = cy * z - vp.clientHeight / 2; });
|
||||
},
|
||||
// #104: Fit = tutta l'immagine nel viewport (altezza massima, non quella corrente che segue l'immagine)
|
||||
@@ -475,6 +475,7 @@ function dxfRecipeWizard(taskId, csrf, msgs) {
|
||||
const z = Math.min(8, Math.max(0.05, Math.min(vp.clientWidth / img.naturalWidth, this._maxVpH() / img.naturalHeight)));
|
||||
this.zoom = z;
|
||||
this.fitZoom = z;
|
||||
this.drawOverlay(); // #121: ridisegno al nuovo zoom
|
||||
vp.scrollLeft = 0; vp.scrollTop = 0;
|
||||
},
|
||||
// #113: zoom per chiave ('img' | 'dxf'), stessa logica di #104 ma con stato in views[k]. Viewport fisso di 240px.
|
||||
@@ -581,26 +582,15 @@ function dxfRecipeWizard(taskId, csrf, msgs) {
|
||||
{ maximumFractionDigits: 3 }) : '-';
|
||||
},
|
||||
|
||||
// Come vision_execute.js: canvas della dimensione dell'immagine, coordinate in pixel immagine
|
||||
// #121: overlay SVG in pixel immagine (viewBox = dimensioni naturali); tratto a spessore costante a ogni zoom.
|
||||
// Senza VisionOverlay.svg resta vuoto, senza errori.
|
||||
drawOverlay() {
|
||||
const img = this.$refs.img, cv = this.$refs.overlay;
|
||||
if (!img || !cv || !img.naturalWidth) return;
|
||||
cv.width = img.naturalWidth;
|
||||
cv.height = img.naturalHeight;
|
||||
const g = cv.getContext('2d');
|
||||
g.clearRect(0, 0, cv.width, cv.height);
|
||||
g.lineWidth = Math.max(2, cv.width / 400);
|
||||
g.lineJoin = 'round';
|
||||
const img = this.$refs.img, sv = this.$refs.overlay;
|
||||
if (!img || !sv || !img.naturalWidth) return;
|
||||
sv.setAttribute('viewBox', '0 0 ' + img.naturalWidth + ' ' + img.naturalHeight);
|
||||
const shapes = (this.result && this.result.result && this.result.result.overlay) || [];
|
||||
for (const item of shapes) {
|
||||
const rows = item.rows || [], cols = item.cols || [];
|
||||
if (!rows.length || rows.length !== cols.length) continue;
|
||||
g.strokeStyle = ROLE_COLORS[item.role] || '#ef4444';
|
||||
g.beginPath();
|
||||
g.moveTo(cols[0], rows[0]);
|
||||
for (let i = 1; i < rows.length; i++) g.lineTo(cols[i], rows[i]);
|
||||
g.stroke();
|
||||
}
|
||||
const VO = (typeof window !== 'undefined' && window.VisionOverlay) || null;
|
||||
sv.innerHTML = (VO && typeof VO.svg === 'function') ? VO.svg(shapes, { zoom: this.zoom }) : '';
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user