• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark-pixel / 13727326526

07 Mar 2025 06:52PM CUT coverage: 28.089% (-19.3%) from 47.374%
13727326526

push

github

web-flow
Add first plot drawers (#8)

7 of 677 new or added lines in 11 files covered. (1.03%)

457 of 1627 relevant lines covered (28.09%)

55.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/plot/bars.go
1
package plot
2

3
import (
4
        "fmt"
5
        "image/color"
6

7
        pixel "github.com/gopxl/pixel/v2"
8
        "github.com/gopxl/pixel/v2/backends/opengl"
9
        "github.com/mlange-42/ark-tools/observer"
10
        "github.com/mlange-42/ark/ecs"
11
        "gonum.org/v1/plot"
12
        "gonum.org/v1/plot/plotter"
13
        "gonum.org/v1/plot/vg"
14
        "gonum.org/v1/plot/vg/draw"
15
        "gonum.org/v1/plot/vg/vgimg"
16
)
17

18
// Bars plot drawer.
19
//
20
// Creates a bar per column of the observer.
21
type Bars struct {
22
        Observer observer.Row // Observer providing a data series for bars.
23
        Columns  []string     // Columns to show, by name. Optional, default all.
24
        YLim     [2]float64   // Y axis limits. Optional, default auto.
25
        Labels   Labels       // Labels for plot and axes. Optional.
26

27
        indices []int
28
        headers []string
29
        series  plotter.Values
30
        scale   float64
31
}
32

33
// Initialize the drawer.
NEW
34
func (b *Bars) Initialize(w *ecs.World, win *opengl.Window) {
×
NEW
35
        b.Observer.Initialize(w)
×
NEW
36

×
NEW
37
        headers := b.Observer.Header()
×
NEW
38

×
NEW
39
        if len(b.Columns) == 0 {
×
NEW
40
                b.indices = make([]int, len(headers))
×
NEW
41
                for i := 0; i < len(b.indices); i++ {
×
NEW
42
                        b.indices[i] = i
×
NEW
43
                }
×
NEW
44
        } else {
×
NEW
45
                b.indices = make([]int, len(b.Columns))
×
NEW
46
                var ok bool
×
NEW
47
                for i := 0; i < len(b.indices); i++ {
×
NEW
48
                        b.indices[i], ok = find(headers, b.Columns[i])
×
NEW
49
                        if !ok {
×
NEW
50
                                panic(fmt.Sprintf("column '%s' not found", b.Columns[i]))
×
51
                        }
52
                }
53
        }
54

NEW
55
        b.series = make([]float64, len(b.indices))
×
NEW
56
        b.headers = make([]string, len(b.indices))
×
NEW
57
        for i, idx := range b.indices {
×
NEW
58
                b.headers[i] = headers[idx]
×
NEW
59
        }
×
60

NEW
61
        b.scale = calcScaleCorrection()
×
62

63
}
64

65
// Update the drawer.
NEW
66
func (b *Bars) Update(w *ecs.World) {
×
NEW
67
        b.Observer.Update(w)
×
NEW
68
}
×
69

70
// UpdateInputs handles input events of the previous frame update.
NEW
71
func (b *Bars) UpdateInputs(w *ecs.World, win *opengl.Window) {}
×
72

73
// Draw the drawer.
NEW
74
func (b *Bars) Draw(w *ecs.World, win *opengl.Window) {
×
NEW
75
        width := win.Canvas().Bounds().W()
×
NEW
76
        height := win.Canvas().Bounds().H()
×
NEW
77

×
NEW
78
        b.updateData(w)
×
NEW
79

×
NEW
80
        c := vgimg.New(vg.Points(width*b.scale)-10, vg.Points(height*b.scale)-10)
×
NEW
81

×
NEW
82
        p := plot.New()
×
NEW
83
        setLabels(p, b.Labels)
×
NEW
84

×
NEW
85
        if b.YLim[0] != 0 || b.YLim[1] != 0 {
×
NEW
86
                p.Y.Min = b.YLim[0]
×
NEW
87
                p.Y.Max = b.YLim[1]
×
NEW
88
        }
×
89

NEW
90
        bw := 0.5 * (width - 50) / float64(len(b.series))
×
NEW
91
        bars, err := plotter.NewBarChart(b.series, vg.Points(bw))
×
NEW
92
        if err != nil {
×
NEW
93
                panic(err)
×
94
        }
NEW
95
        bars.Color = defaultColors[0]
×
NEW
96
        p.Add(bars)
×
NEW
97
        p.NominalX(b.headers...)
×
NEW
98

×
NEW
99
        win.Clear(color.White)
×
NEW
100
        p.Draw(draw.New(c))
×
NEW
101

×
NEW
102
        img := c.Image()
×
NEW
103
        picture := pixel.PictureDataFromImage(img)
×
NEW
104

×
NEW
105
        sprite := pixel.NewSprite(picture, picture.Bounds())
×
NEW
106
        sprite.Draw(win, pixel.IM.Moved(pixel.V(picture.Rect.W()/2.0+5, picture.Rect.H()/2.0+5)))
×
107
}
108

NEW
109
func (b *Bars) updateData(w *ecs.World) {
×
NEW
110
        values := b.Observer.Values(w)
×
NEW
111

×
NEW
112
        for i, idx := range b.indices {
×
NEW
113
                b.series[i] = values[idx]
×
NEW
114
        }
×
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc