func execute()

in hack/benchmark/cpu_usage/auto_pause/chart.go [55:238]


func execute() error {
	// sessionID is generated and used at cpu usage benchmark
	if len(os.Args) <= 1 || len(os.Args[1]) == 0 {
		return errors.New("Please identify sessionID")
	}
	sessionID := os.Args[1]

	// Create plot instance
	p := plot.New()

	// Set view options
	if runtime.GOOS == "darwin" {
		p.Title.Text = "CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause (less is better)"
	} else if runtime.GOOS == "linux" {
		p.Title.Text = "CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause (less is better)"
	}
	p.Y.Label.Text = "CPU overhead%"

	// Open non-autopause csv file of benchmark summary
	napResults := []float64{}
	napFn := "./out/benchmark-results/" + sessionID + "/cstat.nonautopause.summary"
	napFile, err := os.Open(napFn)
	if err != nil {
		return errors.Wrap(err, "Missing summary csv")
	}
	defer napFile.Close()

	// Read result values from benchmark summary csv
	napReader := csv.NewReader(napFile)
	var napLine []string
	for {
		napLine, err = napReader.Read()
		if err != nil {
			break
		}

		s, err := strconv.ParseFloat(napLine[0], 64)
		if err != nil {
			return errors.Wrap(err, "Failed to convert to float64")
		}
		napResults = append(napResults, s)
	}

	// Open auto-pause csv file of benchmark summary
	apResults := []float64{}
	apFn := "./out/benchmark-results/" + sessionID + "/cstat.autopause.summary"
	apFile, err := os.Open(apFn)
	if err != nil {
		return errors.Wrap(err, "Missing summary csv")
	}
	defer apFile.Close()

	// Read result values from benchmark summary csv
	apReader := csv.NewReader(apFile)
	var apLine []string
	for {
		apLine, err = apReader.Read()
		if err != nil {
			break
		}

		s, err := strconv.ParseFloat(apLine[0], 64)
		if err != nil {
			return errors.Wrap(err, "Failed to convert to float64")
		}
		apResults = append(apResults, s)
	}

	// Set bar graph width
	breadth := vg.Points(40)

	// Create Bar instance with non-autopause benchmark results
	barNAP, err := plotter.NewBarChart(plotter.Values(napResults), breadth)
	if err != nil {
		return errors.Wrap(err, "Failed to create bar chart")
	}

	// Set border of the bar graph. 0 is no border color
	barNAP.LineStyle.Width = vg.Length(0)
	// Add bar name
	p.Legend.Add("Initial Start CPU usage Before Pause", barNAP)
	// Set bar color to gray.
	barNAP.Color = color.RGBA{184, 184, 184, 255}

	// Create Bar instance with auto-pause benchmark results
	barAP, err := plotter.NewBarChart(plotter.Values(apResults), breadth)
	if err != nil {
		return errors.Wrap(err, "Failed to create bar chart")
	}

	// Set border of the bar graph. 0 is no border color
	barAP.LineStyle.Width = vg.Length(0)
	// Add bar name
	p.Legend.Add("Auto Paused CPU usage", barAP)
	// Set bar color. 1 is green
	barAP.Color = plotutil.Color(1)

	hb := vg.Points(20)
	barNAP.Offset = -hb
	barAP.Offset = hb
	p.Add(barNAP, barAP)

	// Set legend position upper
	p.Legend.Top = true

	// Add x-lay names
	if runtime.GOOS == "darwin" {
		p.NominalX("OS idle", "minikube hyperkit", "minikube virtualbox", "minikube docker", "Docker for Mac Kubernetes", "k3d", "kind")
	} else if runtime.GOOS == "linux" {
		p.NominalX("OS idle", "minikube kvm2", "minikube virtualbox", "minikube docker", "Docker idle", "k3d", "kind")
	}

	// Set non-autopause data label to each bar
	var napLabels []string
	for i := range napResults {
		nLabel := strconv.FormatFloat(napResults[i], 'f', -1, 64)
		napLabels = append(napLabels, nLabel)
	}

	var napCPU []plotter.XY
	for i := range napResults {
		napXPos := float64(i) - 0.25
		napYPos := napResults[i] + 0.1
		napXY := plotter.XY{X: napXPos, Y: napYPos}
		napCPU = append(napCPU, napXY)
	}
	// CPU Busy% non-autopause data label
	napl, err := plotter.NewLabels(plotter.XYLabels{
		XYs:    napCPU,
		Labels: napLabels,
	},
	)
	if err != nil {
		return err
	}

	// Set auto-pause data label to each bar
	var apLabels []string
	for i := range apResults {
		if apResults[i] == 0 {
			apLabels = append(apLabels, "N/A")
		} else {
			apLabel := strconv.FormatFloat(apResults[i], 'f', -1, 64)
			apLabels = append(apLabels, apLabel)
		}
	}

	var apCPU []plotter.XY
	for i := range apResults {
		apXPos := float64(i) + 0.05
		apYPos := apResults[i] + 0.1
		apXY := plotter.XY{X: apXPos, Y: apYPos}
		apCPU = append(apCPU, apXY)
	}
	// CPU Busy% auto-pause data label
	apl, err := plotter.NewLabels(plotter.XYLabels{
		XYs:    apCPU,
		Labels: apLabels,
	},
	)
	if err != nil {
		return err
	}

	// define max cpu busy% to 20%
	p.Y.Max = 20
	p.Y.Tick.Marker = integerTicks{}
	// Add CPU Busy% label to plot
	p.Add(napl, apl)

	// Output bar graph
	if runtime.GOOS == "darwin" {
		if err := p.Save(13*vg.Inch, 8*vg.Inch, FOLDER+"/mac.png"); err != nil {
			return errors.Wrap(err, "Failed to create bar graph png")
		}
		log.Printf("Generated graph png to %s/mac.png", FOLDER)
	} else if runtime.GOOS == "linux" {
		if err := p.Save(13*vg.Inch, 10*vg.Inch, FOLDER+"/linux.png"); err != nil {
			return errors.Wrap(err, "Failed to create bar graph png")
		}
		log.Printf("Generated graph png to %s/linux.png", FOLDER)
	}
	return nil
}