diff --git a/barchart.png b/barchart.png new file mode 100644 index 0000000..76376c8 Binary files /dev/null and b/barchart.png differ diff --git a/internal/export.go b/internal/export.go index d1cd3db..f1ae4a8 100644 --- a/internal/export.go +++ b/internal/export.go @@ -147,6 +147,7 @@ func Export(formats []string, filename string, results []*SpeedResult, timeUnit for _, format := range formats { switch format { case "json": + // todo make the json tags hyperfine output compatible jsonMap := map[string]any{"time_unit": timeUnit.String()[1:], "results": results} jsonData, err := jsonify(jsonMap) if err != nil { diff --git a/internal/plotter.go b/internal/plotter.go index 95d23de..0f4fca9 100644 --- a/internal/plotter.go +++ b/internal/plotter.go @@ -7,12 +7,14 @@ import ( "time" "gonum.org/v1/plot" + "gonum.org/v1/plot/font" "gonum.org/v1/plot/plotter" + "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" ) func VerifyPlotFormats(formats string) ([]string, error) { - validFormats := []string{"hist", "histogram", "box", "boxplot", "bar", "errorbar", "bubble"} + validFormats := []string{"hist", "histogram", "box", "boxplot", "bar", "errorbar"} formatList := strings.Split(strings.ToLower(formats), ",") for _, f := range formatList { if !slices.Contains(validFormats, f) { @@ -48,6 +50,41 @@ func histogram(results []*SpeedResult, timeUnit string) { } } -func Plot(plotFormats []string, results []*SpeedResult, timeUnit time.Duration) { +func barPlot(results []*SpeedResult, timeUnit string) { + p := plot.New() + p.Title.Text = "Bar Chart" + p.Y.Label.Text = fmt.Sprintf("Mean times (in %s)", timeUnit) + meanTimes := make(plotter.Values, len(results)) + copy(meanTimes, MapFunc[[]*SpeedResult, []float64](func(sr *SpeedResult) float64 { return sr.AverageElapsed }, results)) + + w := vg.Points(20) + bars, err := plotter.NewBarChart(meanTimes, w) + if err != nil { + panic(err) + } + bars.LineStyle.Width = vg.Length(0) + bars.Color = plotutil.Color(0) + + p.Add(bars) + + p.NominalX(MapFunc[[]*SpeedResult, []string](func(r *SpeedResult) string { return r.Command }, results)...) -} \ No newline at end of file + barWidth := max(3, len(results)) + if err := p.Save(font.Length(barWidth)*vg.Inch, 3*vg.Inch, "barchart.png"); err != nil { + panic(err) + } +} + +func Plot(plotFormats []string, results []*SpeedResult, timeUnit time.Duration) { + if slices.Contains(plotFormats, "all") { + plotFormats = []string{"histogram", "bar", "errorbar", "boxplot"} + } + for _, plotFormat := range plotFormats { + switch plotFormat { + case "hist", "histogram": + histogram(results, timeUnit.String()[1:]) + case "bar": + barPlot(results, timeUnit.String()[1:]) + } + } +}