cyberai-1 commited on
Commit
a8d671e
·
1 Parent(s): 0551166

update filter error

Browse files
Files changed (1) hide show
  1. index.html +74 -24
index.html CHANGED
@@ -548,6 +548,17 @@ let filteredRows = []; // current filtered rows based on group/scene select
548
  // CSV drag-drop
549
  setupDrop('csvZone', 'csvInput', handleCSVFiles);
550
 
 
 
 
 
 
 
 
 
 
 
 
551
  function setupDrop(zoneId, inputId, handler) {
552
  const zone = document.getElementById(zoneId);
553
  const input = document.getElementById(inputId);
@@ -646,6 +657,11 @@ function buildDashboard() {
646
  renderSceneTable();
647
  renderSceneSelector();
648
  populateFilterDropdowns();
 
 
 
 
 
649
 
650
  showPage('dash');
651
  toast(`Loaded ${allRows.length.toLocaleString()} detections across ${Object.keys(scenes).length} scene(s).`, 'ok');
@@ -957,18 +973,19 @@ function drawOverlay(frameNum) {
957
  const vid = document.getElementById('videoEl');
958
  const wrap = document.getElementById('videoWrap');
959
 
 
 
 
 
960
  // Set canvas to actual display size (not internal resolution)
961
- canvas.style.width = wrap.offsetWidth + 'px';
962
- canvas.style.height = wrap.offsetHeight + 'px';
963
 
964
  // Internal resolution for drawing (higher precision)
965
- canvas.width = wrap.offsetWidth * window.devicePixelRatio;
966
- canvas.height = wrap.offsetHeight * window.devicePixelRatio;
967
  ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
968
 
969
- const displayWidth = wrap.offsetWidth;
970
- const displayHeight = wrap.offsetHeight;
971
-
972
  ctx.clearRect(0, 0, displayWidth, displayHeight);
973
 
974
  if (!activeScene) return;
@@ -990,12 +1007,38 @@ function drawOverlay(frameNum) {
990
  }
991
 
992
  // Get original frame dimensions from CSV
993
- const frameWidth = parseInt(rows[0]?.frame_width) || displayWidth;
994
- const frameHeight = parseInt(rows[0]?.frame_height) || displayHeight;
995
 
996
- // Calculate scale factors (CSV coords → display coords)
997
- const scaleX = displayWidth / frameWidth;
998
- const scaleY = displayHeight / frameHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
999
 
1000
  const liveCounts = {};
1001
 
@@ -1005,11 +1048,11 @@ function drawOverlay(frameNum) {
1005
  const x2 = parseInt(r.bbox_x2);
1006
  const y2 = parseInt(r.bbox_y2);
1007
 
1008
- // Scale to display coordinates
1009
- const dispX1 = x1 * scaleX;
1010
- const dispY1 = y1 * scaleY;
1011
- const dispX2 = x2 * scaleX;
1012
- const dispY2 = y2 * scaleY;
1013
 
1014
  const w = dispX2 - dispX1;
1015
  const h = dispY2 - dispY1;
@@ -1036,8 +1079,8 @@ function drawOverlay(frameNum) {
1036
  ctx.fillText(lbl, dispX1 + 4, dispY1 - 4);
1037
 
1038
  // Center dot (scaled)
1039
- const cx = parseInt(r.cx) * scaleX;
1040
- const cy = parseInt(r.cy) * scaleY;
1041
  ctx.beginPath();
1042
  ctx.arc(cx, cy, 4, 0, Math.PI*2);
1043
  ctx.fillStyle = col;
@@ -1046,8 +1089,8 @@ function drawOverlay(frameNum) {
1046
  liveCounts[r.class_name] = (liveCounts[r.class_name]||0) + 1;
1047
  });
1048
 
1049
- // Counting line (55% height)
1050
- const lineY = displayHeight * 0.55;
1051
  ctx.setLineDash([8, 6]);
1052
  ctx.strokeStyle = '#e8ff47';
1053
  ctx.lineWidth = 1.5;
@@ -1122,8 +1165,13 @@ function populateFilterDropdowns() {
1122
  groups.add(r.group_id || '?');
1123
  });
1124
 
1125
- // Populate group filter
1126
  const groupSelect = document.getElementById('groupFilter');
 
 
 
 
 
1127
  const groupOptions = Array.from(groups).sort();
1128
  groupOptions.forEach(group => {
1129
  const option = document.createElement('option');
@@ -1140,8 +1188,10 @@ function updateSceneFilter() {
1140
  const selectedGroup = document.getElementById('groupFilter').value;
1141
  const sceneSelect = document.getElementById('sceneFilter');
1142
 
1143
- // Clear existing options except "ALL SCENES"
1144
- sceneSelect.innerHTML = '<option value="">ALL SCENES</option>';
 
 
1145
 
1146
  // Get scenes for selected group (or all scenes if no group selected)
1147
  const sceneNames = new Set();
 
548
  // CSV drag-drop
549
  setupDrop('csvZone', 'csvInput', handleCSVFiles);
550
 
551
+ // Handle window resize for video overlay
552
+ window.addEventListener('resize', () => {
553
+ if (activeScene && document.getElementById('videoEl').style.display !== 'none') {
554
+ const frameNum = lastDrawnFrame;
555
+ if (frameNum >= 0) {
556
+ // Redraw with new dimensions
557
+ drawOverlay(frameNum);
558
+ }
559
+ }
560
+ });
561
+
562
  function setupDrop(zoneId, inputId, handler) {
563
  const zone = document.getElementById(zoneId);
564
  const input = document.getElementById(inputId);
 
657
  renderSceneTable();
658
  renderSceneSelector();
659
  populateFilterDropdowns();
660
+
661
+ // Reset filter selections when loading new data
662
+ document.getElementById('groupFilter').value = '';
663
+ document.getElementById('sceneFilter').value = '';
664
+ filteredRows = [];
665
 
666
  showPage('dash');
667
  toast(`Loaded ${allRows.length.toLocaleString()} detections across ${Object.keys(scenes).length} scene(s).`, 'ok');
 
973
  const vid = document.getElementById('videoEl');
974
  const wrap = document.getElementById('videoWrap');
975
 
976
+ // Get actual display dimensions
977
+ const displayWidth = wrap.offsetWidth;
978
+ const displayHeight = wrap.offsetHeight;
979
+
980
  // Set canvas to actual display size (not internal resolution)
981
+ canvas.style.width = displayWidth + 'px';
982
+ canvas.style.height = displayHeight + 'px';
983
 
984
  // Internal resolution for drawing (higher precision)
985
+ canvas.width = displayWidth * window.devicePixelRatio;
986
+ canvas.height = displayHeight * window.devicePixelRatio;
987
  ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
988
 
 
 
 
989
  ctx.clearRect(0, 0, displayWidth, displayHeight);
990
 
991
  if (!activeScene) return;
 
1007
  }
1008
 
1009
  // Get original frame dimensions from CSV
1010
+ const frameWidth = parseInt(rows[0]?.frame_width);
1011
+ const frameHeight = parseInt(rows[0]?.frame_height);
1012
 
1013
+ if (!frameWidth || !frameHeight) {
1014
+ ctx.font = '12px DM Mono';
1015
+ ctx.fillStyle = 'rgba(255,255,255,0.3)';
1016
+ ctx.fillText(`FRAME ${frameNum} - Invalid frame dimensions`, 10, displayHeight - 10);
1017
+ return;
1018
+ }
1019
+
1020
+ // Calculate scale factors accounting for video aspect ratio and display size
1021
+ // Video maintains aspect ratio with object-fit:contain, so we need to calculate the actual video display area
1022
+ const videoAspect = frameWidth / frameHeight;
1023
+ const displayAspect = displayWidth / displayHeight;
1024
+
1025
+ let scaleX, scaleY, offsetX = 0, offsetY = 0;
1026
+
1027
+ if (displayAspect > videoAspect) {
1028
+ // Display is wider than video - letterbox left/right
1029
+ const scaledHeight = displayHeight;
1030
+ const scaledWidth = scaledHeight * videoAspect;
1031
+ offsetX = (displayWidth - scaledWidth) / 2;
1032
+ scaleX = scaledWidth / frameWidth;
1033
+ scaleY = scaledHeight / frameHeight;
1034
+ } else {
1035
+ // Display is taller than video - letterbox top/bottom
1036
+ const scaledWidth = displayWidth;
1037
+ const scaledHeight = scaledWidth / videoAspect;
1038
+ offsetY = (displayHeight - scaledHeight) / 2;
1039
+ scaleX = scaledWidth / frameWidth;
1040
+ scaleY = scaledHeight / frameHeight;
1041
+ }
1042
 
1043
  const liveCounts = {};
1044
 
 
1048
  const x2 = parseInt(r.bbox_x2);
1049
  const y2 = parseInt(r.bbox_y2);
1050
 
1051
+ // Scale to display coordinates accounting for aspect ratio and centering
1052
+ const dispX1 = offsetX + x1 * scaleX;
1053
+ const dispY1 = offsetY + y1 * scaleY;
1054
+ const dispX2 = offsetX + x2 * scaleX;
1055
+ const dispY2 = offsetY + y2 * scaleY;
1056
 
1057
  const w = dispX2 - dispX1;
1058
  const h = dispY2 - dispY1;
 
1079
  ctx.fillText(lbl, dispX1 + 4, dispY1 - 4);
1080
 
1081
  // Center dot (scaled)
1082
+ const cx = parseInt(r.cx) * scaleX + offsetX;
1083
+ const cy = parseInt(r.cy) * scaleY + offsetY;
1084
  ctx.beginPath();
1085
  ctx.arc(cx, cy, 4, 0, Math.PI*2);
1086
  ctx.fillStyle = col;
 
1089
  liveCounts[r.class_name] = (liveCounts[r.class_name]||0) + 1;
1090
  });
1091
 
1092
+ // Counting line (55% height from video area top)
1093
+ const lineY = offsetY + (displayHeight - offsetY * 2) * 0.55;
1094
  ctx.setLineDash([8, 6]);
1095
  ctx.strokeStyle = '#e8ff47';
1096
  ctx.lineWidth = 1.5;
 
1165
  groups.add(r.group_id || '?');
1166
  });
1167
 
1168
+ // Populate group filter - clear first to avoid duplicates
1169
  const groupSelect = document.getElementById('groupFilter');
1170
+ // Remove all options except the first "ALL GROUPS"
1171
+ while (groupSelect.options.length > 1) {
1172
+ groupSelect.remove(1);
1173
+ }
1174
+
1175
  const groupOptions = Array.from(groups).sort();
1176
  groupOptions.forEach(group => {
1177
  const option = document.createElement('option');
 
1188
  const selectedGroup = document.getElementById('groupFilter').value;
1189
  const sceneSelect = document.getElementById('sceneFilter');
1190
 
1191
+ // Clear existing options except "ALL SCENES" - remove all except first
1192
+ while (sceneSelect.options.length > 1) {
1193
+ sceneSelect.remove(1);
1194
+ }
1195
 
1196
  // Get scenes for selected group (or all scenes if no group selected)
1197
  const sceneNames = new Set();