Skip to main content

Overview

GitHub Star Tracker generates animated SVG charts that visualize your star history over time. Charts support both light and dark color schemes using CSS @media (prefers-color-scheme: dark) queries.

Chart Types

Star History Chart

Displays the total star count across all tracked repositories over time.
import { generateSvgChart } from '@presentation/svg-chart';

const svgChart = generateSvgChart({
  history: historyData,
  title: 'Star History',
  locale: 'en'
});
Features:
  • Smooth curved lines using cubic Bézier splines
  • Animated line drawing with staggered point appearance
  • Milestone markers at key star thresholds (1k, 5k, 10k, etc.)
  • Automatic axis scaling with nice step values

Per-Repository Chart

Visualize star growth for individual repositories.
import { generatePerRepoSvgChart } from '@presentation/svg-chart';

const repoChart = generatePerRepoSvgChart({
  history: historyData,
  repoFullName: 'owner/repo',
  title: 'owner/repo Star History',
  locale: 'en'
});

Comparison Chart

Compare star growth across multiple repositories.
import { generateComparisonSvgChart } from '@presentation/svg-chart';

const comparisonChart = generateComparisonSvgChart({
  history: historyData,
  repoNames: ['owner/repo1', 'owner/repo2', 'owner/repo3'],
  title: 'Repository Comparison',
  locale: 'en'
});
Features:
  • Up to 10 repositories per chart (see src/presentation/constants.ts:54)
  • Distinct colors for each repository (10 color palette)
  • Smart label shortening when all repos share the same owner
  • Interactive legend showing all tracked repositories

Forecast Chart

Visualize predicted star growth using multiple forecasting methods.
import { generateForecastSvgChart } from '@presentation/svg-chart';

const forecastChart = generateForecastSvgChart({
  history: historyData,
  forecastData: forecastResults,
  locale: 'en',
  title: 'Star Growth Forecast'
});
Features:
  • Historical data shown as solid line with fill
  • Forecast projections shown as dashed lines
  • Multiple forecast methods displayed simultaneously
  • Seamless connection from historical to predicted data

Chart Configuration

Charts are configured via constants in src/presentation/constants.ts:50:
export const CHART = {
  width: 800,
  height: 400,
  maxDataPoints: 30,
  maxComparison: 10,
} as const;

export const SVG_CHART = {
  margin: { top: 50, right: 30, bottom: 50, left: 60 },
  pointRadius: 4,
  lineWidth: 2.5,
  gridOpacity: 0.3,
  fontSize: { title: 16, label: 11, milestone: 10 },
  animation: { 
    lineDuration: 2, 
    pointDuration: 0.5, 
    pointStagger: 0.05, 
    pointDelay: 1.5 
  },
  font: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif",
} as const;

Dark Mode Support

All charts automatically adapt to the user’s color scheme preference:
@media (prefers-color-scheme: dark) {
  .chart-bg { fill: #0d1117; }
  .chart-text { fill: #e6edf3; }
  .chart-muted { fill: #8b949e; }
  .chart-grid { stroke: #21262d; }
  .chart-axis { stroke: #8b949e; }
}
See color palettes in src/presentation/constants.ts:3.

Animation

Charts feature smooth CSS animations (see src/presentation/svg-chart.ts:278):
  • Line drawing: 2-second animation using stroke-dasharray technique
  • Point fade-in: 0.5-second fade with 0.05s stagger between points
  • Point delay: 1.5s delay to start after line animation
Charts require at least 2 snapshots to generate. Check MIN_SNAPSHOTS_FOR_CHART in src/presentation/constants.ts:75.

Data Format

Charts expect history data in this format:
interface History {
  snapshots: Array<{
    timestamp: string;
    totalStars: number;
    repos: Array<{
      fullName: string;
      stars: number;
    }>;
  }>;
}

Best Practices

Data Points

Charts display up to 30 data points maximum to prevent overcrowding

Null Handling

Supports null values in data, creating gaps with multiple segments

Axis Scaling

Automatic nice axis steps using magnitude-based rounding algorithm

Performance

Smooth path generation uses tension of 0.4 for optimal curves

Build docs developers (and LLMs) love