• 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/contour.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/palette"
13
        "gonum.org/v1/plot/plotter"
14
        "gonum.org/v1/plot/vg"
15
        "gonum.org/v1/plot/vg/draw"
16
        "gonum.org/v1/plot/vg/vgimg"
17
)
18

19
// Contour plot drawer.
20
//
21
// Plots a grid as a contours.
22
// For large grids, this is relatively slow.
23
// Consider using [Image] instead.
24
type Contour struct {
25
        Observer   observer.Grid   // Observers providing a Grid for contours.
26
        Levels     []float64       // Levels for iso lines. Optional.
27
        Palette    palette.Palette // Color palette. Optional.
28
        Labels     Labels          // Labels for plot and axes. Optional.
29
        HideLegend bool            // Hides the legend.
30

31
        data  plotGrid
32
        scale float64
33
}
34

35
// Initialize the drawer.
NEW
36
func (c *Contour) Initialize(w *ecs.World, win *opengl.Window) {
×
NEW
37
        c.Observer.Initialize(w)
×
NEW
38
        c.data = plotGrid{
×
NEW
39
                Grid: c.Observer,
×
NEW
40
        }
×
NEW
41
        c.scale = calcScaleCorrection()
×
NEW
42
}
×
43

44
// Update the drawer.
NEW
45
func (c *Contour) Update(w *ecs.World) {
×
NEW
46
        c.Observer.Update(w)
×
NEW
47
}
×
48

49
// UpdateInputs handles input events of the previous frame update.
NEW
50
func (c *Contour) UpdateInputs(w *ecs.World, win *opengl.Window) {}
×
51

52
// Draw the drawer.
NEW
53
func (c *Contour) Draw(w *ecs.World, win *opengl.Window) {
×
NEW
54
        width := win.Canvas().Bounds().W()
×
NEW
55
        height := win.Canvas().Bounds().H()
×
NEW
56

×
NEW
57
        c.updateData(w)
×
NEW
58

×
NEW
59
        canvas := vgimg.New(vg.Points(width*c.scale)-10, vg.Points(height*c.scale)-10)
×
NEW
60

×
NEW
61
        p := plot.New()
×
NEW
62
        setLabels(p, c.Labels)
×
NEW
63

×
NEW
64
        p.X.Tick.Marker = removeLastTicks{}
×
NEW
65

×
NEW
66
        cols := c.Palette.Colors()
×
NEW
67
        min := 0.0
×
NEW
68
        max := 1.0
×
NEW
69
        if len(c.Levels) > 0 {
×
NEW
70
                min = c.Levels[0]
×
NEW
71
                max = c.Levels[len(c.Levels)-1]
×
NEW
72
        } else {
×
NEW
73
                c.Levels = []float64{0.01, 0.05, 0.25, 0.5, 0.75, 0.95, 0.99}
×
NEW
74
        }
×
75

NEW
76
        contours := plotter.Contour{
×
NEW
77
                GridXYZ:    &c.data,
×
NEW
78
                Levels:     c.Levels,
×
NEW
79
                LineStyles: []draw.LineStyle{plotter.DefaultLineStyle},
×
NEW
80
                Palette:    c.Palette,
×
NEW
81
                Underflow:  cols[0],
×
NEW
82
                Overflow:   cols[len(cols)-1],
×
NEW
83
                Min:        min,
×
NEW
84
                Max:        max,
×
NEW
85
        }
×
NEW
86

×
NEW
87
        if !c.HideLegend {
×
NEW
88
                p.Legend = plot.NewLegend()
×
NEW
89
                p.Legend.TextStyle.Font.Variant = "Mono"
×
NEW
90
                c.populateLegend(&p.Legend, &contours)
×
NEW
91
        }
×
92

NEW
93
        p.Add(&contours)
×
NEW
94

×
NEW
95
        win.Clear(color.White)
×
NEW
96
        p.Draw(draw.New(canvas))
×
NEW
97

×
NEW
98
        img := canvas.Image()
×
NEW
99
        picture := pixel.PictureDataFromImage(img)
×
NEW
100

×
NEW
101
        sprite := pixel.NewSprite(picture, picture.Bounds())
×
NEW
102
        sprite.Draw(win, pixel.IM.Moved(pixel.V(picture.Rect.W()/2.0+5, picture.Rect.H()/2.0+5)))
×
103
}
104

NEW
105
func (c *Contour) updateData(w *ecs.World) {
×
NEW
106
        c.data.Values = c.Observer.Values(w)
×
NEW
107
}
×
108

NEW
109
func (c *Contour) populateLegend(legend *plot.Legend, contours *plotter.Contour) {
×
NEW
110
        var pal []color.Color
×
NEW
111
        if c.Palette != nil {
×
NEW
112
                pal = c.Palette.Colors()
×
NEW
113
        }
×
NEW
114
        ps := float64(len(pal)-1) / (c.Levels[len(c.Levels)-1] - c.Levels[0])
×
NEW
115
        if len(c.Levels) == 1 {
×
NEW
116
                ps = 0
×
NEW
117
        }
×
NEW
118
        for i := len(c.Levels) - 1; i >= 0; i-- {
×
NEW
119
                z := c.Levels[i]
×
NEW
120
                var col color.Color
×
NEW
121
                switch {
×
NEW
122
                case z < contours.Min:
×
NEW
123
                        col = contours.Underflow
×
NEW
124
                case z > contours.Max:
×
NEW
125
                        col = contours.Overflow
×
NEW
126
                case len(pal) == 0:
×
NEW
127
                        col = contours.Underflow
×
NEW
128
                default:
×
NEW
129
                        col = pal[int((z-c.Levels[0])*ps+0.5)] // Apply palette scaling.
×
130
                }
NEW
131
                legend.Add(fmt.Sprintf("%f", z), colorThumbnailer{col})
×
132
        }
133
}
134

135
// colorThumbnailer implements the Thumbnailer interface.
136
type colorThumbnailer struct {
137
        color color.Color
138
}
139

140
// Thumbnail satisfies the plot.Thumbnailer interface.
NEW
141
func (t colorThumbnailer) Thumbnail(c *draw.Canvas) {
×
NEW
142
        pts := []vg.Point{
×
NEW
143
                {X: c.Min.X, Y: c.Min.Y},
×
NEW
144
                {X: c.Min.X, Y: c.Max.Y},
×
NEW
145
                {X: c.Max.X, Y: c.Max.Y},
×
NEW
146
                {X: c.Max.X, Y: c.Min.Y},
×
NEW
147
        }
×
NEW
148
        poly := c.ClipPolygonY(pts)
×
NEW
149
        c.FillPolygon(t.color, poly)
×
NEW
150
}
×
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