Documentation
¶
Overview ¶
Package output is the back of the rendering pipe: it carries a Figure (a built plot) to a destination Surface — a file, an in-memory image, a desktop GPU window, or a browser canvas — through one frame model.
The drawing seam lives in package canvas (canvas.Canvas and its RasterCanvas / RecordingCanvas backends). This package sits on top: a Figure paints itself onto a canvas.Canvas, and a Surface decides where those pixels or vectors go. Render presents exactly one frame and is the entire static story (PNG/SVG/PDF/in-memory image); interactive surfaces add an event loop on top (see Session).
Concrete surfaces live in subpackages (output/file, output/image, output/window, output/web) and register themselves via Register in their init(). Platform selection is therefore a blank import — no build tag ever appears in user code. This core package imports none of them.
Index ¶
- Variables
- func Register(name string, f SurfaceFactory)
- func Render(ctx context.Context, fig Figure, surf Surface) error
- type Action
- type Controller
- type ControllerFunc
- type Event
- type EventKind
- type Figure
- type Imager
- type LiveSurface
- type Measurable
- type PanelInfo
- type Session
- type SessionOpt
- type Sizer
- type Source
- type State
- type Surface
- type SurfaceFactory
- type SurfaceOpt
- type SurfaceOptions
- type Zoomable
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUnknownSurface is returned by [NewSurface] when no factory is // registered under the requested name — usually because the platform // subpackage providing it was not blank-imported. ErrUnknownSurface = errors.New("output: unknown surface (blank-import its package to register it)") // ErrSurfaceConsumed is returned by a single-shot [Surface] (file, image) // when Acquire is called a second time. Such surfaces present exactly one // frame. ErrSurfaceConsumed = errors.New("output: surface already consumed (single-shot surface allows one frame)") // ErrNotLive is returned by [NewLiveSurface] when the named surface is // registered but does not implement [LiveSurface] (e.g. "file"). ErrNotLive = errors.New("output: surface is not interactive") // ErrUnsupportedFormat is returned by a surface factory when the requested // encoder format is not one it can produce. ErrUnsupportedFormat = errors.New("output: unsupported format") // ErrNoImage is returned when an image was requested from a surface that // does not implement [Imager]. ErrNoImage = errors.New("output: surface does not produce an image") )
Sentinel errors returned by the output layer.
Functions ¶
func Register ¶ added in v0.0.10
func Register(name string, f SurfaceFactory)
Register associates a SurfaceFactory with a name. It is called from a platform subpackage's init(); registering the same name twice panics, as it indicates two packages claiming the same surface.
Types ¶
type Action ¶ added in v0.0.10
type Action uint8
Action is the decision a Controller returns for an Event: what the Session should do next.
const ( // ActionIgnore does nothing. ActionIgnore Action = iota // ActionRedraw is the fast path: re-render the current Figure under the // (possibly updated) viewport transform in [State]. GPU-bound, no rebuild. ActionRedraw // ActionRebuild is the slow path: call Source.Build again because the data // extent changed (viewport crossed the trained bounds, or a brush changed a // stat input). Scales retrain and stats recompute. ActionRebuild // ActionExport renders the current frame to the session's export surface, // if one was configured via [WithExportSurface]. ActionExport // ActionClose ends the session. ActionClose )
type Controller ¶ added in v0.0.10
Controller decides, per event, what the Session does next. The default controller is DataSpaceController (data-space pan/zoom); swap it via WithController for linked brushing, custom gestures, etc.
func DataSpaceController ¶ added in v0.0.10
func DataSpaceController() Controller
DataSpaceController provides data-space pan (drag) and zoom (scroll wheel) that operates on scale bounds rather than a canvas-level affine transform.
Axes remain at fixed screen positions; only the data visible within the panel changes. Tick labels update dynamically to reflect the current viewport. This is the interactive behavior expected in professional plotting tools (matplotlib, Plotly, ggplot2 shiny).
Performance: each interaction mutates two float64 values per axis (O(1)), then triggers ActionRedraw. No rebuild, no data iteration.
For faceted plots, zoom/pan applies only to the panel under the cursor.
type ControllerFunc ¶ added in v0.0.10
ControllerFunc adapts a plain function to the Controller interface.
type Event ¶ added in v0.0.10
type Event struct {
Kind EventKind
X, Y float64 // logical coordinates
DX, DY float64 // scroll / drag deltas
Buttons uint8
Key string
Modifiers uint8
}
Event is the platform-neutral input event. output/window translates OS events into it; output/web translates DOM events into it. The Session and Controller see only this type — never a platform-specific event.
type EventKind ¶ added in v0.0.10
type EventKind uint8
EventKind enumerates the platform-neutral input event kinds delivered by a LiveSurface.
const ( EventResize EventKind = iota EventPointerMove EventPointerDown EventPointerUp EventScroll EventKey EventClose EventDoubleClick // double-click / double-tap for viewport reset )
Event kinds delivered by a LiveSurface.
type Figure ¶ added in v0.0.10
Figure is something that can paint itself onto a canvas.Canvas at a given size. *ggplot.Built satisfies Figure with no change — its Draw method already has exactly this signature.
type Imager ¶ added in v0.0.10
Imager is implemented by surfaces that publish an in-memory image (the "image" surface). Image returns the frame published by the last Commit.
type LiveSurface ¶ added in v0.0.10
LiveSurface is a Surface with an interactive lifecycle. Desktop windows and browser canvases implement it; file and image surfaces do not. Interaction is deliberately absent from the Surface contract — a PNG export never links an event loop.
func NewLiveSurface ¶ added in v0.0.10
func NewLiveSurface(ctx context.Context, name string, opts ...SurfaceOpt) (LiveSurface, error)
NewLiveSurface is NewSurface plus a runtime assertion to LiveSurface. It returns ErrNotLive if the named surface is not interactive.
type Measurable ¶ added in v0.0.10
type Measurable interface {
// PanelInfos returns the geometry of all panels from the last Draw call.
// Returns nil if Draw has not been called yet.
PanelInfos() []PanelInfo
}
Measurable is an optional Figure extension that exposes per-panel layout geometry after a Draw call. Controllers use this to convert pixel mouse positions to data coordinates for data-space pan/zoom.
The returned PanelInfos are valid only for the width×height that was last passed to Draw. A resize triggers a new Draw, which updates the geometry.
type PanelInfo ¶ added in v0.0.10
type PanelInfo struct {
// Index is the zero-based panel index in the figure's panel slice.
Index int
// Bounds is the data-area rectangle in figure pixel coordinates.
// This is the region where data is drawn — axes/titles are outside.
Bounds image.Rectangle
// XRange is the current (possibly zoomed) X data-space bounds [min, max].
XRange [2]float64
// YRange is the current (possibly zoomed) Y data-space bounds [min, max].
YRange [2]float64
// OrigXRange is the full trained X data-space bounds (for reset).
OrigXRange [2]float64
// OrigYRange is the full trained Y data-space bounds (for reset).
OrigYRange [2]float64
}
PanelInfo describes the pixel geometry and data-space bounds of one panel. Returned by Measurable after a Draw call so that controllers can convert pixel positions to data coordinates and perform per-panel hit-testing.
func (PanelInfo) ContainsPixel ¶ added in v0.0.10
ContainsPixel reports whether the pixel position (px, py) falls within this panel's data-area bounds.
func (PanelInfo) PixelToData ¶ added in v0.0.10
PixelToData converts a pixel position (px, py) within this panel's Bounds to data-space coordinates. Returns (NaN, NaN) if the pixel is outside the panel bounds.
type Session ¶ added in v0.0.10
type Session struct {
// contains filtered or unexported fields
}
Session drives a Source onto a LiveSurface: build once, draw, then re-render on events. It owns the fast-path / slow-path policy.
The fast path (ActionRedraw) re-renders the current figure under a viewport affine transform — cheap and frequent. The slow path (ActionRebuild) calls Source.Build again when the data extent changes. By default the rebuild is synchronous; WithRebuildDelay makes it asynchronous and debounced — the last good figure keeps drawing while the next one is computed off the event loop.
func NewSession ¶ added in v0.0.10
func NewSession(src Source, surf LiveSurface, opts ...SessionOpt) *Session
NewSession creates a session that drives src onto surf. With no options it uses DataSpaceController for data-space pan/zoom.
func (*Session) Run ¶ added in v0.0.10
Run builds the initial figure, draws one frame, then processes events until the surface's event channel closes, a controller returns ActionClose, an EventClose arrives, or ctx is cancelled.
type SessionOpt ¶ added in v0.0.10
type SessionOpt func(*Session)
SessionOpt configures a Session.
func WithController ¶ added in v0.0.10
func WithController(c Controller) SessionOpt
WithController overrides the default pan/zoom controller.
func WithExportSurface ¶ added in v0.0.10
func WithExportSurface(fn func(ctx context.Context) (Surface, error)) SessionOpt
WithExportSurface sets the factory used to create a destination surface when a controller returns ActionExport.
func WithRebuildDelay ¶ added in v0.0.10
func WithRebuildDelay(d time.Duration) SessionOpt
WithRebuildDelay enables asynchronous, debounced rebuilds. When d > 0, an ActionRebuild no longer blocks the event loop: rapid triggers within d are coalesced into a single background [Source.Build], the last good figure stays on screen until it completes, and the result is swapped in when ready. When d <= 0 (the default) rebuilds run synchronously on the event loop.
Pending async rebuilds are flushed when the event channel closes, but are dropped on ActionClose/EventClose or context cancellation (the session is shutting down).
func WithRebuildError ¶ added in v0.0.10
func WithRebuildError(fn func(error)) SessionOpt
WithRebuildError sets a handler for errors from asynchronous rebuilds. Such errors are non-fatal: the last good figure is kept and the session continues. Without a handler they are dropped. (Synchronous rebuilds instead return the error from Session.Run.)
type Sizer ¶ added in v0.0.10
Sizer is an optional Figure extension: given a width, it proposes a preferred size. Façades (Save/Encode/Image) use it to infer a height when the caller passes a non-positive one. *ggplot.Built implements Sizer by wrapping its existing auto-height rules.
type Source ¶ added in v0.0.10
Source yields a fresh Figure. *ggplot.Plot is a Source. Live surfaces hold a Source so they can rebuild when an interaction crosses the trained data extent (scales retrain, stats recompute — the slow path).
type State ¶ added in v0.0.10
type State struct {
// Bounds is the surface's current logical drawing size, refreshed before
// each event is dispatched.
Bounds image.Rectangle
// Figure is the current figure being displayed (read-only for controllers
// that need the trained extent, e.g. to decide redraw vs. rebuild).
Figure Figure
}
State is the mutable interaction state shared between the Session and its Controller. The controller reads events and mutates the viewport; the session reads the viewport to render.
type Surface ¶ added in v0.0.10
type Surface interface {
// Acquire returns the drawing Canvas for the next frame, sized to Bounds.
// The returned Canvas is valid only until the next Commit.
Acquire(ctx context.Context) (canvas.Canvas, error)
// Commit finalizes the frame acquired by Acquire:
// file -> encode + flush bytes to disk
// image -> publish the in-memory image
// window -> submit GPU work + present (zero-copy)
// web -> submit + swapchain present
Commit(ctx context.Context) error
// Bounds is the current logical drawing size (device scale handled
// internally). Fixed for file/image; tracks the window/canvas for live.
Bounds() image.Rectangle
Close() error
}
Surface is a destination a Figure is drawn to — one interface for file, in-memory image, desktop GPU window, and browser canvas.
Static surfaces (file, image) accept exactly one Acquire/Commit cycle and return ErrSurfaceConsumed on a second Acquire. Live surfaces accept repeated cycles. The single- vs. multi-shot contract is documented per implementation; the type is shared.
func NewSurface ¶ added in v0.0.10
NewSurface constructs a registered surface by name. It returns ErrUnknownSurface if the corresponding subpackage was not blank-imported.
type SurfaceFactory ¶ added in v0.0.10
type SurfaceFactory func(ctx context.Context, opt SurfaceOptions) (Surface, error)
SurfaceFactory constructs a Surface from resolved options. Platform subpackages register one via Register in their init().
type SurfaceOpt ¶ added in v0.0.10
type SurfaceOpt func(*SurfaceOptions)
SurfaceOpt configures SurfaceOptions functionally.
func WithCPU ¶ added in v0.0.10
func WithCPU(cpu bool) SurfaceOpt
WithCPU forces a pure-CPU rasterizer for raster output.
func WithFormat ¶ added in v0.0.10
func WithFormat(format string) SurfaceOpt
WithFormat overrides the encoder format ("png", "svg", "pdf").
func WithPath ¶ added in v0.0.10
func WithPath(path string) SurfaceOpt
WithPath sets the destination file path (file surface).
func WithScale ¶ added in v0.0.10
func WithScale(scale float64) SurfaceOpt
WithScale sets the device-pixel multiplier for HiDPI output.
func WithSize ¶ added in v0.0.10
func WithSize(w, h int) SurfaceOpt
WithSize sets the logical drawing size.
func WithWriter ¶ added in v0.0.10
func WithWriter(w io.Writer) SurfaceOpt
WithWriter sets an io.Writer destination for the file surface (used in place of a path).
type SurfaceOptions ¶ added in v0.0.10
type SurfaceOptions struct {
// Width and Height are the logical drawing size in pixels.
Width, Height int
// Path is the destination file path (file surface). The encoder is
// inferred from its extension unless Format is set.
Path string
// Writer is an alternative destination for the file surface: when set,
// encoded bytes are written here instead of to Path.
Writer io.Writer
// Format overrides the encoder ("png", "svg", "pdf"). Empty means infer
// from Path.
Format string
// Scale is the device-pixel multiplier for HiDPI output (1 = none).
Scale float64
// CPU forces a pure-CPU rasterizer for raster output (deterministic,
// headless-safe), bypassing the GPU accelerator.
CPU bool
}
SurfaceOptions is the resolved configuration passed to a SurfaceFactory. Fields not relevant to a given surface are ignored by its factory.
func BuildOptions ¶ added in v0.0.10
func BuildOptions(opts ...SurfaceOpt) SurfaceOptions
BuildOptions applies the given options and returns the resolved SurfaceOptions. Surface packages use this to build options from variadic SurfaceOpt slices.
type Zoomable ¶ added in v0.0.10
type Zoomable interface {
// SetPanelViewport overrides the X and Y scale bounds for the panel at
// panelIndex. Pass nil for either limit endpoint to keep the current
// value. After calling this, the next Draw will render with the new
// viewport (clipped data, updated ticks).
SetPanelViewport(panelIndex int, xlim, ylim [2]*float64)
// ResetViewport restores all panels to their original trained bounds.
ResetViewport()
}
Zoomable is an optional Figure extension that supports fast viewport changes without rebuilding the figure from source. The controller mutates scale bounds directly on the built figure, then triggers ActionRedraw.
This is O(1) — no data iteration, no stat recomputation, no memory allocation. Only the scale endpoints change; ticks regenerate on the next Draw call.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package file provides a output.Surface that encodes a single frame to disk (or any io.Writer) as PNG, SVG, or PDF.
|
Package file provides a output.Surface that encodes a single frame to disk (or any io.Writer) as PNG, SVG, or PDF. |
|
Package image provides a output.Surface that renders a single frame into an in-memory image.Image.
|
Package image provides a output.Surface that renders a single frame into an in-memory image.Image. |
|
Package web — serve.go provides a development HTTP server for serving WASM ggplot applications.
|
Package web — serve.go provides a development HTTP server for serving WASM ggplot applications. |
|
Package window presents a ggplot figure in a native desktop GPU window via gogpu + ggcanvas, the zero-copy GPU rendering integration.
|
Package window presents a ggplot figure in a native desktop GPU window via gogpu + ggcanvas, the zero-copy GPU rendering integration. |