Skeletal Element Inventory Visualizer
What you'll learn
~25 min- Build a skeletal element inventory visualizer with a single AI prompt
- Parse recovery inventory CSV and highlight elements on an interactive SVG skeleton diagram
- Troubleshoot common issues with SVG rendering, element mapping, and MNI calculations
- Customize the visualizer with condition scoring, side-by-side comparison, or printable inventory sheets
What youβre building
A forensic anthropologist opens a storage box at the DPAA laboratory. Inside are skeletal elements from a Pacific battlefield recovery β commingled remains from what the field team believes is at least two individuals. Every bone needs to be inventoried: which elements are present, which side they come from, what condition they are in, and critically, how many individuals are represented. Right now that inventory is recorded on a paper osteological form β a printed outline of a skeleton where the anthropologist shades in recovered elements by hand, then manually counts duplicated elements to estimate the minimum number of individuals.
A browser-based inventory visualizer that accepts a CSV CSV Comma-Separated Values β a text file where each line is a row and commas separate columns. Exportable from Excel, Google Sheets, etc. Full lesson → of recovered elements and highlights them on an interactive SVG skeleton diagram would let the analyst see completeness at a glance, calculate MNI automatically, and generate a printable inventory sheet β all from a single HTML file that runs on any lab computer.
That is what you will build in the next 25 minutes.
This tool demonstrates osteological inventory concepts for training purposes. Real forensic work requires validated, accredited inventory systems that meet federal evidence standards and laboratory SOPs. This is a training prototype, not a validated forensic evidence system.
Paper osteological inventory forms are the standard in forensic anthropology labs, but they fail in specific ways: they cannot be searched, they cannot calculate MNI automatically, they cannot be shared digitally without scanning, and when you shade in element 47 of 206, mistakes are permanent. A digital inventory does not replace the analystβs expertise β it replaces the paper.
By the end of this lesson you will have a skeletal element inventory visualizer that runs entirely in the browser. It accepts a CSV upload of recovered elements, renders a simplified anterior-view SVG skeleton with highlighted regions for each recovered bone, calculates MNI from duplicate elements, and provides a detail sidebar for element-level metadata. You will build it by giving a single, carefully-crafted prompt to an LLM CLI tool.
Parse structured data from a CSV, map each row to a visual region, and render an interactive diagram. This pattern works for any spatial inventory: anatomical specimens on a body map, equipment locations on a floor plan, sensor readings on a facility diagram.
πDomain Primer: Key osteological inventory terms
New to forensic osteology? Here are the key terms you will encounter:
- Skeletal element β An individual bone in the human skeleton. The adult skeleton has 206 named bones. In forensic contexts, elements are identified by name, side (left/right for paired bones), and portion (complete, proximal, distal, fragment).
- Osteological inventory β A systematic catalog of which skeletal elements have been recovered from a case. The inventory records element identity, side, completeness, condition, and any pathological or taphonomic observations.
- MNI (Minimum Number of Individuals) β The smallest number of individuals that can account for all recovered elements. Determined by finding the most frequently duplicated element. Example: if you have 3 left femora, the MNI is at least 3 regardless of how many other bones are present.
- Commingled remains β Skeletal elements from multiple individuals mixed together in the same context. Common in mass graves, battlefield recoveries, and mass disaster scenes. Sorting commingled remains is one of the most challenging tasks in forensic anthropology.
- Side designation (L/R) β Whether a bone is from the left or right side of the body. Paired bones (femora, humeri, tibiae, etc.) must be sided. Midline bones (sacrum, sternum, cranium) have no side designation.
- Condition score β A numeric or descriptive rating of bone preservation. Common scales range from 1 (excellent, complete) to 5 (poor, fragmentary). Condition affects what analyses can be performed β DNA extraction requires better preservation than morphological assessment.
- DPAA (Defense POW/MIA Accounting Agency) β The U.S. Department of Defense organization responsible for recovering and identifying missing service members. DPAA laboratories process skeletal remains using standardized osteological inventory protocols.
- Provenience β The precise three-dimensional location where an element was recovered. Links the inventory to field recovery data (grid square, depth, spatial relationships).
- Taphonomy β The study of what happens to remains after death β weathering, root damage, animal scavenging, soil staining. Taphonomic observations are recorded in the inventory alongside condition scores.
You do not need to be an expert in forensic anthropology β the AI tool will handle the technical implementation. You just need to know what the visualizer is mapping and why MNI matters.
Who this is for
- Forensic anthropologists and lab analysts who inventory skeletal remains and need a faster way to visualize recovery completeness and calculate MNI.
- MIA recovery team members who need to communicate inventory status to case managers and family liaisons without mailing paper forms.
- Students in forensic anthropology or bioarchaeology courses learning osteological inventory methods and MNI calculation.
The showcase
Here is what the finished visualizer looks like once you open the HTML file in a browser:
- SVG skeleton diagram (anterior view) in the center, with labeled bone regions that light up green when a matching element is present in the uploaded CSV. Unrecovered elements stay gray.
- Recovery progress bar at the top showing the percentage of standard skeletal elements accounted for (e.g., β37 of 206 elements recovered β 18%β).
- MNI calculation panel displaying the minimum number of individuals with the determining element (e.g., βMNI = 3, determined by Left Femurβ).
- Element detail sidebar β click any bone region on the SVG to see its metadata: case number, provenience, condition score, date recovered, and notes.
- CSV upload area with drag-and-drop support and a βLoad Exampleβ button with embedded sample data.
- Case filter dropdown to show elements from a single case or all cases combined.
Everything runs client-side. No data leaves the browser. The sample data loads instantly so you can see the full workflow before uploading your own inventory.
The prompt
Open your terminal Terminal The app where you type commands. Mac: Cmd+Space, type "Terminal". Windows: open WSL (Ubuntu) from the Start menu.
Full lesson →
, navigate to a project folder project folder A directory on your computer where the tool lives. Create one with "mkdir my-project && cd my-project".
Full lesson →
, start your AI CLI tool AI CLI tool Claude Code, Gemini CLI, or Codex CLI β a command-line AI that reads files, writes code, and runs commands.
Full lesson →
(e.g., by typing claude), and paste this prompt:
Build a single self-contained HTML file called skeletal-inventory.html that servesas an interactive skeletal element inventory visualizer for forensic anthropologycasework. Requirements:
1. PRELOADED SAMPLE DATA (embed as a JS array on page load) CSV columns: Element_Name, Side, Case_Number, Provenience, Condition_Score, Date_Recovered, Notes
Embed this dataset directly:
Element_Name,Side,Case_Number,Provenience,Condition_Score,Date_Recovered,Notes Cranium,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Frontal and parietals intact Mandible,M,DPAA-2024-0147,N24-E15 depth 1.2m,3,2024-03-15,Right ramus fragmented L_Humerus,L,DPAA-2024-0147,N24-E16 depth 1.3m,2,2024-03-15,Complete R_Humerus,R,DPAA-2024-0147,N25-E15 depth 1.0m,2,2024-03-16,Complete L_Femur,L,DPAA-2024-0147,N24-E15 depth 1.2m,3,2024-03-15,Proximal fragment only R_Femur,R,DPAA-2024-0147,N24-E16 depth 1.4m,2,2024-03-16,Complete L_Tibia,L,DPAA-2024-0147,N24-E16 depth 1.3m,2,2024-03-16,Complete Sternum,M,DPAA-2024-0147,N24-E15 depth 1.0m,4,2024-03-15,Manubrium only L_Clavicle,L,DPAA-2024-0147,N25-E15 depth 0.9m,2,2024-03-16,Complete Sacrum,M,DPAA-2024-0147,N24-E16 depth 1.5m,3,2024-03-17,Partial - S1-S3 fused C1_Vertebra,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Complete atlas C2_Vertebra,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Complete axis L_Radius,L,DPAA-2024-0147,N24-E16 depth 1.3m,3,2024-03-16,Distal third missing R_Ulna,R,DPAA-2024-0147,N25-E15 depth 1.0m,2,2024-03-16,Complete L_Femur,L,DPAA-2024-0152,S08-W22 depth 0.6m,2,2024-04-02,Complete - different size from 0147 R_Femur,R,DPAA-2024-0152,S08-W23 depth 0.7m,3,2024-04-02,Midshaft fragment L_Tibia,L,DPAA-2024-0152,S09-W22 depth 0.7m,3,2024-04-02,Distal half only Cranium,M,DPAA-2024-0152,S08-W22 depth 0.5m,4,2024-04-02,Calvarium only fragmented R_Humerus,R,DPAA-2024-0152,S08-W23 depth 0.5m,3,2024-04-03,Proximal half L_Femur,L,DPAA-2024-0193,T12-N04 depth 0.8m,1,2024-05-10,Complete excellent condition R_Scapula,R,DPAA-2024-0193,T12-N04 depth 0.8m,2,2024-05-10,Glenoid fossa intact
Note: L_Femur appears 3 times (cases 0147, 0152, 0193) = MNI of at least 3. Side "M" means midline (no left/right designation).
2. SVG SKELETON DIAGRAM - Draw a simplified anterior-view human skeleton using SVG paths/shapes - Include these labeled regions that can be individually highlighted: Cranium, Mandible, L_Clavicle, R_Clavicle, Sternum, L_Scapula, R_Scapula, L_Humerus, R_Humerus, L_Radius, R_Radius, L_Ulna, R_Ulna, L_Hand, R_Hand, Cervical_Vertebrae, Thoracic_Vertebrae, Lumbar_Vertebrae, Sacrum, L_Ilium, R_Ilium, L_Femur, R_Femur, L_Patella, R_Patella, L_Tibia, R_Tibia, L_Fibula, R_Fibula, L_Foot, R_Foot, Ribs - Each region is a clickable SVG group with a data-element attribute - Default state: gray fill (#374151) with subtle outline - Recovered state: green fill (#10b981) with brighter outline - Hover state: lighter shade with tooltip showing element name - Map CSV Element_Name values to SVG regions (handle C1_Vertebra, C2_Vertebra mapping to Cervical_Vertebrae group, etc.)
3. RECOVERY PROGRESS - Progress bar showing: "X of Y standard elements recovered (Z%)" - Count unique element+side combinations from the CSV - Y = total mappable skeleton regions (around 33 for this simplified diagram) - Color gradient from red (< 25%) to yellow (25-75%) to green (> 75%)
4. MNI CALCULATION - For each element+side combination, count how many times it appears across all case numbers - MNI = the highest count for any single element+side - Display: "Minimum Number of Individuals: N" with the determining element - Show a breakdown table: element, side, count β sorted by count descending - Highlight any element with count > 1 in amber on the table
5. ELEMENT DETAIL SIDEBAR - Click any SVG bone region to show its details in a right sidebar - If multiple entries exist for that element (from different cases), show all as stacked cards - Each card shows: Case_Number, Provenience, Condition_Score (as colored badge: 1=green, 2=light green, 3=yellow, 4=orange, 5=red), Date_Recovered, Notes - If no data exists for a clicked element, show "Not recovered" message
6. DATA INPUT - File upload area (drag-and-drop) for CSV files - "Load Example" button that populates with the embedded sample data - "Clear" button to reset everything - Case filter dropdown: "All Cases" plus one option per unique case number - When a single case is selected, only that case's elements are highlighted on the skeleton and MNI recalculates for the filtered set
7. DESIGN - Dark theme: background #0f172a, cards #1e293b, text #e2e8f0, accent #10b981 - Clean sans-serif font (Inter from Google Fonts CDN) - Layout: CSV upload top, SVG skeleton center-left, detail sidebar right, MNI panel and progress bar below the skeleton - SVG skeleton should be roughly 400px wide and 600px tall - Responsive: sidebar collapses below skeleton on narrow screens
8. TECHNICAL - Pure HTML/CSS/JS in one file, no build step - No external libraries needed (SVG is hand-drawn, no Chart.js required) - CSV parsing handles quoted fields and different line endings - All data stored in JS arrays, no localStorage needed - Element name mapping is case-insensitive and handles underscores vs spacesThat entire block is the prompt. Paste it as-is. The sample dataset uses realistic forensic recovery data across three case numbers with deliberately duplicated elements to demonstrate MNI calculation. The three left femora from three different cases produce an MNI of 3.
What you get
After the LLM finishes (typically 60-90 seconds), you will have a single file: skeletal-inventory.html. Open it in any browser.
Expected output structure
skeletal-inventory.html (~600-900 lines)Click Load Example and you should see:
- An SVG skeleton with approximately 14 regions highlighted in green (the recovered elements from the sample data) and the remaining regions in gray.
- A progress bar showing roughly β14 of 33 regions recovered (42%)β in yellow.
- An MNI panel displaying βMinimum Number of Individuals: 3β with βLeft Femurβ as the determining element.
- The MNI breakdown table showing Left Femur with a count of 3 (highlighted in amber), Cranium with 2, Right Femur with 2, Right Humerus with 2, and Left Tibia with 2.
- Click any green region on the skeleton to see the element detail cards in the sidebar. Clicking the Left Femur region should show three cards β one for each case.
- Use the case filter to select DPAA-2024-0147 alone and watch the skeleton update to show only that caseβs elements, with MNI recalculating to 1.
If something is off
| Problem | Follow-up prompt |
|---|---|
| SVG skeleton regions do not highlight when data is loaded | The SVG bone regions are not updating when the CSV data loads. Make sure each SVG group has a data-element attribute that exactly matches the Element_Name values from the CSV. Use case-insensitive matching and map individual vertebrae (C1_Vertebra, C2_Vertebra) to the Cervical_Vertebrae group. |
| MNI shows 1 even though Left Femur appears 3 times | The MNI calculation is not grouping by element+side correctly. Can you group the CSV rows by a normalized key of Element_Name + Side, count the number of unique Case_Numbers per group, and take the maximum count as MNI? |
| Clicking a bone region does nothing | The click handler is not attached to the SVG groups. Can you add click event listeners to each SVG group with a data-element attribute? When clicked, filter the loaded data for matching elements and display the results in the sidebar. |
When Things Go Wrong
Use the Symptom β Evidence β Request pattern: describe what you see, paste the error, then ask for a fix.
How it works (the 2-minute explanation)
You do not need to understand every line of the generated code, but here is the mental model:
- CSV parsing reads each row as a recovered skeletal element. The Element_Name and Side columns identify which bone region to highlight. Multiple rows can map to the same SVG region (duplicates from different cases), and that duplication is exactly what drives MNI calculation.
- SVG region mapping uses a lookup table to connect CSV element names to SVG group IDs. Each SVG group has a
data-elementattribute. When the CSV data loads, JavaScript iterates through the parsed rows, finds the matching SVG group, and changes its fill color from gray to green. Individual vertebrae (C1, C2, etc.) map to their respective vertebral group. - MNI calculation groups elements by their normalized name+side key, counts unique case numbers per group, and reports the maximum count. This is the standard forensic method: the most-duplicated element determines the minimum number of individuals because you cannot have three left femora from fewer than three people.
- Click interaction attaches event listeners to each SVG group. When clicked, the sidebar filters the loaded data for elements that map to that region and displays metadata cards for each match. If multiple cases contributed elements to that region, all cards are shown.
When remains from multiple individuals are recovered in the same context β a mass grave, a battlefield trench, a disaster site β the first question is always βhow many people are represented here?β MNI provides a defensible lower bound. It is conservative by design: three left femora means at least three individuals, but there could be more if some individuals are represented only by elements that are not duplicated. More sophisticated methods (pair-matching, osteometric sorting, DNA) can refine the count, but MNI from the inventory is always the starting point and is calculated before any laboratory analysis begins.
Customize it
The base visualizer handles the core inventory workflow, but real lab operations have additional needs. Each of these is a single follow-up prompt:
Add taphonomic modification annotations
Add a "Taphonomic Notes" dropdown to each element detail card with checkboxesfor common modifications: root etching, rodent gnawing, carnivore gnawing,weathering stage (0-5), soil staining, thermal alteration, cut marks,green bone fracture. When any taphonomic modification is selected, add a smallicon overlay on the corresponding SVG bone region (e.g., a tiny orange dot forthermal alteration, a blue dot for soil staining). Include a legend below theskeleton explaining the icons.Add side-by-side comparison view
Add a "Compare Cases" button that displays two skeleton diagrams side by side,one per selected case. Each skeleton highlights only that case's elements.Between the two skeletons, show a comparison panel listing elements presentin both cases (potential commingling overlap), elements unique to Case A,and elements unique to Case B. Color shared elements in amber on both diagrams.Add printable inventory sheet
Add a "Print Inventory" button that generates a printable osteologicalinventory form. Use CSS @media print to show: case number header, a tableof all recovered elements with columns for Element, Side, Condition,Provenience, Date, and Notes. Include the SVG skeleton diagram scaled tofit on the page with recovered elements highlighted. Add blank signaturelines for "Examined by" and "Date". Hide all interactive controls in print.Add photo reference placeholders
Add a photo upload zone to each element detail card in the sidebar. AcceptJPG/PNG images via drag-and-drop. Display uploaded photos as thumbnails(100x100px) in the card. Store images as base64 data URLs. When printing theinventory sheet, show photo placeholders with "Photo on file - see digitalrecord" text instead of the actual images.Notice the pattern: you start with a working inventory visualizer, then add features one prompt at a time. The taphonomic annotations transform it from a simple inventory into a preservation assessment tool. The printable sheet bridges digital and paper workflows. You never need to plan the entire tool upfront.
Try it yourself
- Open your CLI tool in an empty folder.
- Paste the main prompt from above.
- Open the generated
skeletal-inventory.htmlin your browser. - Click Load Example and verify the skeleton highlights the correct regions.
- Click the Left Femur region on the SVG β you should see three detail cards from three different cases.
- Check the MNI panel β it should show 3, determined by Left Femur.
- Use the case filter to select DPAA-2024-0152 alone β the skeleton should update to show only 5 highlighted regions and MNI should drop to 1.
- Pick one customization from the list above and add it.
Key takeaways
- One prompt, one tool: a detailed, specific prompt produces a working skeletal inventory visualizer in under 2 minutes.
- SVG diagrams make spatial data instantly comprehensible β a highlighted skeleton communicates recovery completeness faster than any table or spreadsheet.
- MNI calculation is simple but critical β count duplicated elements by side, and the highest count is the minimum number of individuals. The tool automates a calculation that is tedious by hand when inventories are large.
- Element name mapping is the hardest part β the prompt must specify how CSV names correspond to SVG regions, especially for grouped elements like vertebrae. Be explicit about the mapping in your prompt.
- Case filtering turns one tool into a case comparison system β toggling between cases on the same skeleton diagram reveals which elements overlap and which are unique.
A recovery inventory contains 3 left femora, 2 right femora, 2 crania, and 1 sacrum, each from different case numbers. What is the MNI?
You filter the inventory to a single case and the skeleton shows 37 of 33 standard regions recovered (112%). What does this indicate?
Whatβs next
In the next lesson, you will build another forensic field tool that extends the inventory workflow β taking the recovered elements you have cataloged here and connecting them to the broader identification pipeline. Same pattern: one prompt, one working tool, then customize.