spec

package
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: 4 Imported by: 0

Documentation

Overview

Package spec contains the Go types that mirror the Prism v1 JSON schema bundle (schema/v1/*.json). Decoding is strict: unknown fields fail. Use Decode to read a spec from an io.Reader; it sets DisallowUnknownFields and returns the typed *Spec.

Type structure intentionally uses pointer-to-struct for optional nested blocks so omitempty works correctly with json.Marshal.

Index

Constants

View Source
const (
	AnimationDefaultDurationMs = 400
	AnimationDefaultEasing     = "cubic_in_out"
	AnimationDefaultStaggerMs  = 0
	AnimationDefaultEnter      = "fade"
	AnimationDefaultExit       = "fade"

	AnimationMaxDurationMs = 5000
	AnimationMaxStaggerMs  = 1000
)

Defaults applied at encode time. Kept here so the validator and the encoder agree on the empty-field semantics.

Variables

View Source
var AnimationEasings = []string{
	"linear",
	"cubic_in", "cubic_out", "cubic_in_out",
	"quad_in", "quad_out", "quad_in_out",
	"sine_in", "sine_out", "sine_in_out",
	"expo_in", "expo_out", "expo_in_out",
}

AnimationEasings is the canonical set of accepted easing names. Validation rule animation_easing_known enforces membership.

View Source
var AnimationEnterExit = []string{"fade", "none"}

AnimationEnterExit is the set of accepted enter/exit modes.

Functions

This section is empty.

Types

type AggregateOp

type AggregateOp struct {
	Op    string `json:"op"`
	Field string `json:"field,omitempty"`
	As    string `json:"as"`
}

AggregateOp is one aggregate calculation.

type AggregateTransform

type AggregateTransform struct {
	Aggregate []AggregateOp `json:"aggregate"`
	Groupby   []string      `json:"groupby,omitempty"`
	Data      string        `json:"data,omitempty"`
	As        string        `json:"as,omitempty"`
}

AggregateTransform: group-by aggregate.

type Animation

type Animation struct {
	DurationMs *int   `json:"duration_ms,omitempty"`
	Easing     string `json:"easing,omitempty"`
	StaggerMs  *int   `json:"stagger_ms,omitempty"`
	Enter      string `json:"enter,omitempty"`
	Exit       string `json:"exit,omitempty"`
}

Animation declares an optional client-side tween between successive scenes. Animation hints live in the Scene IR but are honoured only by the browser web component and the WASM runtime; static SVG and PDF renderers ignore the block entirely so their output stays terminal.

At most one encoding channel may carry `key: true`; that channel's resolved value becomes the per-mark identity used to diff old vs new scenes (enter / update / exit partitioning).

type Axis

type Axis struct {
	Orient       string   `json:"orient,omitempty"`
	Title        any      `json:"title,omitempty"`
	Format       string   `json:"format,omitempty"`
	TickCount    *int     `json:"tick_count,omitempty"`
	TickMinStep  *float64 `json:"tick_min_step,omitempty"`
	TickSize     *float64 `json:"tick_size,omitempty"`
	Values       []any    `json:"values,omitempty"`
	Grid         *bool    `json:"grid,omitempty"`
	Labels       *bool    `json:"labels,omitempty"`
	LabelAngle   *float64 `json:"label_angle,omitempty"`
	LabelOverlap any      `json:"label_overlap,omitempty"`
	LabelPadding *float64 `json:"label_padding,omitempty"`
	LabelLimit   *float64 `json:"label_limit,omitempty"`
	Domain       *bool    `json:"domain,omitempty"`
	Ticks        *bool    `json:"ticks,omitempty"`
	Zindex       *int     `json:"zindex,omitempty"`
}

Axis models the axis block on a position channel.

type BinSpec

type BinSpec struct {
	Auto    *bool
	Maxbins *int      `json:"maxbins,omitempty"`
	Step    *float64  `json:"step,omitempty"`
	Extent  []float64 `json:"extent,omitempty"`
}

BinSpec is either a bool (auto) or an object with bin params.

type BinTransform

type BinTransform struct {
	Bin   any    `json:"bin"`
	Field string `json:"field"`
	As    string `json:"as"`
	Data  string `json:"data,omitempty"`
}

BinTransform: numeric bin.

type CalculateTransform

type CalculateTransform struct {
	Calculate string `json:"calculate"`
	As        string `json:"as"`
	Data      string `json:"data,omitempty"`
}

CalculateTransform: compute new column.

type ChannelCommon

type ChannelCommon struct {
	Field     string     `json:"field,omitempty"`
	FieldRef  *RepeatRef `json:"-"`
	Type      string     `json:"type,omitempty"`
	Aggregate string     `json:"aggregate,omitempty"`
	Scale     *Scale     `json:"scale,omitempty"`
	Title     string     `json:"title,omitempty"`
	Format    string     `json:"format,omitempty"`
	Bin       any        `json:"bin,omitempty"`
	Sort      any        `json:"sort,omitempty"`
	Value     any        `json:"value,omitempty"`
	// Condition carries a per-channel conditional encoding clause.
	// nil for unconditional channels (the common case). See
	// spec/condition.go and validate rules PRISM_SPEC_025/026/027.
	Condition *Condition `json:"condition,omitempty"`
	// Key marks this channel as the join key used by the client-side
	// animator to match marks across successive scenes (object
	// constancy). At most one channel per encoding block may set this;
	// the validator enforces uniqueness via PRISM_SPEC_024.
	Key bool `json:"key,omitempty"`
}

ChannelCommon holds the fields shared by every channel class.

Field is the bare field-name binding. FieldRef carries the {"repeat": "row"|"column"} substitution placeholder when the spec uses the polymorphic form; the build-time repeat walker (plan/build/composite.go) rewrites FieldRef into Field per cell. At most one of the two is populated for a given channel — never both. See D055.

type Condition

type Condition struct {
	Single *ConditionTest  `json:"-"`
	Multi  []ConditionTest `json:"-"`
}

Condition is the per-channel conditional encoding clause. JSON form accepts either a single test object or an ordered array of test objects evaluated in order; the first match wins. The "otherwise" branch is supplied by the channel's own `value` (or `field`/`type`) at the surrounding ChannelCommon level.

See `.planning/tier1-01-condition-encodings-plan.md` and docs/src/concepts/encoding.md (Conditions).

func (*Condition) Entries

func (c *Condition) Entries() []ConditionTest

Entries returns the condition list in iteration order regardless of whether the spec used the single-object or array form.

func (Condition) MarshalJSON

func (c Condition) MarshalJSON() ([]byte, error)

MarshalJSON emits a single object or an array depending on which field is populated.

func (*Condition) UnmarshalJSON

func (c *Condition) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts either an array (Multi) or an object (Single) of ConditionTest entries.

type ConditionTest

type ConditionTest struct {
	Selection string `json:"selection,omitempty"`
	Test      string `json:"test,omitempty"`
	Field     string `json:"field,omitempty"`
	Type      string `json:"type,omitempty"`
	Value     any    `json:"value,omitempty"`
	Scale     *Scale `json:"scale,omitempty"`
}

ConditionTest is one entry in a condition list. Exactly one of {Selection, Test} must be set (enforced by validate rule PRISM_SPEC_025/026). Exactly one of {Value, Field} must be set — PRISM_SPEC_027 — except that a selection-form entry with no Value inherits the channel's own field binding implicitly.

type Config

type Config struct {
	Background string         `json:"background,omitempty"`
	Padding    *Padding       `json:"padding,omitempty"`
	Font       string         `json:"font,omitempty"`
	FontSize   float64        `json:"font_size,omitempty"`
	Color      string         `json:"color,omitempty"`
	Mark       map[string]any `json:"mark,omitempty"`
	Axis       map[string]any `json:"axis,omitempty"`
	Legend     map[string]any `json:"legend,omitempty"`
	Scale      map[string]any `json:"scale,omitempty"`
	Title      map[string]any `json:"title,omitempty"`
}

Config is the inline spec-level config block. Values override registered theme defaults but lose to inline spec properties.

type Data

type Data struct {
	Source string `json:"source,omitempty"`
	// Ref is an opaque identifier resolved at compile time by the
	// caller-supplied DataResolver (see resolve.DataResolver / the
	// WASM `prism.setDataResolver` hook). Lets a spec stay portable
	// across rendering environments: the spec describes *what to
	// draw*; the resolver supplies *the data to draw it with*.
	Ref    string `json:"ref,omitempty"`
	Format string `json:"format,omitempty"`
	Name   string `json:"name,omitempty"`

	// Inline-only fields.
	Values []map[string]any `json:"values,omitempty"`
	Fields []FieldSpec      `json:"fields,omitempty"`

	// FeatureCollection synthesizes a table with one row per feature in
	// the named geodata tier. Used for "render every country" basemap
	// charts: pair with mark=geoshape and the encoder walks the
	// embedded manifest. Tier defaults to "world-110m" when empty.
	FeatureCollection *FeatureCollectionRef `json:"feature_collection,omitempty"`
}

Data is the data binding: source path, named ref, runtime resolver ref, inline values, or a synthesized feature_collection (geoshape basemap mode). The discriminator is which key is present.

func (*Data) UnmarshalJSON

func (d *Data) UnmarshalJSON(data []byte) error

UnmarshalJSON enforces strict decode and picks the variant from the keys present.

type DetailChannel

type DetailChannel struct {
	Single *DetailChannelEntry
	Multi  []DetailChannelEntry
}

DetailChannel is either a single entry or an array.

func (DetailChannel) MarshalJSON

func (c DetailChannel) MarshalJSON() ([]byte, error)

MarshalJSON emits the underlying form.

func (*DetailChannel) UnmarshalJSON

func (c *DetailChannel) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts either form.

type DetailChannelEntry

type DetailChannelEntry struct {
	Field     string `json:"field,omitempty"`
	Type      string `json:"type,omitempty"`
	Aggregate string `json:"aggregate,omitempty"`
}

DetailChannelEntry is one detail-channel element.

type Dimension

type Dimension struct {
	Number *float64
	Token  string
}

Dimension is either a numeric pixel value or a token string ("container", "step", etc.).

func (Dimension) MarshalJSON

func (d Dimension) MarshalJSON() ([]byte, error)

MarshalJSON emits either the number or the token.

func (*Dimension) UnmarshalJSON

func (d *Dimension) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts a number or string.

type Encoding

type Encoding struct {
	X         *PositionChannel `json:"x,omitempty"`
	Y         *PositionChannel `json:"y,omitempty"`
	X2        *PositionChannel `json:"x2,omitempty"`
	Y2        *PositionChannel `json:"y2,omitempty"`
	Theta     *PositionChannel `json:"theta,omitempty"`
	Radius    *PositionChannel `json:"radius,omitempty"`
	Color     *MarkChannel     `json:"color,omitempty"`
	Fill      *MarkChannel     `json:"fill,omitempty"`
	Stroke    *MarkChannel     `json:"stroke,omitempty"`
	Opacity   *MarkChannel     `json:"opacity,omitempty"`
	Size      *MarkChannel     `json:"size,omitempty"`
	Shape     *MarkChannel     `json:"shape,omitempty"`
	Text      *TextChannel     `json:"text,omitempty"`
	Tooltip   *TooltipChannel  `json:"tooltip,omitempty"`
	Order     *OrderChannel    `json:"order,omitempty"`
	Detail    *DetailChannel   `json:"detail,omitempty"`
	Row       *FacetChannel    `json:"row,omitempty"`
	Column    *FacetChannel    `json:"column,omitempty"`
	Source    *MarkChannel     `json:"source,omitempty"`
	Target    *MarkChannel     `json:"target,omitempty"`
	Value     *MarkChannel     `json:"value,omitempty"`
	Longitude *MarkChannel     `json:"longitude,omitempty"`
	Latitude  *MarkChannel     `json:"latitude,omitempty"`
	// Feature is the geoshape-specific binding: the table field whose
	// values are geodata feature IDs (e.g. "USA", "US-CA"). Resolves
	// to polygon geometry via the geodata.Store.
	Feature *MarkChannel `json:"feature,omitempty"`
}

Encoding is the map of channel name → channel binding for a leaf spec.

Source / Target / Value (P11) are sankey-specific bindings carrying a field name without an axis scale. See D064.

type Facet

type Facet struct {
	Row    *FacetChannel `json:"row,omitempty"`
	Column *FacetChannel `json:"column,omitempty"`
}

Facet binds row/column facet channels for small multiples.

type FacetChannel

type FacetChannel struct {
	Field  string            `json:"field,omitempty"`
	Type   string            `json:"type,omitempty"`
	Sort   any               `json:"sort,omitempty"`
	Header *FacetChannelHead `json:"header,omitempty"`
}

FacetChannel binds a field for row/column facetting.

type FacetChannelHead

type FacetChannelHead struct {
	Title  string `json:"title,omitempty"`
	Labels *bool  `json:"labels,omitempty"`
}

FacetChannelHead carries optional header rendering options.

type FeatureCollectionRef

type FeatureCollectionRef struct {
	Tier string `json:"tier,omitempty"`
}

FeatureCollectionRef binds a Data block to a geodata tier. Currently carries only the tier name; future fields could add per-feature filtering (regions=continent_codes, parent_in=[...]).

type FieldSpec

type FieldSpec struct {
	Name string `json:"name"`
	Type string `json:"type"`
}

FieldSpec optionally types an inline dataset column.

type FilterTransform

type FilterTransform struct {
	Filter string `json:"filter"`
	Data   string `json:"data,omitempty"`
	As     string `json:"as,omitempty"`
}

FilterTransform: row predicate.

type IntervalMarkProp

type IntervalMarkProp struct {
	Fill        string   `json:"fill,omitempty"`
	FillOpacity *float64 `json:"fill_opacity,omitempty"`
	Stroke      string   `json:"stroke,omitempty"`
	StrokeWidth *float64 `json:"stroke_width,omitempty"`
}

IntervalMarkProp is the brush rectangle styling.

type IntervalSelection

type IntervalSelection struct {
	Type      string            `json:"type"`
	Encodings []string          `json:"encodings,omitempty"`
	Mark      *IntervalMarkProp `json:"mark,omitempty"`
	Translate any               `json:"translate,omitempty"`
	Zoom      any               `json:"zoom,omitempty"`
	On        string            `json:"on,omitempty"`
}

IntervalSelection captures a continuous range over one or more channels.

type JoinTransform

type JoinTransform struct {
	Join string `json:"join"`
	With string `json:"with"`
	On   any    `json:"on"`
	Data string `json:"data,omitempty"`
	As   string `json:"as,omitempty"`
}

JoinTransform: equality join.

type Legend

type Legend struct {
	Type       string   `json:"type,omitempty"`
	Orient     string   `json:"orient,omitempty"`
	Title      any      `json:"title,omitempty"`
	Direction  string   `json:"direction,omitempty"`
	Format     string   `json:"format,omitempty"`
	TickCount  *int     `json:"tick_count,omitempty"`
	Values     []any    `json:"values,omitempty"`
	SymbolType string   `json:"symbol_type,omitempty"`
	SymbolSize *float64 `json:"symbol_size,omitempty"`
	Padding    *float64 `json:"padding,omitempty"`
	Offset     *float64 `json:"offset,omitempty"`
	LabelLimit *float64 `json:"label_limit,omitempty"`
}

Legend models the legend block on a mark channel.

type LimitTransform

type LimitTransform struct {
	Limit  int    `json:"limit"`
	Offset *int   `json:"offset,omitempty"`
	Data   string `json:"data,omitempty"`
	As     string `json:"as,omitempty"`
}

LimitTransform: head with optional offset.

type Mark

type Mark struct {
	// Shorthand is the bare mark type string ("bar", "line", ...).
	Shorthand string
	// Def is the full mark definition. When Shorthand is set, Def is nil
	// and vice versa.
	Def *MarkDef
}

Mark is the discriminated mark form: string shorthand or full mark_def object. The discriminator is the JSON type of the input. UnmarshalJSON is implemented in mark_union.go (T01.14).

func (Mark) MarshalJSON

func (m Mark) MarshalJSON() ([]byte, error)

MarshalJSON emits either the bare type-string shorthand or the full mark definition object.

func (*Mark) TypeName

func (m *Mark) TypeName() string

TypeName returns the effective mark type regardless of input form.

func (*Mark) UnmarshalJSON

func (m *Mark) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts either a string ("bar", "line", ...) or a full MarkDef object. The discriminator is the JSON token kind.

type MarkChannel

type MarkChannel struct {
	ChannelCommon
	Legend *Legend `json:"legend,omitempty"`
}

MarkChannel adds legend to ChannelCommon.

func (*MarkChannel) UnmarshalJSON

func (m *MarkChannel) UnmarshalJSON(data []byte) error

UnmarshalJSON intercepts the `field` key for the same reason as PositionChannel.

type MarkDef

type MarkDef struct {
	Type          string    `json:"type"`
	Fill          string    `json:"fill,omitempty"`
	Stroke        string    `json:"stroke,omitempty"`
	StrokeWidth   *float64  `json:"stroke_width,omitempty"`
	StrokeDash    []float64 `json:"stroke_dash,omitempty"`
	Opacity       *float64  `json:"opacity,omitempty"`
	FillOpacity   *float64  `json:"fill_opacity,omitempty"`
	StrokeOpacity *float64  `json:"stroke_opacity,omitempty"`
	CornerRadius  *float64  `json:"corner_radius,omitempty"`
	Size          *float64  `json:"size,omitempty"`
	Shape         string    `json:"shape,omitempty"`
	Interpolate   string    `json:"interpolate,omitempty"`
	Tension       *float64  `json:"tension,omitempty"`
	Orient        string    `json:"orient,omitempty"`
	Align         string    `json:"align,omitempty"`
	Baseline      string    `json:"baseline,omitempty"`
	Font          string    `json:"font,omitempty"`
	FontSize      *float64  `json:"font_size,omitempty"`
	FontWeight    any       `json:"font_weight,omitempty"`
	FontStyle     string    `json:"font_style,omitempty"`
	Angle         *float64  `json:"angle,omitempty"`
	Dx            *float64  `json:"dx,omitempty"`
	Dy            *float64  `json:"dy,omitempty"`
	Tooltip       any       `json:"tooltip,omitempty"`
	InnerRadius   *float64  `json:"inner_radius,omitempty"`
	OuterRadius   *float64  `json:"outer_radius,omitempty"`
	// InnerRadiusRatio (P10) is the donut hole's inner radius as a
	// fraction of OuterR (0–1). When set, takes precedence over the
	// default donut ratio (0.55). Ignored when InnerRadius is also
	// set (InnerRadius is absolute pixels, wins).
	InnerRadiusRatio *float64 `json:"inner_radius_ratio,omitempty"`
	PadAngle         *float64 `json:"pad_angle,omitempty"`
	URL              string   `json:"url,omitempty"`
	Path             string   `json:"path,omitempty"`
	// Maxbins (P10) caps the bin count for histogram marks. nil = use
	// Sturges' rule default (ceil(log2(n) + 1)).
	Maxbins *int `json:"maxbins,omitempty"`
	// ViolinResolution (P10) sets the number of KDE sample points per
	// violin group. nil = 64 (the D061 default).
	ViolinResolution *int `json:"violin_resolution,omitempty"`
	// LinkShape (tree / dendrogram, tier1-04) — "step" | "curve" |
	// "straight". Default "step".
	LinkShape string `json:"link_shape,omitempty"`
	// NodeShape (tree / network) — "circle" | "rect" | "none".
	// Default "circle".
	NodeShape string `json:"node_shape,omitempty"`
	// NodeSize (tree / network) — base node radius / side length.
	// Default 6.
	NodeSize *float64 `json:"node_size,omitempty"`
	// Layout (network) — "force" | "random". Default "force".
	Layout string `json:"layout,omitempty"`
	// Iterations (network) — force iterations. Default 200, cap 2000.
	Iterations *int `json:"iterations,omitempty"`
	// LinkDistance (network) — preferred edge length. Default 30.
	LinkDistance *float64 `json:"link_distance,omitempty"`
	// Charge (network) — repulsion strength. Default -30.
	Charge *float64 `json:"charge,omitempty"`
	// Seed (network) — deterministic seed for the force layout.
	// Default 42.
	Seed *int64 `json:"seed,omitempty"`
}

MarkDef carries all per-mark visual properties. Fields are pointer-typed where a meaningful zero (e.g. 0 stroke width vs unset) must be preserved.

type OrderChannel

type OrderChannel struct {
	Single *OrderChannelEntry
	Multi  []OrderChannelEntry
}

OrderChannel is either a single entry or an array.

func (OrderChannel) MarshalJSON

func (c OrderChannel) MarshalJSON() ([]byte, error)

MarshalJSON emits a single entry or array.

func (*OrderChannel) UnmarshalJSON

func (c *OrderChannel) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts either form.

type OrderChannelEntry

type OrderChannelEntry struct {
	Field     string `json:"field,omitempty"`
	Type      string `json:"type,omitempty"`
	Aggregate string `json:"aggregate,omitempty"`
	Sort      string `json:"sort,omitempty"`
}

OrderChannelEntry is one element in an order channel.

type Padding

type Padding struct {
	Uniform *float64
	Top     *float64
	Right   *float64
	Bottom  *float64
	Left    *float64
}

Padding is either a uniform pixel value or a per-side map.

func (Padding) MarshalJSON

func (p Padding) MarshalJSON() ([]byte, error)

MarshalJSON emits a uniform number or a per-side object.

func (*Padding) UnmarshalJSON

func (p *Padding) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts a number or a per-side object.

type PivotTransform

type PivotTransform struct {
	Pivot   string   `json:"pivot"`
	Value   string   `json:"value"`
	Groupby []string `json:"groupby,omitempty"`
	Op      string   `json:"op,omitempty"`
	Data    string   `json:"data,omitempty"`
	As      string   `json:"as,omitempty"`
}

PivotTransform: long → wide.

type PointSelection

type PointSelection struct {
	Type      string   `json:"type"`
	Fields    []string `json:"fields,omitempty"`
	Encodings []string `json:"encodings,omitempty"`
	Toggle    any      `json:"toggle,omitempty"`
	Nearest   *bool    `json:"nearest,omitempty"`
	Empty     string   `json:"empty,omitempty"`
	On        string   `json:"on,omitempty"`
}

PointSelection captures discrete marks.

type PositionChannel

type PositionChannel struct {
	ChannelCommon
	Axis  *Axis `json:"axis,omitempty"`
	Stack any   `json:"stack,omitempty"`
}

PositionChannel adds axis + stack to ChannelCommon.

func (*PositionChannel) UnmarshalJSON

func (p *PositionChannel) UnmarshalJSON(data []byte) error

UnmarshalJSON intercepts the `field` key so the channel accepts either a bare string or a {"repeat": <axis>} substitution object. All other keys decode through the default struct path; unknown keys still error per Decode's DisallowUnknownFields setting.

type Projection

type Projection struct {
	Type      string      `json:"type,omitempty"`
	Scale     *float64    `json:"scale,omitempty"`
	Center    *[2]float64 `json:"center,omitempty"`
	Rotate    *[3]float64 `json:"rotate,omitempty"`
	Translate *[2]float64 `json:"translate,omitempty"`
	// Tier is the geodata tier the encoder looks up feature geometry
	// from. Defaults to "world-110m" for admin-0 charts; admin-1 charts
	// must request "admin1-50m" explicitly.
	Tier string `json:"tier,omitempty"`
}

Projection configures the lon/lat → pixel mapping used by the geoshape and geopoint marks. Mirrors d3-geo's projection API but pared down to the parameters Prism's projection package actually honours.

Fields are pointer-typed where a meaningful zero (e.g. scale=0 meaning "auto-fit") must be distinguishable from "unset". Strings hold no semantic zero — empty means default.

type Repeat

type Repeat struct {
	Row    []string `json:"row,omitempty"`
	Column []string `json:"column,omitempty"`
	Layer  []string `json:"layer,omitempty"`
}

Repeat lists field names to repeat over.

type RepeatRef

type RepeatRef struct {
	// Axis is "row" or "column"; any other value is accepted at
	// decode time but rejected at build-time substitution.
	Axis string `json:"repeat"`
}

RepeatRef is the in-memory representation of the {"repeat": "row"|"column"} substitution allowed in any channel that accepts a field name. Per D055 the substitution is a pure JSON field-name swap applied at build time by the repeat composite walker (plan/build/composite.go). The walker resolves a RepeatRef to a bare field-name string by looking up Axis in the parent's repeat bindings; unknown axes raise PRISM_SPEC_012.

Example raw JSON:

{"field": {"repeat": "row"}}

After substitution the channel becomes:

{"field": "score"}

At the spec layer both forms decode to the same struct; the distinction lives on whether Field (the bare string) or FieldRef (the {repeat: axis} placeholder) is populated.

type Resolve

type Resolve struct {
	Scale  *ResolveChannelMap `json:"scale,omitempty"`
	Axis   *ResolveChannelMap `json:"axis,omitempty"`
	Legend *ResolveChannelMap `json:"legend,omitempty"`
}

Resolve maps per-channel modes for scale/axis/legend resolution.

type ResolveChannelMap

type ResolveChannelMap struct {
	X       string `json:"x,omitempty"`
	Y       string `json:"y,omitempty"`
	X2      string `json:"x2,omitempty"`
	Y2      string `json:"y2,omitempty"`
	Theta   string `json:"theta,omitempty"`
	Radius  string `json:"radius,omitempty"`
	Color   string `json:"color,omitempty"`
	Fill    string `json:"fill,omitempty"`
	Stroke  string `json:"stroke,omitempty"`
	Opacity string `json:"opacity,omitempty"`
	Size    string `json:"size,omitempty"`
	Shape   string `json:"shape,omitempty"`
}

ResolveChannelMap holds per-channel "shared" or "independent" tokens.

type SampleTransform

type SampleTransform struct {
	Sample int    `json:"sample"`
	Seed   *int64 `json:"seed,omitempty"`
	Data   string `json:"data,omitempty"`
	As     string `json:"as,omitempty"`
}

SampleTransform: random subsample.

type Scale

type Scale struct {
	Type         string   `json:"type,omitempty"`
	Domain       any      `json:"domain,omitempty"`
	Range        any      `json:"range,omitempty"`
	Scheme       string   `json:"scheme,omitempty"`
	Padding      *float64 `json:"padding,omitempty"`
	PaddingInner *float64 `json:"padding_inner,omitempty"`
	PaddingOuter *float64 `json:"padding_outer,omitempty"`
	Align        *float64 `json:"align,omitempty"`
	Base         *float64 `json:"base,omitempty"`
	Exponent     *float64 `json:"exponent,omitempty"`
	Nice         any      `json:"nice,omitempty"`
	Clamp        *bool    `json:"clamp,omitempty"`
	Zero         *bool    `json:"zero,omitempty"`
	Reverse      *bool    `json:"reverse,omitempty"`
	Round        *bool    `json:"round,omitempty"`
	Interpolate  string   `json:"interpolate,omitempty"`
}

Scale models the scale block on a channel.

type Selection

type Selection struct {
	Point    *PointSelection    `json:"-"`
	Interval *IntervalSelection `json:"-"`
}

Selection is point or interval; discriminated by the "type" field.

func (Selection) MarshalJSON

func (s Selection) MarshalJSON() ([]byte, error)

MarshalJSON emits the underlying selection variant.

func (*Selection) UnmarshalJSON

func (s *Selection) UnmarshalJSON(data []byte) error

UnmarshalJSON discriminates on the "type" field.

type SortFieldDef

type SortFieldDef struct {
	Field string `json:"field"`
	Order string `json:"order,omitempty"`
}

SortFieldDef is a per-field sort entry.

type SortTransform

type SortTransform struct {
	Sort []SortFieldDef `json:"sort"`
	Data string         `json:"data,omitempty"`
	As   string         `json:"as,omitempty"`
}

SortTransform: order rows by fields.

type Spec

type Spec struct {
	Schema      string               `json:"$schema"`
	Data        *Data                `json:"data,omitempty"`
	Datasets    map[string]*Data     `json:"datasets,omitempty"`
	Transform   []Transform          `json:"transform,omitempty"`
	Mark        *Mark                `json:"mark,omitempty"`
	Encoding    *Encoding            `json:"encoding,omitempty"`
	Layer       []*Spec              `json:"layer,omitempty"`
	Concat      []*Spec              `json:"concat,omitempty"`
	HConcat     []*Spec              `json:"hconcat,omitempty"`
	VConcat     []*Spec              `json:"vconcat,omitempty"`
	Facet       *Facet               `json:"facet,omitempty"`
	Repeat      *Repeat              `json:"repeat,omitempty"`
	ChildSpec   *Spec                `json:"spec,omitempty"`
	Selection   map[string]Selection `json:"selection,omitempty"`
	Resolve     *Resolve             `json:"resolve,omitempty"`
	Theme       *ThemeOverride       `json:"theme,omitempty"`
	Config      *Config              `json:"config,omitempty"`
	Width       *Dimension           `json:"width,omitempty"`
	Height      *Dimension           `json:"height,omitempty"`
	Padding     *Padding             `json:"padding,omitempty"`
	Background  string               `json:"background,omitempty"`
	Title       *TextOrTextObj       `json:"title,omitempty"`
	Subtitle    *TextOrTextObj       `json:"subtitle,omitempty"`
	Description string               `json:"description,omitempty"`
	Projection  *Projection          `json:"projection,omitempty"`
	Animation   *Animation           `json:"animation,omitempty"`
}

Spec is the top-level Prism chart specification. Maps 1:1 to schema/v1/spec.schema.json. Exactly one of mark/layer/concat/hconcat/ vconcat/facet/repeat must be set; the JSON Schema layer enforces this.

func Decode

func Decode(r io.Reader) (*Spec, error)

Decode reads a Prism spec from r with strict decoding enabled (DisallowUnknownFields). All callers in the validator and CLI route through here so the strictness invariant lives in one place.

func DecodeBytes

func DecodeBytes(data []byte) (*Spec, error)

DecodeBytes is the byte-slice convenience wrapper around Decode.

type TextChannel

type TextChannel struct {
	Field     string `json:"field,omitempty"`
	Type      string `json:"type,omitempty"`
	Aggregate string `json:"aggregate,omitempty"`
	Format    string `json:"format,omitempty"`
	Title     string `json:"title,omitempty"`
	Value     any    `json:"value,omitempty"`
}

TextChannel is a slimmer channel for text marks and tooltips.

type TextObj

type TextObj struct {
	Text       string  `json:"text"`
	Font       string  `json:"font,omitempty"`
	FontSize   float64 `json:"font_size,omitempty"`
	FontWeight any     `json:"font_weight,omitempty"`
	FontStyle  string  `json:"font_style,omitempty"`
	Color      string  `json:"color,omitempty"`
	Align      string  `json:"align,omitempty"`
	Baseline   string  `json:"baseline,omitempty"`
}

TextObj carries text properties when the title/subtitle/text encoding is declared in object form rather than as a bare string.

type TextOrTextObj

type TextOrTextObj struct {
	Text *string
	Obj  *TextObj
}

TextOrTextObj is either a bare string or a rich text object.

func (TextOrTextObj) MarshalJSON

func (t TextOrTextObj) MarshalJSON() ([]byte, error)

MarshalJSON emits the underlying string or object.

func (*TextOrTextObj) UnmarshalJSON

func (t *TextOrTextObj) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts a string or rich text object.

type ThemeOverride

type ThemeOverride struct {
	Name       string         `json:"name,omitempty"`
	Background string         `json:"background,omitempty"`
	Font       string         `json:"font,omitempty"`
	FontSize   float64        `json:"font_size,omitempty"`
	Color      string         `json:"color,omitempty"`
	Palette    []string       `json:"palette,omitempty"`
	Scheme     string         `json:"scheme,omitempty"`
	Padding    *Padding       `json:"padding,omitempty"`
	Mark       map[string]any `json:"mark,omitempty"`
	Axis       map[string]any `json:"axis,omitempty"`
	Legend     map[string]any `json:"legend,omitempty"`
	Scale      map[string]any `json:"scale,omitempty"`
	Title      map[string]any `json:"title,omitempty"`
}

ThemeOverride is a sparse override on top of a registered theme.

type TooltipChannel

type TooltipChannel struct {
	Single *TextChannel
	Multi  []TextChannel
}

TooltipChannel is either a single text channel or an array.

func (TooltipChannel) MarshalJSON

func (c TooltipChannel) MarshalJSON() ([]byte, error)

MarshalJSON emits the single channel or the array.

func (*TooltipChannel) UnmarshalJSON

func (c *TooltipChannel) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts either form.

type Transform

type Transform struct {
	Filter    *FilterTransform
	Calculate *CalculateTransform
	Aggregate *AggregateTransform
	Bin       *BinTransform
	Window    *WindowTransform
	Join      *JoinTransform
	Union     *UnionTransform
	Pivot     *PivotTransform
	Unpivot   *UnpivotTransform
	Sample    *SampleTransform
	Sort      *SortTransform
	Limit     *LimitTransform
}

Transform is the discriminated transform union. Exactly one variant pointer is non-nil after unmarshal. UnmarshalJSON is implemented in transform_union.go (T01.14).

func (Transform) MarshalJSON

func (t Transform) MarshalJSON() ([]byte, error)

MarshalJSON emits the JSON payload of whichever transform variant is populated.

func (*Transform) UnmarshalJSON

func (t *Transform) UnmarshalJSON(data []byte) error

UnmarshalJSON inspects the keys present and routes to the matching variant. Exactly one discriminator key must be present. Unknown keys cause an error via DisallowUnknownFields propagated through strictUnmarshal.

type UnionTransform

type UnionTransform struct {
	Union []string `json:"union"`
	Data  string   `json:"data,omitempty"`
	As    string   `json:"as,omitempty"`
}

UnionTransform: vertical concatenation.

type UnpivotTransform

type UnpivotTransform struct {
	Unpivot []string `json:"unpivot"`
	As      []string `json:"as,omitempty"`
	Data    string   `json:"data,omitempty"`
}

UnpivotTransform: wide → long.

type WindowOp

type WindowOp struct {
	Op    string   `json:"op"`
	Field string   `json:"field,omitempty"`
	As    string   `json:"as"`
	Param *float64 `json:"param,omitempty"`
}

WindowOp is one window operation.

type WindowTransform

type WindowTransform struct {
	Window      []WindowOp     `json:"window"`
	Partitionby []string       `json:"partitionby,omitempty"`
	Sort        []SortFieldDef `json:"sort,omitempty"`
	Frame       []any          `json:"frame,omitempty"`
	Data        string         `json:"data,omitempty"`
	As          string         `json:"as,omitempty"`
}

WindowTransform: windowed aggregate / rank.

Jump to

Keyboard shortcuts

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