chartmux

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 18 Imported by: 0

README

chartmux

chartmux turns CSV, JSON, or a versioned chart spec into terminal charts, PNG, SVG, a self-contained HTML page, or resolved JSON. The data contract uses the familiar dataKey, series, and chart configuration model used by React chart libraries.

Install

With Go:

go install github.com/mertdeveci5/chartmux/cmd/chartmux@latest

Prebuilt macOS, Linux, and Windows binaries are published on GitHub Releases. Homebrew and npm installation are described below once their registry packages are available.

Build and try it

cd ~/Desktop/Code/chartmux
go build -o chartmux ./cmd/chartmux

./chartmux demo line
./chartmux demo grouped-bar
./chartmux demo stacked-bar
./chartmux demo normalized-bar

List every built-in example or display them all:

./chartmux demo --list
./chartmux demo --all

High-resolution terminal UI

One-shot output uses portable Unicode curves and solid terminal bars. The responsive UI uses a real chart image through the Kitty graphics protocol when the terminal supports it, and falls back to Unicode when it does not:

./chartmux demo line --watch
./chartmux demo stacked-bar --watch

Resize the window to resize the chart. When Kitty graphics are available, press g to switch between graphics and Unicode. Press q to quit. Presentation can also be selected explicitly:

./chartmux demo line --watch --terminal-mode kitty
./chartmux demo line --watch --terminal-mode unicode

auto is the default. A nested terminal UI may not pass the graphics protocol through, so Chartmux will use the connected Unicode chart there instead of printing half-block image pixels.

Use your own data

Pass a CSV, TSV, semicolon-delimited file, or JSON array directly:

./chartmux sales.csv --type line --x month --series revenue,cost
./chartmux bar sales.csv --x month --series desktop,mobile --layout grouped
./chartmux bar sales.csv --x month --series desktop,mobile --layout stacked
./chartmux bar sales.csv --x month --series desktop,mobile --orientation horizontal
./chartmux combo sales.csv --x month --series revenue,target --marks bar,line

Use - to read the dataset from stdin. Empty input is an error; examples are only available through the explicit demo command.

Each typed command only exposes options that apply to that chart. For example, line accepts --curve, bar accepts --layout and --orientation, and histogram accepts --bins. Run ./chartmux <command> --help for the exact contract.

Chart types

  • line
  • bar with grouped, stacked, or normalized layout
  • horizontal bar
  • area with overlay, stacked, or normalized layout
  • combo with per-series bar or line marks
  • scatter
  • histogram
  • pie and donut
  • heatmap
  • radar
  • funnel

Output and automation

All chart types use the same output engine, so an exported chart preserves the same data, layout, colors, axes, and legend:

./chartmux demo stacked-area --export png --output chart.png
./chartmux demo grouped-bar --export svg --output chart.svg
./chartmux examples/area.json --export html --output chart.html
./chartmux demo line --export png --output chart.png --copy
./chartmux examples/area.json --export json --output -

PNG defaults to 1200×720. SVG and HTML default to 960×540. Override either with --image-width and --image-height. HTML output is responsive, self-contained, and has no JavaScript or external assets.

Use --output - to stream PNG, SVG, HTML, or resolved JSON without status text. One-shot terminal output automatically removes ANSI color when redirected; --no-color also disables it explicitly. Terminal output can be saved with --export terminal --output chart.txt.

For scripts and editors:

./chartmux --version
./chartmux validate examples/area.json
./chartmux schema > chartmux-v1.schema.json

validate prints valid and exits zero only after data inference and chart validation succeed. --export json emits the final versioned spec after defaults and CLI overrides have been resolved. Histogram --bins 0 means automatic bin selection; negative values and values above 100 are errors.

On macOS and Windows, --copy uses the native clipboard. Linux requires wl-copy or xclip.

Saved chart contract

Saved files are strict, versioned JSON. Unknown fields fail early instead of being silently ignored. See examples/area.json and schema/v1.json.

{
  "$schema": "https://chartmux.dev/schema/v1.json",
  "version": 1,
  "type": "line",
  "title": "Visitors",
  "xAxis": { "dataKey": "month", "kind": "category" },
  "series": [
    { "dataKey": "desktop", "label": "Desktop", "color": "var(--chart-1)" },
    { "dataKey": "mobile", "label": "Mobile", "color": "#60A5FA" }
  ],
  "curve": "smooth",
  "data": [
    { "month": "January", "desktop": 186, "mobile": 80 },
    { "month": "February", "desktop": 305, "mobile": 200 }
  ]
}

Combo charts add a mark to each series. Bar and area charts use layout; bars also support orientation. Display flags use explicit objects such as "legend": { "show": false }.

Go package

The CLI and importable package share the same validated Spec and output engine:

spec := chartmux.Spec{
    Version: chartmux.SpecVersion,
    Type:    chartmux.Line,
    XAxis:   chartmux.AxisSpec{DataKey: "month"},
    Series:  []chartmux.SeriesSpec{{DataKey: "revenue", Label: "Revenue"}},
    Data: []chartmux.Row{
        {"month": "Jan", "revenue": 120},
        {"month": "Feb", "revenue": 180},
    },
}

chart, err := chartmux.New(spec)
if err != nil {
    return err
}
return chart.WriteSVG(writer, chartmux.ImageOptions{Width: 960, Height: 540})

Use chart.WriteJSON(writer) for the resolved chart contract and chartmux.SchemaJSON() for the embedded v1 schema.

The previous implicit demos, hbar, gauge, and --stacked paths were removed. Use demo, bar --orientation horizontal, and --layout stacked; gauge is intentionally absent until it has an engine-backed implementation.

Frontend playground

The terminal-inspired React/Vite playground lives in frontend. It uses smooth SVG charts in the browser and the official Cloudflare Vite plugin for Workers deployment.

cd frontend
npm install
npm run dev

Validate the production bundle and Cloudflare deployment without publishing:

npm run check
npm run build
npm run deploy:dry

Documentation

Index

Constants

View Source
const (
	DefaultTerminalWidth  = 80
	DefaultTerminalHeight = 14
	MinTerminalWidth      = 30
	MinTerminalHeight     = 8
)
View Source
const MaxInputBytes = 8 << 20
View Source
const SchemaURL = "https://chartmux.dev/schema/v1.json"
View Source
const SpecVersion = 1

Variables

This section is empty.

Functions

func DemoNames

func DemoNames() []string

func SchemaJSON

func SchemaJSON() []byte

Types

type AxisSpec

type AxisSpec struct {
	DataKey string `json:"dataKey"`
	Kind    string `json:"kind,omitempty"`
}

type Chart

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

func New

func New(spec Spec) (*Chart, error)

func (*Chart) PNG

func (chart *Chart) PNG(options ImageOptions) ([]byte, error)

func (*Chart) ResolvedSpec

func (chart *Chart) ResolvedSpec() Spec

func (*Chart) Spec

func (chart *Chart) Spec() Spec

func (*Chart) Terminal

func (chart *Chart) Terminal(options TerminalOptions) (string, error)

func (*Chart) WriteHTML

func (chart *Chart) WriteHTML(writer io.Writer, options HTMLOptions) error

func (*Chart) WriteJSON

func (chart *Chart) WriteJSON(writer io.Writer) error

func (*Chart) WritePNG

func (chart *Chart) WritePNG(writer io.Writer, options ImageOptions) error

func (*Chart) WriteSVG

func (chart *Chart) WriteSVG(writer io.Writer, options ImageOptions) error

type Curve

type Curve string
const (
	Linear Curve = "linear"
	Smooth Curve = "smooth"
)

type Dataset

type Dataset struct {
	Columns []string
	Rows    []Row
}

func ParseDataset

func ParseDataset(reader io.Reader) (Dataset, error)

type DisplaySpec

type DisplaySpec struct {
	Show bool `json:"show"`
}

type HTMLOptions

type HTMLOptions struct {
	Width  int
	Height int
}

type ImageOptions

type ImageOptions struct {
	Width  int
	Height int
}

type Layout

type Layout string
const (
	Grouped    Layout = "grouped"
	Overlay    Layout = "overlay"
	Stacked    Layout = "stacked"
	Normalized Layout = "normalized"
)

type Mark

type Mark string
const (
	MarkBar  Mark = "bar"
	MarkLine Mark = "line"
)

type Orientation

type Orientation string
const (
	Vertical   Orientation = "vertical"
	Horizontal Orientation = "horizontal"
)

type Row

type Row map[string]any

type SeriesSpec

type SeriesSpec struct {
	DataKey string `json:"dataKey"`
	Label   string `json:"label,omitempty"`
	Color   string `json:"color,omitempty"`
	Mark    Mark   `json:"mark,omitempty"`
}

type Spec

type Spec struct {
	Schema      string       `json:"$schema,omitempty"`
	Version     int          `json:"version"`
	Type        Type         `json:"type"`
	Title       string       `json:"title,omitempty"`
	Description string       `json:"description,omitempty"`
	Footer      string       `json:"footer,omitempty"`
	Data        []Row        `json:"data"`
	XAxis       AxisSpec     `json:"xAxis"`
	Series      []SeriesSpec `json:"series"`
	Layout      Layout       `json:"layout,omitempty"`
	Orientation Orientation  `json:"orientation,omitempty"`
	Curve       Curve        `json:"curve,omitempty"`
	Legend      *DisplaySpec `json:"legend,omitempty"`
	Axes        *DisplaySpec `json:"axes,omitempty"`
	Labels      *DisplaySpec `json:"labels,omitempty"`
	Theme       string       `json:"theme,omitempty"`
	Bins        int          `json:"bins,omitempty"`
	Max         float64      `json:"max,omitempty"`
}

func Demo

func Demo(name string) (Spec, error)

func ParseSpec

func ParseSpec(reader io.Reader) (Spec, error)

func SpecFromDataset

func SpecFromDataset(dataset Dataset, chartType Type, xKey string, seriesKeys []string) (Spec, error)

type TerminalOptions

type TerminalOptions struct {
	Width  int
	Height int
}

type TerminalSizeError

type TerminalSizeError struct {
	Width  int
	Height int
}

func (*TerminalSizeError) Error

func (err *TerminalSizeError) Error() string

type Type

type Type string
const (
	Bar       Type = "bar"
	Line      Type = "line"
	Area      Type = "area"
	Combo     Type = "combo"
	Scatter   Type = "scatter"
	Histogram Type = "histogram"
	Pie       Type = "pie"
	Donut     Type = "donut"
	Heatmap   Type = "heatmap"
	Radar     Type = "radar"
	Funnel    Type = "funnel"
)

func Types

func Types() []Type

Directories

Path Synopsis
cmd
chartmux command

Jump to

Keyboard shortcuts

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