How I built a Golf Shot Analyzer

How I built a Golf Shot Analyzer

Golfer hitting ball at Hazendal driving range using Inrangeβ„’ Simulator

---

Building a Golf Shot Analyzer with Claude Code


May 11, 2026


---

I've been playing golf seriously for about a year. My launch monitor captures

everything β€” ball speed, carry distance, apex height, launch angle, shot curve

β€” but the default export is a flat CSV that tells you almost nothing at a

glance.

I wanted to actually see my shots.


---

The starting point

The data lived across two sessions in two separate CSV files, with a Google

Sheet that had accurate club assignments the CSVs were missing. Not a clean

situation. About 340 shots total, with 114 where the club was recorded as ? β€”

shots I'd hit without logging which iron I'd grabbed.

The goal was simple: one interactive tool, all sessions, filter by club or

date, see where every shot went.


---

How it was built

I used Claude Code to build the whole thing in a single conversation. No

boilerplate project setup, no scaffolding β€” just described what I had and what

I wanted.


The first step was fixing the data. Claude read both CSVs, cross-referenced

the Google Sheet (via the Google Drive MCP), and corrected 19 misclassified

shots β€” shots 24 through 42 from the April session had all been tagged as 8i

when they were actually 7i, 6i, and 5i.


Once the data was clean, the visualizer itself took shape quickly. A custom

canvas trajectory view renders each shot as a parabolic arc β€” apex Γ— sin(Ο€ Γ—

distance/carry) β€” which turns out to be a surprisingly good approximation of a

real ball flight. The bird's-eye dispersion scatter uses Chart.js. Everything

else is vanilla JavaScript, no framework.


The whole thing is a single self-contained HTML file. No server, no build

step.


---

Reading from Excel directly

Early versions embedded the shot data as a JavaScript blob inside the HTML.

That worked, but it meant regenerating the file every time I added a new

session.


The final version uses SheetJS to parse the Excel file directly in the

browser. Drag Shot Data.xlsx onto the drop zone, and the tool reads it fresh.

Date filters and club tabs populate automatically from whatever sessions are

in the file. Nothing is uploaded anywhere.


Adding a new session means updating one spreadsheet, not touching any code.


---

What surprised me

The trajectory chart was the most useful thing I didn't expect to need.

Looking at ball speed or carry as numbers tells you one thing. Seeing 30 arcs

stacked on top of each other β€” some tight and repeatable, some wildly

inconsistent β€” tells you something completely different about what's actually

happening in your swing.


The predicted shots (marked in amber) stand out immediately too. A cluster of

amber dots in a completely different carry range than the named-club shots is

a signal worth investigating.

---

How to use it

Open golf_visualizer.html in any browser. You'll see the drop screen first.


Load your data. Drag your Shot Data.xlsx onto the drop zone, or click to

browse. The app reads it once and renders everything. Use the ↩ Load different

file button to swap files anytime.

Filter by session. The session dropdown in the top right lets you isolate a

single date or view all sessions together. Tabs reset to match whichever

session you pick.

Filter by club. The tab bar shows every club in the current session with shot

counts. Click any tab to focus on that club β€” all three charts update

together.

Inspect a shot. Hover over any arc in the trajectory chart to see the details

float alongside it. Click to pin it β€” the selected arc turns gold, everything

else fades out, and a detail card appears in the stats panel. Press Esc or

click empty space to deselect.


Bird's eye view. The scatter chart shows lateral landing position versus carry

distance. Each dot represents one shot. Click a dot to select it across both

charts simultaneously. Predicted shots appear in amber.

Stats panel. Average carry, apex, ball speed, and launch angle update live as

you filter. The range beneath each number shows floor and ceiling across the

current selection β€” more useful than the average alone when consistency is

what you're working on.


---

The Excel file

The spreadsheet has one sheet called shot_data with a Date column, a Club

column, and all the launch monitor fields. Adding a new session is just

appending rows with the new date. The tool derives everything else β€” Predicted

flags, date dropdowns, club counts β€” from whatever's in the file at load

time.


No configuration. Just data.


---

Built with Claude Code, Chart.js, and SheetJS. Data from a InRangeβ„’ tracking session hosted at Hazendal Driving range.

---