Help us shape the future of Go! Take the 2026 Go Developer Survey

canvas

package
v0.91.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FieldMetadataKeys = []string{"name", "display_name", "type", "format_d3", "format_preset", "format_type"}

FieldMetadataKeys are the keys ".fields.<param>" exposes. The parser validates references against them, since a mistyped key resolves to Go's "<no value>" placeholder rather than to an error.

View Source
var ParamFieldTypes = []string{"measure", "dimension", "time_dimension"}

ParamFieldTypes are the param types that reference a field of a metrics view. They resolve their metrics view through a sibling param of type "metrics_view".

View Source
var ParamScalarTypes = []string{"string", "number", "boolean"}

ParamScalarTypes are the param types that hold plain values. Scalar params may declare options and are injected as native Vega-Lite params at resolve time.

Functions

func BoundMetricsViewNames

func BoundMetricsViewNames(params []*runtimev1.ComponentParam, bound map[string]any) []string

BoundMetricsViewNames returns the static metrics view names bound to a component's params of type "metrics_view", falling back to their defaults. Pass nil bound to get only the defaults. Templated values are skipped since they resolve at render time and cannot be referenced statically.

func CoerceScalarParams

func CoerceScalarParams(props map[string]any, params []*runtimev1.ComponentParam, args map[string]any) map[string]any

CoerceScalarParams substitutes numeric and boolean param values into renderer properties with their original type, rather than as strings.

Template resolution always yields strings, so a structured renderer property such as a Flint spec's "chartProperties: {innerRadius: {{ .params.inner_radius }}}" would otherwise reach the renderer as "60" instead of 60 and silently degrade. This only applies to values that consist of exactly one placeholder: partial interpolations like "LIMIT {{ .params.limit }}" are strings by nature and are left to normal templating.

It returns a copy; the input is not modified.

func Conditions

func Conditions(rows []*runtimev1.CanvasRow) []string

Conditions returns the distinct `if` conditions of the rows, tabs and items.

func EffectiveArgs

func EffectiveArgs(spec *runtimev1.ComponentSpec, args map[string]any) map[string]any

EffectiveArgs merges a component's declared param defaults with the provided args. Provided args take precedence over declared param defaults, which in turn take precedence over legacy input variable defaults.

func EscapeJSONStrings

func EscapeJSONStrings[T any](val T) T

EscapeJSONStrings returns a copy of the value with every string in it JSON-escaped (without the enclosing quotes), recursing into maps and slices. It prepares template data for resolving a Vega-Lite spec, which is a JSON document held in a string: a display name or string param containing a quote or backslash would otherwise be spliced into the JSON unescaped and make it unparseable. Numbers and booleans are returned as they are.

func FieldTemplateData

func FieldTemplateData(params []*runtimev1.ComponentParam, args map[string]any, metricsViews map[string]*runtimev1.MetricsViewSpec) map[string]any

FieldTemplateData builds the ".fields" template namespace: the metrics view metadata of every field-typed param, keyed by param name.

Params substitute a field's *name* through ".params.<name>", which is all a query needs. A hand-authored Vega-Lite spec also needs the field's presentation metadata (what to title an axis, how to format a value), and that lives in the metrics view rather than in the binding. Exposing it per param rather than per field name keeps the lookup unambiguous when a component declares several metrics_view params: each field-typed param names the one it resolves against.

The exposed keys are:

name:          the bound field name, same as .params.<name>
display_name:  the field's display name ("Time" for the primary time dimension)
type:          the param's declared type ("measure", "dimension" or "time_dimension")
format_d3:     the measure's d3 format string, if it declares one
format_preset: the measure's format preset, if it declares one
format_type:   the name of the Vega expression formatter Rill registers for the measure,
               for use as "formatType" in a vega_spec

Every field-typed param gets an entry, even one whose metrics view or field cannot be resolved: its keys are then empty strings, so a reference degrades to nothing rather than to Go's "<no value>" placeholder, which would reach the renderer as a field or formatter name.

func FilterReferencesRestrictedFields

func FilterReferencesRestrictedFields(filter, timeDimension string, canAccess func(field string) bool) bool

FilterReferencesRestrictedFields reports whether a component's own filter (its dimension_filters) references a field that canAccess rejects. The frontend adds the filter to each of the component's queries, so the query engine fails them if it does. The primary time dimension is always allowed, matching the query engine.

The filter uses the syntax of dashboard URL filters, such as "country IN ('US','CA') AND city HAVING (revenue GT 100)". Instead of parsing that grammar (see web-common/src/features/dashboards/url-state/filters/expression.ne), it relies on a field always coming right before an operator, while a value never does. It assumes that no field is named like an operator, and that quoted field names have no escapes: a field named like an operator is missed, and an escaped name doesn't match its field, so it counts as restricted. A filter the frontend can't parse isn't applied, but the fields before its operators still count; that only removes a component whose filter is broken anyway.

func InjectVegaParams

func InjectVegaParams(vegaSpec string, params []*runtimev1.ComponentParam, args map[string]any) (string, error)

InjectVegaParams injects the values of a component's scalar params as native Vega-Lite params into a Vega-Lite spec (a JSON object), making them usable in Vega expressions, predicates and extents. If the spec already declares a top-level param with the same name, only its "value" is overridden so author-supplied properties like "bind" and "expr" are preserved. Field-typed params are not injected since Vega-Lite cannot parameterize field names; they are substituted through templating instead. Returns the spec unchanged if there is nothing to inject.

func IsMetricsViewParamName

func IsMetricsViewParamName(name string) bool

IsMetricsViewParamName reports whether a param name follows the convention used to discover metrics view bindings before a referenced component has been loaded.

func IsParamOption

func IsParamOption(v *structpb.Value, options []*structpb.Value) bool

IsParamOption reports whether a scalar value is one of a param's options. Protobuf values hold every number as a float64, so all numeric types compare equal when their values match.

func IsTemplated

func IsTemplated(v any) bool

IsTemplated returns true if the value is a string containing template placeholders.

func MetricsViewNamesFromBindings

func MetricsViewNamesFromBindings(bindings map[string]any) []string

MetricsViewNamesFromBindings extracts statically bound metrics view names from a params map. Templated bindings are resolved later and cannot be registered as resource references here.

func PruneRendererProperties

func PruneRendererProperties(renderer string, props map[string]any, timeDimension string, canAccess func(field string) bool) (keep, changed bool)

PruneRendererProperties removes references to fields the viewer can't query from a component's renderer properties. canAccess reports whether a field of the component's metrics view is accessible to the viewer. The primary time dimension (and its encoded time-grain variants) is always allowed, since queries never check access to it.

The props map is modified in place; callers should pass a copy (structpb.Struct.AsMap returns a fresh map). It returns false for keep when the component can't render without the restricted fields (e.g. a chart whose x or y field is restricted), and true for changed when any property was removed.

func PruneRows

func PruneRows(rows []*runtimev1.CanvasRow, keep Keep) ([]*runtimev1.CanvasRow, []string)

PruneRows returns the rows without the elements that keep rejects, and the YAML paths of the rejected elements, such as "rows.1", "rows.0.items.1" or "rows.3.tabs.0.rows.0.items.0". Rows, tabs and tab groups left without content are removed too. The remaining items keep their widths; the frontend splits a row equally when its widths no longer add up to the full width. The input rows are not modified, and they're returned as is if nothing is removed.

func QueryReferencesRestrictedFields

func QueryReferencesRestrictedFields(q *metricsview.Query, timeDimension string, canAccess func(field string) bool) bool

QueryReferencesRestrictedFields reports whether a metrics query selects or filters on a field that canAccess rejects. The query engine fails such a query, so a component that runs it can't render for the viewer. The primary time dimension is always allowed, matching the query engine.

func StripConditions

func StripConditions(rows []*runtimev1.CanvasRow)

StripConditions clears the `if` conditions of the rows, tabs and items, so they aren't sent to viewers. It modifies the rows in place.

func ValidateParamBindings

func ValidateParamBindings(params []*runtimev1.ComponentParam, bound map[string]any, metricsViews map[string]*runtimev1.MetricsViewSpec) error

ValidateParamBindings validates values bound to a component's declared params. It checks unknown keys, missing required params, scalar types and option membership. When metricsViews is non-nil, it additionally checks that params of type "metrics_view" name a valid metrics view and that field-typed params reference fields of their bound metrics view. The provided metricsViews should contain every valid metrics view bound to a param (as determined by refs in the parser); a bound metrics view missing from the map is reported as invalid (don't look it up separately in the catalog). Pass nil metricsViews to skip the metrics view checks (e.g. at resolve time, where they already ran at reconcile time).

Bound string values containing template placeholders (e.g. {{ .env.name }}) are not validated; they resolve at render time.

func ValidateParamValue

func ValidateParamValue(typ string, v any) error

ValidateParamValue checks that a param value (a binding, default or option) conforms to the param's declared type.

func ValidateRendererProperties

func ValidateRendererProperties(renderer string, props map[string]any, metricsViews map[string]*runtimev1.MetricsViewSpec, allowTemplated bool) error

ValidateRendererProperties validates the renderer properties for a component. The provided metricsViews should contain every valid metrics view referenced by the component (as determined in the parser). If the renderer properties reference a metrics view not in metricsViews, assume the metrics view is invalid or does not exist (don't look it up separately in the catalog).

allowTemplated should be true when the component declares params. In that case, properties may contain unresolved template placeholders (e.g. {{ .params.measure }}), which makes field-membership validation impossible for the templated values; those membership checks are skipped and the bound values are validated by the canvas reconciler (ValidateParamBindings) instead. All other checks still run: required keys must be present, values must have the right types, and enum-valued and non-templated field properties are validated as usual.

Note: metrics views referenced through markdown content cannot be validated here. This is because the upstream parser can't extract refs from templates, so the metrics views cannot be passed through to here. Warning: if you try to fix this, note that the refs must be added in the parser, not looked up dynamically here; a dynamic lookup will have a race condition where the metrics view may not have been reconciled yet.

func VegaFormatType

func VegaFormatType(measure string) string

VegaFormatType returns the name of the Vega expression function that Rill registers to format values of the given measure. Vega-Lite compiles a custom "formatType" into an expression function call, so the name is reduced to a JavaScript identifier-safe subset and measure names with spaces or operators stay usable.

Keep in sync with sanitizeFieldName in web-common/src/components/vega/util.ts.

Types

type Keep

type Keep struct {
	// Row is called for plain rows and for tab-group rows.
	Row  func(row *runtimev1.CanvasRow) bool
	Tab  func(tab *runtimev1.CanvasTab) bool
	Item func(item *runtimev1.CanvasItem) bool
}

Keep decides which canvas elements PruneRows keeps. A nil function keeps every element of its kind.

Jump to

Keyboard shortcuts

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