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

viz

package
v0.3.46 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package viz is the visualization core shared by the MCP viz tools (pkg/mcp) and the report renderer (pkg/mcp/reports): the canonical data contracts — flat rows and KPI cards — the chart/column specs, the caps, and the query+jq pipeline that feeds them (query.go). It deliberately knows nothing about MCP itself: tool surfaces, result envelopes and the HTML views stay with their owners. The package lives under pkg/mcp because that is where these contracts were born — they are the viz tools' wire format first, and the report spec reuses them verbatim.

Index

Constants

View Source
const (
	// KPICap bounds a KPI panel: it is a glance surface, not a table. The
	// whole panel always travels inline — no sampling, no refresh channel —
	// and the cap is what keeps that honest.
	KPICap = 32

	// Above the soft limit a browser table stops being usable and the payload
	// stops being reasonable; the hard cap is what a view will never be asked
	// to hold. Between them sits a window the caller opened deliberately with
	// limit/offset, and that is their call to make.
	RowSoftLimit = 2000
	RowHardCap   = 10000
)
View Source
const PagingRecipe = `Three ways, best first: (1) AGGREGATE — a chart wants ` +
	`<object>_bucket_aggregation, not raw rows, and an aggregate is usually what the question ` +
	`actually asked for; (2) NARROW — put a condition in the query's own filter argument, which ` +
	`is also how "only for X" is answered; (3) PAGE — obj(limit: 500, offset: 0) with order_by ` +
	`so the order is stable, then call again with offset: 500 for the next page, each call ` +
	`rendering its own view. Any limit you set is honoured, including a deliberate "first N of ` +
	`the count above" — just tell the user that is what they are looking at.`

PagingRecipe is the one place that spells out how to bound a query, so every refusal points the same way.

Variables

View Source
var (
	ChartTypes    = []string{"line", "bar", "area", "pie", "scatter"}
	KPIDirections = []string{"up_good", "down_good", "neutral"}
	KPIFormats    = []string{"number", "percent"}
)

Functions

func CanonicalRows

func CanonicalRows(v any) ([]map[string]any, error)

CanonicalRows validates the canonical-rows contract: an array of flat objects with scalar values. A single-key object chain (the usual {"module":{"table":[...]}} GraphQL shape) is unwrapped first, so most queries need no jq at all.

func JQPathHint

func JQPathHint(query string) string

JQPathHint recovers the first two selection levels of the query so a failed transform can show the caller the path it probably meant to write.

func QueryHasLimit

func QueryHasLimit(query string) bool

QueryHasLimit reports whether the caller bounded the query themselves, either with a $limit variable or a literal limit: argument. It is a textual check on purpose: the query belongs to the caller and is not re-parsed here.

func QueryLimit

func QueryLimit(query string, vars map[string]any) (int, bool)

QueryLimit recovers the row bound the caller set, from a literal `limit: N` or from the value bound to a $limit variable. Knowing it is what lets the result say "this page is exactly full, there is probably more" instead of leaving the caller to guess from a suspiciously round number.

func QueryRows

func QueryRows(ctx context.Context, q Querier, query string, vars map[string]any, jqTransform string, maxRows int, ttl time.Duration) ([]map[string]any, bool, error)

QueryRows runs a read-only GraphQL query, optionally shapes it with jq, and canonicalizes the outcome into flat rows.

func QueryValue

func QueryValue(ctx context.Context, q Querier, query string, vars map[string]any, jqTransform string, ttl time.Duration) (any, error)

QueryValue is the shared query pipeline: read-only hint, cache hint, jq fail-fast compile, execute, transform, and a JSON round-trip that normalizes engine/gojq value types into plain maps. What the value MEANS — rows or KPI cards — is the caller's canonicalizer's business.

Types

type ChartSpec

type ChartSpec struct {
	Type    string   `json:"type" jsonschema_description:"line | bar | area | pie | scatter"`
	X       string   `json:"x,omitempty" jsonschema_description:"Row field for the category/x value"`
	Y       []string `json:"y,omitempty" jsonschema_description:"Row fields holding values; several = one series each (wide form)"`
	Series  string   `` /* 130-byte string literal not displayed */
	Stacked bool     `json:"stacked,omitempty" jsonschema_description:"Stack the series"`
}

type ColumnSpec

type ColumnSpec struct {
	Field  string `json:"field" jsonschema_description:"Row field"`
	Label  string `json:"label,omitempty" jsonschema_description:"Header label (default: field name)"`
	Format string `json:"format,omitempty" jsonschema_description:"number to right-align and group digits"`
	Align  string `json:"align,omitempty" jsonschema_description:"left | right"`
}

type KPI

type KPI struct {
	Label     string    `json:"label" jsonschema_description:"Card caption"`
	Value     any       `json:"value" jsonschema_description:"The headline value: a number, or a short string"`
	Unit      string    `json:"unit,omitempty" jsonschema_description:"Rendered next to the value ($, %, ms, …)"`
	Format    string    `json:"format,omitempty" jsonschema_description:"number | percent"`
	Delta     *float64  `json:"delta,omitempty" jsonschema_description:"Absolute change vs the comparison period"`
	DeltaPct  *float64  `json:"delta_pct,omitempty" jsonschema_description:"Change in percent vs the comparison period"`
	Direction string    `json:"direction,omitempty" jsonschema_description:"up_good | down_good | neutral — colours the delta"`
	Trend     []float64 `json:"trend,omitempty" jsonschema_description:"Values drawn as a sparkline under the number"`
	Subtitle  string    `json:"subtitle,omitempty" jsonschema_description:"Small line under the value (e.g. \"vs July\")"`
}

KPI is one card on a KPI panel. Label and value are the card; everything else decorates it.

func CanonicalKPIs

func CanonicalKPIs(v any) ([]KPI, error)

CanonicalKPIs validates the canonical KPI-card contract: an array of card objects, label+value required, trend the only array field. Unknown keys are rejected by name — a typo like delta_percent must fail loudly with the allowed list, not render a bare card.

type Querier

type Querier interface {
	Query(ctx context.Context, query string, vars map[string]any) (*types.Response, error)
}

Querier is the one engine capability the pipeline needs; types.Querier satisfies it.

Jump to

Keyboard shortcuts

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