Browse Source

Consolidated logic for data explorer.

refactor/modularize
RUSHIL AMBARISH KADU 7 months ago
parent
commit
85d0bad1d4
  1. 113
      steps/src/dataExplorer.js
  2. 20
      steps/src/main.js

113
steps/src/dataExplorer.js

@ -1,8 +1,12 @@
// In src/dataExplorer.js
import { appState } from './state.js';
import {
canvasContainer,
explorerBtn
} from './dom.js'; // Import the DOM elements we need to listen to
// --- DOM Elements ---
// --- DOM Elements (Internal to this module) ---
const panel = document.getElementById('data-explorer-panel');
const closeBtn = document.getElementById('close-explorer-btn');
const footer = document.getElementById('explorer-footer');
@ -17,7 +21,8 @@ const tabs = {
const gridDiv = document.getElementById('data-grid');
const chartCanvas = document.getElementById('data-chart');
let gridApi = null; // This will hold the grid's API
// --- Module-Local State ---
let gridApi = null;
let chartInstance = null;
let currentGridData = null;
@ -30,7 +35,6 @@ const gridOptions = {
filter: true,
resizable: true,
},
// The onGridReady callback is no longer needed with the new createGrid method.
};
// --- Chart.js Configuration ---
@ -56,7 +60,16 @@ function createChart(data, label) {
});
}
// --- Core Functions ---
// --- Core Functions (Internal) ---
function showExplorer() {
panel.classList.remove('hidden');
updateExplorer();
}
function hideExplorer() {
panel.classList.add('hidden');
}
function switchTab(targetTab) {
Object.values(tabs).forEach(tab => {
@ -81,19 +94,12 @@ function createTreeView(data) {
return pre;
}
export function showExplorer() {
panel.classList.remove('hidden');
updateExplorer();
}
function updateExplorer() {
if (panel.classList.contains('hidden') || !appState.vizData) return;
export function hideExplorer() {
panel.classList.add('hidden');
}
export function updateExplorer() {
if (panel.classList.contains('hidden')) return;
const frame = appState.vizData?.radarFrames[appState.currentFrame];
const frame = appState.vizData.radarFrames[appState.currentFrame];
if (!frame) return;
tabs.tree.panel.innerHTML = '';
tabs.tree.panel.appendChild(createTreeView({
currentFrame: appState.currentFrame,
@ -101,11 +107,17 @@ export function updateExplorer() {
}));
}
export function displayInGrid(data, title) {
function displayInGrid(data, title) {
if (!data || data.length === 0 || !gridApi) return;
currentGridData = data;
const columns = Object.keys(data[0]).map(key => ({ field: key }));
// Auto-generate columns from the first data object
const columns = Object.keys(data[0]).map(key => ({
field: key,
headerName: key, // Set header name
sortable: true, // Ensure all generated columns are sortable
filter: true, // Ensure all generated columns are filterable
}));
gridApi.setGridOption('columnDefs', columns);
gridApi.setGridOption('rowData', data);
@ -114,24 +126,41 @@ export function displayInGrid(data, title) {
switchTab('grid');
}
// --- Event Listeners ---
// --- Initialization Function (The file's only export) ---
export function initializeDataExplorer() {
// Initialize the grid
if (!gridApi) {
gridApi = agGrid.createGrid(gridDiv, gridOptions);
}
// --- Wire up all event listeners ---
// Toggle panel visibility
explorerBtn.addEventListener('click', () => {
if (panel.classList.contains('hidden')) {
showExplorer();
} else {
hideExplorer();
}
});
closeBtn.addEventListener('click', hideExplorer);
// Tab switching
Object.keys(tabs).forEach(key => {
tabs[key].btn.addEventListener('click', () => switchTab(key));
});
// Plot button
plotBtn.addEventListener('click', () => {
// --- START: MODIFIED LOGIC ---
// Fix: Use onColumnHeaderClicked or get column from focused cell
const focusedCell = gridApi.getFocusedCell();
if (!focusedCell) {
alert("Please click a column header to select it for plotting.");
alert("Please click a cell in the column you wish to plot.");
return;
}
const colId = focusedCell.column.getColId();
// --- END: MODIFIED LOGIC ---
const plotData = currentGridData.map(row => row[colId]).filter(val => typeof val === 'number');
if (plotData.length > 0) {
@ -142,7 +171,39 @@ plotBtn.addEventListener('click', () => {
}
});
// --- START: THIS IS THE MAIN FIX ---
// Initialize the grid using the new createGrid method and store its API.
gridApi = agGrid.createGrid(gridDiv, gridOptions);
// --- END: THIS IS THE MAIN FIX ---
// Main canvas click listener
canvasContainer.addEventListener('click', () => {
if (!appState.vizData) return;
const currentFrameData = appState.vizData.radarFrames[appState.currentFrame];
if (currentFrameData && currentFrameData.pointCloud) {
// Send point cloud data to the grid
displayInGrid(currentFrameData.pointCloud, `Frame ${appState.currentFrame} - Point Cloud`);
// Show the explorer if it's hidden
if (panel.classList.contains('hidden')) {
showExplorer();
}
}
});
// Keyboard shortcut listener
document.addEventListener("keydown", (event) => {
// Ignore if typing in an input
const isTextInputFocused =
event.target.tagName === "INPUT" &&
(event.target.type === "text" || event.target.type === "number");
if (isTextInputFocused) {
return;
}
// Toggle explorer with 'i' key
if (event.key === "i") {
event.preventDefault();
if (panel.classList.contains("hidden")) {
showExplorer();
} else {
hideExplorer();
}
}
});
}

20
steps/src/main.js

@ -17,7 +17,8 @@
// ===========================================================================================================
import { zoomSketch } from "./p5/zoomSketch.js";
import { showExplorer, hideExplorer, displayInGrid } from "./dataExplorer.js";
//import { showExplorer, hideExplorer, displayInGrid } from "./dataExplorer.js";
import { initializeDataExplorer } from "./dataExplorer.js"; // <-- ADD THIS
import {
showModal,
hideModal,
@ -103,7 +104,7 @@ import {
menuScrim,
toggleConfirmedOnly,
resetUIForNewLoad,
explorerBtn,
//explorerBtn,
} from "./dom.js";
import { initializeTheme } from "./theme.js";
@ -946,7 +947,7 @@ document.addEventListener("keydown", (event) => {
"m",
"q",
"c",
"i",
//"i",
];
if (!appState.vizData || !recognizedKeys.includes(key)) {
@ -1013,14 +1014,14 @@ document.addEventListener("keydown", (event) => {
appState.p5_instance.redraw();
}
}
if (key === "i") {
/* if (key === "i") {
const panel = document.getElementById("data-explorer-panel");
if (panel.classList.contains("hidden")) {
showExplorer();
} else {
hideExplorer();
}
}
} */
if (key === "p") {
togglePredictedPos.click();
appState.p5_instance.redraw();
@ -1051,7 +1052,7 @@ document.addEventListener("keydown", (event) => {
}
});
canvasContainer.addEventListener('click', () => {
/* canvasContainer.addEventListener('click', () => {
if (!appState.vizData) return;
// For this example, let's just send the pointCloud of the current frame to the grid.
@ -1061,8 +1062,8 @@ canvasContainer.addEventListener('click', () => {
if (currentFrameData && currentFrameData.pointCloud) {
displayInGrid(currentFrameData.pointCloud, `Frame ${appState.currentFrame} - Point Cloud`);
}
});
explorerBtn.addEventListener('click', () => {
}); */
/* explorerBtn.addEventListener('click', () => {
const panel = document.getElementById("data-explorer-panel");
if (panel.classList.contains("hidden")) {
showExplorer();
@ -1070,7 +1071,7 @@ explorerBtn.addEventListener('click', () => {
hideExplorer();
}
});
*/
function calculateAndSetOffset() {
const jsonTimestampInfo = extractTimestampInfo(appState.jsonFilename);
const videoTimestampInfo = extractTimestampInfo(appState.videoFilename);
@ -1106,6 +1107,7 @@ function calculateAndSetOffset() {
// --- [START] CORRECTED INITIALIZATION LOGIC ---
document.addEventListener("DOMContentLoaded", () => {
initializeTheme();
initializeDataExplorer(); // <-- ADD THIS LINE
initDB(async () => {
console.log("Database initialized. Checking for cached session...");

Loading…
Cancel
Save