pulse

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 6 Imported by: 0

README

Pulse

Pulse Banner

Real-time terminal line charts for Charm Lip Gloss and Bubble Tea.

CI Status Go Reference Go Report Card MIT License


Pulse Terminal Chart

Pulse brings rich, responsive time-series visualization to terminal user interfaces (TUIs). Built specifically for the Charm ecosystem (Lip Gloss and Bubble Tea), Pulse features smooth box-drawing curves, high-density Braille sub-pixel rendering, half-tone shaded area fills, and Grafana-style aligned gridlines.

✨ Features

  • ╭╯ Smooth Box-Drawing: Continuous lines rendered with rounded arcs (╭ ╮ ╯ ╰) or bold strokes (┏ ┓ ┛ ┗).
  • ⠒ Sub-Pixel Braille: High-density 2×4 dot Braille matrix interpolated via cubic Catmull-Rom splines.
  • ░ Shaded Area Fill: Half-tone shading beneath curves that cleanly absorbs grid intersections.
  • ┼ Aligned Coordinate Grid: Subtle coordinate grid aligned exactly to Y-axis ticks and width quarter-steps.
  • 📈 Multi-Series Support: Plot multiple named metrics simultaneously with dedicated styles and swatches.
  • 📦 Live Legend Box: Bordered legend overlay displaying swatches, names, and real-time values.
  • 🫧 Charm Native: Fully customizable with Lip Gloss styles and built for Bubble Tea event loops.

🚀 Quick Start

Installation
go get github.com/ingvarch/pulse
Minimal Example
package main

import (
	"fmt"
	"math"

	"github.com/ingvarch/pulse"
	"github.com/ingvarch/pulse/theme"
)

func main() {
	preset := theme.TokyoNight()
	chartW, chartH := 80, 13

	chart := pulse.New(chartW, chartH,
		pulse.WithRange(0, 100),
		pulse.WithTicks(0, 25, 50, 75, 100),
		pulse.WithLineWidth(1), // Smooth rounded corners: ╭ ╮ ╯ ╰
		pulse.WithAxisStyle(preset.Axis),
		pulse.WithLineStyle(preset.LineFor(60)),
	)

	// Stream 80 data points into the sliding window
	for i := 0; i < chartW; i++ {
		val := 50 + 38*math.Sin(float64(i)*0.16)
		chart.Push(val)
	}

	fmt.Println(chart.View())
}

Pulse Quick Start Output

🎨 Lip Gloss Styling & Themes

Pulse is designed from the ground up for Lip Gloss. You can style individual series, axes, borders, and threshold colors:

package main

import (
	"fmt"
	"charm.land/lipgloss/v2"
	"github.com/ingvarch/pulse"
	"github.com/ingvarch/pulse/theme"
)

func main() {
	preset := theme.TokyoNight()

	chart := pulse.New(80, 13,
		pulse.WithRange(0, 100),
		pulse.WithTicks(0, 25, 50, 75, 100),
		pulse.WithLineWidth(2), // Bold curves: ┏ ┓ ┛ ┗
		pulse.WithAxisStyle(preset.Axis),
		pulse.WithSeriesStyle("cluster-a", preset.LineFor(88.0)), // Red warning threshold
		pulse.WithSeriesStyle("cluster-b", lipgloss.NewStyle().Foreground(lipgloss.Color("#bb9af7"))),
	)

	// Wrap the chart in a Lip Gloss bordered container
	box := lipgloss.NewStyle().
		Border(lipgloss.RoundedBorder()).
		BorderForeground(lipgloss.Color("#3b4261")).
		Padding(1, 2).
		Render(chart.View() + "\n" + chart.LegendBox())

	fmt.Println(box)
}

Pulse Lip Gloss Styling

⠒ Braille Sub-Pixel Rendering

For ultra-dense metrics, switch to pulse.ModeBraille to enable 2×4 dot matrix sub-pixel resolution powered by cubic Catmull-Rom spline interpolation:

chart.SetMode(pulse.ModeBraille)

Pulse Braille Sub-Pixel Rendering

📚 Documentation

Detailed guides and API references are available in the docs directory:

Document Description
Getting Started Constructor options, sliding window buffers, multi-series, and runtime controls
Rendering Modes Box-drawing curves (rounded vs bold), Braille sub-pixel matrix, and area fill
Axes & Grid Adaptive NiceTicks, custom tick quarter-steps, and Grafana grid alignment
Bubble Tea Integration Embedding in Bubble Tea models, telemetry ticks, and interactive hotkeys

🎮 Interactive Demos

Try the included examples directly from your terminal:

# Live multi-series stream (CPU, MEM, NET) with hotkeys: t (thickness), m (braille), q (quit)
go run ./examples/multidemo

# Live single-signal generator with thickness & mode toggle
go run ./examples/livedemo

# Real-time hardware telemetry (CPU & RAM) from your machine
go run ./examples/cpulive

# Clean terminal screenshot generator
go run ./examples/cpudemo

🤝 Community & Contributing

We welcome issues and pull requests! Please check our community guidelines:

📄 License

Pulse is licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultTintColor color.Color = lipgloss.Color("#1f2335")

DefaultTintColor is the default background tint used when TintedFill is active and no custom tint color or style background is specified. Defaults to Tokyo Night slate (#1f2335).

Functions

This section is empty.

Types

type BrailleRenderer added in v0.3.0

type BrailleRenderer struct{}

BrailleRenderer renders 2x4 dot Braille patterns.

func (BrailleRenderer) Render added in v0.3.0

func (BrailleRenderer) Render(c Chart, ctx RenderContext) string

Render implements Renderer for BrailleRenderer.

type Chart added in v0.4.0

type Chart interface {
	Width() int
	Height() int
	Min() float64
	Max() float64
	Fill() bool
	TintedFill() bool
	SolidFill() bool
	TintColor() color.Color
	Grid() bool
	Smooth() bool
	LineWidth() int
	AxisStyle() lipgloss.Style
	LineStyle() lipgloss.Style
	SeriesStyle(name string) lipgloss.Style
	SeriesNames() []string
	SeriesData(name string) []float64
}

Chart provides the read-only contract for inspecting chart dimensions, data, and styles.

type LinesRenderer added in v0.3.0

type LinesRenderer struct{}

LinesRenderer renders smooth box-drawing lines with optional area fill.

func (LinesRenderer) Render added in v0.3.0

func (LinesRenderer) Render(c Chart, ctx RenderContext) string

Render implements Renderer for LinesRenderer.

type Model

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

Model is a streaming terminal line chart.

func New

func New(w, h int, opts ...Option) *Model

New creates a chart for a w x h cells plot area.

func (*Model) AxisStyle added in v0.3.0

func (m *Model) AxisStyle() lipgloss.Style

AxisStyle returns the axis lipgloss style.

func (*Model) Fill added in v0.3.0

func (m *Model) Fill() bool

Fill returns whether area fill is enabled.

func (*Model) Grid added in v0.3.0

func (m *Model) Grid() bool

Grid returns whether grid lines are enabled.

func (*Model) Height added in v0.3.0

func (m *Model) Height() int

Height returns the chart plot height in terminal cells.

func (*Model) Last

func (m *Model) Last(name string) (float64, bool)

Last returns the most recent value of a named series.

func (*Model) Legend

func (m *Model) Legend() string

Legend returns a formatted legend for named series, or empty string if none exist.

func (*Model) LegendBox

func (m *Model) LegendBox() string

LegendBox returns a boxed legend with borders, swatches, series names, and recent values.

func (*Model) Len

func (m *Model) Len() int

Len returns the number of points in the default series within the window.

func (*Model) LenSeries

func (m *Model) LenSeries(name string) int

LenSeries returns the number of points in the named series within the window.

func (*Model) LineStyle added in v0.3.0

func (m *Model) LineStyle() lipgloss.Style

LineStyle returns the default line lipgloss style.

func (*Model) LineWidth

func (m *Model) LineWidth() int

LineWidth returns the current line width.

func (*Model) Max added in v0.3.0

func (m *Model) Max() float64

Max returns the chart maximum Y value.

func (*Model) Min added in v0.3.0

func (m *Model) Min() float64

Min returns the chart minimum Y value.

func (*Model) Mode

func (m *Model) Mode() RenderMode

Mode returns the current rendering mode derived from the active renderer.

func (*Model) Push

func (m *Model) Push(v float64)

Push adds a data point to the default series. Maintains a sliding window of width w.

func (*Model) PushSeries

func (m *Model) PushSeries(name string, v float64)

PushSeries adds a data point to a named series.

func (*Model) Renderer added in v0.3.0

func (m *Model) Renderer() Renderer

Renderer returns the current chart renderer.

func (*Model) SeriesData added in v0.3.0

func (m *Model) SeriesData(name string) []float64

SeriesData returns a copy of data points for a series.

func (*Model) SeriesNames added in v0.3.0

func (m *Model) SeriesNames() []string

SeriesNames returns registered series names in order.

func (*Model) SeriesStyle added in v0.4.0

func (m *Model) SeriesStyle(name string) lipgloss.Style

SeriesStyle returns the style for a named series, or default line style.

func (*Model) SetAxisStyle

func (m *Model) SetAxisStyle(s lipgloss.Style)

SetAxisStyle dynamically updates the axis style.

func (*Model) SetFill

func (m *Model) SetFill(on bool)

SetFill enables or disables area fill dynamically.

func (*Model) SetGrid

func (m *Model) SetGrid(on bool)

SetGrid enables or disables the grid dynamically.

func (*Model) SetLabelFormatter added in v0.2.0

func (m *Model) SetLabelFormatter(fn func(float64) string)

SetLabelFormatter dynamically updates the Y-axis label formatter.

func (*Model) SetLabelWidth added in v0.2.0

func (m *Model) SetLabelWidth(w int)

SetLabelWidth dynamically updates the Y-axis label column width.

func (*Model) SetLineStyle

func (m *Model) SetLineStyle(s lipgloss.Style)

SetLineStyle dynamically updates the line style.

func (*Model) SetLineWidth

func (m *Model) SetLineWidth(w int)

SetLineWidth sets the line width: 1 for thin, 2 for bold.

func (*Model) SetMode

func (m *Model) SetMode(mode RenderMode)

SetMode sets the rendering mode (ModeLines or ModeBraille). ModeCustom cannot be set: install the renderer with SetRenderer instead.

func (*Model) SetRange added in v0.3.0

func (m *Model) SetRange(min, max float64)

SetRange dynamically sets the Y-axis range.

func (*Model) SetRenderer added in v0.3.0

func (m *Model) SetRenderer(r Renderer)

SetRenderer dynamically updates the chart renderer and synchronizes Mode(). A nil renderer falls back to LinesRenderer.

func (*Model) SetSeriesStyle

func (m *Model) SetSeriesStyle(name string, s lipgloss.Style)

SetSeriesStyle dynamically sets the style for a named series.

func (*Model) SetSmooth

func (m *Model) SetSmooth(on bool)

SetSmooth enables or disables smoothing dynamically.

func (*Model) SetSolidFill added in v0.4.0

func (m *Model) SetSolidFill(on bool)

SetSolidFill enables or disables solid background fill dynamically.

func (*Model) SetTicks

func (m *Model) SetTicks(ticks ...float64)

SetTicks dynamically sets explicit tick values for the Y axis. Ticks are copied, sorted ascending, and deduplicated.

func (*Model) SetTintColor added in v0.4.0

func (m *Model) SetTintColor(c color.Color)

SetTintColor dynamically updates the chart background tint color.

func (*Model) SetTintedFill added in v0.4.0

func (m *Model) SetTintedFill(on bool)

SetTintedFill enables or disables tinted background fill dynamically.

func (*Model) Smooth added in v0.3.0

func (m *Model) Smooth() bool

Smooth returns whether line smoothing is enabled.

func (*Model) SolidFill added in v0.4.0

func (m *Model) SolidFill() bool

SolidFill returns whether solid background fill is enabled.

func (*Model) String added in v0.3.0

func (m *Model) String() string

String implements fmt.Stringer, returning the rendered chart View().

func (*Model) TintColor added in v0.4.0

func (m *Model) TintColor() color.Color

TintColor returns the custom background tint color, or nil if using default.

func (*Model) TintedFill added in v0.4.0

func (m *Model) TintedFill() bool

TintedFill returns whether tinted area fill is enabled.

func (*Model) ToggleRenderMode

func (m *Model) ToggleRenderMode()

ToggleRenderMode switches between ModeLines and ModeBraille.

func (*Model) View

func (m *Model) View() string

View renders the chart: Y-axis labels + axis border + plot area.

func (*Model) Width added in v0.3.0

func (m *Model) Width() int

Width returns the chart plot width in terminal cells.

type Option

type Option func(*Model)

Option configures a Model.

func WithAxisStyle

func WithAxisStyle(s lipgloss.Style) Option

WithAxisStyle sets the axes and labels style.

func WithFill

func WithFill(on bool) Option

WithFill enables or disables area fill under the line.

func WithGrid

func WithGrid(on bool) Option

WithGrid enables or disables gridlines at tick positions.

func WithLabelFormatter added in v0.2.0

func WithLabelFormatter(fn func(float64) string) Option

WithLabelFormatter sets a custom formatter for Y-axis tick values.

func WithLabelWidth added in v0.2.0

func WithLabelWidth(w int) Option

WithLabelWidth sets an explicit width for Y-axis labels.

func WithLineStyle

func WithLineStyle(s lipgloss.Style) Option

WithLineStyle sets the default line style.

func WithLineWidth

func WithLineWidth(w int) Option

WithLineWidth sets line width: 1 thin, 2 bold.

func WithMode

func WithMode(mode RenderMode) Option

WithMode sets rendering mode (ModeLines or ModeBraille).

func WithRange

func WithRange(min, max float64) Option

WithRange sets the fixed Y range. For example, WithRange(0, 100) for CPU/RAM.

func WithRenderer added in v0.3.0

func WithRenderer(r Renderer) Option

WithRenderer sets a custom chart renderer.

func WithSeriesStyle

func WithSeriesStyle(name string, s lipgloss.Style) Option

WithSeriesStyle sets the style for a named series.

func WithSmooth

func WithSmooth(on bool) Option

WithSmooth enables or disables line smoothing (rounded corners or spline).

func WithSolidFill added in v0.4.0

func WithSolidFill(on bool) Option

WithSolidFill enables or disables solid background fill (spaces with background color) instead of stippled glyphs (░).

func WithTicks

func WithTicks(ticks ...float64) Option

WithTicks sets explicit Y-axis tick values (e.g. 0, 25, 50, 75, 100 or 0, 50, 100).

func WithTintColor added in v0.4.0

func WithTintColor(c color.Color) Option

WithTintColor sets a custom background tint color for tinted fill mode. If nil, DefaultTintColor (#1f2335) is used.

func WithTintedFill added in v0.4.0

func WithTintedFill(on bool) Option

WithTintedFill enables or disables tinted background fill under the line, seamlessly bridging the gap between box-drawing characters and area fill.

type RenderContext added in v0.3.0

type RenderContext struct {
	LabelWidth int
	LabelStyle lipgloss.Style
	RowLabel   map[int]string
	HGrid      []bool
	VGrid      []bool
	Names      []string
	Styles     []lipgloss.Style
	GridStyle  lipgloss.Style
}

RenderContext contains prepared axis, tick, label, and style metadata passed to a Renderer.

type RenderMode

type RenderMode int

RenderMode defines how line curves are rendered on the chart.

const (
	// ModeLines renders smooth continuous lines (box-drawing ╭, ╮, ╯, ╰, ─, │) with Grafana-style area fill ░.
	ModeLines RenderMode = iota
	// ModeBraille renders using a 2x4 dot braille matrix (Unicode Braille Patterns).
	ModeBraille
	// ModeCustom represents a custom user-supplied Renderer.
	ModeCustom
)

type Renderer added in v0.3.0

type Renderer interface {
	Render(c Chart, ctx RenderContext) string
}

Renderer defines how chart series data and axes are rendered into a string. Custom renderers only need the Chart contract: build one with New and Push in tests, no mocks required.

Directories

Path Synopsis
cmd
gen-shots command
examples
cpudemo command
cpulive command
livedemo command
multidemo command

Jump to

Keyboard shortcuts

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