margaid

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2023 License: ISC Imports: 9 Imported by: 4

README

Margaid ⇄ diagraM

The world surely doesn't need another plotting library. But I did, and that's why Margaid was born.

Margaid is a small, no dependencies Golang library for plotting 2D data to SVG images. The idea is to create nice charts with a few lines of code and not having to bring in heavy machinery.

"Margaid" is an old name meaning "pearl", which seemed fitting for something shiny and small. It's also the word "diagraM" spelled backwards.

Features

Margaid plots series of data to an SVG image. Series can be capped by size or time to simplify realtime data collection.

Plots are drawn using straight lines, smooth lines or bars.

Each axis has a fixed or automatic range, linear or log projection, configurable labels and optional grid lines.

Plot colors are automatically picked for each new plot, trying to spread them in hue and saturation to get a good mix.

There is no clever layout or layering going on. Each new command draws on top of the results from previous commands.

Getting started

Minimal example

Minimal plot

These are the minimal steps needed to create a Margaid plot:

  • Import the library
import "github.com/erkkah/margaid"
  • Create a series and add some values
series := margaid.NewSeries()
series.Add(margaid.MakeValue(10, 3.14), margaid.MakeValue(90, 93.8))
// et.c.
  • Create the diagram:
diagram := margaid.New(800, 600)
  • Plot the series
diagram.Line(series)
  • Add a frame and X axis
diagram.Frame()
diagram.Axis(series, margaid.XAxis, diagram.ValueTicker('f', 2, 10), false, "Values")
  • Render to stdout
diagram.Render(os.Stdout)
Example showing more features

Example plot

To generate the diagram above from the code shown below:

> go run -tags example ./example > example.svg
// example/example.go
package main

import (
    "math/rand"
    "os"
    "time"

    m "github.com/erkkah/margaid"
)

func main() {

    randomSeries := m.NewSeries()
    rand.Seed(time.Now().Unix())
    for i := float64(0); i < 10; i++ {
        randomSeries.Add(m.MakeValue(i+1, 200*rand.Float64()))
    }

    testSeries := m.NewSeries()
    multiplier := 2.1
    v := 0.33
    for i := float64(0); i < 10; i++ {
        v *= multiplier
        testSeries.Add(m.MakeValue(i+1, v))
    }

    diagram := m.New(800, 600,
        m.WithAutorange(m.XAxis, testSeries),
        m.WithAutorange(m.YAxis, testSeries),
        m.WithAutorange(m.Y2Axis, testSeries),
        m.WithProjection(m.YAxis, m.Log),
        m.WithInset(70),
        m.WithPadding(2),
        m.WithColorScheme(90),
    )

    diagram.Line(testSeries, m.UsingAxes(m.XAxis, m.YAxis), m.UsingMarker("square"), m.UsingStrokeWidth(1))
    diagram.Smooth(testSeries, m.UsingAxes(m.XAxis, m.Y2Axis), m.UsingStrokeWidth(3.14))
    diagram.Smooth(randomSeries, m.UsingAxes(m.XAxis, m.YAxis), m.UsingMarker("filled-circle"))
    diagram.Axis(testSeries, m.XAxis, diagram.ValueTicker('f', 0, 10), false, "X")
    diagram.Axis(testSeries, m.YAxis, diagram.ValueTicker('f', 1, 2), true, "Y")

    diagram.Frame()
    diagram.Title("A diagram of sorts 📊 📈")

    diagram.Render(os.Stdout)
}

Documentation

For more details, check the reference documentation.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SecondsFromTime

func SecondsFromTime(time time.Time) float64

SecondsFromTime converts from time.Time to seconds since the epoch

func TimeFromSeconds

func TimeFromSeconds(seconds float64) time.Time

TimeFromSeconds converts from seconds since the epoch to time.Time

Types

type Aggregator

type Aggregator func(values []Value, at time.Time) Value

Aggregator is the aggregating function type

type Axis

type Axis int

Axis is the type for all axis constants

const (
	XAxis Axis = iota + 'x'
	YAxis
	X2Axis
	Y2Axis

	X1Axis = XAxis
	Y1Axis = YAxis
)

Axis constants

type BezierPoint

type BezierPoint [3]struct{ X, Y float64 }

BezierPoint is one Bezier curve control point

type Capper

type Capper func(values *list.List)

Capper is the capping function type

type LegendPosition

type LegendPosition int

LegendPosition decides where to draw the legend

const (
	RightTop LegendPosition = iota + 'l'
	RightBottom
	BottomLeft
)

LegendPosition constants

type Margaid

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

Margaid == diagraM

func New

func New(width, height int, options ...Option) *Margaid

New - Margaid constructor

func (*Margaid) Axis

func (m *Margaid) Axis(series *Series, axis Axis, ticker Ticker, grid bool, title string)

Axis draws tick marks and labels using the specified ticker

func (*Margaid) Bar

func (m *Margaid) Bar(series []*Series, using ...Using)

Bar draws bars for the specified group of series.

func (*Margaid) Frame

func (m *Margaid) Frame()

Frame draws a frame around the chart area

func (*Margaid) LabeledTicker

func (m *Margaid) LabeledTicker(labeler func(float64) string) Ticker

LabeledTicker places tick marks and labels for all values of a series. The labels are provided by the labeler function.

func (*Margaid) Legend

func (m *Margaid) Legend(position LegendPosition)

Legend draws a legend for named plots. If position is set to BottomLeft, it will grow the plot size to accommodate the number of legends displayed.

func (*Margaid) Line

func (m *Margaid) Line(series *Series, using ...Using)

Line draws a series using straight lines

func (*Margaid) Render

func (m *Margaid) Render(writer io.Writer) error

Render renders the graph to the given destination.

func (*Margaid) Smooth

func (m *Margaid) Smooth(series *Series, using ...Using)

Smooth draws one series as a smooth curve

func (*Margaid) TimeTicker

func (m *Margaid) TimeTicker(format string) Ticker

TimeTicker returns time valued tick labels in the specified time format. TimeTicker assumes that time is linear.

func (*Margaid) Title

func (m *Margaid) Title(title string)

Title draws a title top center

func (*Margaid) ValueTicker

func (m *Margaid) ValueTicker(style byte, precision int, base int) Ticker

ValueTicker returns tick labels by converting floats using strconv.FormatFloat

type Option

type Option func(*Margaid)

Option is the base type for all series options

func WithAutorange

func WithAutorange(axis Axis, series ...*Series) Option

WithAutorange sets range for an axis from the values of one or more series

func WithBackgroundColor added in v0.2.0

func WithBackgroundColor(background string) Option

WithBackgroundColor sets the chart background color as a valid SVG color attribute string. Default is transparent.

func WithColorScheme

func WithColorScheme(scheme int) Option

WithColorScheme sets the start color for selecting plot colors. The start color is selected as a hue value between 0 and 359.

func WithInset

func WithInset(inset float64) Option

WithInset sets the distance between the chart boundaries and the charting area.

func WithLabelFont

func WithLabelFont(family string, size int) Option

WithLabelFont sets label font family and size in pixels

func WithPadding

func WithPadding(padding float64) Option

WithPadding sets the padding inside the plotting area as a percentage [0..20] of the area width and height

func WithProjection

func WithProjection(axis Axis, proj Projection) Option

WithProjection sets the projection for a given axis

func WithRange

func WithRange(axis Axis, min, max float64) Option

WithRange sets a fixed plotting range for a given axis

func WithTitleFont

func WithTitleFont(family string, size int) Option

WithTitleFont sets title font family and size in pixels

type Projection

type Projection int

Projection is the type for the projection constants

const (
	Lin Projection = iota + 'p'
	Log
)

Projection constants

type Series

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

Series is the plottable type in Margaid

func NewSeries

func NewSeries(options ...SeriesOption) *Series

NewSeries - series constructor

func (*Series) Add

func (s *Series) Add(values ...Value)

Add appends one or more values, optionally peforming aggregation. If the series is capped, capping will be applied after aggregation.

func (*Series) MaxX

func (s *Series) MaxX() float64

MaxX returns the series largest x value, or 0.0 if the series is empty

func (*Series) MaxY

func (s *Series) MaxY() float64

MaxY returns the series largest y value, or 0.0 if the series is empty

func (*Series) MinX

func (s *Series) MinX() float64

MinX returns the series smallest x value, or 0.0 if the series is empty

func (*Series) MinY

func (s *Series) MinY() float64

MinY returns the series smallest y value, or 0.0 if the series is empty

func (*Series) Size

func (s *Series) Size() int

Size returns the current series value count

func (*Series) Values

func (s *Series) Values() SeriesIterator

Values returns an iterator to the series values

func (*Series) Zip

func (s *Series) Zip(xValues, yValues []float64)

Zip merges two slices of floats into pairs and adds them to the series. It is assumed that the two slices have the same length.

type SeriesIterator

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

SeriesIterator helps iterating series values

func (*SeriesIterator) Get

func (si *SeriesIterator) Get() Value

Get returns the iterator current value. A newly created iterator has no current value.

func (*SeriesIterator) Next

func (si *SeriesIterator) Next() bool

Next steps to the next value. A newly created iterator has no current value.

type SeriesOption

type SeriesOption func(s *Series)

SeriesOption is the base type for all series options

func AggregatedBy

func AggregatedBy(f Aggregator, interval time.Duration) SeriesOption

AggregatedBy sets the series aggregator

func CappedByAge

func CappedByAge(cap time.Duration, reference func() time.Time) SeriesOption

CappedByAge caps a series by removing values older than cap in relation to the current value of the reference funcion.

func CappedBySize

func CappedBySize(cap int) SeriesOption

CappedBySize caps a series to at most cap values.

func Titled

func Titled(title string) SeriesOption

Titled sets the series title

type Ticker

type Ticker interface {
	// contains filtered or unexported methods
}

Ticker provides tick marks and labels for axes

type Using

type Using func(*plotOptions)

Using is the base type for plotting options

func UsingAxes

func UsingAxes(x, y Axis) Using

UsingAxes selects the x and y axis for plotting

func UsingMarker

func UsingMarker(marker string) Using

UsingMarker selects a marker for highlighting plotted values. See svg.Marker for valid marker types.

func UsingStrokeWidth added in v0.1.0

func UsingStrokeWidth(width float32) Using

type Value

type Value struct {
	X float64
	Y float64
}

Value is the type of each series element. The X part represents a position on the X axis, which could be time or a regular value.

func Avg

func Avg(values []Value, at time.Time) Value

Avg calculates the Y average of a list of values, reported as observed at the given time.

func Delta

func Delta(values []Value, at time.Time) Value

Delta calculates the Y difference between the first and last value in the list, reported as observed at the given time.

func MakeValue

func MakeValue(x float64, y float64) Value

MakeValue creates a Value from x and y values.

func Sum

func Sum(values []Value, at time.Time) Value

Sum calculates the Y sum of a list of values, reported as observed at the given time.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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