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

plot

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 5 Imported by: 0

README

plot-go

Build Status Coverage Status GoDevDoc Time Tracker Code lines Comments

Renders interactive line, stacked-bar and pie charts (backed by uPlot) as an HTML fragment, so any Go web app can embed a chart by handing it tabular data - no server-side pixel rendering, no JS to write by hand.

Usage

go get github.com/vearutop/plot-go

Mount Handler under a path prefix, include HeadTags with the same prefix in the page's <head>, then Render returns a container element plus the inline script that draws into it once those assets have loaded:

mux.Handle("/plot/", http.StripPrefix("/plot/", plot.Handler()))

chart, err := plot.Render("requests", plot.Data{
	Columns: []string{"time", "requests"},
	Values:  [][]any{{1700000000, 12}, {1700000060, 18}},
}, plot.Options{Caption: "Requests per minute", Time: true})

fmt.Fprintf(w, `<!DOCTYPE html><html><head>%s</head><body>%s</body></html>`,
	plot.HeadTags("/plot/"), chart)

See example/main.go for a complete, runnable app:

go run ./example

The example also has a live chart: the server produces a point every second, and the page polls /points?since=<time of the last point> and calls Plot.append with the new rows (see Live updates).

Live updates

Render draws a chart once. Later (e.g. from a polling script) the chart can be changed in place with two JS calls, so cursor, legend state and user zoom are kept, and the X axis follows new points unless the chart is zoomed in:

// Replace the whole dataset with a new full one.
Plot.replace("requests", {columns: ["time", "requests"], values: [[1700000000, 12], [1700000060, 18]]}, opts)

// Add rows to the existing dataset, rows have the shape of `values`, X is expected to be greater than existing.
Plot.append("requests", [[1700000120, 21]])
  • Plot.replace(id, data, opts) takes the same data as Render, opts is only used if the chart has not been drawn yet, so it can also be used for the first draw. A changed point (e.g. the current, still growing, minute) is simply a part of the new list.
  • Plot.append(id, rows) needs a drawn chart and returns false if there is none. For line charts with ascending X the new values are pushed right to the chart (uPlot has no append call of its own, this is its setData over the same arrays), so the cost does not depend on the number of points already there. Otherwise (rows shape, stacked bars, X is not greater than the last one) the chart data is rebuilt from all the rows.

Line and stacked-bar charts are supported, if the set of series changes the chart is rebuilt.

Data

Data.Columns/Data.Values is a plain table, first column generally the X axis:

plot.Data{
	Columns: []string{"x", "y1", "y2"},
	Values:  [][]any{{1, 10, 20}, {2, 15, 18}},
}

Options

Field Effect
Kind plot.Line (default) or plot.Pie
Rows Treat Data as (x, y, label) rows instead of (x, y1, y2, ...) columns (Line only)
StackedBars Render stacked bars instead of lines (Line only)
Time X axis is UTC Unix timestamps (Line only)
TimeAxisFmt Override the X axis label format, e.g. "{YYYY}-{MM}" (only with Time)
Caption Chart title
Height Pixels, default 300 (Line only)
PieTotal Override the computed total, for a Pie chart showing a partial breakdown

For Kind: Pie, each row of Data is (count, label) or (label, count) -- whichever column parses as a number is used as the count.

Documentation

Overview

Package plot renders interactive line, stacked-bar and pie charts (backed by uPlot) as an HTML fragment, so any Go web app can embed a chart by calling Render with tabular data.

Mount Handler under a path prefix and include HeadTags(prefix) in the page's <head>; then Render returns a container element plus the inline script that draws into it once those assets have loaded:

mux.Handle("/plot/", http.StripPrefix("/plot/", plot.Handler()))
head := plot.HeadTags("/plot/")
chart, err := plot.Render("chart-1", plot.Data{Columns: cols, Values: rows}, plot.Options{Caption: "Requests"})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Handler

func Handler() http.Handler

Handler serves the package's static assets (uPlot library and the chart rendering script).

func HeadTags

func HeadTags(prefix string) template.HTML

HeadTags returns the <script>/<link> tags to load into a page's <head>, with asset URLs rooted at prefix, the same prefix Handler is mounted under.

func Render

func Render(id string, data Data, opts Options) (template.HTML, error)

Render returns an HTML fragment: a container element plus the inline script that draws the chart into it once the page has loaded the assets from Handler/HeadTags. id must be unique within the page.

Types

type Data

type Data struct {
	Columns []string `json:"columns"`
	Values  [][]any  `json:"values"`
}

Data is a generic tabular dataset to chart.

In the default column shape, the first column is the X axis and each remaining column is one series. In row shape (Options.Rows), each row is (x, y, label) and rows sharing a label form one series. For Options.Kind Pie, each row is (count, label) or (label, count).

type Kind

type Kind string

Kind selects the chart type.

const (
	Line Kind = "line"
	Pie  Kind = "pie"
)

Supported chart kinds.

type Options

type Options struct {
	Kind Kind `json:"kind,omitempty"` // Default Line.

	// Rows treats Data as (x, y, label) rows instead of (x, y1, y2, ...) columns. Ignored for Pie.
	Rows bool `json:"rows,omitempty"`

	// StackedBars renders a stacked bar chart instead of lines. Ignored for Pie.
	StackedBars bool `json:"stackedBars,omitempty"`

	// Time treats the X axis as UTC Unix timestamps. Ignored for Pie.
	Time bool `json:"time,omitempty"`

	// TimeAxisFmt overrides the X axis label format, e.g. "{YYYY}-{MM}". Only applies with Time.
	TimeAxisFmt string `json:"timeAxisFmt,omitempty"`

	Caption string `json:"caption,omitempty"`
	Height  int    `json:"height,omitempty"` // Pixels, default 300.

	// PieTotal overrides the computed total, for a Pie chart showing a partial breakdown.
	PieTotal float64 `json:"pieTotal,omitempty"`
}

Options configures how Data is rendered.

Directories

Path Synopsis
Command example demonstrates embedding plot's charts in a plain net/http app -- e.g.
Command example demonstrates embedding plot's charts in a plain net/http app -- e.g.

Jump to

Keyboard shortcuts

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