dashboard

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	WidgetTypeMetric  = "metric"
	WidgetTypeChart   = "chart"
	WidgetTypeTable   = "table"
	WidgetTypeText    = "text"
	WidgetTypeDivider = "divider"
	WidgetTypeImage   = "image"
)

Widget type constants.

Variables

View Source
var ValidAggregates = map[string]bool{
	"count":          true,
	"count_distinct": true,
	"sum":            true,
	"avg":            true,
	"min":            true,
	"max":            true,
}

ValidAggregates lists the supported aggregate functions.

Functions

func AggregateMetricNames

func AggregateMetricNames(metrics map[string]Metric) []string

AggregateMetricNames returns sorted names of all non-expression metrics.

func DimensionAlias

func DimensionAlias(dimension string) string

DimensionAlias returns a clean column alias for a dimension expression. e.g. "geo.country" -> "country", "event_date" -> "event_date".

func EvaluateExpression

func EvaluateExpression(expr string, values map[string]float64) (float64, error)

EvaluateExpression evaluates a simple arithmetic expression with metric name substitution. Supports +, -, *, /, parentheses, and numeric literals. Division by zero returns 0.

func ExpressionMetrics

func ExpressionMetrics(metrics map[string]Metric) []string

ExpressionMetrics returns sorted names of all expression metrics.

func GenerateDimensionalSQL

func GenerateDimensionalSQL(source *Source, allMetrics map[string]Metric, metricNames []string, dim *Dimension, dateFilter map[string]any, limit int) (string, error)

GenerateDimensionalSQL builds a SELECT that computes the given metrics grouped by a dimension column. Used for declarative chart widgets.

func GenerateMetricsSQL

func GenerateMetricsSQL(source *Source, metrics map[string]Metric, dateFilter map[string]any) (string, error)

GenerateMetricsSQL builds a single SELECT that computes all aggregate (non-expression) metrics from the source table. The returned SQL may contain Jinja template expressions (e.g. in the table name) and should be rendered through the template engine before execution.

func IsTSXFile

func IsTSXFile(name string) bool

IsTSXFile checks if a filename matches the .dashboard.tsx convention.

func ResolveDatePreset

func ResolveDatePreset(key string) map[string]any

ResolveDatePreset converts a preset key like "last_30_days" into a map with "start" and "end" date strings. Returns nil if the key is unknown.

func Validate

func Validate(d *Dashboard) error

Validate checks a dashboard definition for correctness.

func ValidateAll

func ValidateAll(dashboards []*Dashboard) error

Types

type Dashboard

type Dashboard struct {
	Schema      string            `yaml:"schema,omitempty" json:"schema,omitempty"`
	Name        string            `yaml:"name" json:"name"`
	Description string            `yaml:"description,omitempty" json:"description,omitempty"`
	Connection  string            `yaml:"connection,omitempty" json:"connection,omitempty"`
	Model       string            `yaml:"model,omitempty" json:"model,omitempty"`
	Models      map[string]string `yaml:"models,omitempty" json:"models,omitempty"`
	Theme       string            `yaml:"theme,omitempty" json:"theme,omitempty"`
	Refresh     *RefreshConfig    `yaml:"refresh,omitempty" json:"refresh,omitempty"`
	Filters     []Filter          `yaml:"filters,omitempty" json:"filters,omitempty"`
	Queries     map[string]Query  `yaml:"queries,omitempty" json:"queries,omitempty"`
	Semantic    *SemanticLayer    `yaml:"semantic,omitempty" json:"semantic,omitempty"`
	Rows        []Row             `yaml:"rows" json:"rows"`

	// FilePath is the source file path, not serialized to JSON for API consumers.
	FilePath string `yaml:"-" json:"-"`

	// FileType indicates the source format: "yaml" or "tsx".
	FileType string `yaml:"-" json:"file_type,omitempty"`
	// contains filtered or unexported fields
}

Dashboard represents a complete dashboard definition loaded from YAML.

func FindByName

func FindByName(dashboards []*Dashboard, name string) *Dashboard

FindByName returns the dashboard with the given name from a slice, or nil.

func LoadDir

func LoadDir(dir string, opts ...TSXOption) ([]*Dashboard, error)

LoadDir discovers and loads all dashboard files from the project's dashboards directory.

func LoadFile

func LoadFile(path string) (*Dashboard, error)

LoadFile loads a single dashboard YAML file.

func LoadOneByName

func LoadOneByName(dir, name string, opts ...TSXOption) (*Dashboard, error)

LoadOneByName finds a dashboard by name using a two-pass approach: first a cheap metadata scan (no query execution) to find the file path, then a full load of just that one file. Returns nil, nil if not found.

func LoadTSXFile

func LoadTSXFile(path string, opts ...TSXOption) (*Dashboard, error)

LoadTSXFile loads a single .dashboard.tsx file by transpiling it with esbuild and executing it with goja to produce a Dashboard struct.

func (*Dashboard) DateRangeFilterName

func (d *Dashboard) DateRangeFilterName() string

DateRangeFilterName returns the name of the first date-range filter, or "".

func (*Dashboard) DefaultFilters

func (d *Dashboard) DefaultFilters() map[string]any

DefaultFilters returns a map of filter names to their default values. For date-range filters, string defaults like "last_30_days" are resolved to {start, end} maps so that query templating works correctly.

func (*Dashboard) ResolveSemanticModel

func (d *Dashboard) ResolveSemanticModel(ref string) (*sem.Model, string, error)

func (*Dashboard) ResolveWidgetSemanticJob

func (d *Dashboard) ResolveWidgetSemanticJob(w *Widget) (*SemanticJob, bool, error)

func (*Dashboard) SemanticDimensions

func (d *Dashboard) SemanticDimensions() map[string]Dimension

SemanticDimensions returns the semantic layer's dimensions, or nil.

func (*Dashboard) SemanticMetrics

func (d *Dashboard) SemanticMetrics() map[string]Metric

SemanticMetrics returns the semantic layer's metrics, or nil.

func (*Dashboard) SemanticSource

func (d *Dashboard) SemanticSource() *Source

SemanticSource returns the semantic layer's source, or nil.

func (*Dashboard) SetProjectContext

func (d *Dashboard) SetProjectContext(projectRoot string, semanticModels map[string]*sem.Model, semanticInvalid map[string]error)

func (*Dashboard) SourceConnection

func (d *Dashboard) SourceConnection() string

SourceConnection returns the connection for the semantic source, falling back to the dashboard default.

type Dimension

type Dimension struct {
	Column string `yaml:"column" json:"column"`                 // the SQL column expression (e.g. "geo.country")
	Type   string `yaml:"type,omitempty" json:"type,omitempty"` // "date" for chronological ordering, empty for top-N
}

Dimension defines a named grouping column for dimensional queries.

func (*Dimension) IsDate

func (dim *Dimension) IsDate() bool

IsDate returns true if this dimension represents a date/time column.

type Filter

type Filter struct {
	Name     string         `yaml:"name" json:"name"`
	Type     string         `yaml:"type" json:"type"`
	Multiple bool           `yaml:"multiple,omitempty" json:"multiple,omitempty"`
	Default  any            `yaml:"default,omitempty" json:"default,omitempty"`
	Options  *FilterOptions `yaml:"options,omitempty" json:"options,omitempty"`
}

type FilterOptions

type FilterOptions struct {
	Values     []string `yaml:"values,omitempty" json:"values,omitempty"`
	Query      string   `yaml:"query,omitempty" json:"query,omitempty"`
	Connection string   `yaml:"connection,omitempty" json:"connection,omitempty"`
	Presets    []string `yaml:"presets,omitempty" json:"presets,omitempty"` // date-range: which presets to show
}

type Metric

type Metric struct {
	Aggregate  string            `yaml:"aggregate,omitempty" json:"aggregate,omitempty"` // count, count_distinct, sum, avg, min, max
	Column     string            `yaml:"column,omitempty" json:"column,omitempty"`
	Filter     map[string]string `yaml:"filter,omitempty" json:"filter,omitempty"`
	Expression string            `yaml:"expression,omitempty" json:"expression,omitempty"`
}

Metric defines a named scalar value computed from the source table. Use Aggregate for database-computed metrics, or Expression for client-side arithmetic over other metrics.

func (*Metric) IsExpression

func (m *Metric) IsExpression() bool

IsExpression returns true if this metric is computed from other metrics.

type NoQueryError

type NoQueryError struct {
	Widget string
}

func (*NoQueryError) Error

func (e *NoQueryError) Error() string

type ProjectPaths

type ProjectPaths struct {
	RootDir      string
	DashboardDir string
	SemanticDir  string
	ThemesDir    string
}

func ResolveProjectPaths

func ResolveProjectPaths(dir string) ProjectPaths

func ResolveProjectPathsForFile

func ResolveProjectPathsForFile(path string) ProjectPaths

type Query

type Query struct {
	SQL        string                 `yaml:"sql,omitempty" json:"sql,omitempty"`
	File       string                 `yaml:"file,omitempty" json:"file,omitempty"`
	Connection string                 `yaml:"connection,omitempty" json:"connection,omitempty"`
	Model      string                 `yaml:"model,omitempty" json:"model,omitempty"`
	Dimensions []SemanticDimensionRef `yaml:"dimensions,omitempty" json:"dimensions,omitempty"`
	Metrics    []string               `yaml:"metrics,omitempty" json:"metrics,omitempty"`
	Filters    []SemanticQueryFilter  `yaml:"filters,omitempty" json:"filters,omitempty"`
	Segments   []string               `yaml:"segments,omitempty" json:"segments,omitempty"`
	Sort       []SemanticSort         `yaml:"sort,omitempty" json:"sort,omitempty"`
	Limit      int                    `yaml:"limit,omitempty" json:"limit,omitempty"`
}

Query represents a named query definition.

func (*Query) IsSemantic

func (q *Query) IsSemantic() bool

type QueryNotFoundError

type QueryNotFoundError struct {
	Name   string
	Widget string
}

func (*QueryNotFoundError) Error

func (e *QueryNotFoundError) Error() string

type RefreshConfig

type RefreshConfig struct {
	Interval string `yaml:"interval" json:"interval"`
}

type Row

type Row struct {
	Tab     string   `yaml:"tab,omitempty" json:"tab,omitempty"`
	Height  any      `yaml:"height,omitempty" json:"height,omitempty"`
	Widgets []Widget `yaml:"widgets" json:"widgets"`
}

type SemanticDimensionRef

type SemanticDimensionRef struct {
	Name        string `yaml:"name" json:"name"`
	Granularity string `yaml:"granularity,omitempty" json:"granularity,omitempty"`
}

type SemanticJob

type SemanticJob struct {
	Model      *sem.Model
	ModelName  string
	Connection string
	Query      sem.Query
}

type SemanticLayer

type SemanticLayer struct {
	Source     *Source              `yaml:"source,omitempty" json:"source,omitempty"`
	Metrics    map[string]Metric    `yaml:"metrics,omitempty" json:"metrics,omitempty"`
	Dimensions map[string]Dimension `yaml:"dimensions,omitempty" json:"dimensions,omitempty"`
}

SemanticLayer groups the declarative source, metrics, and dimensions.

type SemanticQueryFilter

type SemanticQueryFilter struct {
	Dimension  string `yaml:"dimension,omitempty" json:"dimension,omitempty"`
	Operator   string `yaml:"operator,omitempty" json:"operator,omitempty"`
	Value      any    `yaml:"value,omitempty" json:"value,omitempty"`
	Expression string `yaml:"expression,omitempty" json:"expression,omitempty"`
}

type SemanticSort

type SemanticSort struct {
	Name      string `yaml:"name" json:"name"`
	Direction string `yaml:"direction,omitempty" json:"direction,omitempty"`
}

type Source

type Source struct {
	Table      string `yaml:"table" json:"table"`
	DateColumn string `yaml:"date_column,omitempty" json:"date_column,omitempty"`
	DateFormat string `yaml:"date_format,omitempty" json:"date_format,omitempty"`
	Connection string `yaml:"connection,omitempty" json:"connection,omitempty"`
}

Source defines the base table for declarative metrics.

type TSXOption

type TSXOption func(*tsxConfig)

TSXOption configures TSX loading behavior.

func WithQueryFunc

func WithQueryFunc(fn func(connection, sql string) (map[string]interface{}, error)) TSXOption

WithQueryFunc provides a query function for load-time SQL execution.

type TableColumn

type TableColumn struct {
	Name   string `yaml:"name" json:"name"`
	Label  string `yaml:"label,omitempty" json:"label,omitempty"`
	Format string `yaml:"format,omitempty" json:"format,omitempty"`
}

type ValidationError

type ValidationError struct {
	Dashboard string
	Errors    []string
}

ValidationError holds all validation issues for a dashboard.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type ValidationSetError

type ValidationSetError struct {
	Errors []error
}

func (*ValidationSetError) Error

func (e *ValidationSetError) Error() string

type Widget

type Widget struct {
	Name        string `yaml:"name" json:"name"`
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	Type        string `yaml:"type" json:"type"` // metric, chart, table, text
	Col         int    `yaml:"col,omitempty" json:"col,omitempty"`

	// Query source (pick one)
	QueryRef  string `yaml:"query,omitempty" json:"query,omitempty"` // reference to queries map key
	SQL       string `yaml:"sql,omitempty" json:"sql,omitempty"`
	File      string `yaml:"file,omitempty" json:"file,omitempty"`
	MetricRef string `yaml:"metric,omitempty" json:"metric,omitempty"` // reference to metrics map key
	Model     string `yaml:"model,omitempty" json:"model,omitempty"`

	// Connection override for inline queries
	Connection string `yaml:"connection,omitempty" json:"connection,omitempty"`

	// Metric fields
	Column string `yaml:"column,omitempty" json:"column,omitempty"`
	Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"`
	Suffix string `yaml:"suffix,omitempty" json:"suffix,omitempty"`
	Format string `yaml:"format,omitempty" json:"format,omitempty"`

	// Declarative chart fields (use with source + metrics)
	Dimension   string                 `yaml:"dimension,omitempty" json:"dimension,omitempty"` // GROUP BY column
	Granularity string                 `yaml:"granularity,omitempty" json:"granularity,omitempty"`
	Dimensions  []SemanticDimensionRef `yaml:"dimensions,omitempty" json:"dimensions,omitempty"`
	MetricRefs  []string               `yaml:"metrics,omitempty" json:"metrics,omitempty"` // metric names to aggregate
	Filters     []SemanticQueryFilter  `yaml:"filters,omitempty" json:"filters,omitempty"`
	Segments    []string               `yaml:"segments,omitempty" json:"segments,omitempty"`
	Sort        []SemanticSort         `yaml:"sort,omitempty" json:"sort,omitempty"`
	Limit       int                    `yaml:"limit,omitempty" json:"limit,omitempty"` // LIMIT for dimensional queries

	// Chart fields
	Chart   string   `yaml:"chart,omitempty" json:"chart,omitempty"` // line, bar, area, pie, scatter, bubble, combo, histogram, boxplot, funnel, sankey, heatmap, calendar, sparkline, waterfall, xmr, dumbbell
	X       string   `yaml:"x,omitempty" json:"x,omitempty"`
	Y       []string `yaml:"y,omitempty" json:"y,omitempty"`
	Label   string   `yaml:"label,omitempty" json:"label,omitempty"`     // for pie/funnel
	Value   string   `yaml:"value,omitempty" json:"value,omitempty"`     // for pie/funnel/heatmap/calendar
	Stacked bool     `yaml:"stacked,omitempty" json:"stacked,omitempty"` // for bar/area charts
	Size    string   `yaml:"size,omitempty" json:"size,omitempty"`       // bubble: size dimension column
	Source  string   `yaml:"source,omitempty" json:"source,omitempty"`   // sankey: source column
	Target  string   `yaml:"target,omitempty" json:"target,omitempty"`   // sankey: target column
	Bins    int      `yaml:"bins,omitempty" json:"bins,omitempty"`       // histogram: number of bins
	Lines   []string `yaml:"lines,omitempty" json:"lines,omitempty"`     // combo: which y series render as lines
	YMin    string   `yaml:"yMin,omitempty" json:"yMin,omitempty"`       // xmr: min control limit column
	YMax    string   `yaml:"yMax,omitempty" json:"yMax,omitempty"`       // xmr: max control limit column

	// Table fields
	Columns []TableColumn `yaml:"columns,omitempty" json:"columns,omitempty"`

	// Text fields
	Content string `yaml:"content,omitempty" json:"content,omitempty"`

	// Image fields
	Src string `yaml:"src,omitempty" json:"src,omitempty"`
	Alt string `yaml:"alt,omitempty" json:"alt,omitempty"`
}

Widget represents a single dashboard widget. Query resolution priority: query (named ref) > sql (inline) > file (external).

func (*Widget) IsSemantic

func (w *Widget) IsSemantic() bool

func (*Widget) ResolvedQuery

func (w *Widget) ResolvedQuery(dashboard *Dashboard) (sql, connection string, err error)

ResolvedQuery returns the SQL and connection for this widget, resolving named query references. Widgets with MetricRef are handled separately and should not call this method.

Jump to

Keyboard shortcuts

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