Viewing a saved revision (read-only)
D4hea5MZ-1g320GIVhVfQ
Fork from AI: Adapt Reference Visualization Work
Interactive scatter plot of gig bookings (gigs.csv), adapted from the Interactive Scatter Plot reference with axis menus, color encoding, legend, and tooltips, plus a README documenting the dataset.
Sam's Gigs
An interactive exploration of Sam's 10 upcoming music gigs, built as a D3 + React scatter plot explorer. The app loads data/gigs.csv at runtime and lets you re-map the X axis, Y axis, and color encoding to compare engagements across time, pay, band size, and planning status.
Dataset
data/gigs.csv contains 10 gigs with the following fields:
| Field | Type | Notes |
|---|---|---|
Name |
text | Gig / event name |
Date & Time Start |
ISO datetime | Some entries are date-only (interpreted as UTC midnight) |
Date & Time End |
ISO datetime | Blank for some gigs |
Load In |
ISO datetime | Blank for some gigs |
Place |
text | Venue or city label |
Address |
text | Full postal address |
Band Size |
number | 2, 4, or 5 |
Total Pay |
number (USD) | Blank / missing for several gigs |
Planning |
text | Complete or In progress |
Notion URL |
URL | Link to the Notion page for the gig |
Derived measures
- Gig Duration (min) β
End β Start, computed where both are present. - Days From First Gig β days between a gig's start and the earliest start date in the dataset.
Current Visualization
GigsScatterPlotExplorer.jsx renders an interactive scatter plot with:
- X axis / Y axis menus β switch between Start Date, End Date, Load In, Total Pay, Band Size, Gig Duration, and Days From First Gig.
- Color menu β encode by Planning status, Band Size, or Place.
- Color legend β hovering a legend swatch fades non-matching marks.
- Voronoi tooltips β hover anywhere in the plot to see the nearest gig's details. Press
Vto toggle the Voronoi cell outlines for debugging. - Staggered entry transitions β circles animate in, and axes transition on re-encoding.
Rows with a missing X or Y value are dropped so nothing lands at the origin.
Observations
- Total Pay is present for only 5 of 10 gigs, so pay-based views show a subset of the data.
- Planning is heavily skewed toward
In progress, which makes it a useful but low-cardinality color encoding. - End times and Load In times are frequently blank, so duration and lead-time views are naturally sparse.
Visualization Ideas
Timeline of Gigs (Gantt-style bars)
- Main question: How do the 10 gigs lay out across the calendar, and where do they overlap or cluster?
- Relevant fields:
Name,Date & Time Start,Date & Time End,Planning. - Encoding: Horizontal bars positioned on a time X axis, one row per gig, bar length = duration (or a fixed 1-day height when End is missing); color by
Planning. - Interaction: Hover a bar to see name, place, and pay; brush a date range to filter other views.
- Implementation: Use
d3.scaleTimefor X,d3.scaleBandfor Y over gig names, draw<rect>marks; a brush overlay recomputes a filtered dataset to pass down.
Load-In Lead Time vs. Gig Duration
- Main question: Do gigs with earlier load-ins tend to be longer shows?
- Relevant fields:
Load In,Date & Time Start,Date & Time End,Name,Place. - Encoding: Scatter plot with X = days between Load In and Start, Y = duration in minutes, color =
Planning. - Interaction: Voronoi tooltip showing load-in date, start, end, and computed lead time; click to open the Notion URL.
- Implementation: Derive
leadDays = (start β loadIn) / MS_PER_DAY, reuse the existingMarks/VoronoiOverlaycomponents with a new derived column added to thecolumnsarray.
Band Size Composition by Planning Status
- Main question: Are larger bands more or less likely to still be
In progress? - Relevant fields:
Band Size,Planning,Name. - Encoding: Stacked bar chart, X = band size (2 / 4 / 5), stacked segments = planning status counts.
- Interaction: Hover a segment to highlight the corresponding gigs and list their names in a side panel.
- Implementation:
d3.rollupcounts by(bandSize, planning), thend3.stack; render rects with a shared ordinal color scale.
- Main question: Are larger bands more or less likely to still be
Total Pay Distribution Stripplot by Place
- Main question: Which places pay more, and how much missing pay data is there?
- Relevant fields:
Place,Total Pay,Name. - Encoding: 1-D stripplot per place along a shared pay axis; present gigs as dots, missing-pay gigs as hollow rings at zero-height jitter.
- Interaction: Hover a dot to see the gig name; a toggle overlays the missing-pay markers as a separate row.
- Implementation: Group by
Place, jitter Y for overlapping pay values, used3.scalePointfor the place axis.
Planning Status Donut with Linked Highlight
- Main question: What fraction of gigs are
CompletevsIn progressvsUnknown? - Relevant fields:
Planning,Name. - Encoding: Donut / arc chart with slice size = count, colored consistently with the scatter legend.
- Interaction: Click a slice to filter the scatter plot and highlight matching circles; a hover tooltip lists the gigs in that slice.
- Implementation:
d3.pie()+d3.arc(), expose a sharedselectedPlanningstate that the scatter marks read.
- Main question: What fraction of gigs are
Calendar Heatmap of Gigs by Weekday and Week
- Main question: Which days of the week does Sam actually gig on?
- Relevant fields:
Date & Time Start,Name,Place. - Encoding: Weekday rows Γ ISO-week columns, cell shade = number of gigs that day, small dot annotations for gig names.
- Interaction: Click a cell to route the scatter plot to that gig's tooltip state.
- Implementation:
d3.timeWeek+d3.timeDaybucketing,scaleSequentialfor the count; text nodes for overlapping-gig counts.
Small-Multiple Scatter Grid by Place
- Main question: How does the Start-vs-Pay relationship differ across places?
- Relevant fields:
Date & Time Start,Total Pay,Place,Band Size. - Encoding: A faceted grid of mini scatter plots, one panel per distinct
Place, X = start date, Y = total pay, color = band size. - Interaction: Hover a point to highlight the same gig across all panels; a shared legend supports cross-panel comparison.
- Implementation:
d3.rollupto group rows byPlace, then render N small<svg>panels sharing scale domains.
Parallel Coordinates for All Numeric/Ordinal Fields
- Main question: What combinations of band size, pay, duration, and lead time characterize each gig?
- Relevant fields:
Band Size,Total Pay,durationMin(derived), lead-time days,Planning. - Encoding: Parallel coordinates with 4β5 vertical axes (Band Size, Total Pay, Duration, Lead Time), each gig as a polyline colored by
Planning. - Interaction: Hover a line to raise it and show a tooltip with the gig name and all axis values; brush an axis range to filter.
- Implementation:
d3.scaleLinearper axis, draw<path>per row, add axis brushes that filter the shared row set.
Notion Coverage / Data Completeness Bars
- Main question: For each gig, which fields are populated and which are missing?
- Relevant fields: All fields β
Date & Time Start,Date & Time End,Load In,Total Pay,Notion URL,Address, etc. - Encoding: Horizontal bars per gig, segmented into "present" / "missing" ticks per field; missing ticks rendered as hollow outlines.
- Interaction: Hover a missing tick to show what value is expected and link to the Notion page for filling it in.
- Implementation: Build a matrix of booleans from the parsed rows, render rects in a fixed column order.
Duration Ranking Bar Chart (Tornado / Diverging)
- Main question: Which gigs are the longest and shortest, and does planning status correlate with length?
- Relevant fields:
Name, deriveddurationMin,Planning. - Encoding: Sortable horizontal bar chart, bar length = duration, color = planning status; gigs missing End date shown as a distinct "unknown" bar.
- Interaction: Re-sort buttons (by duration, by planning, by date); hovering a bar syncs a highlight on the scatter plot.
- Implementation:
d3.scaleLinearon duration,scaleBandon name; animate bar width changes withd3-transition.
Gig Density Over Time (Cumulative Step + Event Rug)
- Main question: How does the gig count accumulate from first to last gig, and where are the gaps?
- Relevant fields:
Date & Time Start,Name. - Encoding: Step area of cumulative gig count over time, with a rug of date ticks at the bottom marking each gig's start.
- Interaction: Hover the step line to read the running count at that date; hovering a rug tick shows the gig name.
- Implementation: Sort starts, use
d3.binor a simple running sum, render a<path>for the step area and tick marks at the bottom.
Pay vs. Band Size Bubble Chart (Bubble = Duration)
- Main question: Does paying more scale with band size and/or show length?
- Relevant fields:
Total Pay,Band Size, deriveddurationMin,Name,Place. - Encoding: Scatter with X = band size, Y = total pay, bubble radius = duration; color = planning status.
- Interaction: Hover a bubble to enlarge it and show a tooltip with all values; click to pin the bubble and open the Notion URL.
- Implementation:
d3.scaleSqrtfor radius, reuse Voronoi for the tooltip hit-region, add a click handler towindow.open(notionUrl).
Load-In Schedule Timeline (Lead-In Lanes)
- Main question: When are the load-ins relative to the shows, and how much setup buffer is happening?
- Relevant fields:
Load In,Date & Time Start,Name,Place. - Encoding: Two-row timeline per gig β top lane is the load-in moment, bottom lane is the show; connecting line shows lead time.
- Interaction: Hover the connecting line to show the lead-time number in days/hours; click a lane to scroll the scatter plot to that gig.
- Implementation:
scaleTimeX axis, one<g>per gig with two circles + a<line>; animate line length on transition.
Place-Pay Dumbbell / Lollipop Chart
- Main question: For gigs with known pay, how does pay vary within the same place?
- Relevant fields:
Place,Total Pay,Name,Band Size. - Encoding: Sortable lollipop chart per place, dot = pay amount, connecting line to a place baseline; color = band size.
- Interaction: Sort by place, pay, or date; hovering a dot fades all other places' dots.
- Implementation:
scaleBandon place,scaleLinearon pay; use the same fade logic as the scatter'shoveredColor.
Gig "Card Deck" Small-Figure Grid
- Main question: What is the at-a-glance state of each gig?
- Relevant fields:
Name,Place,Date & Time Start,Band Size,Total Pay,Planning,Notion URL. - Encoding: A grid of 10 small cards, each with a mini sparkline of the gig's date range, key numbers, and a planning badge.
- Interaction: Hover a card to highlight its mark on the scatter plot; click to open the Notion URL.
- Implementation: Absolutely-positioned HTML grid overlaid on the SVG area (or a sibling panel); drive hover state from the same
hoveredIndexused by the scatter.
Gig Overlap Detection (Concentric Interval Lanes)
- Main question: Do any two gigs overlap in time or load-in, and does that create a travel/setup conflict?
- Relevant fields:
Name,Date & Time Start,Date & Time End,Load In,Place,Address. - Encoding: Overlapping-interval layout where each gig is a horizontal bar; overlapping bars drop to a second lane; connectors flag "too close" pairs.
- Interaction: Hover a connector to show both gig names, lead time between them, and driving distance note (manually entered or left as
β); click to filter to that pair. - Implementation: Custom lane-assignment algorithm over sorted start times; connectors as
<path>curves between bars.
Monthly Gig Volume + Planning Stack
- Main question: How is gig workload distributed by month, and how much of each month is still unplanned?
- Relevant fields:
Date & Time Start,Planning. - Encoding: Stacked column chart, X = month (SepβDec 2026), stacked segments = planning status, with a line overlay for cumulative planned %.
- Interaction: Hover a column to show the exact gigs in that month and jump the scatter plot to that date window.
- Implementation:
d3.rollupby month + planning,d3.stack,d3.timeMonthticks.
Pay Per Hour by Gig (Bar with Missing-Data Callout)
- Main question: Which gigs pay the best per hour of time on stage?
- Relevant fields:
Total Pay, deriveddurationMin,Name,Place. - Encoding: Horizontal bars of $ per hour, sorted descending; gigs missing pay or duration are shown in a red "unknown" panel below.
- Interaction: Hover a bar to show total pay, duration, and rate; click to open the gig's Notion URL.
- Implementation: Derive
payPerHour = totalPay / (durationMin / 60), partition rows into "known" and "unknown" sets, render both groups.
Geographic Sketch of Gig Locations (Approximate by Address Text)
- Main question: Are Sam's gigs clustering on the West Coast early and the East Coast late?
- Relevant fields:
Address,Place,Date & Time Start,Name. - Encoding: Simplified map-like layout with region groupings (WA, NH, ME) as columns, gigs as dots jittered vertically, x = region band; color by month.
- Interaction: Hover a dot to show gig name and date; a region header click filters the scatter plot to that region's gigs.
- Implementation: Parse region codes from the
Addressstring (last but one comma-separated chunk), usescaleBandfor regions; no basemap needed, just labeled lanes.
Notion-Gap Tracker (Field Γ Gig Missing-Value Heatmap)
- Main question: Which gig has the most missing information, and which field is missing most often?
- Relevant fields: Every field β
Total Pay,Load In,Date & Time End,Notion URL, etc. - Encoding: Heatmap with gigs as rows and fields as columns; cells shaded by missingness (present = light, missing = dark), with count of missing fields as a right-hand summary bar.
- Interaction: Click a cell to open the Notion page for that gig; hover a row to highlight its mark on the scatter plot.
- Implementation: Build a boolean matrix from parsed rows,
scaleSequentialfor shading, click handler opensnotionUrl.