Skip to content

Latest commit

 

History

History
410 lines (300 loc) · 10.9 KB

File metadata and controls

410 lines (300 loc) · 10.9 KB

ChartGo 📊

A lightweight, beautiful charting library for Go Terminal User Interfaces (TUIs). Built to work seamlessly with the Charm.sh ecosystem.

Go Version License: MIT Bubble Tea

✨ Features

  • 🎨 10 Chart Types - Line, Bar, Pie, Doughnut, Scatter, Bubble, Radar, Polar Area, Funnel, and KPI Cards
  • 🎯 Zero Dependencies - Pure Unicode rendering using Braille patterns (⣿) and block characters (█)
  • 📐 Responsive Design - Auto-scaling with terminal window resizes
  • 🚀 Declarative API - Simple, chainable methods for quick setup
  • 🎭 Customizable Themes - Cyberpunk aesthetics with full color control
  • 🧩 Bubble Tea Native - All components implement tea.Model interface
  • ⚡ High Performance - Efficient rendering for real-time data visualization

📦 Installation

go get github.com/aayanmtn/chartgo

🚀 Quick Start

package main

import (
    "fmt"
    "github.com/aayanmtn/chartgo/components"
)

func main() {
    // Create a simple line chart
    data := []float64{10, 25, 15, 40, 30, 55, 45}
    chart := components.NewLineChart(data).
        SetWidth(40).
        SetHeight(10).
        SetTitle("Server Response Time")
    
    fmt.Println(chart.View())
}

Output:

╭────────────────────────────────────────╮
│      Server Response Time              │
│ 55 ⡤⠤⢤⡀                                  │
│ 50 ⠀⠀⠀⠹⡄⢀⡀                              │
│ 45 ⠀⠀⠀⠀⠘⠁⠈⢦                            │
│ 40 ⢀⠀⠀⠀⠀⠀⠀⠀⠱⡀                          │
│ 35 ⡜⢣⠀⠀⠀⠀⠀⠀⠀⠈⢆                        │
│ 30 ⠁⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠙⡄                      │
│ 25 ⠀⠀⠀⠀⠀⠉⠢⣀⠀⠀⠀⠀⠀⠘⢆                    │
│ 10 ⡎⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠑⢦                │
╰────────────────────────────────────────╯

📊 Chart Components

KPI Card

Display single metrics with elegant formatting.

kpi := components.NewKPICard("CPU Usage", "85%").
    SetWidth(20)

fmt.Println(kpi.View())

Output:

╭──────────────────╮
│    CPU Usage     │
│       85%        │
╰──────────────────╯

Line Chart

Smooth time-series visualization using Braille patterns for high resolution.

data := []float64{10, 25, 15, 40, 30, 55, 45, 60, 50, 70}
chart := components.NewLineChart(data).
    SetWidth(40).
    SetHeight(8).
    SetTitle("Server Response Time")

fmt.Println(chart.View())

Uses Braille characters for 2×4 sub-pixel resolution per character, creating smooth curves.

Bar Chart

Categorical data comparison using block characters.

data := []float64{85, 72, 65, 48, 30}
labels := []string{"Chrome", "Node.js", "Docker", "Slack", "VSCode"}

chart := components.NewBarChart(data, labels).
    SetWidth(50).
    SetTitle("Process CPU %")

fmt.Println(chart.View())

Funnel Chart

Visualize conversion funnels and pipelines.

data := []float64{1000, 750, 400, 200, 50}
labels := []string{"Visitors", "Signups", "Trials", "Paid", "Enterprise"}

chart := components.NewFunnelChart(data, labels).
    SetWidth(50).
    SetTitle("Conversion Funnel")

fmt.Println(chart.View())

Pie Chart

Proportional data representation with legend.

data := []float64{45, 25, 15, 10, 5}
labels := []string{"API", "Database", "Cache", "Auth", "Other"}

chart := components.NewPieChart(data, labels).
    SetWidth(40).
    SetTitle("Request Distribution")

fmt.Println(chart.View())

Scatter Plot

Plot individual data points with Braille precision.

data := []components.Point{
    {X: 1, Y: 2}, {X: 2, Y: 4}, {X: 3, Y: 3},
    {X: 4, Y: 5}, {X: 5, Y: 4}, {X: 6, Y: 6},
}

chart := components.NewScatterChart(data).
    SetWidth(30).
    SetHeight(10).
    SetTitle("Data Points")

fmt.Println(chart.View())

Bubble Chart

Multi-dimensional data with variable-sized bubbles.

data := []components.BubblePoint{
    {X: 1, Y: 3, Size: 10}, {X: 3, Y: 5, Size: 20},
    {X: 5, Y: 2, Size: 15}, {X: 7, Y: 6, Size: 25},
}

chart := components.NewBubbleChart(data).
    SetWidth(30).
    SetHeight(10).
    SetMaxRadius(6).
    SetTitle("Performance Metrics")

fmt.Println(chart.View())

Radar Chart

Spider/web chart for multi-dimensional comparisons.

data := []float64{85, 70, 90, 60, 75}
labels := []string{"Speed", "Power", "Range", "Armor", "Magic"}

chart := components.NewRadarChart(data, labels).
    SetWidth(20).
    SetHeight(10).
    SetTitle("Character Stats")

fmt.Println(chart.View())

Doughnut Chart

Ring-shaped proportional visualization.

data := []float64{40, 30, 20, 10}
labels := []string{"React", "Vue", "Angular", "Svelte"}

chart := components.NewDoughnutChart(data, labels).
    SetWidth(20).
    SetHeight(10).
    SetTitle("Framework Usage")

fmt.Println(chart.View())

Polar Area Chart

Radial chart with variable segment sizes.

data := []float64{50, 75, 60, 90, 45}
labels := []string{"Jan", "Feb", "Mar", "Apr", "May"}

chart := components.NewPolarAreaChart(data, labels).
    SetWidth(20).
    SetHeight(10).
    SetTitle("Monthly Sales")

fmt.Println(chart.View())

🎭 Bubble Tea Integration

All components are native Bubble Tea models and can be used directly in your TUI applications:

package main

import (
    tea "github.com/charmbracelet/bubbletea"
    "github.com/aayanmtn/chartgo/components"
)

type model struct {
    chart *components.LineChart
    data  []float64
}

func (m model) Init() tea.Cmd {
    return nil
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.KeyMsg:
        if msg.String() == "q" {
            return m, tea.Quit
        }
    case tea.WindowSizeMsg:
        m.chart.SetWidth(msg.Width).SetHeight(msg.Height / 2)
    }
    return m, nil
}

func (m model) View() string {
    return m.chart.View()
}

func main() {
    data := []float64{10, 25, 15, 40, 30, 55, 45}
    p := tea.NewProgram(model{
        chart: components.NewLineChart(data).SetTitle("Live Data"),
        data:  data,
    })
    p.Run()
}

🎨 Customization

Theming

Customize colors and styles using Lip Gloss:

import (
    "github.com/charmbracelet/lipgloss"
    "github.com/aayanmtn/chartgo/components"
)

customStyle := lipgloss.NewStyle().
    Foreground(lipgloss.Color("#FF6600")).
    Bold(true)

chart := components.NewLineChart(data).
    SetStyle(customStyle).
    SetTitle("Custom Styled Chart")

Configuration Methods

All charts support chainable configuration:

Method Description Applies To
SetWidth(int) Set chart width in characters All components
SetHeight(int) Set chart height Line, Scatter, Bubble, Radar
SetTitle(string) Set chart title All components
SetData([]float64) Update chart data All components
SetLabels([]string) Set axis/category labels Bar, Funnel, Pie, Radar, etc.
SetShowValues(bool) Toggle value labels Bar, Funnel
SetStyle(lipgloss.Style) Custom text styling All components
SetBorderStyle(lipgloss.Style) Custom border styling All components
SetMaxRadius(int) Maximum bubble size Bubble chart

Color Palette

Default cyberpunk theme:

Color Hex Usage
Cyan #00FFFF Primary lines/bars
Purple #9D4EDD Secondary elements
Magenta #FF00FF Highlights
Neon Green #39FF14 Accents
Pink #FF6EC7 Alternative highlights

📁 Project Structure

chartgo/
├── canvas/              # Rendering engine
│   └── canvas.go        # Braille canvas with Bresenham's algorithm
├── components/          # Chart implementations
│   ├── barchart.go      # Bar Chart
│   ├── bubble.go        # Bubble Chart
│   ├── doughnut.go      # Doughnut Chart
│   ├── funnel.go        # Funnel Chart
│   ├── kpi.go           # KPI Card
│   ├── linechart.go     # Line Chart
│   ├── piechart.go      # Pie Chart
│   ├── polararea.go     # Polar Area Chart
│   ├── radar.go         # Radar/Spider Chart
│   └── scatter.go       # Scatter Plot
├── styles/              # Theming system
│   └── theme.go         # Color palette definitions
├── utils/               # Helper functions
│   └── math.go          # Mathematical utilities
└── examples/            # Demo applications
    └── main.go          # Interactive dashboard example

🎮 Running the Demo

See all chart types in action with the interactive demo:

git clone https://github.com/aayanmtn/chartgo.git
cd chartgo
go run ./examples/

Controls:

  • Press q to quit

The demo showcases real-time updates, multiple chart types, and responsive layouts.

🔧 Technical Details

Canvas Rendering Engine

ChartGo uses a sophisticated Braille-based rendering system:

  • Sub-pixel Precision: Each terminal character represents a 2×4 pixel grid
  • Unicode Range: U+2800 to U+28FF (256 possible patterns per character)
  • Line Drawing: Bresenham's algorithm for smooth, anti-aliased lines
  • Circle Rendering: Midpoint circle algorithm for bubbles and radial charts
  • Bounds Checking: Safe coordinate handling prevents rendering errors

Performance

  • Zero Allocations in hot paths during rendering
  • Efficient Data Structures for O(1) pixel lookups
  • Optimized String Building for terminal output
  • Minimal Dependencies - only Charm.sh ecosystem

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

📄 License

MIT License - see LICENSE file for details

🙏 Acknowledgments

Built with love using:

  • Bubble Tea - The fun, functional TUI framework
  • Lip Gloss - Style definitions for nice terminal layouts

Documentation • Examples • Report Bug • Request Feature

Made with ❤️ for the terminal