playoff visual fixes
This commit is contained in:
@@ -1,76 +1,18 @@
|
||||
package seasonsview
|
||||
|
||||
import "git.haelnorr.com/h/oslstats/internal/db"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
// groupSeriesByRound groups playoff series by their round field
|
||||
func groupSeriesByRound(series []*db.PlayoffSeries) map[string][]*db.PlayoffSeries {
|
||||
grouped := make(map[string][]*db.PlayoffSeries)
|
||||
"git.haelnorr.com/h/oslstats/internal/db"
|
||||
)
|
||||
|
||||
// seriesByNumber returns a map of series_number -> *PlayoffSeries for quick lookup
|
||||
func seriesByNumber(series []*db.PlayoffSeries) map[int]*db.PlayoffSeries {
|
||||
m := make(map[int]*db.PlayoffSeries, len(series))
|
||||
for _, s := range series {
|
||||
grouped[s.Round] = append(grouped[s.Round], s)
|
||||
}
|
||||
return grouped
|
||||
}
|
||||
|
||||
// getRoundOrder returns the display order of rounds for a given format
|
||||
func getRoundOrder(format db.PlayoffFormat) []string {
|
||||
switch format {
|
||||
case db.PlayoffFormat5to6:
|
||||
return []string{
|
||||
"upper_bracket",
|
||||
"lower_bracket",
|
||||
"upper_final",
|
||||
"lower_final",
|
||||
"grand_final",
|
||||
}
|
||||
case db.PlayoffFormat7to9:
|
||||
return []string{
|
||||
"quarter_final",
|
||||
"semi_final",
|
||||
"third_place",
|
||||
"grand_final",
|
||||
}
|
||||
case db.PlayoffFormat10to15:
|
||||
return []string{
|
||||
"qualifying_final",
|
||||
"elimination_final",
|
||||
"semi_final",
|
||||
"preliminary_final",
|
||||
"third_place",
|
||||
"grand_final",
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// formatRoundName converts a round slug to a human-readable name
|
||||
func formatRoundName(round string) string {
|
||||
switch round {
|
||||
case "upper_bracket":
|
||||
return "Upper Bracket"
|
||||
case "lower_bracket":
|
||||
return "Lower Bracket"
|
||||
case "upper_final":
|
||||
return "Upper Final"
|
||||
case "lower_final":
|
||||
return "Lower Final"
|
||||
case "quarter_final":
|
||||
return "Quarter Finals"
|
||||
case "semi_final":
|
||||
return "Semi Finals"
|
||||
case "qualifying_final":
|
||||
return "Qualifying Finals"
|
||||
case "elimination_final":
|
||||
return "Elimination Finals"
|
||||
case "preliminary_final":
|
||||
return "Preliminary Finals"
|
||||
case "third_place":
|
||||
return "Third Place Playoff"
|
||||
case "grand_final":
|
||||
return "Grand Final"
|
||||
default:
|
||||
return round
|
||||
m[s.SeriesNumber] = s
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// formatLabel returns a human-readable format description
|
||||
@@ -86,3 +28,59 @@ func formatLabel(format db.PlayoffFormat) string {
|
||||
return string(format)
|
||||
}
|
||||
}
|
||||
|
||||
// bracketConnection represents a line to draw between two series cards
|
||||
type bracketConnection struct {
|
||||
From int `json:"from"`
|
||||
To int `json:"to"`
|
||||
Type string `json:"type"` // "winner" or "loser"
|
||||
ToSide string `json:"toSide,omitempty"` // "left" or "right" — enters side of dest card
|
||||
}
|
||||
|
||||
// connectionsJSON returns a JSON string of connections for the bracket overlay JS.
|
||||
// Connections are derived from the series advancement links stored in the DB.
|
||||
// For the 10-15 format, QF winner lines enter PF cards from the side.
|
||||
func connectionsJSON(series []*db.PlayoffSeries) string {
|
||||
// Build a lookup of series ID → series for resolving advancement targets
|
||||
byID := make(map[int]*db.PlayoffSeries, len(series))
|
||||
for _, s := range series {
|
||||
byID[s.ID] = s
|
||||
}
|
||||
|
||||
var conns []bracketConnection
|
||||
for _, s := range series {
|
||||
if s.WinnerNextID != nil {
|
||||
if target, ok := byID[*s.WinnerNextID]; ok {
|
||||
conn := bracketConnection{
|
||||
From: s.SeriesNumber,
|
||||
To: target.SeriesNumber,
|
||||
Type: "winner",
|
||||
}
|
||||
// QF winners enter PF cards from the side in the 10-15 format
|
||||
if s.Round == "qualifying_final" && target.Round == "preliminary_final" {
|
||||
if s.SeriesNumber == 1 {
|
||||
conn.ToSide = "left"
|
||||
} else if s.SeriesNumber == 2 {
|
||||
conn.ToSide = "right"
|
||||
}
|
||||
}
|
||||
conns = append(conns, conn)
|
||||
}
|
||||
}
|
||||
if s.LoserNextID != nil {
|
||||
if target, ok := byID[*s.LoserNextID]; ok {
|
||||
conns = append(conns, bracketConnection{
|
||||
From: s.SeriesNumber,
|
||||
To: target.SeriesNumber,
|
||||
Type: "loser",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b, err := json.Marshal(conns)
|
||||
if err != nil {
|
||||
return "[]"
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user