prism

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 14 Imported by: 0

README

Prism

Prism is a visualization library for .pulse files. It compiles declarative JSON specs into charts — server-side SVG / PNG / PDF via Go, and live in-browser via web components — using Vega-Lite-inspired vocabulary with snake_case naming and Pulse expression syntax.

Install

go install github.com/frankbardon/prism/cmd/prism@latest
prism version   # prism v0.2.0

First chart in 5 lines

prism init
cp .prism/examples/bar_basic.json my-chart.prism.json
prism plot my-chart.prism.json > chart.svg
open chart.svg

What ships in v0.1

  • Six-stage pipeline — Spec → Validate → Plan → Compile → Encode → Render.
  • 20+ marks — bar, line, area, point, rule, text, tick, rect, arc, pie, donut, histogram, heatmap, boxplot, violin, sankey, funnel, sparkline, image, path.
  • Compositionlayer, concat, hconcat, vconcat, facet, repeat. Cross-layer scale resolution (shared/independent).
  • Multi-sourcedatasets block + hash join + parallel Source execution. Server-side + browser-side dataset registries.
  • Selections — point + interval; client + server reactive modes.
  • Themeslight, dark, print built-in. Sparse override via spec or custom theme.json.
  • Renderers — SVG (Go), Canvas-via-JS (vendored ESM web component), PDF (gopdf with embedded fonts, paginated grids).
  • Service surface — Twirp HTTP + MCP stdio. prism serve, prism mcp.
  • CLIvalidate, plan, execute, plot, scene, serve, mcp, inspect, examples, schema, init, errors lookup, static-bundle, version.

Documentation

The full manual is an mdBook under docs/, published to https://frankbardon.github.io/prism/. Build locally with make docs-serve.

License

MIT — see LICENSE.

Contributing

See CONTRIBUTING.md for setup, conventions, and PR guidelines, and CLAUDE.md for the full set of conventions, contracts, and the Update Demand table. The .planning/ directory carries the design discussion, phase plans, and locked decisions; new features should land with a PHASE.md + PLAN.md following the existing pattern.

Documentation

Overview

Package prism is the public Go entry point for the Prism visualization library. The full pipeline lives in subpackages (spec, validate, plan, plan/build, encode, render, …); this root package exposes the two highest-level operations callers reach for:

  • Compile — run the pipeline up to but not including the rasterising render stage. Returns a renderer-agnostic CompiledPlan describing what would be drawn. Typically 10-50× cheaper than a full Render (the encode + raster stages are the expensive ones).

  • Render — full pipeline → byte stream (SVG today; PDF gated by build tag).

Both helpers accept either a parsed *spec.Spec or raw JSON bytes and surface diagnostics (PRISM_WARN_* warnings) alongside any hard-error envelope.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyPatch

func ApplyPatch(s *spec.Spec, p Patch) (*spec.Spec, error)

ApplyPatch returns a new *spec.Spec with the patch's operations applied. The input spec is not mutated. On any operation failure (path miss, type mismatch, schema violation post-apply), the returned spec is nil and the error envelope carries PRISM_SPEC_PATCH_001 with the failing operation index in Details.

Types

type CompileOptions

type CompileOptions struct {
	Build  build.Options
	Exec   plan.ExecOpts
	Encode encode.EncodeOpts
}

CompileOptions controls the compile pipeline. Build, Exec, and Encode are passed through to the corresponding stages. When zero, sensible defaults are filled in (in-memory backend, single-worker executor, 800×600 layout).

type CompiledMark

type CompiledMark struct {
	SceneID       string         `json:"scene_id"`
	LayerID       string         `json:"layer_id"`
	MarkIndex     int            `json:"mark_index"`
	Type          scene.MarkType `json:"type"`
	InstanceCount int            `json:"instance_count"`
	Source        string         `json:"source,omitempty"`
}

CompiledMark summarises one layer's worth of marks. MarkIndex is the layer's index within its enclosing scene; InstanceCount is the number of individual mark geometries (one per data row in the general case).

type CompiledPlan

type CompiledPlan struct {
	Scene       *scene.SceneDoc `json:"scene"`
	Marks       []CompiledMark  `json:"marks"`
	Scales      []CompiledScale `json:"scales"`
	Data        []DataBinding   `json:"data"`
	Layout      LayoutInfo      `json:"layout"`
	Diagnostics []Diagnostic    `json:"diagnostics"`
}

CompiledPlan is the structured output of Compile: the same information the renderer would consume, exposed as a stable JSON shape. Callers can inspect the plan, diff two plans against each other, or hand it to a renderer separately via RenderPlan.

The Scene field carries the canonical IR; the flattened views (Marks, Scales, Data, Layout) summarise it for programmatic inspection so callers don't have to traverse the full tree.

func Compile

func Compile(ctx context.Context, s *spec.Spec, opts CompileOptions) (*CompiledPlan, error)

Compile runs Validate → Plan → Execute → Encode and returns a CompiledPlan. The result is renderer-agnostic; pass it to RenderPlan to produce pixel bytes. Typical cost is dominated by the executor (data I/O + aggregation); the marshalled CompiledPlan itself is light. Callers that want only the plan summary can discard CompiledPlan.Scene to drop the full IR.

func CompileJSON

func CompileJSON(ctx context.Context, specJSON []byte, opts CompileOptions) (*CompiledPlan, error)

CompileJSON decodes specJSON and delegates to Compile.

type CompiledScale

type CompiledScale struct {
	SceneID string          `json:"scene_id"`
	Channel scene.Channel   `json:"channel"`
	Type    scene.ScaleType `json:"type"`
	Domain  []any           `json:"domain"`
	Range   [2]float64      `json:"range"`
}

CompiledScale is the post-resolve scale descriptor for one channel. Domain values are typed `any` because categorical scales carry strings while quantitative scales carry numbers / times.

type DataBinding

type DataBinding struct {
	Name     string `json:"name"`
	Hash     string `json:"hash,omitempty"`
	Resolved bool   `json:"resolved"`
}

DataBinding is one dataset reference resolved during compile. Resolved is always true when present in the CompiledPlan (compile failed otherwise); the field is retained for forward-compatibility with the data-reference variant which can produce data-pending states.

type Diagnostic

type Diagnostic struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Path    string `json:"path,omitempty"`
}

Diagnostic mirrors a SceneDoc warning. Code is a PRISM_WARN_* (or any future PRISM_* code emitted during compile); Path is the layer / channel context when known.

type LayoutInfo

type LayoutInfo struct {
	Width  float64 `json:"width"`
	Height float64 `json:"height"`
	Rows   int     `json:"rows"`
	Cols   int     `json:"cols"`
}

LayoutInfo carries the resolved chart-frame dimensions and the composition grid shape (rows/cols).

type Patch

type Patch []PatchOp

Patch is an RFC 6902 JSON Patch — an ordered list of operations to transform one spec into another. Use ApplyPatch to apply a patch to a spec; DiffSpecs to compute one between two specs.

Atomic semantics: ApplyPatch either succeeds with every operation applied, or fails with no state change. A failing operation's index is returned in the error envelope.

func DiffSpecs

func DiffSpecs(before, after *spec.Spec) (Patch, error)

DiffSpecs returns a Patch that, when applied to before, produces after. The result is a sequence of `replace` / `add` / `remove` operations expressed against the JSON form of the specs — not necessarily the minimal patch, but a correct one. Useful for callers that want to think in full specs and transmit minimal updates.

type PatchOp

type PatchOp struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value any    `json:"value,omitempty"`
	From  string `json:"from,omitempty"`
}

PatchOp is one RFC 6902 operation.

Op:    "add" | "remove" | "replace" | "move" | "copy" | "test"
Path:  JSON Pointer (RFC 6901) targeting the value to operate on.
Value: required for add / replace / test.
From:  required for move / copy (the source pointer).

type Scene

type Scene struct {
	// contains filtered or unexported fields
}

Scene is a stateful wrapper around a Prism spec + its last CompiledPlan. Use it when the consumer wants to evolve a chart incrementally via patches: each Apply mutates the in-memory spec and re-compiles, exposing the new plan via Plan().

Scene is not safe for concurrent use; serialise Apply calls externally if multiple goroutines drive a single scene.

func NewScene

func NewScene(ctx context.Context, s *spec.Spec, opts CompileOptions) (*Scene, error)

NewScene compiles an initial spec and returns a Scene bound to it. The returned Scene can be patched via Apply / ApplyAndRender.

func (*Scene) Apply

func (s *Scene) Apply(p Patch) error

Apply transforms the scene's spec by the given RFC 6902 patch and re-compiles. The mutation is atomic: if any operation fails, or the resulting spec fails to decode / re-compile, the scene's state is unchanged and the error envelope explains why.

func (*Scene) ApplyAndRender

func (s *Scene) ApplyAndRender(p Patch) (*CompiledPlan, error)

ApplyAndRender applies the patch and returns the updated plan in one call. It is shorthand for Apply followed by Plan(). The "render" half of the name follows the upgrade-spec API; the returned object is the structured CompiledPlan — callers wanting pixels should hand it to a Renderer.

func (*Scene) Plan

func (s *Scene) Plan() *CompiledPlan

Plan returns the most recent CompiledPlan.

func (*Scene) Spec

func (s *Scene) Spec() *spec.Spec

Spec returns the scene's current *spec.Spec. The returned value is shared with the scene; callers should not mutate it directly — patches must travel through Apply / ApplyAndRender so the compiled plan stays in sync.

Directories

Path Synopsis
cmd
prism command
Command prism is the CLI entry point for the Prism visualization library.
Command prism is the CLI entry point for the Prism visualization library.
prismwasm command
Command prismwasm is the WebAssembly entry point for the Prism visualization library.
Command prismwasm is the WebAssembly entry point for the Prism visualization library.
Package compile holds the cross-backend types used by Prism's compile stage: the Backend interface alias, the friendly aggregate alias map, and the expression-passthrough shim that wraps expr-lang/expr exactly the way Pulse's processing/filterer.go does.
Package compile holds the cross-backend types used by Prism's compile stage: the Backend interface alias, the friendly aggregate alias map, and the expression-passthrough shim that wraps expr-lang/expr exactly the way Pulse's processing/filterer.go does.
inmem
Package inmem is the default P04 implementation of plan.Backend.
Package inmem is the default P04 implementation of plan.Backend.
format
Package format implements a small subset of the d3-format mini-DSL plus a strftime-style mini-mapping for time formats.
Package format implements a small subset of the d3-format mini-DSL plus a strftime-style mini-mapping for time formats.
marks
Package marks holds the per-mark encoders that turn rows of a materialised table into scene.Mark entries with pixel-resolved geometry.
Package marks holds the per-mark encoders that turn rows of a materialised table into scene.Mark entries with pixel-resolved geometry.
marks/layout
Package layout holds the shared graph + tree layout helpers used by the encode/marks tree, dendrogram, and network encoders.
Package layout holds the shared graph + tree layout helpers used by the encode/marks tree, dendrogram, and network encoders.
projection
Package projection maps geographic coordinates (longitude / latitude in degrees) to plot-space pixels for the geoshape mark family.
Package projection maps geographic coordinates (longitude / latitude in degrees) to plot-space pixels for the geoshape mark family.
resolve
Package resolve carries cross-layer scale + axis resolution.
Package resolve carries cross-layer scale + axis resolution.
scale
Package scale holds the per-type scale implementations consumed by the encode stage.
Package scale holds the per-type scale implementations consumed by the encode stage.
scene
Package scene holds the Prism Scene IR — the renderer-agnostic intermediate representation produced by the encode stage and consumed by every Renderer (SVG ships in P05; PNG / PDF / canvas land in later phases).
Package scene holds the Prism Scene IR — the renderer-agnostic intermediate representation produced by the encode stage and consumed by every Renderer (SVG ships in P05; PNG / PDF / canvas land in later phases).
Package errors defines Prism's typed application errors and the code catalog with fixup metadata.
Package errors defines Prism's typed application errors and the code catalog with fixup metadata.
Package geodata embeds vector boundary data (countries + admin-1 regions) for Prism's geoshape mark.
Package geodata embeds vector boundary data (countries + admin-1 regions) for Prism's geoshape mark.
internal
devtools
Package devtools holds Go-side tooling tests that don't fit any runtime package.
Package devtools holds Go-side tooling tests that don't fit any runtime package.
devtools/gen-fixtures command
Command gen-fixtures regenerates the deterministic .pulse fixtures used by Prism tests.
Command gen-fixtures regenerates the deterministic .pulse fixtures used by Prism tests.
limits
Package limits centralises the env-driven memory ceilings declared in DECISIONS.md D007.
Package limits centralises the env-driven memory ceilings declared in DECISIONS.md D007.
observability
Package observability ships an opt-in OpenTelemetry adapter that bridges Prism's executor hooks (P03's plan.ExecOpts.OnNodeStart / OnNodeDone) to an OTel-emitting Bridge.
Package observability ships an opt-in OpenTelemetry adapter that bridges Prism's executor hooks (P03's plan.ExecOpts.OnNodeStart / OnNodeDone) to an OTel-emitting Bridge.
tools/build_geodata command
Command build_geodata fetches Natural Earth GeoJSON from the public-domain nvkelso/natural-earth-vector GitHub mirror and writes the Prism geo-bundle artifacts under geodata/:
Command build_geodata fetches Natural Earth GeoJSON from the public-domain nvkelso/natural-earth-vector GitHub mirror and writes the Prism geo-bundle artifacts under geodata/:
validatorutil
Package validatorutil shares the SchemaLookup construction logic the CLI's `prism validate` command and the Twirp `Validate` RPC both need.
Package validatorutil shares the SchemaLookup construction logic the CLI's `prism validate` command and the Twirp `Validate` RPC both need.
Package mcp wires Prism into the Model Context Protocol via mark3labs/mcp-go (D008 parity with Pulse, pinned at v0.54.0).
Package mcp wires Prism into the Model Context Protocol via mark3labs/mcp-go (D008 parity with Pulse, pinned at v0.54.0).
Package plan holds Prism's logical DAG: the Node interface every node type satisfies, the immutable DAG type with structural-sharing optimizer passes, the sequential / bounded-pool executor, and the DOT / text / JSON renderers used by `prism plan`.
Package plan holds Prism's logical DAG: the Node interface every node type satisfies, the immutable DAG type with structural-sharing optimizer passes, the sequential / bounded-pool executor, and the DOT / text / JSON renderers used by `prism plan`.
build
Package build translates a *spec.Spec into a *plan.DAG.
Package build translates a *spec.Spec into a *plan.DAG.
nodes
Package nodes holds the DAG node implementations.
Package nodes holds the DAG node implementations.
passes
Package passes holds the optimizer passes.
Package passes holds the optimizer passes.
Package render carries the cross-renderer surface: the Renderer interface every output backend satisfies, the RenderOpts shape, and the RenderPrecision constant that pins float formatting across the SVG (P05), PNG (P12), PDF (P15), and canvas-JSON (P12) backends.
Package render carries the cross-renderer surface: the Renderer interface every output backend satisfies, the RenderOpts shape, and the RenderPrecision constant that pins float formatting across the SVG (P05), PNG (P12), PDF (P15), and canvas-JSON (P12) backends.
pdf
Package pdf is the Prism PDF renderer.
Package pdf is the Prism PDF renderer.
svg
Package svg implements render.Renderer for SVG output.
Package svg implements render.Renderer for SVG output.
Package resolve maps user-facing dataset refs to a (ReadCloser, Schema) pair.
Package resolve maps user-facing dataset refs to a (ReadCloser, Schema) pair.
Package rpc carries the Twirp service implementation for Prism.
Package rpc carries the Twirp service implementation for Prism.
Package schema embeds the canonical Prism JSON Schema bundle and exposes a loader for downstream packages.
Package schema embeds the canonical Prism JSON Schema bundle and exposes a loader for downstream packages.
Package selection defines the canonical structured selection event emitted by every Prism rendering context (Go-native, WASM/browser, Twirp /prism/scene).
Package selection defines the canonical structured selection event emitted by every Prism rendering context (Go-native, WASM/browser, Twirp /prism/scene).
Package spec contains the Go types that mirror the Prism v1 JSON schema bundle (schema/v1/*.json).
Package spec contains the Go types that mirror the Prism v1 JSON schema bundle (schema/v1/*.json).
Package staticfs exposes the vendored Prism browser assets (prism.mjs, prism-element.mjs, prism-resolver.mjs, prism-selection.mjs, d3/*.mjs, the README files) as an embed.FS so commands compiled from cmd/prism can extract or serve them without depending on the repo layout at runtime.
Package staticfs exposes the vendored Prism browser assets (prism.mjs, prism-element.mjs, prism-resolver.mjs, prism-selection.mjs, d3/*.mjs, the README files) as an embed.FS so commands compiled from cmd/prism can extract or serve them without depending on the repo layout at runtime.
Package table holds Prism's columnar in-memory table type (`Table`), shared by every DAG node from Source through Encode.
Package table holds Prism's columnar in-memory table type (`Table`), shared by every DAG node from Source through Encode.
Package theme owns the resolved-theme registry, JSON loader, and sparse-override engine.
Package theme owns the resolved-theme registry, JSON loader, and sparse-override engine.
Package validate runs the two-stage Prism spec validator:
Package validate runs the two-stage Prism spec validator:
rules
Package rules holds the individual SemanticRule implementations that fire PRISM_SPEC_* error codes.
Package rules holds the individual SemanticRule implementations that fire PRISM_SPEC_* error codes.

Jump to

Keyboard shortcuts

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