Using go-chart to generate a graph based on the PRO Prisundersökning data converted using https://gist.github.com/peterhellberg/ceed862a83c29a80b5bbd4631c24fb27
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"os" | |
"strings" | |
_ "embed" | |
"github.com/wcharczuk/go-chart/v2" | |
"github.com/wcharczuk/go-chart/v2/drawing" | |
) | |
var ( | |
orange = drawing.ColorFromHex("FF6600") | |
blue = drawing.ColorFromHex("0099FF") | |
gray = drawing.ColorFromHex("363636") | |
) | |
func main() { | |
var butiker []butik | |
if err := json.Unmarshal(data, &butiker); err != nil { | |
panic(err) | |
} | |
totals := make([]float64, len(butiker)) | |
var combinedTotal float64 | |
for i, butik := range butiker { | |
totals[i] = butik.Total | |
combinedTotal += butik.Total | |
} | |
averageTotal := combinedTotal / float64(len(totals)) | |
zero := chart.GridLine{ | |
Value: averageTotal, | |
Style: chart.Style{ | |
StrokeWidth: 15, | |
StrokeColor: orange.WithAlpha(30), | |
StrokeDashArray: []float64{20, 20}, | |
}, | |
} | |
S, N := 0, 36 | |
for n := S; n < N; n++ { | |
var varorNamn string | |
priser := make([]float64, len(butiker)) | |
for i, butik := range butiker { | |
priser[i] = butik.Varor[n].Pris | |
varorNamn = butik.Varor[n].Namn | |
} | |
mainSeries := chart.ContinuousSeries{ | |
YAxis: chart.YAxisSecondary, | |
Style: chart.Style{ | |
StrokeColor: orange.WithAlpha(80), | |
StrokeWidth: 32, | |
DotColor: orange, | |
DotWidth: 6, | |
}, | |
XValues: chart.LinearRange(1, float64(len(totals))), | |
YValues: chart.ValueSequence(totals...).Values(), | |
} | |
priserSeries := chart.ContinuousSeries{ | |
Style: chart.Style{ | |
StrokeColor: blue.WithAlpha(100), | |
StrokeWidth: 3, | |
DotColor: blue.WithAlpha(130), | |
DotWidth: 9, | |
}, | |
XValues: chart.LinearRange(1, float64(len(totals))), | |
YValues: chart.ValueSequence(priser...).Values(), | |
} | |
graph := chart.Chart{ | |
Title: "Hela matkassens pris jämfört med " + varorNamn, | |
TitleStyle: chart.Style{ | |
FontSize: 20, | |
FontColor: gray, | |
}, | |
DPI: 216, | |
Width: 3072, | |
Height: 1536, | |
XAxis: chart.XAxis{ | |
Style: chart.Style{ | |
Hidden: true, | |
}, | |
}, | |
YAxisSecondary: chart.YAxis{ | |
Zero: zero, | |
Name: "Hela matkassen", | |
NameStyle: chart.Style{ | |
FontSize: -16, | |
FontColor: orange, | |
}, | |
Style: chart.Style{ | |
FontSize: 14, | |
StrokeWidth: 4, | |
StrokeColor: orange, | |
FontColor: orange, | |
}, | |
ValueFormatter: krFormatter, | |
}, | |
YAxis: chart.YAxis{ | |
Name: varorNamn, | |
NameStyle: chart.Style{ | |
FontSize: 16, | |
FontColor: blue, | |
}, | |
Style: chart.Style{ | |
FontSize: 14, | |
StrokeWidth: 4, | |
StrokeColor: blue, | |
FontColor: blue, | |
}, | |
ValueFormatter: krFormatter, | |
}, | |
Background: chart.Style{ | |
Padding: chart.NewBox(80, 60, 20, 20), | |
}, | |
Series: []chart.Series{ | |
priserSeries, | |
mainSeries, | |
}, | |
} | |
fn := strings.ToLower( | |
fmt.Sprintf("pro-prisundersokning-total-vs-%s.png", | |
strings.ReplaceAll(varorNamn, " ", "-"), | |
), | |
) | |
f, err := os.Create(fn) | |
if err != nil { | |
panic(err) | |
} | |
defer f.Close() | |
if err := graph.Render(chart.PNG, f); err != nil { | |
panic(err) | |
} | |
} | |
} | |
func krFormatter(v interface{}) string { | |
return chart.FloatValueFormatterWithFormat(v, " %.0f kr") | |
} | |
//go:embed data.json | |
var data []byte | |
type butik struct { | |
Butiksnamn string `json:"butiksnamn"` | |
Distrikt string `json:"distrikt"` | |
Typ string `json:"typ"` | |
AntalVaror int `json:"antal_varor"` | |
Total float64 `json:"total"` | |
Varor []vara `json:"varor"` | |
} | |
type vara struct { | |
Namn string `json:"namn"` | |
Pris float64 `json:"pris"` | |
} |
Author
peterhellberg
commented
Sep 29, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment