Skip to content

fix: render share-card chart for single-bucket origins#1026

Closed
onchainlu wants to merge 1 commit into
mainfrom
fix-share-volume-chart
Closed

fix: render share-card chart for single-bucket origins#1026
onchainlu wants to merge 1 commit into
mainfrom
fix-share-volume-chart

Conversation

@onchainlu

Copy link
Copy Markdown
Contributor

Problem

On the origin Share this page modal, the chart area renders labels but no line — for every metric (Volume, Buyers, Transactions). Reported on the ClaudeLines origin (3 txns, $0.45, 3 buyers).

Root cause

The modal's AreaChart (a hand-rolled SVG in screenshot-card.tsx) bails out with if (data.length < 2) return null. The card itself renders whenever dataReady = stats && chartData.length > 0 — so with a single data point (1 > 0 true), the card shows stats/labels but AreaChart draws nothing.

A single point is the norm for new/low-activity origins: the share modal queries stats.bucketed at the AllTime timeframe, which reads recipient_stats_bucketed_0d — a materialized view bucketed at 1-day granularity with no gap-fill. Verified against prod: ClaudeLines' recipient has exactly one row in that MV:

bucket                 txns   amount(6dp)  buyers
2026-07-12 00:00:00     3     450000        3

Secondary issue: the y-axis floor Math.max(...data, 1) was written for integer counts. For fractional volume (dollars, often < 1) it squished the line to the bottom edge, so even with ≥2 buckets the volume line looked absent.

Fix

screenshot-card.tsx AreaChart:

  • Bail only on data.length === 0. For a single point, duplicate it so the path spans the full width and renders a flat line instead of nothing.
  • Scale the y-axis to the data's real peak (Math.max(...series) || 1) so fractional volume values aren't pinned to the bottom.

Scope is intentionally the one component that had the bug. Every other chart in the app uses the shared recharts components (no length < 2 guard), so they already render single-bucket origins fine — confirmed, not affected.

Out of scope

Server-side gap-fill / honoring numBuckets in getBucketedStatisticsMV. It's shared by ~15 chart surfaces (broad blast radius) and — because the AllTime MV is 1-day granularity — wouldn't improve a 2-day-old origin like ClaudeLines beyond the flat line here. Tracked as a separate consideration (finer AllTime bucket resolution is the real lever, an MV redesign).

Verification

  • pnpm exec eslint <file> --max-warnings 0 → clean
  • pnpm exec prettier --check <file> → clean
  • tsc --noEmit → no new errors in the changed file (pre-existing repo errors are unrelated missing generated-DB module decls in a fresh worktree)
  • Data layer verified via psql against the transfers DB: ClaudeLines' AllTime MV returns exactly 1 bucket row, reproducing chartData.length === 1

Not exercised: live browser render of the modal (needs the running app against prod data); the fix is a pure client-render change validated statically + at the data layer.

A brand-new / low-activity origin (e.g. ClaudeLines: 3 txns, $0.45, 3 buyers)
has all its activity in one materialized bucket, so the bucketed stats query
returns a single data point. The share card rendered (dataReady checks
length > 0) but AreaChart bailed on length < 2, so every metric — volume,
buyers, transactions — showed labels with no line.

- AreaChart: draw a flat line for a single point instead of returning null
- Scale the y-axis to the data's real peak (Math.max(...) || 1) so fractional
  volume values no longer get squished to the bottom edge

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
x402scan Ready Ready Preview, Comment Jul 13, 2026 4:47pm

Request Review

@onchainlu onchainlu closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant