-
Notifications
You must be signed in to change notification settings - Fork 13
Implement frontend mock data display for bone images and annotations #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
UcheWendy
merged 6 commits into
main
from
120-frontend-logic-for-image-and-annotation-display-using-mock-data
Sep 22, 2025
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
4706457
Implement frontend mock data display for bone images and annotations
c3845d1
changes
7b6ca59
linting errors
716add4
resolve merge conflicts
b139bd7
Merge branch 'main' into 120-frontend-logic-for-image-and-annotation-…
UcheWendy 89068e2
resolve error
UcheWendy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,42 @@ | ||
| // api.js - Centralized API configuration and data fetching | ||
|
|
||
| // Centralized API configuration | ||
| const API_CONFIG = { | ||
| BASE_URL: "http://127.0.0.1:8000", | ||
| ENDPOINTS: { | ||
| COMBINED_DATA: "/combined-data", | ||
| MOCK_BONE_DATA: "./js/mock-bone-data.json" | ||
| } | ||
| }; | ||
|
|
||
| export async function fetchCombinedData() { | ||
| // --- CORRECTED: Use the full URL of the backend server --- | ||
| const API_URL = "http://127.0.0.1:8000/combined-data"; | ||
| const API_URL = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.COMBINED_DATA}`; | ||
|
|
||
| try { | ||
| const response = await fetch(API_URL); | ||
| if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| return await response.json(); | ||
| } catch (error) { | ||
| console.error("Error fetching combined data:", error); | ||
| alert("Failed to load data."); | ||
| return { bonesets: [], bones: [], subbones: [] }; | ||
| throw error; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function fetchMockBoneData() { | ||
| try { | ||
| const response = await fetch(API_CONFIG.ENDPOINTS.MOCK_BONE_DATA); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| const data = await response.json(); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("Error fetching mock bone data:", error); | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| // Export configuration for other modules to use | ||
| export { API_CONFIG }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| { | ||
| "bones": [ | ||
| { | ||
| "id": "ischium", | ||
| "name": "Ischium", | ||
| "image_url": "https://via.placeholder.com/600x400/4A90E2/FFFFFF?text=Ischium+Bone", | ||
| "annotations": [ | ||
| { | ||
| "text": "Ischial Tuberosity - Attachment point for hamstring muscles", | ||
| "position": { "x": 300, "y": 150 } | ||
| }, | ||
| { | ||
| "text": "Ischial Spine - Forms part of the lesser sciatic notch", | ||
| "position": { "x": 250, "y": 100 } | ||
| }, | ||
| { | ||
| "text": "Ischial Ramus - Forms part of the obturator foramen", | ||
| "position": { "x": 350, "y": 200 } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "id": "ilium", | ||
| "name": "Ilium", | ||
| "image_url": "https://via.placeholder.com/600x400/50C878/FFFFFF?text=Ilium+Bone", | ||
| "annotations": [] | ||
| }, | ||
| { | ||
| "id": "pubis", | ||
| "name": "Pubis", | ||
| "annotations": [ | ||
| { | ||
| "text": "Pubic Symphysis - Joint where left and right pubic bones meet", | ||
| "position": { "x": 300, "y": 60 } | ||
| }, | ||
| { | ||
| "text": "Superior Pubic Ramus - Upper branch of the pubis", | ||
| "position": { "x": 250, "y": 180 } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| // viewer.js - Dedicated module for managing viewer state and display | ||
|
|
||
| /** | ||
| * Displays bone image with error handling for broken URLs | ||
| * @param {Object} boneData - The bone object from mock data | ||
| */ | ||
| export function displayBoneImage(boneData) { | ||
| const boneImage = document.getElementById("bone-image"); | ||
| if (!boneImage) { | ||
| console.error("Bone image element not found"); | ||
| return; | ||
| } | ||
|
|
||
| if (boneData.image_url) { | ||
| boneImage.src = boneData.image_url; | ||
| boneImage.alt = `${boneData.name} bone image`; | ||
| boneImage.style.display = "block"; | ||
|
|
||
| // Handle image load errors gracefully | ||
| boneImage.onerror = () => { | ||
| console.warn(`Failed to load image for ${boneData.name}: ${boneData.image_url}`); | ||
| boneImage.src = "https://via.placeholder.com/600x400/CCCCCC/666666?text=Image+Load+Failed"; | ||
| boneImage.alt = `${boneData.name} - Image failed to load`; | ||
| }; | ||
|
|
||
| // Clear any previous error handlers when image loads successfully | ||
| boneImage.onload = () => { | ||
| boneImage.onerror = null; | ||
| }; | ||
| } else { | ||
| // Handle missing image_url | ||
| boneImage.src = "https://via.placeholder.com/600x400/CCCCCC/666666?text=No+Image+Available"; | ||
| boneImage.alt = `${boneData.name} - No image available`; | ||
| boneImage.style.display = "block"; | ||
| console.warn(`No image URL provided for bone: ${boneData.name}`); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Displays annotations list for the selected bone | ||
| * @param {Array} annotations - Array of annotation objects | ||
| */ | ||
| export function displayAnnotations(annotations) { | ||
| const annotationsOverlay = document.getElementById("annotations-overlay"); | ||
| if (!annotationsOverlay) { | ||
| console.error("Annotations overlay element not found"); | ||
| return; | ||
| } | ||
|
|
||
| // Clear previous annotations | ||
| annotationsOverlay.innerHTML = ""; | ||
|
|
||
| if (!annotations || annotations.length === 0) { | ||
| annotationsOverlay.innerHTML = "<p>No annotations available for this bone.</p>"; | ||
| return; | ||
| } | ||
|
|
||
| // Create annotation list | ||
| const annotationsList = document.createElement("ul"); | ||
| annotationsList.className = "annotations-list"; | ||
|
|
||
| annotations.forEach((annotation) => { | ||
| const listItem = document.createElement("li"); | ||
| listItem.className = "annotation-item"; | ||
| listItem.textContent = annotation.text; | ||
| annotationsList.appendChild(listItem); | ||
| }); | ||
|
|
||
| annotationsOverlay.appendChild(annotationsList); | ||
| } | ||
|
|
||
| /** | ||
| * Main function to display complete bone data (image + annotations) | ||
| * @param {Object} boneData - The complete bone object | ||
| */ | ||
| export function displayBoneData(boneData) { | ||
| if (!boneData) { | ||
| console.error("No bone data provided to display"); | ||
| return; | ||
| } | ||
|
|
||
| displayBoneImage(boneData); | ||
| displayAnnotations(boneData.annotations); | ||
| } | ||
|
|
||
| /** | ||
| * Clears the viewer display | ||
| */ | ||
| export function clearViewer() { | ||
| const boneImage = document.getElementById("bone-image"); | ||
| const annotationsOverlay = document.getElementById("annotations-overlay"); | ||
|
|
||
| if (boneImage) { | ||
| boneImage.src = ""; | ||
| boneImage.alt = ""; | ||
| boneImage.style.display = "none"; | ||
| boneImage.onerror = null; // Clear error handlers | ||
| boneImage.onload = null; | ||
| } | ||
|
|
||
| if (annotationsOverlay) { | ||
| annotationsOverlay.innerHTML = "<p>Select a bone to view image and annotations.</p>"; | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mock data file is well-structured and accurately mimics the expected format of a complete bone object. This is exactly what was needed for the frontend to be developed independently.
However, The mock file should include examples for a few different scenarios to help with testing. For instance, it should include an object for a bone that has no annotations and another for a bone that is missing an image_url. This will help us ensure the frontend handles these cases gracefully.
Please expand the mock data to include these edge cases so we can verify the frontend doesn't break when the data isn't perfect.