Browse Source

Coloring of the Tracks and Pred. Info text in zoom tooltip and close up display.

refactor/modularize
RUSHIL AMBARISH KADU 7 months ago
parent
commit
059350dba8
  1. 44
      steps/src/drawUtils.js
  2. 33
      steps/src/p5/radarSketch.js
  3. 72
      steps/src/p5/zoomSketch.js

44
steps/src/drawUtils.js

@ -449,7 +449,7 @@ export function drawTrackMarkers(p, plotScales) {
// --- END: Add the Same Safeguard Here ---
const log = track.historyLog.find(
(log) => log.frameIdx === appState.currentFrame + 1
(log) => log.frameIdx === appState.currentFrame
);
if (log) {
@ -639,30 +639,49 @@ export function handleCloseUpDisplay(p, plotScales) {
const infoStrings = [];
for (const item of hoveredItems) {
let infoText = "";
let itemColor = item.color || null; // Initialize with existing item color or null
const data = item.data;
switch (item.type) {
case "point":
const vel = data.velocity !== null ? data.velocity.toFixed(2) : "N/A";
const snr = data.snr !== null ? data.snr.toFixed(1) : "N/A";
infoText = `Point ${item.index} | X:${data.x.toFixed(2)}, Y:${data.y.toFixed(
infoText = `Point ${item.index} | X:${data.x.toFixed(
2
)} | V:${vel}, SNR:${snr}, Cluster: ${data.clusterNumber}`;
)}, Y:${data.y.toFixed(2)} | V:${vel}, SNR:${snr}, Cluster: ${
data.clusterNumber
}`;
break;
case "cluster":
const rs =
data.radialSpeed !== null ? data.radialSpeed.toFixed(2) : "N/A";
const vx = data.vx !== null ? data.vx.toFixed(2) : "N/A";
const vy = data.vy !== null ? data.vy.toFixed(2) : "N/A";
infoText = `Cluster ${data.id} | X:${data.x.toFixed(
infoText = `Cluster ${data.id} | X:${data.x.toFixed(2)}, Y:${data.y.toFixed(
2
)}, Y:${data.y.toFixed(2)} | rSpeed:${rs}, vX:${vx}, vY:${vy}`;
)} | rSpeed:${rs}, vX:${vx}, vY:${vy}`;
// itemColor is already set for clusters when pushed to hoveredItems
break;
case "track":
infoText = `Track ${
item.trackId
} | X:${data.correctedPosition[0].toFixed(
const trackX = data.correctedPosition[0];
const trackY = data.correctedPosition[1];
let trackSpeed = "N/A";
if (
data.predictedVelocity &&
data.predictedVelocity[0] !== null &&
data.predictedVelocity[1] !== null
) {
const [vx, vy] = data.predictedVelocity;
// Calculate speed in km/h, similar to drawTrackMarkers
trackSpeed = (p.sqrt(vx * vx + vy * vy) * 3.6).toFixed(1) + " km/h";
}
infoText = `Track ${item.trackId} | X:${trackX.toFixed(
2
)}, Y:${data.correctedPosition[1].toFixed(2)}`;
)}, Y:${trackY.toFixed(2)} | Speed: ${trackSpeed}`;
// Check for dark mode to ensure visibility
const isDark = document.documentElement.classList.contains("dark");
itemColor = isDark
? p.color(100, 149, 237) // A lighter "Cornflower Blue" for dark mode
: p.color(0, 0, 255); // Original blue for light mode
break;
case "prediction":
const p_vx =
@ -673,15 +692,14 @@ export function handleCloseUpDisplay(p, plotScales) {
data.predictedVelocity[1] !== null
? data.predictedVelocity[1].toFixed(2)
: "N/A";
infoText = `Pred. for ${
item.trackId
} | X:${data.predictedPosition[0].toFixed(
infoText = `Pred. for ${item.trackId} | X:${data.predictedPosition[0].toFixed(
2
)}, Y:${data.predictedPosition[1].toFixed(2)} | vX:${p_vx}, vY:${p_vy}`;
itemColor = p.color(255, 0, 0); // Red color for prediction info
break;
}
if (infoText) {
infoStrings.push({ text: infoText, color: item.color || null });
infoStrings.push({ text: infoText, color: itemColor });
}
}

33
steps/src/p5/radarSketch.js

@ -151,7 +151,7 @@ export const radarSketch = function (p) {
if (togglePredictedPos.checked) {
for (const track of appState.vizData.tracks) {
const log = track.historyLog.find(
(log) => log.frameIdx === appState.currentFrame + 1
(log) => log.frameIdx === appState.currentFrame
);
if (
log &&
@ -243,29 +243,32 @@ export const radarSketch = function (p) {
);
}
} else if (zoomPanel.style.display === "block") {
// --- THIS BLOCK IS THE FIX ---
// If NOT hovering, but the panel is still visible:
// --- THIS BLOCK IS THE FIX ---
// If NOT hovering, but the panel is still visible:
// 1. Continue to update the zoom sketch's position to follow the mouse.
// We pass an empty array for hoveredItems, so no tooltip is drawn.
if (appState.zoomSketchInstance && appState.zoomSketchInstance.updateAndDraw) {
appState.zoomSketchInstance.updateAndDraw(
// 1. Continue to update the zoom sketch's position to follow the mouse.
// We pass an empty array for hoveredItems, so no tooltip is drawn.
if (
appState.zoomSketchInstance &&
appState.zoomSketchInstance.updateAndDraw
) {
appState.zoomSketchInstance.updateAndDraw(
p.mouseX,
p.mouseY,
[], // Pass empty array
plotScales
);
}
);
}
// 2. If a "hide" timer isn't already running, start one.
if (!appState.zoomHoverTimeout) {
appState.zoomHoverTimeout = setTimeout(() => {
// 2. If a "hide" timer isn't already running, start one.
if (!appState.zoomHoverTimeout) {
appState.zoomHoverTimeout = setTimeout(() => {
console.log("Cooling period ended. Hiding zoom panel.");
zoomPanel.style.display = "none";
appState.zoomHoverTimeout = null;
}, COOLING_PERIOD_MS);
}
}
}, COOLING_PERIOD_MS);
}
}
} else {
zoomPanel.style.display = "none";
}

72
steps/src/p5/zoomSketch.js

@ -17,7 +17,6 @@ import {
toggleCovariance,
} from "../dom.js";
function drawZoomTooltip(p, hoveredItems, mainMouseX) {
if (!hoveredItems || hoveredItems.length === 0) return;
@ -25,35 +24,71 @@ function drawZoomTooltip(p, hoveredItems, mainMouseX) {
const infoStrings = [];
for (const item of hoveredItems) {
let infoText = "";
let itemColor = item.color || null; // Initialize with existing item color or null
const data = item.data;
switch (item.type) {
case "point":
infoText = `Point${item.index} | X:${data.x.toFixed(2)}, Y:${data.y.toFixed(
const vel = data.velocity !== null ? data.velocity.toFixed(2) : "N/A";
const snr = data.snr !== null ? data.snr.toFixed(1) : "N/A";
infoText = `Point ${item.index} | X:${data.x.toFixed(
2
)} | V:${data.velocity?.toFixed(2)}, SNR:${data.snr?.toFixed(1)}`;
)}, Y:${data.y.toFixed(2)} | V:${vel}, SNR:${snr}, Cluster: ${
data.clusterNumber
}`;
break;
case "cluster":
const rs =
data.radialSpeed !== null ? data.radialSpeed.toFixed(2) : "N/A";
const vx = data.vx !== null ? data.vx.toFixed(2) : "N/A";
const vy = data.vy !== null ? data.vy.toFixed(2) : "N/A";
infoText = `Cluster ${data.id} | X:${data.x.toFixed(
2
)}, Y:${data.y.toFixed(2)} | rSpeed:${data.radialSpeed?.toFixed(2)}`;
)}, Y:${data.y.toFixed(2)} | rSpeed:${rs}, vX:${vx}, vY:${vy}`;
break;
case "track":
infoText = `Track ${
item.trackId
} | X:${data.correctedPosition[0].toFixed(
const trackX = data.correctedPosition[0];
const trackY = data.correctedPosition[1];
let trackSpeed = "N/A",
trackVx = "N/A",
trackVy = "N/A";
if (
data.predictedVelocity &&
data.predictedVelocity[0] !== null &&
data.predictedVelocity[1] !== null
) {
const [vx, vy] = data.predictedVelocity;
trackVx = vx.toFixed(2);
trackVy = vy.toFixed(2);
trackSpeed = (p.sqrt(vx * vx + vy * vy) * 3.6).toFixed(1) + " km/h";
}
infoText = `Track ${item.trackId} | X:${trackX.toFixed(
2
)}, Y:${data.correctedPosition[1].toFixed(2)}`;
)}, Y:${trackY.toFixed(2)} | Speed: ${trackSpeed}`;
const isDark = document.documentElement.classList.contains("dark");
itemColor = isDark
? p.color(100, 149, 237) // Lighter blue for dark mode
: p.color(0, 0, 255); // Original blue for light mode
break;
case "prediction":
infoText = `Pred. for ${
const p_vx =
data.predictedVelocity[0] !== null
? data.predictedVelocity[0].toFixed(2)
: "N/A";
const p_vy =
data.predictedVelocity[1] !== null
? data.predictedVelocity[1].toFixed(2)
: "N/A";
infoText = `Pred. ${
item.trackId
} | X:${data.predictedPosition[0].toFixed(
2
)}, Y:${data.predictedPosition[1].toFixed(2)}`;
)}, Y:${data.predictedPosition[1].toFixed(2)} | Vx:${p_vx}, Vy:${p_vy}`;
itemColor = p.color(255, 0, 0); // Red color for prediction info
break;
}
if (infoText)
infoStrings.push({ text: infoText, color: item.color || null });
if (infoText) {
infoStrings.push({ text: infoText, color: itemColor });
}
}
// 2. Find the average screen position of hovered items
@ -171,22 +206,24 @@ export const zoomSketch = function (p) {
canvas.parent(containerId);
//console.log(`zoomSketch: Canvas CREATED with dimensions ${p.width}x${p.height}`); // debug
} else {
console.warn("zoomSketch: updateAndDraw called, but container is not ready. Aborting draw."); //debug
console.warn(
"zoomSketch: updateAndDraw called, but container is not ready. Aborting draw."
); //debug
return;
}
}
p.redraw();
};
p.handleResize = function() {
p.handleResize = function () {
console.log("zoomSketch: handleResize triggered. Destroying old canvas.");
if (canvas) {
canvas.remove(); // p5.js function to properly remove the canvas from the DOM
canvas = null; // Set the internal reference to null
canvas = null; // Set the internal reference to null
}
// The canvas will be recreated automatically the next time updateAndDraw() is called,
// at which point the container will have its correct, final dimensions.
}
};
p.draw = function () {
if (!appState.vizData || !canvas) return;
p.background(
@ -277,7 +314,7 @@ export const zoomSketch = function (p) {
p.fill(textColor);
p.noStroke();
p.textSize(16);
p.textAlign(p.LEFT -2, p.TOP);
p.textAlign(p.LEFT - 2, p.TOP);
p.textStyle(p.BOLD);
p.text(titleText, 10, 10);
p.pop();
@ -289,5 +326,4 @@ export const zoomSketch = function (p) {
p.line(p.width / 2 - 15, p.height / 2, p.width / 2 + 15, p.height / 2);
p.line(p.width / 2, p.height / 2 - 15, p.width / 2, p.height / 2 + 15);
};
};
Loading…
Cancel
Save