Files
ghstats/docs/design-guidelines.md
T
tiennm99 0310b7a2d9 docs: refresh for context plumbing, rate-limit handling, phase 6
- Fetcher signatures across codebase-summary and system-architecture
  now show the ctx-first arguments and document the rate-limit retry
  loop in Client.query.
- Attribution pseudo-code hoists the per-repo total out of the commit
  loop to match the current implementation (I6).
- Failure-modes table enumerates primary rate-limit retry, per-year
  nil-user warn, and -timeout / Ctrl-C cancellation.
- design-guidelines notes the single-slice donut special case.
- deployment-guide's release section documents the new test gate and
  the SHA-pinned Docker/GHA actions; troubleshooting adds the
  rate-limit-reset-too-long error. Rate-limit section describes the
  sleep-and-retry policy and -timeout flag.
- project-roadmap records Phase 6 (code-review remediation) as done,
  renumbers later planned phases, links the new review report.
2026-04-18 22:55:32 +07:00

4.4 KiB
Raw Blame History

Design Guidelines

Visual conventions for ghstats SVG cards. All cards share a single frame shape so they stack cleanly in a README.

Card frame

Property Value
Width × Height 500 × 220
Corner radius 8 px
Stroke theme.Stroke at theme.StrokeOpacity
Fill theme.Background
Font family 'Segoe UI', Ubuntu, Sans-Serif
Title 18 px, weight 600, theme.Title, anchored at (25, 35)

Generated by header(width, height, bg, stroke, strokeOpacity, titleColor, title) in internal/card/svg.go.

Theme role mapping

Theme field Used for
Title Card title text
Text Primary content (values, names)
Background Card fill + stroke around donut slices to separate colors
Stroke + StrokeOpacity Card outline
Muted Axis lines, axis labels, icons, legend metadata
Accent Bars, area fills, stat values, fallback slice color

Cards MUST NOT hardcode colors outside these fields. If a new visual needs a shade, pick the closest existing field — don't extend the schema without a strong reason.

Row-based cards (profile, stats)

Single-column rows of icon + label or icon + label + value.

Metric Value
First row baseline (y) 70
Row spacing 24 px
Icon scale 14/16 = 0.875 from 16×16 Octicon viewBox
Icon color theme.Muted
Right-aligned value anchor (stats) x = 475, text-anchor="end"
Value font weight 600
Value color theme.Accent

Cap rows at what fits: 7 for profile, 7 for stats (commits row splits into lifetime + last-year).

Donut cards (language breakdowns)

Metric Value
Donut centre (380, 120)
Outer radius 70
Inner radius 38
Top-N entries shown 6 (overflow collapses into "Other")
Slice stroke theme.Background, 1.5 px (gap between slices)
Legend origin (30, 70)
Legend row height 22 px
Swatch size 12 × 12

Language colors come from linguist via GraphQL (repo.languages.edges[].node.color). Missing colors fall back to theme.Accent.

When there's exactly one slice (one language at 100%), the renderer emits two concentric <circle> elements instead of a pie arc, because SVG's A command from point P back to the same P draws nothing. Regression guarded by TestDonutSingleSlice.

Bar-chart cards (productive time)

Metric Value
Chart area x ∈ [50, 475], y ∈ [60, 170] (110 tall)
Bars 24 bars, 2 px gap
Bar fill theme.Accent
Y-axis ticks niceTicks(max, 5) — 1/2/5 × 10^k ladder
X-axis labels Hours 0, 6, 12, 18, 23
Axis caption "hour of day" bottom-center
Title format Commits by Hour (<window>, UTC±N.NN)
Hover <title>HH:00 — N commits</title> inside each bar

Area-chart cards (contributions)

Metric Value
Chart area x ∈ [35, 465], y ∈ [60, 180] (120 tall)
Curve Catmull-Rom → cubic Bezier (tension 0.5)
Fill theme.Accent at 25% opacity
Stroke theme.Accent, 2 px
Y-axis Both sides, mirrored, same tick values
X-axis labels mm/yy, stride-thinned to ~6 labels regardless of bucket count
Axis caption "mm/yy" bottom-center
First/last labels Always printed (pinned endpoints)

Missing months in the [first, last] range are inserted as zero-count rows to keep the curve time-continuous.

Icons

  • Sourced from Primer Octicons 16×16 set.
  • Stored as raw <path d="…"/> strings in internal/card/icons.go.
  • Rendered inside <g transform="translate(x,y) scale(0.875)" fill="muted">…</g>.
  • Used: iconRepos, iconCompany, iconLocation, iconClock, iconLink, iconPeople, iconStar, iconCommit, iconPR, iconIssue, iconReview.

Add new icons by copying the <path> from Octicons and appending to icons.go. Keep them to the same 16×16 viewBox so the existing scale math applies.

Accessibility

  • Contrast is the theme author's responsibility — we don't validate at runtime.
  • Tooltips (<title>) on productive-time bars let screen readers announce counts.
  • No motion, no <animate> elements — profile READMEs render statically.

Text overflow

  • Long strings (bio, repo names) are not truncated; they're XML-escaped and printed as-is.
  • If a card looks crowded at 500 px width, that's a card design problem — fix the layout, not the data.