mirror of
https://github.com/tiennm99/ghstats.git
synced 2026-05-20 18:24:19 +00:00
d0d3862780
New 5-contributions.svg renders the last year's contribution calendar as a monthly smooth-filled area chart. Pure Go SVG; no extra API calls — one additional contributionCalendar.weeks block in the existing profile GraphQL query carries the data. - Y-axis mirrored on both sides with nice ticks. - X-axis labels in YY/MM format, every other month to avoid overlap. - Smooth curve via Catmull-Rom interpolation converted to cubic Bezier (d3.curveCatmullRom default tension 0.5). - Missing months between first and last are inserted as zero-count so the chart stays time-continuous.
50 lines
1.3 KiB
Go
50 lines
1.3 KiB
Go
// Package card renders Profile data into SVG cards on disk.
|
|
package card
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/tiennm99/ghstats/internal/github"
|
|
"github.com/tiennm99/ghstats/internal/theme"
|
|
)
|
|
|
|
// Card renders one SVG for a Profile under the given theme.
|
|
type Card interface {
|
|
// Filename is the on-disk basename (e.g. "0-profile-details.svg").
|
|
Filename() string
|
|
// SVG returns the rendered SVG bytes.
|
|
SVG(p *github.Profile, t theme.Theme) ([]byte, error)
|
|
}
|
|
|
|
// allCards is the ordered list rendered by RenderAll.
|
|
// Keep filename prefixes numeric so the output directory lists in a predictable order.
|
|
var allCards = []Card{
|
|
profileCard{},
|
|
reposPerLanguageCard{},
|
|
mostCommitLanguageCard{},
|
|
statsCard{},
|
|
productiveCard{},
|
|
contributionsCard{},
|
|
}
|
|
|
|
// RenderAll writes every card into outDir/<themeID>/.
|
|
func RenderAll(p *github.Profile, t theme.Theme, outDir string) error {
|
|
dir := filepath.Join(outDir, t.ID)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("mkdir %s: %w", dir, err)
|
|
}
|
|
for _, c := range allCards {
|
|
data, err := c.SVG(p, t)
|
|
if err != nil {
|
|
return fmt.Errorf("render %s: %w", c.Filename(), err)
|
|
}
|
|
path := filepath.Join(dir, c.Filename())
|
|
if err := os.WriteFile(path, data, 0o644); err != nil {
|
|
return fmt.Errorf("write %s: %w", path, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|