plot

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2024 License: MIT Imports: 27 Imported by: 1

Documentation

Overview

Package plot provides live plotting drawers for window.Window, using the gonum/plot package or direct OpenGL drawing.

For the window, see package github.com/mlange-42/arche-pixel/window.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMonitorWindow added in v0.0.3

func NewMonitorWindow(drawInterval int) *window.Window

NewMonitorWindow creates a window with Monitor drawer, for immediate use as a system. See Monitor for details.

Also adds Controls for pausing/resuming the simulation.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a Monitor drawer, using the shorthand constructor.
	m.AddUISystem(plot.NewMonitorWindow(10))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}
Output:

Types

type Bars added in v0.3.0

type Bars struct {
	Observer observer.Row // Observer providing a data series for bars.
	Columns  []string     // Columns to show, by name. Optional, default all.
	YLim     [2]float64   // Y axis limits. Optional, default auto.
	Labels   Labels       // Labels for plot and axes. Optional.
	// contains filtered or unexported fields
}

Bars plot drawer.

Creates a bar per column of the observer.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30

// Create a time series plot.
m.AddUISystem((&window.Window{}).
	With(&plot.Bars{
		Observer: &RowObserver{},
		YLim:     [...]float64{0, 4}, // Optional Y axis limits.
	}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

func (*Bars) Draw added in v0.3.0

func (b *Bars) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*Bars) Initialize added in v0.3.0

func (b *Bars) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*Bars) Update added in v0.3.0

func (b *Bars) Update(w *ecs.World)

Update the drawer.

func (*Bars) UpdateInputs added in v0.3.0

func (b *Bars) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Contour added in v0.3.0

type Contour struct {
	Observer   observer.Grid   // Observers providing a Grid for contours.
	Levels     []float64       // Levels for iso lines. Optional.
	Palette    palette.Palette // Color palette. Optional.
	Labels     Labels          // Labels for plot and axes. Optional.
	HideLegend bool            // Hides the legend.
	// contains filtered or unexported fields
}

Contour plot drawer.

Plots a grid as a contours. For large grids, this is relatively slow. Consider using Image instead.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30
m.FPS = 0

// Create a contour plot.
m.AddUISystem(
	(&window.Window{}).
		With(&plot.Contour{
			Observer: observer.MatrixToGrid(&MatrixObserver{}, nil, nil),
			Palette:  palette.Heat(16, 1),
			Levels:   []float64{-2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2},
		}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

func (*Contour) Draw added in v0.3.0

func (c *Contour) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*Contour) Initialize added in v0.3.0

func (c *Contour) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*Contour) Update added in v0.3.0

func (c *Contour) Update(w *ecs.World)

Update the drawer.

func (*Contour) UpdateInputs added in v0.3.0

func (c *Contour) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Controls added in v0.0.3

type Controls struct {
	Scale float64 // Spatial scaling: cell size in screen pixels. Optional, default 1.
	// contains filtered or unexported fields
}

Controls adds UI and keyboard input for controlling the simulation. UI controls are displayed in the bottom right corner of the window.

Pause and resume the simulation via a button or by pressing SPACE. Manipulate simulation speed (TPS) using buttons or UP/DOWN keys.

Expects a world resource of type Systems (github.com/mlange-42/arche-model/model.Systems).

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a Controls drawer.
	m.AddUISystem((&window.Window{}).
		With(&plot.Controls{Scale: 2}))

	// Controls is intended as an overlay, so more drawers can be added before it.
	m.AddUISystem((&window.Window{}).
		With(
			&plot.Monitor{},
			&plot.Controls{},
		))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}
Output:

func (*Controls) Draw added in v0.0.3

func (c *Controls) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Controls) Initialize added in v0.0.3

func (c *Controls) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Controls) Update added in v0.0.3

func (c *Controls) Update(w *ecs.World)

Update the drawer.

func (*Controls) UpdateInputs added in v0.0.3

func (c *Controls) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Field added in v0.3.0

type Field struct {
	Observer observer.GridLayers // Observers providing field component grids.
	Labels   Labels              // Labels for plot and axes. Optional.
	Layers   []int               // Layer indices. Optional, defaults to (0, 1).
	// contains filtered or unexported fields
}

Field plot drawer.

Plots a vector field from a GridLayers observer. For large grids, this is relatively slow. Consider using ImageRGB instead.

Example
package main

import (
	"math"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/observer"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
	"github.com/mlange-42/arche/ecs"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30
	m.FPS = 0

	// Create a contour plot.
	m.AddUISystem(
		(&window.Window{}).
			With(&plot.Field{
				Observer: observer.LayersToLayers(&FieldObserver{}, nil, nil),
			}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}

type FieldObserver struct {
	cols   int
	rows   int
	values [][]float64
}

func (o *FieldObserver) Initialize(w *ecs.World) {
	o.cols = 60
	o.rows = 40
	o.values = make([][]float64, 2)
	for i := 0; i < len(o.values); i++ {
		o.values[i] = make([]float64, o.cols*o.rows)
	}
}

func (o *FieldObserver) Update(w *ecs.World) {}

func (o *FieldObserver) Dims() (int, int) {
	return o.cols, o.rows
}

func (o *FieldObserver) Layers() int {
	return 2
}

func (o *FieldObserver) Values(w *ecs.World) [][]float64 {
	ln := len(o.values[0])
	for idx := 0; idx < ln; idx++ {
		i := idx % o.cols
		j := idx / o.cols
		o.values[0][idx] = math.Sin(float64(i))
		o.values[1][idx] = -math.Sin(float64(j))
	}
	return o.values
}
Output:

func (*Field) Draw added in v0.3.0

func (f *Field) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*Field) Initialize added in v0.3.0

func (f *Field) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*Field) Update added in v0.3.0

func (f *Field) Update(w *ecs.World)

Update the drawer.

func (*Field) UpdateInputs added in v0.3.0

func (f *Field) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type HeatMap added in v0.3.0

type HeatMap struct {
	Observer observer.Grid   // Observers providing a Grid for contours.
	Palette  palette.Palette // Color palette. Optional.
	Min      float64         // Minimum value for color mapping. Optional.
	Max      float64         // Maximum value for color mapping. Optional. Is set to 1.0 if both Min and Max are zero.
	Labels   Labels          // Labels for plot and axes. Optional.
	// contains filtered or unexported fields
}

HeatMap plot drawer.

Plots a grid as a heatmap image. For large grids, this is relatively slow. Consider using Image instead.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30
m.FPS = 0

// Create a contour plot.
m.AddUISystem(
	(&window.Window{}).
		With(&plot.HeatMap{
			Observer: observer.MatrixToGrid(&MatrixObserver{}, nil, nil),
			Palette:  palette.Heat(16, 1),
			Min:      -2,
			Max:      2,
		}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

func (*HeatMap) Draw added in v0.3.0

func (h *HeatMap) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*HeatMap) Initialize added in v0.3.0

func (h *HeatMap) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*HeatMap) Update added in v0.3.0

func (h *HeatMap) Update(w *ecs.World)

Update the drawer.

func (*HeatMap) UpdateInputs added in v0.3.0

func (h *HeatMap) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Image added in v0.0.3

type Image struct {
	Scale    float64            // Spatial scaling: cell size in screen pixels. Optional, default auto.
	Observer observer.Matrix    // Observer providing 2D matrix or grid data.
	Colors   colorgrad.Gradient // Colors for mapping values.
	Min      float64            // Minimum value for color mapping. Optional.
	Max      float64            // Maximum value for color mapping. Optional. Is set to 1.0 if both Min and Max are zero.
	// contains filtered or unexported fields
}

Image drawer.

Draws an image from a Matrix observer. The image is scaled to the canvas extent, with preserved aspect ratio. Does not add plot axes etc.

Example
package main

import (
	"math"

	"github.com/mazznoer/colorgrad"
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
	"github.com/mlange-42/arche/ecs"
)

func main() {

	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30
	m.FPS = 0

	// Create an image plot.
	// See below for the implementation of the MatrixObserver.
	m.AddUISystem(
		(&window.Window{}).
			With(&plot.Image{
				Scale:    4,
				Observer: &MatrixObserver{},
				Colors:   colorgrad.Inferno(),
				Min:      -2,
				Max:      2,
			}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}

// Example observer, reporting a matrix with z = sin(0.1*i) + sin(0.2*j).
type MatrixObserver struct {
	cols   int
	rows   int
	values []float64
}

func (o *MatrixObserver) Initialize(w *ecs.World) {
	o.cols = 160
	o.rows = 120
	o.values = make([]float64, o.cols*o.rows)
}

func (o *MatrixObserver) Update(w *ecs.World) {}

func (o *MatrixObserver) Dims() (int, int) {
	return o.cols, o.rows
}

func (o *MatrixObserver) Values(w *ecs.World) []float64 {
	for idx := 0; idx < len(o.values); idx++ {
		i := idx % o.cols
		j := idx / o.cols
		o.values[idx] = math.Sin(0.1*float64(i)) + math.Sin(0.2*float64(j))
	}
	return o.values
}
Output:

func (*Image) Draw added in v0.0.3

func (i *Image) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Image) Initialize added in v0.0.3

func (i *Image) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Image) Update added in v0.0.3

func (i *Image) Update(w *ecs.World)

Update the drawer.

func (*Image) UpdateInputs added in v0.0.3

func (i *Image) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type ImageRGB added in v0.0.3

type ImageRGB struct {
	Scale    float64               // Spatial scaling: cell size in screen pixels. Optional, default auto.
	Observer observer.MatrixLayers // Observer providing data for color channels.
	Layers   []int                 // Layer indices. Optional, defaults to [0, 1, 2]. Use -1 to ignore a channel.
	Min      []float64             // Minimum value for channel color mapping. Optional, default [0, 0, 0].
	Max      []float64             // Maximum value for channel color mapping. Optional, default [1, 1, 1].
	// contains filtered or unexported fields
}

ImageRGB drawer.

Draws an image from a Matrix observer per RGB color channel. The image is scaled to the canvas extent, with preserved aspect ratio. Does not add plot axes etc.

Example
package main

import (
	"math"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/observer"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
	"github.com/mlange-42/arche/ecs"
)

func main() {

	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create an RGB image plot.
	// See below for the implementation of the CallbackMatrixObserver.
	m.AddUISystem((&window.Window{}).
		With(&plot.ImageRGB{
			Observer: observer.MatrixToLayers(
				&CallbackMatrixObserver{Callback: func(i, j int) float64 { return float64(i) / 240 }},
				&CallbackMatrixObserver{Callback: func(i, j int) float64 { return math.Sin(0.1 * float64(i)) }},
				&CallbackMatrixObserver{Callback: func(i, j int) float64 { return float64(j) / 160 }},
			),
			Min: []float64{0, 0, 0},
			Max: []float64{1, 1, 1},
		}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}

// Example observer, reporting a matrix filled with a callback(i, j).
type CallbackMatrixObserver struct {
	Callback func(i, j int) float64
	cols     int
	rows     int
	values   []float64
}

func (o *CallbackMatrixObserver) Initialize(w *ecs.World) {
	o.cols = 240
	o.rows = 160
	o.values = make([]float64, o.cols*o.rows)
}

func (o *CallbackMatrixObserver) Update(w *ecs.World) {}

func (o *CallbackMatrixObserver) Dims() (int, int) {
	return o.cols, o.rows
}

func (o *CallbackMatrixObserver) Values(w *ecs.World) []float64 {
	for idx := 0; idx < len(o.values); idx++ {
		i := idx % o.cols
		j := idx / o.cols
		o.values[idx] = o.Callback(i, j)
	}
	return o.values
}
Output:

func (*ImageRGB) Draw added in v0.0.3

func (i *ImageRGB) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*ImageRGB) Initialize added in v0.0.3

func (i *ImageRGB) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*ImageRGB) Update added in v0.0.3

func (i *ImageRGB) Update(w *ecs.World)

Update the drawer.

func (*ImageRGB) UpdateInputs added in v0.0.3

func (i *ImageRGB) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Inspector added in v0.2.0

type Inspector struct {
	HideFields bool // Hides components fields.
	HideTypes  bool // Hides field types.
	HideValues bool // Hides field values.
	HideNames  bool // Hide field names of nested structs.
	// contains filtered or unexported fields
}

Inspector drawer for inspecting entities.

Shows information of the entity indicated by the SelectedEntity resource (github.com/mlange-42/arche-model/resource.SelectedEntity). Entity selection is to be done by another system, e.g. by user input.

Details can be adjusted using the HideXxx fields. Further, keys F, T, V and N can be used to toggle details during a running simulation. The view can be scrolled using arrow keys or the mouse wheel.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30

// Create an entity to inspect it.
posID := ecs.ComponentID[Position](&m.World)
velID := ecs.ComponentID[Velocity](&m.World)
entity := m.World.NewEntity(posID, velID)

// Set it as selected entity.
ecs.AddResource(&m.World, &resource.SelectedEntity{Selected: entity})

// Create a window with an Inspector drawer.
m.AddUISystem((&window.Window{}).
	With(&plot.Inspector{}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

func (*Inspector) Draw added in v0.2.0

func (i *Inspector) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Inspector) Initialize added in v0.2.0

func (i *Inspector) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Inspector) Update added in v0.2.0

func (i *Inspector) Update(w *ecs.World)

Update the drawer.

func (*Inspector) UpdateInputs added in v0.2.0

func (i *Inspector) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Labels added in v0.3.0

type Labels struct {
	Title string // Plot title
	X     string // X axis label
	Y     string // Y axis label
}

Labels for plots.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30

// Create a time series plot, wit labels.
m.AddUISystem((&window.Window{}).
	With(&plot.TimeSeries{
		Observer: &RowObserver{},
		Labels: plot.Labels{
			Title: "Plot example",
			X:     "X axis label",
			Y:     "Y axis label",
		},
	}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

type Lines added in v0.3.0

type Lines struct {
	Observer observer.Table // Observer providing a data series for lines.
	X        string         // X column name. Optional. Defaults to row index.
	Y        []string       // Y column names. Optional. Defaults to all but X column.
	YLim     [2]float64     // Y axis limits. Optional, default auto.
	Labels   Labels         // Labels for plot and axes. Optional.
	// contains filtered or unexported fields
}

Lines plot drawer.

Creates a line series per column of the observer. Replaces the complete data by the table provided by the observer on every update. Particularly useful for live histograms.

Example
package main

import (
	"math/rand"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
	"github.com/mlange-42/arche/ecs"
)

func main() {

	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a line plot.
	// See below for the implementation of the TableObserver.
	m.AddUISystem((&window.Window{}).
		With(&plot.Lines{
			Observer: &TableObserver{},
			X:        "X",                     // Optional, defaults to row index
			Y:        []string{"A", "B", "C"}, // Optional, defaults to all but X
		}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}

// TableObserver to generate random time series.
type TableObserver struct {
	data [][]float64
}

func (o *TableObserver) Initialize(w *ecs.World) {
	rows := 25
	o.data = make([][]float64, rows)

	for i := 0; i < rows; i++ {
		o.data[i] = []float64{float64(i), float64(i) / float64(rows), float64(rows-i) / float64(rows), 0}
	}
}
func (o *TableObserver) Update(w *ecs.World) {}
func (o *TableObserver) Header() []string {
	return []string{"X", "A", "B", "C"}
}
func (o *TableObserver) Values(w *ecs.World) [][]float64 {
	for i := 0; i < len(o.data); i++ {
		o.data[i][3] = rand.Float64()
	}
	return o.data
}
Output:

func (*Lines) Draw added in v0.3.0

func (l *Lines) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*Lines) Initialize added in v0.3.0

func (l *Lines) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*Lines) Update added in v0.3.0

func (l *Lines) Update(w *ecs.World)

Update the drawer.

func (*Lines) UpdateInputs added in v0.3.0

func (l *Lines) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Monitor added in v0.0.3

type Monitor struct {
	PlotCapacity   int           // Number of values in time series plots. Optional, default 300.
	SampleInterval time.Duration // Approx. time between measurements for time series plots. Optional, default 1 second.
	HidePlots      bool          // Hides time series plots
	HideArchetypes bool          // Hides archetype stats
	// contains filtered or unexported fields
}

Monitor drawer for visualizing world and performance statistics.

Symbology:

  • Green bars: archetypes without entity relations
  • Cyan bars: archetypes with entity relations
  • Light green/cyan: currently used
  • Dark green/cyan: reserved

Top info:

  • Tick: current model tick
  • Ent: total number of entities
  • Nodes: active/total nodes in archetype graph
  • Comp: number of component types
  • Cache: number of cached filters
  • Mem: total memory reserved for entities and components
  • TPS: (simulation) ticks per second
  • TPT: time per (simulation) tick
  • Time: total run time of the simulation
Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a Monitor drawer.
	m.AddUISystem((&window.Window{}).
		With(&plot.Monitor{}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Uncomment the next line. It is commented out as the CI has no display device to test the model run.

	// window.Run(m)

}
Output:

func (*Monitor) Draw added in v0.0.3

func (m *Monitor) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Monitor) Initialize added in v0.0.3

func (m *Monitor) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Monitor) Update added in v0.0.3

func (m *Monitor) Update(w *ecs.World)

Update the drawer.

func (*Monitor) UpdateInputs added in v0.0.3

func (m *Monitor) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type PerfStats added in v0.1.0

type PerfStats struct {
	SampleInterval time.Duration // Approx. time between measurements. Optional, default 1 second.
	// contains filtered or unexported fields
}

PerfStats drawer for performance statistics.

Adds an overlay with performance statistics in the top left corner of the window.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a PerfStats drawer.
	// PerfStats is intended as an overlay, so more drawers can be added before it.
	m.AddUISystem((&window.Window{}).
		With(&plot.PerfStats{}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}
Output:

func (*PerfStats) Draw added in v0.1.0

func (p *PerfStats) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*PerfStats) Initialize added in v0.1.0

func (p *PerfStats) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*PerfStats) Update added in v0.1.0

func (p *PerfStats) Update(w *ecs.World)

Update the drawer.

func (*PerfStats) UpdateInputs added in v0.1.0

func (p *PerfStats) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Resources added in v0.4.0

type Resources struct {
	HideFields bool // Hides components fields.
	HideTypes  bool // Hides field types.
	HideValues bool // Hides field values.
	HideNames  bool // Hide field names of nested structs.
	// contains filtered or unexported fields
}

Resources drawer for inspecting ECS resources.

Lists all resources with their public fields.

Details can be adjusted using the HideXxx fields. Further, keys F, T, V and N can be used to toggle details during a running simulation. The view can be scrolled using arrow keys or the mouse wheel.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a Resources drawer.
	m.AddUISystem((&window.Window{}).
		With(&plot.Resources{}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}
Output:

func (*Resources) Draw added in v0.4.0

func (i *Resources) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Resources) Initialize added in v0.4.0

func (i *Resources) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Resources) Update added in v0.4.0

func (i *Resources) Update(w *ecs.World)

Update the drawer.

func (*Resources) UpdateInputs added in v0.4.0

func (i *Resources) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Scatter added in v0.3.0

type Scatter struct {
	Observers []observer.Table // Observers providing XY data series.
	X         []string         // X column name per observer. Optional. Defaults to first column. Empty strings also falls back to the default.
	Y         [][]string       // Y column names per observer. Optional. Defaults to second column. Empty strings also falls back to the default.
	XLim      [2]float64       // X axis limits. Optional, default auto.
	YLim      [2]float64       // Y axis limits. Optional, default auto.
	Labels    Labels           // Labels for plot and axes. Optional.
	// contains filtered or unexported fields
}

Scatter plot drawer.

Creates a scatter plot from multiple observers. Supports multiple series per observer. The series in a particular observer must share a common X column.

Example
// Create a new model.
m := model.New()

// Limit the the simulation speed.
m.TPS = 30

// Create a scatter plot.
m.AddUISystem((&window.Window{}).
	With(&plot.Scatter{
		Observers: []observer.Table{
			&TableObserver{}, // One or more observers.
		},
		X: []string{
			"X", // One X column per observer.
		},
		Y: [][]string{
			{"A", "B", "C"}, // One or more Y columns per observer.
		},
	}))

// Add a termination system that ends the simulation.
m.AddSystem(&system.FixedTermination{
	Steps: 100,
})

m.Run()

// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.

// window.Run(m)
Output:

func (*Scatter) Draw added in v0.3.0

func (s *Scatter) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*Scatter) Initialize added in v0.3.0

func (s *Scatter) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*Scatter) Update added in v0.3.0

func (s *Scatter) Update(w *ecs.World)

Update the drawer.

func (*Scatter) UpdateInputs added in v0.3.0

func (s *Scatter) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type Systems added in v0.4.0

type Systems struct {
	HideUISystems bool // Hides UI systems.
	HideFields    bool // Hides components fields.
	HideTypes     bool // Hides field types.
	HideValues    bool // Hides field values.
	HideNames     bool // Hide field names of nested structs.
	// contains filtered or unexported fields
}

Systems drawer for inspecting ECS systems.

Lists all systems and UI systems in their scheduling order, with their public fields.

Details can be adjusted using the HideXxx fields. Further, keys U, F, T, V and N can be used to toggle details during a running simulation. The view can be scrolled using arrow keys or the mouse wheel.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
)

func main() {
	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a window with a Systems drawer.
	m.AddUISystem((&window.Window{}).
		With(&plot.Systems{}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}
Output:

func (*Systems) Draw added in v0.4.0

func (i *Systems) Draw(w *ecs.World, win *opengl.Window)

Draw the system

func (*Systems) Initialize added in v0.4.0

func (i *Systems) Initialize(w *ecs.World, win *opengl.Window)

Initialize the system

func (*Systems) Update added in v0.4.0

func (i *Systems) Update(w *ecs.World)

Update the drawer.

func (*Systems) UpdateInputs added in v0.4.0

func (i *Systems) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

type TimeSeries

type TimeSeries struct {
	Observer       observer.Row // Observer providing a data row per update.
	Columns        []string     // Columns to show, by name. Optional, default all.
	UpdateInterval int          // Interval for getting data from the the observer, in model ticks. Optional.
	Labels         Labels       // Labels for plot and axes. Optional.
	MaxRows        int          // Maximum number of rows to keep. Zero means unlimited. Optional.
	// contains filtered or unexported fields
}

TimeSeries plot drawer.

Creates a line series per column of the observer. Adds one row to the data per update.

Example
package main

import (
	"math/rand"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche-pixel/plot"
	"github.com/mlange-42/arche-pixel/window"
	"github.com/mlange-42/arche/ecs"
)

func main() {

	// Create a new model.
	m := model.New()

	// Limit the the simulation speed.
	m.TPS = 30

	// Create a time series plot.
	// See below for the implementation of the RowObserver.
	m.AddUISystem((&window.Window{}).
		With(&plot.TimeSeries{
			Observer: &RowObserver{},
		}))

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	m.Run()

	// Run the simulation.
	// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
	// Comment out the code line above, and uncomment the next line to run this example stand-alone.

	// window.Run(m)

}

// RowObserver to generate random time series.
type RowObserver struct{}

func (o *RowObserver) Initialize(w *ecs.World) {}
func (o *RowObserver) Update(w *ecs.World)     {}
func (o *RowObserver) Header() []string {
	return []string{"A", "B", "C"}
}
func (o *RowObserver) Values(w *ecs.World) []float64 {
	return []float64{rand.Float64(), rand.Float64() + 1, rand.Float64() + 2}
}
Output:

func (*TimeSeries) Draw added in v0.0.3

func (t *TimeSeries) Draw(w *ecs.World, win *opengl.Window)

Draw the drawer.

func (*TimeSeries) Initialize

func (t *TimeSeries) Initialize(w *ecs.World, win *opengl.Window)

Initialize the drawer.

func (*TimeSeries) Update

func (t *TimeSeries) Update(w *ecs.World)

Update the drawer.

func (*TimeSeries) UpdateInputs added in v0.0.3

func (t *TimeSeries) UpdateInputs(w *ecs.World, win *opengl.Window)

UpdateInputs handles input events of the previous frame update.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL