termui_ext

package module
v0.0.0-...-d11f64b Latest Latest
Warning

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

Go to latest
Published: May 23, 2020 License: MIT Imports: 12 Imported by: 0

README

termui-ext

termui-ext is an extension of the termui library. It provides a set of data sources and renderers that allow the widgets to pull the data periodically from a data source. This effectively enables a "data pull" model for the widget. Rather than the code pushing data into the widget, widgets can be configured to automatically retrieve data from a data provider.

Installation

To install this library, run the following:

go get -u github.com/samaddison/termui-ext

Quick example:

package main

import (
	ui "github.com/gizak/termui/v3"
	"log"
	termui_ext "termui-ext"
	"time"
)

func main() {
	if err := ui.Init(); err != nil {
		log.Fatalf("failed to initialize termui: %v", err)
	}
	defer ui.Close()

	dataProvider := termui_ext.File{Path: "./docs/stacked_barchart_input.json"}

	bc := termui_ext.NewStackedBarChart(dataProvider)
	bc.Title = "Stacked Bar Chart"
	bc.SetRect(5, 5, 100, 25)
	bc.BarWidth = 5
	bc.BarColors = []ui.Color{ui.ColorRed, ui.ColorGreen}
	bc.LabelStyles = []ui.Style{ui.NewStyle(ui.ColorBlue)}
	bc.NumStyles = []ui.Style{ui.NewStyle(ui.ColorYellow)}

	ui.Render(bc)

	bc.GoRefresh(5 * time.Second)

	uiEvents := ui.PollEvents()
	for {
		e := <-uiEvents
		switch e.ID {
		case "q", "<C-c>":
			return
		case "<C-d>":
			bc.Shutdown()
		}
	}
}

As you can see, you can use the same API provided by the termui widgets, as the termui_ext widgets are essentially a wrapper around those. The only big differences are the call to GoRefresh, which configures the refresh rate, and the introduction of a data provider which needs to be passed in the constructor.

The library provides 2 data providers: an HTTP/S data provider and a File data provider. With the HTTP data provider, you can configure a url endpoint which the widgets will call periodically. The endpoint will return a JSON string whose format depends on the widget type.

The File data provider reads the JSON from a file. It is probably more of a proof of concept than anything else, but it is certainly usable if you have an application that pushes data periodically into a file.

You can of course create your own data provider. See the source for both the http and file providers for an example. It is actually quite simple. You can for instance create a data provider that will retrieve data from a MySQL database, a time series database like InfluxDB or any other source you can think of.

Refreshing the Data

After you create and configure a widget, you have to call the Refresh method. You can call the Refresh method directly as a goroutine:

go bc.Refresh(5 * time.Second)

or you can call

bc.GoRefresh(5 * time.Second)

which will automatically create an internal goroutine to refresh the widget every 5 seconds.

Typically, widgets will run on its own goroutine. This allows you to set up the widgets and let them periodically refresh themselves.

However, you can also use the OneRefresh method which will refresh the widget just once. This allows you to take full control of the widgets.

bc.OneRefresh()

You can stop a widget at any time:

bc.Shutdown()

Data Sources

Data Sources know where the new data source is, connect to the source and retrieve the data. Typically, data would be retrieved from an API, so all you have to do is to configure the widget with the API endpoint and let the data source handle it.

Renderers

Renderers are the components that receive the JSON from the data source, parse it and refresh the widget data with it. As such, they are specific to each of the widgets, unlike data sources that are general and can be used by any widget.

Renderers are less likely to change, but you can still create your own renderer and assign it to a widget:

// Code

Hooks

It is unlikely however that existing APIs will return the JSON data in exactly the format required by the widget. For that purpose, Data Sources provide hooks, which you can use to transform the data into a format suitable for the widget.

Both data sources and renderers provide hooks. If you have multiple widgets of different types which might consume the same data source, it might make sense to use the data source hooks, as you will use the same data source for all the widgets, but you are unlikely to use the same renderer for multiple widget types.

Licence

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InterfaceSlice

func InterfaceSlice(slice interface{}) []interface{}

Types

type BarChart

type BarChart struct {
	*widgets.BarChart
	BaseWidget
}

func NewBarChart

func NewBarChart(provider DataProvider) *BarChart

func NewBarChartWithRenderer

func NewBarChartWithRenderer(provider DataProvider, renderer BarChartRenderer) *BarChart

type BarChartRenderer

type BarChartRenderer struct {
	BarChart BarChart
}

func (BarChartRenderer) PostRender

func (renderer BarChartRenderer) PostRender(data *WidgetData) error

func (BarChartRenderer) PreRender

func (renderer BarChartRenderer) PreRender(data *WidgetData) error

func (BarChartRenderer) Render

func (renderer BarChartRenderer) Render(data *WidgetData) error

type BaseWidget

type BaseWidget struct {
	Name string
	DataProvider
	DataRenderer
	Drawable ui.Drawable
	// contains filtered or unexported fields
}

func (*BaseWidget) GetDrawable

func (widget *BaseWidget) GetDrawable() ui.Drawable

func (*BaseWidget) GetName

func (widget *BaseWidget) GetName() *string

func (*BaseWidget) GoRefresh

func (widget *BaseWidget) GoRefresh(d time.Duration)

func (*BaseWidget) OneRefresh

func (widget *BaseWidget) OneRefresh()

func (*BaseWidget) Refresh

func (widget *BaseWidget) Refresh(d time.Duration)

func (*BaseWidget) Shutdown

func (widget *BaseWidget) Shutdown()

type DataProvider

type DataProvider interface {
	PreRetrieve() error
	Retrieve() (*WidgetData, error)
	PostRetrieve(*WidgetData, error) error
}

type DataRenderer

type DataRenderer interface {
	PreRender(*WidgetData) error
	Render(*WidgetData) error
	PostRender(*WidgetData) error
}

type File

type File struct {
	Path string
}

func (File) PostRetrieve

func (dp File) PostRetrieve(*WidgetData, error) error

func (File) PreRetrieve

func (dp File) PreRetrieve() error

func (File) Retrieve

func (dp File) Retrieve() (*WidgetData, error)

type Gauge

type Gauge struct {
	*widgets.Gauge
	BaseWidget
}

func NewGauge2

func NewGauge2(gaugeWidget *widgets.Gauge, provider DataProvider) *Gauge

func NewGaugeDefaultRenderer

func NewGaugeDefaultRenderer(provider DataProvider) *Gauge

func NewGaugeWithExisting

func NewGaugeWithExisting(gaugeWidget *widgets.Gauge, provider DataProvider, renderer GaugeRenderer) *Gauge

func NewGaugeWithRenderer

func NewGaugeWithRenderer(provider DataProvider, renderer GaugeRenderer) *Gauge

type GaugeRenderer

type GaugeRenderer struct {
	Gauge Gauge
}

func (GaugeRenderer) PostRender

func (renderer GaugeRenderer) PostRender(data *WidgetData) error

func (GaugeRenderer) PreRender

func (renderer GaugeRenderer) PreRender(data *WidgetData) error

func (GaugeRenderer) Render

func (renderer GaugeRenderer) Render(data *WidgetData) error

type Grid

type Grid struct {
	termui.Block
	Items []*GridItem
}

func NewGrid

func NewGrid() *Grid

func (*Grid) Draw

func (self *Grid) Draw(buf *termui.Buffer)

func (*Grid) Set

func (self *Grid) Set(entries ...interface{})

Set is used to add Columns and Rows to the grid. It recursively searches the GridItems, adding leaves to the grid and calculating the dimensions of the leaves.

func (*Grid) StartRefresh

func (self *Grid) StartRefresh(d time.Duration)

type GridItem

type GridItem struct {
	Type        gridItemType
	XRatio      float64
	YRatio      float64
	WidthRatio  float64
	HeightRatio float64
	Entry       interface{} // Entry.type == GridBufferer if IsLeaf else []GridItem
	IsLeaf      bool
	// contains filtered or unexported fields
}

GridItem represents either a Row or Column in a grid. Holds sizing information and either an []GridItems or a widget.

func NewCol

func NewCol(ratio float64, i ...interface{}) GridItem

NewCol takes a height percentage and either a widget or a Row or Column

func NewRow

func NewRow(ratio float64, i ...interface{}) GridItem

NewRow takes a width percentage and either a widget or a Row or Column

type HTTP

type HTTP struct {
	Url string
}

func (HTTP) PostRetrieve

func (dp HTTP) PostRetrieve(*WidgetData, error) error

func (HTTP) PreRetrieve

func (dp HTTP) PreRetrieve() error

func (HTTP) Retrieve

func (dp HTTP) Retrieve() (*WidgetData, error)

type Image

type Image struct {
	*widgets.Image
	BaseWidget
}

func NewImage

func NewImage(provider DataProvider) *Image

func NewImageWithRenderer

func NewImageWithRenderer(provider DataProvider, renderer ImageRenderer) *Image

type ImageRenderer

type ImageRenderer struct {
	Image Image
}

func (ImageRenderer) PostRender

func (renderer ImageRenderer) PostRender(data *WidgetData) error

func (ImageRenderer) PreRender

func (renderer ImageRenderer) PreRender(data *WidgetData) error

func (ImageRenderer) Render

func (renderer ImageRenderer) Render(data *WidgetData) error

type List

type List struct {
	*widgets.List
	BaseWidget
}

func NewList

func NewList(provider DataProvider) *List

func NewListWithRenderer

func NewListWithRenderer(provider DataProvider, renderer ListRenderer) *List

type ListRenderer

type ListRenderer struct {
	List List
}

func (ListRenderer) PostRender

func (renderer ListRenderer) PostRender(data *WidgetData) error

func (ListRenderer) PreRender

func (renderer ListRenderer) PreRender(data *WidgetData) error

func (ListRenderer) Render

func (renderer ListRenderer) Render(data *WidgetData) error

type Paragraph

type Paragraph struct {
	*widgets.Paragraph
	BaseWidget
}

func NewParagraph

func NewParagraph(provider DataProvider) *Paragraph

func NewParagraphWithRenderer

func NewParagraphWithRenderer(provider DataProvider, renderer ParagraphRenderer) *Paragraph

type ParagraphRenderer

type ParagraphRenderer struct {
	Paragraph Paragraph
}

func (ParagraphRenderer) PostRender

func (renderer ParagraphRenderer) PostRender(data *WidgetData) error

func (ParagraphRenderer) PreRender

func (renderer ParagraphRenderer) PreRender(data *WidgetData) error

func (ParagraphRenderer) Render

func (renderer ParagraphRenderer) Render(data *WidgetData) error

type PieChart

type PieChart struct {
	*widgets.PieChart
	BaseWidget
}

func NewPieChart

func NewPieChart(provider DataProvider) *PieChart

func NewPieChartWithRenderer

func NewPieChartWithRenderer(provider DataProvider, renderer PieChartRenderer) *PieChart

type PieChartRenderer

type PieChartRenderer struct {
	PieChart PieChart
}

func (PieChartRenderer) PostRender

func (renderer PieChartRenderer) PostRender(data *WidgetData) error

func (PieChartRenderer) PreRender

func (renderer PieChartRenderer) PreRender(data *WidgetData) error

func (PieChartRenderer) Render

func (renderer PieChartRenderer) Render(data *WidgetData) error

type Plot

type Plot struct {
	*widgets.Plot
	BaseWidget
}

func NewPlot

func NewPlot(provider DataProvider) *Plot

func NewPlotWithRenderer

func NewPlotWithRenderer(provider DataProvider, renderer PlotRenderer) *Plot

type PlotRenderer

type PlotRenderer struct {
	Plot Plot
}

func (PlotRenderer) PostRender

func (renderer PlotRenderer) PostRender(data *WidgetData) error

func (PlotRenderer) PreRender

func (renderer PlotRenderer) PreRender(data *WidgetData) error

func (PlotRenderer) Render

func (renderer PlotRenderer) Render(data *WidgetData) error

type Refreshable

type Refreshable interface {
	Refresh(d time.Duration)
	GoRefresh(d time.Duration)
	GetDrawable() ui.Drawable
	GetName() *string
}

type SparklineGroup

type SparklineGroup struct {
	*widgets.SparklineGroup
	BaseWidget
}

func NewSparklineGroup

func NewSparklineGroup(provider DataProvider) *SparklineGroup

func NewSparklineGroupWithRenderer

func NewSparklineGroupWithRenderer(provider DataProvider, renderer SparklineGroupRenderer) *SparklineGroup

type SparklineGroupRenderer

type SparklineGroupRenderer struct {
	SparklineGroup SparklineGroup
}

func (SparklineGroupRenderer) PostRender

func (renderer SparklineGroupRenderer) PostRender(data *WidgetData) error

func (SparklineGroupRenderer) PreRender

func (renderer SparklineGroupRenderer) PreRender(data *WidgetData) error

func (SparklineGroupRenderer) Render

func (renderer SparklineGroupRenderer) Render(data *WidgetData) error

type StackedBarChart

type StackedBarChart struct {
	*widgets.StackedBarChart
	BaseWidget
}

func NewStackedBarChart

func NewStackedBarChart(provider DataProvider) *StackedBarChart

func NewStackedBarChartWithRenderer

func NewStackedBarChartWithRenderer(provider DataProvider, renderer StackedBarChartRenderer) *StackedBarChart

type StackedBarChartRenderer

type StackedBarChartRenderer struct {
	StackedBarChart StackedBarChart
}

func (StackedBarChartRenderer) PostRender

func (renderer StackedBarChartRenderer) PostRender(data *WidgetData) error

func (StackedBarChartRenderer) PreRender

func (renderer StackedBarChartRenderer) PreRender(data *WidgetData) error

func (StackedBarChartRenderer) Render

func (renderer StackedBarChartRenderer) Render(data *WidgetData) error

type Table

type Table struct {
	*widgets.Table
	BaseWidget
}

func NewTable

func NewTable(provider DataProvider) *Table

func NewTableWithRenderer

func NewTableWithRenderer(provider DataProvider, renderer TableRenderer) *Table

type TableRenderer

type TableRenderer struct {
	Table Table
}

func (TableRenderer) PostRender

func (renderer TableRenderer) PostRender(data *WidgetData) error

func (TableRenderer) PreRender

func (renderer TableRenderer) PreRender(data *WidgetData) error

func (TableRenderer) Render

func (renderer TableRenderer) Render(data *WidgetData) error

type WidgetData

type WidgetData struct {
	Time time.Time
	Json []byte
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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