visualization

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

Visualization Package

Status: ✅ Implemented (v0.6.0+) Tests: 15 test functions, 100% pass rate with -race detector

Overview

The visualization package provides intelligent chart generation and HTML report assembly for Loom agents. It transforms aggregated data from presentation tools into beautiful, interactive visualizations using the Hawk StyleGuide aesthetic.

Key Innovation: Automatic chart type selection based on data patterns, combined with ECharts rendering and Hawk terminal aesthetic.

Architecture

Presentation Tools → Visualization Layer → Interactive HTML
    (data aggregation)    (chart generation)    (report output)

top_n_query(50 rows) ─┐
                      ├─> ChartSelector ──> EChartsGenerator ──> ReportGenerator ──> HTML
group_by_query(4 rows)┘     (bar/pie/line)     (JSON config)       (embedded charts)

Components

1. ChartSelector

Analyzes data patterns and recommends appropriate chart types.

File: chart_selector.go

Features:

  • Automatic pattern detection (ranking, categories, time series, continuous)
  • Schema inference from data
  • Confidence scoring (0.0-1.0)
  • Support for complex data structures

Example:

selector := visualization.NewChartSelector(nil)
rec := selector.RecommendChart(dataset)
// rec.ChartType = ChartTypeBar
// rec.Confidence = 0.95
// rec.Rationale = "Ranked data with 50 items, ideal for bar chart"

Decision Rules (in priority order):

  • Time series data → Line chart (0.9)
  • Network/graph data (source-target) → Graph chart (0.90)
  • Statistical distribution (min/q1/median/q3/max) → Box plot (0.88)
  • Ranking with 5-50 items → Bar chart (0.95)
  • Multi-dimensional (3+ numeric cols) → Radar chart (0.82)
  • Hierarchical structure (parent/children) → TreeMap (0.78)
  • Few categories (2-7) → Pie chart (0.85)
  • Many categories (>7) → Bar chart (0.80)
  • Two+ numeric dimensions → Scatter plot (0.75)
2. EChartsGenerator

Generates ECharts JSON configurations with Hawk StyleGuide.

File: echarts.go

Supported Charts:

  • Bar charts - horizontal/vertical, gradient fills, for ranking and comparison
  • Line charts - smooth curves, area fill, for time series and trends
  • Pie charts - with percentages, for categorical distribution
  • Scatter plots - correlation analysis, two-dimensional relationships
  • Radar charts - multi-dimensional comparisons, spider charts
  • Box plots - statistical distribution, quartiles and outliers
  • TreeMaps - hierarchical data, nested categories with sizes
  • Graph charts - network visualization, nodes and edges with force layout

Hawk StyleGuide Tokens:

ColorPrimary:      "#f37021" // Teradata Orange
FontFamily:        "IBM Plex Mono, monospace"
AnimationDuration: 1500ms
AnimationEasing:   "cubicOut"
ShadowBlur:        15px

Example:

gen := visualization.NewEChartsGenerator(nil)
config, _ := gen.Generate(dataset, recommendation)
// Returns ECharts JSON config with Hawk aesthetic
3. StyleGuideClient

Fetches styling from Hawk StyleGuide service.

File: styleguide_client.go

Features:

  • Dynamic style fetching from Hawk (future)
  • Fallback to default Hawk aesthetic
  • Theme variants: dark, light, teradata, minimal
  • Style merging and validation

Example:

client := visualization.NewStyleGuideClient("hawk:50051")
style := client.FetchStyleWithFallback(ctx, "dark")

// Or use built-in themes
style = visualization.GetThemeVariant("teradata")
4. ReportGenerator

Assembles complete HTML reports with multiple charts.

File: report_generator.go

Features:

  • Multi-chart reports
  • Executive summary section
  • AI-generated insights per chart
  • Metadata (source, reduction stats, timestamps)
  • Self-contained HTML (ECharts from CDN)
  • Print-friendly CSS

Example:

rg := visualization.NewReportGenerator(nil)
report, _ := rg.GenerateReport(ctx, datasets, title, summary)
html, _ := rg.ExportHTML(report)
os.WriteFile("/tmp/report.html", []byte(html), 0644)
5. VisualizationTool

Agent tool interface for workflow integration.

File: tool.go

Tool Name: generate_visualization

Parameters:

  • datasets: Array of presentation tool results
  • title: Report title
  • summary: Executive summary
  • output_path: Where to save HTML file
  • theme: Theme variant (dark/light/teradata/minimal)

Example:

tool := visualization.NewVisualizationTool()
result, _ := tool.Execute(ctx, map[string]interface{}{
    "datasets": [...],
    "title": "Analysis Report",
    "summary": "Executive summary...",
    "output_path": "/tmp/report.html",
    "theme": "teradata",
})

Quick Start

Programmatic Usage
package main

import (
    "context"
    "github.com/teradata-labs/loom/pkg/visualization"
)

func main() {
    // 1. Parse presentation tool result
    dataset, _ := visualization.ParseDataFromPresentationToolResult(
        topNResult,  // From top_n_query tool
        "top_50_patterns",
    )

    // 2. Generate report
    rg := visualization.NewReportGeneratorWithStyle(
        visualization.GetThemeVariant("teradata"))

    report, _ := rg.GenerateReport(context.Background(),
        []*visualization.Dataset{dataset},
        "Customer Journey Analysis",
        "Analysis of 10,000 patterns reveals...",
    )

    // 3. Export to HTML
    html, _ := rg.ExportHTML(report)
    os.WriteFile("/tmp/report.html", []byte(html), 0644)
}
Agent Tool Usage

In workflow YAML:

stages:
  - agent_id: visualization-agent
    tools:
      - generate_visualization

    prompt_template: |
      Generate an interactive HTML report:

      generate_visualization(
        datasets=[
          {name: "top_50_patterns", data: [JSON from top_n_query]},
          {name: "path_distribution", data: [JSON from group_by_query]}
        ],
        title="nPath Analysis Report",
        summary="Analysis summary...",
        output_path="/tmp/report.html",
        theme="teradata"
      )

Examples

Complete Demo
# Run the full pipeline demo
go run examples/visualization/main.go

# Output:
# - /tmp/loom-customer-journey-report.html (7.5 KB)
# - /tmp/loom-tool-generated-report.html (7.1 KB)
Workflow Integration
# Run v3.5 workflow (if you have looms running)
looms workflow execute examples/visualization/workflow-v3.5-visualization-demo.yaml

Testing

# Run all tests
go test ./pkg/visualization -v

# With race detector (REQUIRED)
go test ./pkg/visualization -race -v

# Specific test
go test ./pkg/visualization -run TestVisualizationTool -v

# Coverage
go test ./pkg/visualization -cover

Test Coverage: 15 functions, 100% pass, 0 race conditions

API Reference

Types

ChartType: bar, line, pie, scatter, timeseries, radar, boxplot, treemap, graph

DataPattern: Detected patterns in data

  • HasRanking: Data can be ranked
  • HasCategories: Categorical dimensions
  • HasTimeSeries: Temporal ordering
  • HasContinuous: Continuous distribution
  • Cardinality: Number of unique items

Dataset: Aggregated data from presentation tools

  • Name: Dataset identifier
  • Data: Array of data objects
  • Schema: Column types
  • Source: Original data source key
  • RowCount: Number of rows

Report: Complete report with visualizations

  • Title: Report title
  • Summary: Executive summary
  • Visualizations: Array of charts
  • GeneratedAt: Timestamp
  • Metadata: Source, reduction stats
Functions

ParseDataFromPresentationToolResult(result, name) → Dataset

  • Converts presentation tool output to Dataset struct

NewChartSelector(style) → ChartSelector

  • Creates chart selector with optional custom style

NewEChartsGenerator(style) → EChartsGenerator

  • Creates ECharts config generator with style

NewStyleGuideClient(endpoint) → StyleGuideClient

  • Creates client for Hawk StyleGuide service

NewReportGenerator(client) → ReportGenerator

  • Creates report generator with StyleGuide client

NewReportGeneratorWithStyle(style) → ReportGenerator

  • Creates report generator with custom style

NewVisualizationTool() → Tool

  • Creates agent tool for workflow integration

DefaultStyleConfig() → StyleConfig

  • Returns default Hawk StyleGuide configuration

GetThemeVariant(variant) → StyleConfig

  • Returns theme variant: dark, light, teradata, minimal

Performance

Benchmarks
Operation Dataset Size Time Memory
ChartSelector.RecommendChart 50 rows < 1ms < 100 KB
EChartsGenerator.Generate 50 rows 2-5ms < 200 KB
ReportGenerator.GenerateReport 3 datasets 10-20ms < 1 MB
ReportGenerator.ExportHTML 3 charts 5-10ms < 500 KB

Chart Rendering (browser):

  • ECharts init: 100-200ms per chart
  • Animation: 1500ms (smooth)
  • Interaction: < 16ms (60 FPS)
Data Reduction

Combined with presentation tools:

  • Original: 10,000 rows → Presentation: 54 rows → Visualization: 2 charts
  • Total reduction: 99.86%
  • Context savings: ~2.5 MB → 14 KB
  • Performance gain: 450x faster data transfer

Hawk StyleGuide Integration

Default Aesthetic
  • Primary Color: Teradata Orange (#f37021)
  • Font: IBM Plex Mono (monospace)
  • Background: Transparent/dark (#0d0d0d)
  • Text: Light (#f5f5f5) / Muted (#b5b5b5)
  • Effects: Glass morphism, glowing shadows
  • Animations: 1500ms with elastic easing
Theme Variants

Dark (default):

style := visualization.DefaultStyleConfig()
// Teradata Orange, dark background, light text

Light:

style := visualization.GetThemeVariant("light")
// Light background, dark text, adjusted borders

Teradata:

style := visualization.GetThemeVariant("teradata")
// Teradata Orange + Navy color palette

Minimal:

style := visualization.GetThemeVariant("minimal")
// Monochrome grayscale, reduced animations

Integration Patterns

Pattern 1: Programmatic API
// Direct Go integration
rg := visualization.NewReportGeneratorWithStyle(nil)
report, _ := rg.GenerateReport(ctx, datasets, title, summary)
html, _ := rg.ExportHTML(report)
Pattern 2: Agent Tool
# In workflow
tools:
  - generate_visualization

prompt: |
  Use generate_visualization to create report from datasets.
Pattern 3: Complete Pipeline
Analytics Agent
  ↓ stores full results
SharedMemory
  ↓ queries with presentation tools
Aggregation Agent (top_n_query, group_by_query)
  ↓ reduced data
Visualization Agent (generate_visualization)
  ↓ HTML report
Output File

Recent Additions

✅ Implemented (v0.7.0):

  • Radar charts - Multi-dimensional spider/radar charts for comparative analysis
  • Box plot charts - Statistical distribution visualization with quartiles
  • TreeMap charts - Hierarchical data visualization with nested rectangles
  • Graph charts - Network/relationship visualization with force-directed layout

Future Enhancements

Planned Features (📋):

  • LLM integration for enhanced AI-generated insights
  • Interactive features (drill-down, filtering, data table views)
  • gRPC client to Hawk StyleGuide service for dynamic themes
  • Custom report templates (executive, technical, presentation)
  • React component export for web applications
  • PDF generation via headless browser
  • Additional chart variants (stacked bar, multi-line, heatmap)

Contributing

When adding new chart types:

  1. Add chart type constant to types.go
  2. Implement generation logic in echarts.go
  3. Add decision rule to chart_selector.go
  4. Write tests with -race detector
  5. Update documentation

License

Apache 2.0 - See LICENSE file for details

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateSummary

func GenerateSummary(datasets []*Dataset) string

GenerateSummary creates a summary from datasets

func GenerateTitle

func GenerateTitle(datasets []*Dataset) string

GenerateTitle creates a title from datasets

func ValidateStyle

func ValidateStyle(style *StyleConfig) error

ValidateStyle validates a StyleConfig has all required fields

Types

type ChartRecommendation

type ChartRecommendation struct {
	ChartType  ChartType
	Title      string
	Rationale  string                 // Why this chart was recommended
	Config     map[string]interface{} // Chart-specific config
	Confidence float64                // 0.0 to 1.0
}

ChartRecommendation represents a chart selection with confidence

type ChartSelector

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

ChartSelector analyzes data and recommends appropriate chart types

func NewChartSelector

func NewChartSelector(styleConfig *StyleConfig) *ChartSelector

NewChartSelector creates a new chart selector

func (*ChartSelector) AnalyzeDataset

func (cs *ChartSelector) AnalyzeDataset(ds *Dataset) *DataPattern

AnalyzeDataset examines dataset structure and patterns

func (*ChartSelector) RecommendChart

func (cs *ChartSelector) RecommendChart(ds *Dataset) *ChartRecommendation

RecommendChart analyzes a dataset and recommends the best chart type

func (*ChartSelector) RecommendChartsForDatasets

func (cs *ChartSelector) RecommendChartsForDatasets(datasets []*Dataset) []*ChartRecommendation

RecommendChartsForDatasets recommends charts for multiple datasets

type ChartType

type ChartType string

ChartType represents the type of visualization

const (
	ChartTypeBar        ChartType = "bar"
	ChartTypeLine       ChartType = "line"
	ChartTypePie        ChartType = "pie"
	ChartTypeScatter    ChartType = "scatter"
	ChartTypeRadar      ChartType = "radar"
	ChartTypeBoxPlot    ChartType = "boxplot"
	ChartTypeTreeMap    ChartType = "treemap"
	ChartTypeGraph      ChartType = "graph"
	ChartTypeTimeSeries ChartType = "timeseries"
)

type DataPattern

type DataPattern struct {
	HasRanking     bool     // Data can be ranked (frequency, score, etc.)
	HasCategories  bool     // Data has categorical dimensions
	HasTimeSeries  bool     // Data has temporal ordering
	HasContinuous  bool     // Data has continuous distribution
	HasArrayFields bool     // Data has array/nested fields
	HasRelations   bool     // Data has relationships/edges
	Cardinality    int      // Number of unique items
	DataPoints     int      // Total data points
	NumericCols    []string // Numeric column names
	CategoryCols   []string // Categorical column names
	TimeCols       []string // Time/date column names
}

DataPattern represents the structure/pattern of data

type Dataset

type Dataset struct {
	Name     string                   // e.g., "top_50_patterns", "risk_distribution"
	Data     []map[string]interface{} // Array of data objects
	Schema   map[string]string        // Column name → type mapping
	Source   string                   // e.g., "stage-9-npath-full-results"
	RowCount int
	Metadata map[string]interface{}
}

Dataset represents aggregated data from presentation tools

func ParseDataFromPresentationToolResult

func ParseDataFromPresentationToolResult(result map[string]interface{}, name string) (*Dataset, error)

ParseDataFromPresentationToolResult converts presentation tool result to Dataset

type EChartsGenerator

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

EChartsGenerator generates ECharts configurations with Hawk StyleGuide

func NewEChartsGenerator

func NewEChartsGenerator(style *StyleConfig) *EChartsGenerator

NewEChartsGenerator creates a new ECharts config generator

func (*EChartsGenerator) Generate

func (eg *EChartsGenerator) Generate(ds *Dataset, rec *ChartRecommendation) (string, error)

Generate creates ECharts JSON configuration for a dataset and chart type

type Report

type Report struct {
	Title          string          `json:"title"`
	Summary        string          `json:"summary"` // Executive summary
	Visualizations []Visualization `json:"visualizations"`
	GeneratedAt    string          `json:"generated_at"`
	Metadata       ReportMetadata  `json:"metadata"`
}

Report represents a complete report with multiple visualizations

type ReportGenerator

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

ReportGenerator assembles complete HTML reports with embedded charts

func NewReportGenerator

func NewReportGenerator(styleClient *StyleGuideClient) *ReportGenerator

NewReportGenerator creates a new report generator

func NewReportGeneratorWithStyle

func NewReportGeneratorWithStyle(style *StyleConfig) *ReportGenerator

NewReportGeneratorWithStyle creates a report generator with custom style

func (*ReportGenerator) ExportHTML

func (rg *ReportGenerator) ExportHTML(report *Report) (string, error)

ExportHTML generates self-contained HTML with embedded charts

func (*ReportGenerator) ExportJSON

func (rg *ReportGenerator) ExportJSON(report *Report) (string, error)

ExportJSON exports report as JSON

func (*ReportGenerator) GenerateReport

func (rg *ReportGenerator) GenerateReport(ctx context.Context, datasets []*Dataset, title, summary string) (*Report, error)

GenerateReport creates a complete report from datasets

type ReportMetadata

type ReportMetadata struct {
	DataSource  string                 `json:"data_source"`
	WorkflowID  string                 `json:"workflow_id"`
	AgentID     string                 `json:"agent_id"`
	RowsSource  int                    `json:"rows_source"`  // Original row count
	RowsReduced int                    `json:"rows_reduced"` // Reduced row count
	Reduction   float64                `json:"reduction"`    // Percentage reduction
	Extra       map[string]interface{} `json:"extra"`
}

ReportMetadata contains metadata about report generation

type StyleConfig

type StyleConfig struct {
	ColorPrimary    string   // Teradata Orange
	ColorBackground string   // Transparent or dark
	ColorText       string   // Light text
	ColorTextMuted  string   // Muted text
	ColorBorder     string   // Border color
	ColorGlass      string   // Glass morphism
	ColorPalette    []string // Color palette for series

	FontFamily      string // IBM Plex Mono
	FontSizeTitle   int    // Title font size
	FontSizeLabel   int    // Label font size
	FontSizeTooltip int    // Tooltip font size

	AnimationDuration int    // Animation duration in ms
	AnimationEasing   string // Easing function

	ShadowBlur    int     // Shadow blur radius
	GlowIntensity float64 // Glow intensity (0.0-1.0)
}

StyleConfig holds Hawk StyleGuide design tokens

func DefaultStyleConfig

func DefaultStyleConfig() *StyleConfig

DefaultStyleConfig returns Hawk StyleGuide defaults

func GetThemeVariant

func GetThemeVariant(variant string) *StyleConfig

GetThemeVariant returns a style config for a specific theme variant

func MergeStyles

func MergeStyles(custom, defaults *StyleConfig) *StyleConfig

MergeStyles merges a custom style with defaults (custom overrides defaults)

type StyleGuideClient

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

StyleGuideClient fetches styling from Hawk StyleGuide service

func NewStyleGuideClient

func NewStyleGuideClient(endpoint string) *StyleGuideClient

NewStyleGuideClient creates a new StyleGuide client

func (*StyleGuideClient) FetchStyle

func (sgc *StyleGuideClient) FetchStyle(ctx context.Context, theme string) (*StyleConfig, error)

FetchStyle retrieves the current style configuration from Hawk TODO: Implement gRPC client to Hawk StyleGuide service

func (*StyleGuideClient) FetchStyleWithFallback

func (sgc *StyleGuideClient) FetchStyleWithFallback(ctx context.Context, theme string) *StyleConfig

FetchStyleWithFallback attempts to fetch from Hawk, falls back to defaults on error

type Visualization

type Visualization struct {
	Type          ChartType              `json:"type"`
	Title         string                 `json:"title"`
	Description   string                 `json:"description"`
	EChartsConfig string                 `json:"echarts_config"` // JSON string
	Insight       string                 `json:"insight"`        // AI-generated caption
	DataPoints    int                    `json:"data_points"`
	Metadata      map[string]interface{} `json:"metadata"`
}

Visualization represents a single chart with embedded data

type VisualizationTool

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

VisualizationTool provides visualization capabilities for agents

func NewVisualizationTool

func NewVisualizationTool() *VisualizationTool

NewVisualizationTool creates a new visualization tool

func (*VisualizationTool) Backend

func (t *VisualizationTool) Backend() string

func (*VisualizationTool) Description

func (t *VisualizationTool) Description() string

func (*VisualizationTool) Execute

func (t *VisualizationTool) Execute(ctx context.Context, params map[string]interface{}) (*shuttle.Result, error)

func (*VisualizationTool) InputSchema

func (t *VisualizationTool) InputSchema() *shuttle.JSONSchema

func (*VisualizationTool) Name

func (t *VisualizationTool) Name() string

Jump to

Keyboard shortcuts

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