data

package
v0.188.3 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2024 License: Apache-2.0 Imports: 25 Imported by: 16

README

data

Testing

This package uses golden files to verify Arrow serialization.

Add the update flag to go test to update the golden files:

go test -update

Make sure you check in any updated golden files.

Documentation

Overview

Package data provides data structures that Grafarg recognizes.

The Frame object represents a Grafarg Dataframe which can represent data such as tables and time series.

Frames can be encoded using Apache Arrow (https://arrow.apache.org/) for transmission.

The corresponding Grafarg frontend package the @grafarg/data package (https://github.com/famarker/grafarg/tree/master/packages/grafarg-data).

Index

Examples

Constants

View Source
const (
	// VisTypeGraph indicates the response should be visualized using a graph.
	VisTypeGraph VisType = "graph"

	// VisTypeTable indicates the response should be visualized using a table.
	VisTypeTable = "table"

	// VisTypeLogs indicates the response should be visualized using a logs visualization.
	VisTypeLogs = "logs"

	// VisTypeTrace indicates the response should be visualized using a trace view visualization.
	VisTypeTrace = "trace"

	// VisTypeNodeGraph indicates the response should be visualized using a node graph visualization.
	VisTypeNodeGraph = "nodeGraph"

	// VisTypeFlameGraph indicates the response should be visualized using a flame graph visualization.
	VisTypeFlameGraph = "flamegraph"
)

Should be kept in sync with grafarg/packages/grafarg-data/src/types/data.ts#PreferredVisualisationType

View Source
const ExplicitNullValue = "null"

ExplicitNullValue is the string representation for null

View Source
const TimeSeriesTimeFieldName = "Time"

TimeSeriesTimeFieldName is the standard name for time series time fields

View Source
const TimeSeriesValueFieldName = "Value"

TimeSeriesValueFieldName is the standard name for time series value fields

Variables

This section is empty.

Functions

func ArrowBufferToJSON

func ArrowBufferToJSON(b []byte, include FrameInclude) ([]byte, error)

ArrowBufferToJSON writes a frame to JSON NOTE: the format should be considered experimental until grafarg 8 is released.

func ArrowToJSON

func ArrowToJSON(record arrow.Record, include FrameInclude) ([]byte, error)

ArrowToJSON writes a frame to JSON NOTE: the format should be considered experimental until grafarg 8 is released.

func FrameTestCompareOptions

func FrameTestCompareOptions() []cmp.Option

FrameTestCompareOptions returns go-cmp testing options to allow testing of Frame equivalence. Since the data within a Frame's Fields is not exported, this function allows the unexported values to be tested. The intent is to only use this for testing. nolint:gocyclo

func FrameToJSON

func FrameToJSON(frame *Frame, include FrameInclude) ([]byte, error)

FrameToJSON creates an object that holds schema and data independently. This is useful for explicit control between the data and schema. For standard json serialization use `json.Marshal(frame)`

NOTE: the format should be considered experimental until grafarg 8 is released.

func GetMissing

func GetMissing(fillMissing *FillMissing, field *Field, previousRowIdx int) (interface{}, error)

GetMissing returns the value to be filled for a missing row field.

func SortWideFrameFields

func SortWideFrameFields(frame *Frame, keys ...string) error

SortWideFrameFields sorts the order of a wide time series Frame's Fields. If the frame is not a WideFrame, then an error is returned.

The Time that is the time index (the first time field of the original frame) is sorted first. Then Fields are sorted by their name followed by the order of the label keys provided. If no keys are provided, they are sorted by the string representation of their labels.

func ValidFieldType

func ValidFieldType(t interface{}) bool

ValidFieldType returns if a primitive slice is a valid supported Field type.

Types

type ConfFloat64

type ConfFloat64 float64

ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf to null.

func (*ConfFloat64) MarshalJSON

func (sf *ConfFloat64) MarshalJSON() ([]byte, error)

MarshalJSON fullfills the json.Marshaler interface.

func (*ConfFloat64) UnmarshalJSON

func (sf *ConfFloat64) UnmarshalJSON(data []byte) error

UnmarshalJSON fullfills the json.Unmarshaler interface.

type Converter

type Converter func(v interface{}) (interface{}, error)

Converter is a function type for converting values in a Frame. It is the consumers responsibility to the check the underlying interface types of the input and return types to avoid panics.

type DataLink struct {
	Title       string            `json:"title,omitempty"`
	TargetBlank bool              `json:"targetBlank,omitempty"`
	URL         string            `json:"url,omitempty"`
	Internal    *InternalDataLink `json:"internal,omitempty"`
}

DataLink define what

type DataTopic

type DataTopic string

DataTopic is used to identify which topic the frame should be assigned to.

const (
	// DataTopicAnnotations is used to specify that the frame should be used as annotation of the actual data frame response.
	// Example: When DataTopic is set to DataTopicAnnotations, the frame will be used as exemplar data in timeseries panel
	DataTopicAnnotations DataTopic = "annotations"
)

type EnumFieldConfig

type EnumFieldConfig struct {
	// Value is the string display value for a given index
	Text []string `json:"text"`

	// Color is the color value for a given index (empty is undefined)
	Color []string `json:"color,omitempty"`

	// Icon supports setting an icon for a given index value
	Icon []string `json:"icon,omitempty"`

	// Description of the enum state
	Description []string `json:"description,omitempty"`
}

Enum field config Vector values are used as lookup keys into the enum fields

type EnumItemIndex

type EnumItemIndex uint16

type ExplorePanelsState

type ExplorePanelsState any

This is an object constructed with the keys as the values of the enum VisType and the value being a bag of properties

type Field

type Field struct {
	// Name is default identifier of the field. The name does not have to be unique, but the combination
	// of name and Labels should be unique for proper behavior in all situations.
	Name string `json:"name,omitempty"`

	// Labels is an optional set of key=value pairs that in addition to the name, should uniquely
	// identify a Field within a Frame.
	Labels Labels `json:"labels,omitempty"`

	// Config is optional display configuration information for Grafarg
	Config *FieldConfig `json:"config,omitempty"`
	// contains filtered or unexported fields
}

Field represents a typed column of data within a Frame.

A Field is essentially a slice of various types with extra properties and methods. See NewField() for supported types.

The slice data in the Field is a not exported, so methods on the Field are used to to manipulate its data.

func NewField

func NewField(name string, labels Labels, values interface{}) *Field

NewField returns a instance of *Field. Supported types for values are:

Integers:

[]int8, []*int8, []int16, []*int16, []int32, []*int32, []int64, []*int64

Unsigned Integers:

[]uint8, []*uint8, []uint16, []*uint16, []uint32, []*uint32, []uint64, []*uint64

Floats:

[]float32, []*float32, []float64, []*float64

String, Bool, and Time:

[]string, []*string, []bool, []*bool, []time.Time, and []*time.Time.

JSON:

[]json.RawMessage, []*json.RawMessage

Enum:

[]data.EnumItemIndex, []*data.EnumItemIndex

If an unsupported values type is passed, NewField will panic. nolint:gocyclo

func NewFieldFromFieldType

func NewFieldFromFieldType(p FieldType, n int) *Field

NewFieldFromFieldType creates a new Field of the given FieldType of length n. nolint:gocyclo

func (*Field) Append

func (f *Field) Append(e interface{})

Append appends element e to the Field. it will panic if the underlying type of e does not match the element type of the Field.

func (*Field) At

func (f *Field) At(idx int) interface{}

At returns the the element at index idx of the Field. It will panic if idx is out of range.

func (*Field) ConcreteAt

func (f *Field) ConcreteAt(idx int) (val interface{}, ok bool)

ConcreteAt returns the concrete value at the specified index idx. A non-pointer type is returned regardless if the underlying vector is a pointer type or not. If the value is a pointer type, and is nil, then the zero value is returned and ok will be false.

func (*Field) CopyAt

func (f *Field) CopyAt(idx int) interface{}

CopyAt returns a copy of the value of the specified index idx. It will panic if idx is out of range.

func (*Field) Delete

func (f *Field) Delete(idx int)

Delete delete element at index idx of the Field.

func (*Field) Extend

func (f *Field) Extend(i int)

Extend extends the Field length by i. Consider using Frame.Extend() when possible since all Fields within a Frame need to be of the same length before marshalling and transmission.

func (*Field) FloatAt

func (f *Field) FloatAt(idx int) (float64, error)

FloatAt returns a float64 at the specified index idx for all supported Field types. It will panic if idx is out of range.

If the Field type is numeric and the value at idx is nil, NaN is returned. Precision may be lost on large numbers.

If the Field type is a bool then 0 is return if false or nil, and 1 if true.

If the Field type is time.Time, then the millisecond epoch representation of the time is returned, or NaN is the value is nil.

If the Field type is a string, then strconv.ParseFloat is called on it and will return an error if ParseFloat errors. If the value is nil, NaN is returned. nolint:gocyclo

func (*Field) Insert

func (f *Field) Insert(idx int, val interface{})

Insert extends the Field length by 1, shifts any existing field values at indices equal or greater to idx by one place and inserts val at index idx of the Field. If idx is equal to the Field length, then val will be appended. It idx exceeds the Field length, this method will panic.

func (*Field) Len

func (f *Field) Len() int

Len returns the number of elements in the Field. It will return 0 if the field is nil.

func (*Field) Nullable

func (f *Field) Nullable() bool

Nullable returns if the the Field's elements are nullable.

func (*Field) NullableFloatAt

func (f *Field) NullableFloatAt(idx int) (*float64, error)

NullableFloatAt it is similar to FloatAt but returns a *float64 at the specified index idx for all supported Field types. It will panic if idx is out of range. nolint:gocyclo

func (*Field) PointerAt

func (f *Field) PointerAt(idx int) interface{}

PointerAt returns a pointer to the value at idx of the Field. It will panic if idx is out of range.

func (*Field) Set

func (f *Field) Set(idx int, val interface{})

Set sets the Field's value at index idx to val. It will panic if idx is out of range or if the underlying type of val does not match the element type of the Field.

func (*Field) SetConcrete

func (f *Field) SetConcrete(idx int, val interface{})

SetConcrete sets the Field's value at index idx to val. val must be a non-pointer type or a panic will occur. If the underlying FieldType is nullable it will set val as a pointer to val. If the FieldType is not nullable, then this method behaves the same as the Set method. It will panic if the underlying type of val does not match the element concrete type of the Field.

func (*Field) SetConfig

func (f *Field) SetConfig(conf *FieldConfig) *Field

SetConfig modifies the Field's Config property to be set to conf and returns the Field.

func (*Field) Type

func (f *Field) Type() FieldType

Type returns the FieldType of the Field, which indicates what type of slice it is.

type FieldConfig

type FieldConfig struct {

	// DisplayName overrides Grafarg default naming, should not be used from a data source
	DisplayName string `json:"displayName,omitempty"`

	// DisplayNameFromDS overrides Grafarg default naming strategy.
	DisplayNameFromDS string `json:"displayNameFromDS,omitempty"`

	// Path is an explicit path to the field in the datasource. When the frame meta includes a path,
	// this will default to `${frame.meta.path}/${field.name}
	//
	// When defined, this value can be used as an identifier within the datasource scope, and
	// may be used as an identifier to update values in a subsequent request
	Path string `json:"path,omitempty"`

	// Description is human readable field metadata
	Description string `json:"description,omitempty"`

	// Filterable indicates if the Field's data can be filtered by additional calls.
	Filterable *bool `json:"filterable,omitempty"`

	// Writeable indicates that the datasource knows how to update this value
	Writeable *bool `json:"writeable,omitempty"`

	// Numeric Options
	Unit     string       `json:"unit,omitempty"`     // is the string to display to represent the Field's unit, such as "Requests/sec"
	Decimals *uint16      `json:"decimals,omitempty"` // is the number of decimal places to display
	Min      *ConfFloat64 `json:"min,omitempty"`      // is the maximum value of fields in the column. When present the frontend can skip the calculation.
	Max      *ConfFloat64 `json:"max,omitempty"`      // see Min

	// Interval indicates the expected regular step between values in the series.
	// When an interval exists, consumers can identify "missing" values when the expected value is not present.
	// The grafarg timeseries visualization will render disconnected values when missing values are found it the time field.
	// The interval uses the same units as the values.  For time.Time, this is defined in milliseconds.
	Interval float64 `json:"interval,omitempty"`

	// Convert input values into a display string
	Mappings ValueMappings `json:"mappings,omitempty"`

	// Map numeric values to states
	Thresholds *ThresholdsConfig `json:"thresholds,omitempty"`

	// Map values to a display color
	// NOTE: this interface is under development in the frontend... so simple map for now
	Color map[string]interface{} `json:"color,omitempty"`

	// The behavior when clicking on a result
	Links []DataLink `json:"links,omitempty"`

	// Alternative to empty string
	NoValue string `json:"noValue,omitempty"`

	// Type specific configs
	TypeConfig *FieldTypeConfig `json:"type,omitempty"`

	// Panel Specific Values
	Custom map[string]interface{} `json:"custom,omitempty"`
}

FieldConfig represents the display properties for a Field.

func (*FieldConfig) SetDecimals

func (fc *FieldConfig) SetDecimals(v uint16) *FieldConfig

SetDecimals modifies the FieldConfig's Decimals property to be set to v and returns the FieldConfig. It is a convenience function since the Decimals property is a pointer.

func (*FieldConfig) SetFilterable

func (fc *FieldConfig) SetFilterable(b bool) *FieldConfig

SetFilterable modifies the FieldConfig's Filterable property to be set to b and returns the FieldConfig. It is a convenience function since the Filterable property is a pointer.

func (*FieldConfig) SetMax

func (fc *FieldConfig) SetMax(v float64) *FieldConfig

SetMax modifies the FieldConfig's Max property to be set to v and returns the FieldConfig. It is a convenience function since the Min property is a pointer.

func (*FieldConfig) SetMin

func (fc *FieldConfig) SetMin(v float64) *FieldConfig

SetMin modifies the FieldConfig's Min property to be set to v and returns the FieldConfig. It is a convenience function since the Min property is a pointer.

type FieldConverter

type FieldConverter struct {
	// OutputFieldType is the type of Field that will be created.
	OutputFieldType FieldType

	// Converter is a conversion function that is called when setting Field values with a FrameInputConverter.
	// Care must be taken that the type returned by the conversion function matches the member type of the FieldType,
	// and that the input type matches the expected input type for the Converter function, or panics can occur.
	// If the Converter is nil, no conversion is performed when calling methods to set values.
	Converter Converter
}

A FieldConverter is a type to support building Frame fields of a different type than one's input data.

type FieldType

type FieldType int

FieldType indicates the Go type underlying the Field.

const (
	// FieldTypeUnknown indicates that we do not know the field type
	FieldTypeUnknown FieldType = iota

	// FieldTypeInt8 indicates the underlying primitive is a []int8.
	FieldTypeInt8
	// FieldTypeNullableInt8 indicates the underlying primitive is a []*int8.
	FieldTypeNullableInt8

	// FieldTypeInt16 indicates the underlying primitive is a []int16.
	FieldTypeInt16
	// FieldTypeNullableInt16 indicates the underlying primitive is a []*int16.
	FieldTypeNullableInt16

	// FieldTypeInt32 indicates the underlying primitive is a []int32.
	FieldTypeInt32
	// FieldTypeNullableInt32 indicates the underlying primitive is a []*int32.
	FieldTypeNullableInt32

	// FieldTypeInt64 indicates the underlying primitive is a []int64.
	FieldTypeInt64
	// FieldTypeNullableInt64 indicates the underlying primitive is a []*int64.
	FieldTypeNullableInt64

	// FieldTypeUint8 indicates the underlying primitive is a []uint8.
	FieldTypeUint8
	// FieldTypeNullableUint8 indicates the underlying primitive is a []*uint8.
	FieldTypeNullableUint8

	// FieldTypeUint16 indicates the underlying primitive is a []uint16.
	FieldTypeUint16
	// FieldTypeNullableUint16 indicates the underlying primitive is a []*uint16.
	FieldTypeNullableUint16

	// FieldTypeUint32 indicates the underlying primitive is a []uint32.
	FieldTypeUint32
	// FieldTypeNullableUint32 indicates the underlying primitive is a []*uint32.
	FieldTypeNullableUint32

	// FieldTypeUint64 indicates the underlying primitive is a []uint64.
	FieldTypeUint64
	// FieldTypeNullableUint64 indicates the underlying primitive is a []*uint64.
	FieldTypeNullableUint64

	// FieldTypeFloat32 indicates the underlying primitive is a []float32.
	FieldTypeFloat32
	// FieldTypeNullableFloat32 indicates the underlying primitive is a []*float32.
	FieldTypeNullableFloat32

	// FieldTypeFloat64 indicates the underlying primitive is a []float64.
	FieldTypeFloat64
	// FieldTypeNullableFloat64 indicates the underlying primitive is a []*float64.
	FieldTypeNullableFloat64

	// FieldTypeString indicates the underlying primitive is a []string.
	FieldTypeString
	// FieldTypeNullableString indicates the underlying primitive is a []*string.
	FieldTypeNullableString

	// FieldTypeBool indicates the underlying primitive is a []bool.
	FieldTypeBool
	// FieldTypeNullableBool indicates the underlying primitive is a []*bool.
	FieldTypeNullableBool

	// FieldTypeTime indicates the underlying primitive is a []time.Time.
	FieldTypeTime
	// FieldTypeNullableTime indicates the underlying primitive is a []*time.Time.
	FieldTypeNullableTime

	// FieldTypeJSON indicates the underlying primitive is a []json.RawMessage.
	FieldTypeJSON
	// FieldTypeNullableJSON indicates the underlying primitive is a []*json.RawMessage.
	FieldTypeNullableJSON

	// FieldTypeEnum indicates the underlying primitive is a []data.EnumItemIndex, with field mapping metadata
	FieldTypeEnum
	// FieldTypeNullableEnum indicates the underlying primitive is a []*data.EnumItemIndex, with field mapping metadata
	FieldTypeNullableEnum
)

func FieldTypeFor

func FieldTypeFor(item interface{}) FieldType

FieldTypeFor will return the FieldType that holds items of item's type. If the FieldType is not recognized, FieldTypeUnknown is returned. For example, for an item of type *int8, FieldTypeNullableInt8 will be returned. nolint:gocyclo

func FieldTypeFromItemTypeString

func FieldTypeFromItemTypeString(s string) (FieldType, bool)

FieldTypeFromItemTypeString returns a field type from the current string

func NumericFieldTypes

func NumericFieldTypes() []FieldType

NumericFieldTypes returns a slice of FieldTypes that are numeric.

func (FieldType) ItemTypeString

func (p FieldType) ItemTypeString() string

ItemTypeString returns the string representation of the type of element within in the vector nolint:gocyclo

func (FieldType) JSON

func (p FieldType) JSON() bool

JSON returns if Field type is a json type (FieldTypeJSON or FieldTypeNullableJSON).

func (FieldType) MarshalJSON

func (p FieldType) MarshalJSON() ([]byte, error)

MarshalJSON marshals the enum as a quoted json string

func (FieldType) NonNullableType

func (p FieldType) NonNullableType() FieldType

NonNullableType converts the FieldType to the corresponding not-nullable type. Calling this on FieldTypeUnknown will panic.

func (FieldType) Nullable

func (p FieldType) Nullable() bool

Nullable returns true if the field type is nullable

func (FieldType) NullableType

func (p FieldType) NullableType() FieldType

NullableType converts the FieldType to the corresponding nullable type. Calling this on FieldTypeUnknown will panic.

func (FieldType) Numeric

func (p FieldType) Numeric() bool

Numeric returns true if the field type is numeric

func (FieldType) String

func (p FieldType) String() string

func (FieldType) Time

func (p FieldType) Time() bool

Time returns if Field type is a time type (FieldTypeTime or FieldTypeNullableTime).

func (*FieldType) UnmarshalJSON

func (p *FieldType) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals a quoted json string to the enum value

type FieldTypeConfig

type FieldTypeConfig struct {
	Enum *EnumFieldConfig `json:"enum,omitempty"`
}

FieldTypeConfig has type specific configs, only one should be active at a time

type Fields

type Fields []*Field

Fields is a slice of Field pointers.

type FillMissing

type FillMissing struct {
	Mode  FillMode
	Value float64
}

FillMissing is a struct containing the fill mode and the fill value if fill mode is FillModeValue

type FillMode

type FillMode int

FillMode is an integer type denoting how missing values should be filled.

const (
	// FillModePrevious fills with the last seen value unless that does not exist, in which case it fills with null.
	FillModePrevious FillMode = iota
	// FillModeNull fills with null
	FillModeNull
	// FillModeValue fills with a specific value
	FillModeValue
)

type Fingerprint

type Fingerprint uint64

func (Fingerprint) String

func (f Fingerprint) String() string

type Frame

type Frame struct {
	// Name is used in some Grafarg visualizations.
	Name string

	// Fields are the columns of a frame.
	// All Fields must be of the same the length when marshalling the Frame for transmission.
	// There should be no `nil` entries in the Fields slice (making them pointers was a mistake).
	Fields []*Field

	// RefID is a property that can be set to match a Frame to its originating query.
	RefID string

	// Meta is metadata about the Frame, and includes space for custom metadata.
	Meta *FrameMeta
}

Frame is a columnar data structure where each column is a Field.

Each Field is well typed by its FieldType and supports optional Labels.

A Frame is a general data container for Grafarg. A Frame can be table data or time series data depending on its content and field types.

Example (TimeSeriesLong)
package main

import (
	"fmt"
	"time"

	"github.com/famarker/grafarg-plugin-sdk-go/data"
)

func main() {
	// a common SQL or CSV like pattern is to have repeated times, multiple numbered value
	// columns, and string columns to identify a factors. This is a "Long" time series.

	// Presently the backend supports converting Long formatted series to "Wide" format
	// which the frontend understands. Goal is frontend support eventually
	// (https://github.com/famarker/grafarg/issues/22219).

	// See https://grafarg.github.io/dataplane/contract/timeseries for more information.

	type aTable struct {
		Headers []string
		Rows    [][]interface{}
	}

	iSlice := func(is ...interface{}) []interface{} {
		s := make([]interface{}, len(is))
		copy(s, is)
		return s
	}

	myLongTable := aTable{
		Headers: []string{"time", "aMetric", "bMetric", "SomeFactor"},
	}
	myLongTable.Rows = append(myLongTable.Rows,
		iSlice(time.Date(2020, 1, 2, 3, 4, 0, 0, time.UTC), 2.0, 10.0, "foo"),
		iSlice(time.Date(2020, 1, 2, 3, 4, 0, 0, time.UTC), 5.0, 15.0, "bar"),

		iSlice(time.Date(2020, 1, 2, 3, 5, 0, 0, time.UTC), 3.0, 11.0, "foo"),
		iSlice(time.Date(2020, 1, 2, 3, 5, 0, 0, time.UTC), 6.0, 16.0, "bar"),
	)

	frame := data.NewFrameOfFieldTypes("Long", 0,
		data.FieldTypeTime,
		data.FieldTypeFloat64, data.FieldTypeFloat64,
		data.FieldTypeString,
	).SetMeta(&data.FrameMeta{
		Type:        data.FrameTypeTimeSeriesLong,
		TypeVersion: data.FrameTypeVersion{0, 1},
	})
	_ = frame.SetFieldNames(myLongTable.Headers...)
	for _, row := range myLongTable.Rows {
		frame.AppendRow(row...)
	}
	st, _ := frame.StringTable(-1, -1)
	fmt.Println(st)
}
Output:

Name: Long
Dimensions: 4 Fields by 4 Rows
+-------------------------------+-----------------+-----------------+------------------+
| Name: time                    | Name: aMetric   | Name: bMetric   | Name: SomeFactor |
| Labels:                       | Labels:         | Labels:         | Labels:          |
| Type: []time.Time             | Type: []float64 | Type: []float64 | Type: []string   |
+-------------------------------+-----------------+-----------------+------------------+
| 2020-01-02 03:04:00 +0000 UTC | 2               | 10              | foo              |
| 2020-01-02 03:04:00 +0000 UTC | 5               | 15              | bar              |
| 2020-01-02 03:05:00 +0000 UTC | 3               | 11              | foo              |
| 2020-01-02 03:05:00 +0000 UTC | 6               | 16              | bar              |
+-------------------------------+-----------------+-----------------+------------------+
Example (TimeSeriesMulti)
package main

import (
	"fmt"
	"time"

	"github.com/famarker/grafarg-plugin-sdk-go/data"
)

type mockPoint struct {
	Time  time.Time
	Value float64
}

type mockSeries struct {
	Name   string
	Labels map[string]string
	Points []mockPoint
}

type mockResponse struct {
	Series []mockSeries
}

func main() {
	// A common tsdb response pattern is to return a collection
	// of time series where each time series is uniquely identified
	// by a Name and a set of key value pairs (Labels (a.k.a Tags)).

	// In the case where the responses does not share identical time values and length (a single time index),
	// then the proper representation is Frames ([]*Frame). Where each Frame has a Time type field and one or more
	// Number fields.

	// Each Frame should have its value sorted by time in ascending order.

	// See https://grafarg.github.io/dataplane/contract/timeseries for more information.

	res := mockResponse{
		[]mockSeries{
			{
				Name:   "cpu",
				Labels: map[string]string{"host": "a"},
				Points: []mockPoint{
					{
						time.Date(2020, 1, 2, 3, 4, 0, 0, time.UTC), 3,
					},
					{
						time.Date(2020, 1, 2, 3, 5, 0, 0, time.UTC), 6,
					},
				},
			},
			{
				Name:   "cpu",
				Labels: map[string]string{"host": "b"},
				Points: []mockPoint{
					{
						time.Date(2020, 1, 2, 3, 4, 1, 0, time.UTC), 4,
					},
					{
						time.Date(2020, 1, 2, 3, 5, 1, 0, time.UTC), 7,
					},
				},
			},
		},
	}

	frames := make([]*data.Frame, len(res.Series))
	for i, series := range res.Series {
		frames[i] = data.NewFrame("multiExample",
			data.NewField("time", nil, make([]time.Time, len(series.Points))),
			data.NewField(series.Name, series.Labels, make([]float64, len(series.Points))),
		).SetMeta(&data.FrameMeta{
			Type:        data.FrameTypeTimeSeriesMulti,
			TypeVersion: data.FrameTypeVersion{0, 1},
		})

		for pIdx, point := range series.Points {
			frames[i].Set(0, pIdx, point.Time)
			frames[i].Set(1, pIdx, point.Value)
		}
	}

	for _, frame := range frames {
		st, _ := frame.StringTable(-1, -1)
		fmt.Println(st)
	}
}
Output:

Name: multiExample
Dimensions: 2 Fields by 2 Rows
+-------------------------------+-----------------+
| Name: time                    | Name: cpu       |
| Labels:                       | Labels: host=a  |
| Type: []time.Time             | Type: []float64 |
+-------------------------------+-----------------+
| 2020-01-02 03:04:00 +0000 UTC | 3               |
| 2020-01-02 03:05:00 +0000 UTC | 6               |
+-------------------------------+-----------------+

Name: multiExample
Dimensions: 2 Fields by 2 Rows
+-------------------------------+-----------------+
| Name: time                    | Name: cpu       |
| Labels:                       | Labels: host=b  |
| Type: []time.Time             | Type: []float64 |
+-------------------------------+-----------------+
| 2020-01-02 03:04:01 +0000 UTC | 4               |
| 2020-01-02 03:05:01 +0000 UTC | 7               |
+-------------------------------+-----------------+
Example (TimeSeriesWide)
package main

import (
	"fmt"
	"time"

	"github.com/famarker/grafarg-plugin-sdk-go/data"
)

type mockPoint struct {
	Time  time.Time
	Value float64
}

type mockSeries struct {
	Name   string
	Labels map[string]string
	Points []mockPoint
}

type mockResponse struct {
	Series []mockSeries
}

func main() {
	// In the case where you do know all the response will share the same time index, then
	// a "wide" dataframe can be created that holds all the responses. So your response is
	// all in a Single Frame.

	// See https://grafarg.github.io/dataplane/contract/timeseries for more information.

	singleTimeIndexRes := mockResponse{
		[]mockSeries{
			{
				Name:   "cpu",
				Labels: map[string]string{"host": "a"},
				Points: []mockPoint{
					{
						time.Date(2020, 1, 2, 3, 4, 0, 0, time.UTC), 3,
					},
					{
						time.Date(2020, 1, 2, 3, 5, 0, 0, time.UTC), 6,
					},
				},
			},
			{
				Name:   "cpu",
				Labels: map[string]string{"host": "b"},
				Points: []mockPoint{
					{
						time.Date(2020, 1, 2, 3, 4, 0, 0, time.UTC), 4,
					},
					{
						time.Date(2020, 1, 2, 3, 5, 0, 0, time.UTC), 7,
					},
				},
			},
		},
	}

	frame := &data.Frame{Name: "wideExample"}
	frame = frame.SetMeta(&data.FrameMeta{
		Type:        data.FrameTypeTimeSeriesWide,
		TypeVersion: data.FrameTypeVersion{0, 1},
	})

	for i, series := range singleTimeIndexRes.Series {
		if i == 0 {
			frame.Fields = append(frame.Fields,
				data.NewField("time", nil, make([]time.Time, len(series.Points))),
			)
		}
		frame.Fields = append(frame.Fields,
			data.NewField(series.Name, series.Labels, make([]float64, len(series.Points))),
		)
		for pIdx, point := range series.Points {
			if i == 0 {
				frame.Set(i, pIdx, point.Time)
			}
			frame.Set(i+1, pIdx, point.Value)
		}
	}

	st, _ := frame.StringTable(-1, -1)
	fmt.Println(st)
}
Output:

Name: wideExample
Dimensions: 3 Fields by 2 Rows
+-------------------------------+-----------------+-----------------+
| Name: time                    | Name: cpu       | Name: cpu       |
| Labels:                       | Labels: host=a  | Labels: host=b  |
| Type: []time.Time             | Type: []float64 | Type: []float64 |
+-------------------------------+-----------------+-----------------+
| 2020-01-02 03:04:00 +0000 UTC | 3               | 4               |
| 2020-01-02 03:05:00 +0000 UTC | 6               | 7               |
+-------------------------------+-----------------+-----------------+

func FromArrowRecord

func FromArrowRecord(record arrow.Record) (*Frame, error)

FromArrowRecord converts a an Arrow record batch into a Frame.

func LongToWide

func LongToWide(longFrame *Frame, fillMissing *FillMissing) (*Frame, error)

LongToWide converts a Long formatted time series Frame to a Wide format (see TimeSeriesType for descriptions). The first Field of type time.Time or *time.Time will be the time index for the series, and will be the first field of the outputted longFrame.

During conversion: String and bool Fields in the longFrame become Labels on the Fields of wideFrame. The name of each string or bool Field becomes a label key, and the values of that Field become label values. Each unique combination of value Fields and set of Label key/values become a Field of longFrame.

Additionally, if the time index is a *time.Time field, it will become time.Time Field. If a *string Field has nil values, they are equivalent to "" when converted into labels.

Finally, the Meta field of the result Wide Frame is pointing to the reference of the Meta field of the input Long Frame.

An error is returned if any of the following are true: The input frame is not a long formatted time series frame. The input frame's Fields are of length 0. The time index is not sorted ascending by time. The time index has null values.

With a conversion of Long to Wide, and then back to Long via WideToLong(), the outputted Long Frame may not match the original inputted Long frame.

func NewFrame

func NewFrame(name string, fields ...*Field) *Frame

NewFrame returns a new Frame.

Example
package main

import (
	"fmt"
	"math"
	"time"

	"github.com/famarker/grafarg-plugin-sdk-go/data"
)

func main() {
	aTime := time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC)
	var anInt64 int64 = 12
	frame := data.NewFrame("Frame Name",
		data.NewField("Time", nil, []time.Time{aTime, aTime.Add(time.Minute)}),
		data.NewField("Temp", data.Labels{"place": "Ecuador"}, []float64{1, math.NaN()}),
		data.NewField("Count", data.Labels{"place": "Ecuador"}, []*int64{&anInt64, nil}),
	)
	st, _ := frame.StringTable(-1, -1)
	fmt.Println(st)
}
Output:

Name: Frame Name
Dimensions: 3 Fields by 2 Rows
+-------------------------------+-----------------------+-----------------------+
| Name: Time                    | Name: Temp            | Name: Count           |
| Labels:                       | Labels: place=Ecuador | Labels: place=Ecuador |
| Type: []time.Time             | Type: []float64       | Type: []*int64        |
+-------------------------------+-----------------------+-----------------------+
| 2020-01-02 03:04:05 +0000 UTC | 1                     | 12                    |
| 2020-01-02 03:05:05 +0000 UTC | NaN                   | null                  |
+-------------------------------+-----------------------+-----------------------+

func NewFrameOfFieldTypes

func NewFrameOfFieldTypes(name string, fieldLen int, fTypes ...FieldType) *Frame

NewFrameOfFieldTypes returns a Frame where the Fields are initialized to the corresponding field type in fTypes. Each Field will be of length FieldLen.

func UnmarshalArrowFrame

func UnmarshalArrowFrame(b []byte) (*Frame, error)

UnmarshalArrowFrame converts a byte representation of an arrow table to a Frame.

func WideToLong

func WideToLong(wideFrame *Frame) (*Frame, error)

WideToLong converts a Wide formatted time series Frame to a Long formatted time series Frame (see TimeSeriesType for descriptions). The first Field of type time.Time or *time.Time in wideFrame will be the time index for the series, and will be the first field of the outputted wideFrame.

During conversion: All the unique keys in all of the Labels across the Fields of wideFrame become string Fields with the corresponding name in longFrame. The corresponding Labels values become values in those Fields of longFrame. For each unique non-timeIndex Field across the Fields of wideFrame (value fields), a Field of the same type is created in longFrame. For each unique set of Labels across the Fields of wideFrame, a row is added to longFrame, and then for each unique value Field, the corresponding value Field of longFrame is set.

Finally, the Meta field of the result Long Frame is pointing to the reference of the Meta field of the input Wide Frame.

An error is returned if any of the following are true: The input frame is not a wide formatted time series frame. The input row has no rows. The time index not sorted ascending by time. The time index has null values. Two numeric Fields have the same name but different types.

With a conversion of Wide to Long, and then back to Wide via LongToWide(), the outputted Wide Frame may not match the original inputted Wide frame.

func (*Frame) AppendNotices

func (f *Frame) AppendNotices(notices ...Notice)

AppendNotices adds notices to Frame f's metadata (Frame.Meta.Notices). If f has no metadata, this method will initialize it before adding notices.

func (*Frame) AppendRow

func (f *Frame) AppendRow(vals ...interface{})

AppendRow adds a new row to the Frame by appending to each element of vals to the corresponding Field in the data. The Frame's Fields must be initialized or AppendRow will panic. The number of arguments must match the number of Fields in the Frame and each type must correspond to the Field type or AppendRow will panic.

func (*Frame) At

func (f *Frame) At(fieldIdx int, rowIdx int) interface{}

At returns the value of the specified fieldIdx and rowIdx. It will panic if either fieldIdx or rowIdx are out of range.

func (*Frame) ConcreteAt

func (f *Frame) ConcreteAt(fieldIdx int, rowIdx int) (val interface{}, ok bool)

ConcreteAt returns the concrete value at the specified fieldIdx and rowIdx. A non-pointer type is returned regardless if the underlying type is a pointer type or not. If the value is a nil pointer, the the zero value is returned and ok will be false.

func (*Frame) CopyAt

func (f *Frame) CopyAt(fieldIdx int, rowIdx int) interface{}

CopyAt returns a copy of the value of the specified fieldIdx and rowIdx. It will panic if either fieldIdx or rowIdx are out of range.

func (*Frame) DeleteRow

func (f *Frame) DeleteRow(rowIdx int)

DeleteRow deletes row at index rowIdx of the Frame. DeleteRow calls each field's Delete If idx is out of range, this method will panic.

func (*Frame) EmptyCopy

func (f *Frame) EmptyCopy() *Frame

EmptyCopy returns a copy of Frame f but with Fields of zero length, and no copy of the FieldConfigs, Metadata, or Warnings.

func (*Frame) Extend

func (f *Frame) Extend(i int)

Extend extends all the Fields by length by i.

func (*Frame) FieldByName

func (f *Frame) FieldByName(fieldName string) (*Field, int)

FieldByName returns Field by its name and its index in Frame.Fields. If not found then *Field will be nil and index will be -1.

func (*Frame) FilterRowsByField

func (f *Frame) FilterRowsByField(fieldIdx int, filter func(i interface{}) (bool, error)) (*Frame, error)

FilterRowsByField returns a copy of frame f (as per EmptyCopy()) that includes rows where the filter returns true and no error. If filter returns an error, then an error is returned.

func (*Frame) FloatAt

func (f *Frame) FloatAt(fieldIdx int, rowIdx int) (float64, error)

FloatAt returns a float64 representation of the value at the specified fieldIdx and rowIdx, as per Field.FloatAt(). It will panic if either the fieldIdx or rowIdx are out of range.

func (*Frame) InsertRow

func (f *Frame) InsertRow(rowIdx int, vals ...interface{})

InsertRow adds a row at index rowIdx of the Frame. InsertRow calls each field's Insert which extends the Field length by 1, shifts any existing field values at indices equal or greater to rowIdx by one place and inserts the corresponding val at index rowIdx of the Field. If rowIdx is equal to the Frame RowLen, then val will be appended. If rowIdx exceeds the Field length, this method will panic.

func (*Frame) MarshalArrow

func (f *Frame) MarshalArrow() ([]byte, error)

MarshalArrow converts the Frame to an arrow table and returns a byte representation of that table. All fields of a Frame must be of the same length or an error is returned.

func (*Frame) MarshalJSON

func (f *Frame) MarshalJSON() ([]byte, error)

MarshalJSON marshals Frame to JSON.

func (*Frame) RowCopy

func (f *Frame) RowCopy(rowIdx int) []interface{}

RowCopy returns an interface slice that contains the values of each Field for the given rowIdx.

func (*Frame) RowLen

func (f *Frame) RowLen() (int, error)

RowLen returns the the length of the Frame Fields. If the lengths of all the Fields are not the same an error is returned.

func (*Frame) Rows

func (f *Frame) Rows() int

Rows returns the number of rows in the frame.

func (*Frame) Set

func (f *Frame) Set(fieldIdx int, rowIdx int, val interface{})

Set sets the val at the specified fieldIdx and rowIdx. It will panic if either fieldIdx or rowIdx are out of range or if the underlying type of val does not match the element type of the Field.

func (*Frame) SetConcrete

func (f *Frame) SetConcrete(fieldIdx int, rowIdx int, val interface{})

SetConcrete sets the val at the specified fieldIdx and rowIdx. val must be a non-pointer type or a panic will occur. If the underlying FieldType is nullable it will set val as a pointer to val. If the FieldType is not nullable this method behaves the same as the Set method. It will panic if the underlying type of val does not match the element concrete type of the Field.

func (*Frame) SetFieldNames

func (f *Frame) SetFieldNames(names ...string) error

SetFieldNames sets each Field Name in the frame to the corresponding frame. If the number of provided names does not match the number of Fields in the frame an error is returned.

func (*Frame) SetMeta

func (f *Frame) SetMeta(m *FrameMeta) *Frame

SetMeta sets the Frame's Meta attribute to m and returns the Frame.

func (*Frame) SetRow

func (f *Frame) SetRow(rowIdx int, vals ...interface{})

SetRow sets vals at the index rowIdx of the Frame. SetRow calls each field's Set which sets the Field's value at index idx to val.

func (*Frame) StringTable

func (f *Frame) StringTable(maxFields, maxRows int) (string, error)

StringTable prints a human readable table of the Frame. The output should not be used for programmatic consumption or testing. The table's width is limited to maxFields and the length is limited to maxRows (a value of -1 is unlimited). If the width or length is exceeded, the last column or row displays "..." as the contents.

func (*Frame) TimeSeriesSchema

func (f *Frame) TimeSeriesSchema() TimeSeriesSchema

TimeSeriesSchema returns the TimeSeriesSchema of the frame. The TimeSeriesSchema's Type value will be TimeSeriesNot if it is not a time series. Deprecated

func (*Frame) TypeIndices

func (f *Frame) TypeIndices(fTypes ...FieldType) []int

TypeIndices returns a slice of Field index positions for the given fTypes.

func (*Frame) TypeInfo

func (f *Frame) TypeInfo(_ string) (FrameType, FrameTypeVersion)

TypeInfo returns the FrameType and FrameTypeVersion from the frame's Meta.Type and Meta.TypeVersion properties. If either of those properties are absent, the corresponding zero value (FrameTypeUnknown and FrameTypeVersion{0,0}) is returned per each missing property.

func (*Frame) UnmarshalJSON

func (f *Frame) UnmarshalJSON(b []byte) error

UnmarshalJSON allows unmarshalling Frame from JSON.

type FrameInclude

type FrameInclude int

FrameInclude - custom type to hold Frame serialization options.

const (
	// IncludeAll serializes the entire Frame with both Schema and Data.
	IncludeAll FrameInclude = iota + 1
	// IncludeDataOnly only serializes data part of a frame.
	IncludeDataOnly
	// IncludeSchemaOnly only serializes schema part of a frame.
	IncludeSchemaOnly
)

Known FrameInclude constants.

type FrameInputConverter

type FrameInputConverter struct {
	Frame *Frame
	// contains filtered or unexported fields
}

FrameInputConverter is a type to support building a Frame while also doing conversion as data is added to the Frame.

func NewFrameInputConverter

func NewFrameInputConverter(fieldConvs []FieldConverter, rowLen int) (*FrameInputConverter, error)

NewFrameInputConverter returns a FrameInputConverter which is used to create a Frame from data that needs value conversions. The FrameInputConverter will create a new Frame with fields based on the FieldConverters' OutputFieldTypes of length rowLen.

Example
package main

import (
	"fmt"
	"log"
	"strconv"
	"time"

	"github.com/famarker/grafarg-plugin-sdk-go/data"
	conv "github.com/famarker/grafarg-plugin-sdk-go/data/converters"
)

func main() {
	inputData := struct { // inputData is a pretend table-like structure response from an API.
		ColumnTypes []string
		ColumnNames []string
		Rows        [][]string
	}{
		[]string{
			"Stringz",
			"Floatz",
			"Timez",
		},
		[]string{
			"Animal",
			"Weight (lbs)",
			"Time",
		},
		[][]string{
			{"sloth", "3.5", "1586014367"},
			{"sloth", "5.5", "1586100767"},
			{"sloth", "7", "1586187167"},
		},
	}

	// Build field converters appropriate for converting out pretend data structure.
	stringzFieldConverter := data.FieldConverter{
		OutputFieldType: data.FieldTypeString,
		// No Converter, string = string
	}
	floatzFieldConverter := data.FieldConverter{ // a converter appropriate for our pretend API's Floatz type.
		OutputFieldType: data.FieldTypeFloat64,
		Converter: func(v interface{}) (interface{}, error) {
			val, ok := v.(string)
			if !ok { // or return some default value instead of erroring
				return nil, fmt.Errorf("expected string input but got type %T", v)
			}
			return strconv.ParseFloat(val, 64)
		},
	}
	timezFieldConverter := data.FieldConverter{ // a converter appropriate for our pretend API's Timez type.
		OutputFieldType: data.FieldTypeTime,
		Converter: func(v interface{}) (interface{}, error) {
			val, ok := v.(string)
			if !ok { // or return some default value instead of erroring
				return nil, fmt.Errorf("expected string input but got type %T", v)
			}
			iV, err := strconv.ParseInt(val, 10, 64)
			if err != nil {
				return nil, fmt.Errorf("could not parse epoch time into an int64")
			}
			return time.Unix(iV, 0).UTC(), nil
		},
	}

	// a map of pretend API's types to converters
	converterMap := map[string]data.FieldConverter{
		"Stringz": stringzFieldConverter,
		"Floatz":  floatzFieldConverter,
		"Timez":   timezFieldConverter,
	}

	// build a slice of converters for Pretend API known types in the appropriate Field/Column order
	// for this specific response.
	converters := make([]data.FieldConverter, len(inputData.ColumnTypes))
	for i, cType := range inputData.ColumnTypes {
		fc, ok := converterMap[cType]
		if !ok {
			fc = conv.AnyToString
		}
		converters[i] = fc
	}

	// Get a new FrameInputConverter, which includes a Frame with appropriate Field types and length
	// for out input data.
	convBuilder, err := data.NewFrameInputConverter(converters, len(inputData.Rows))
	if err != nil {
		log.Fatal(err)
	}

	// Set field names
	err = convBuilder.Frame.SetFieldNames(inputData.ColumnNames...)
	if err != nil {
		log.Fatal(err)
	}

	// Insert data into the frame, passing data through the Converters before
	// writing to the frame.
	for rowIdx, row := range inputData.Rows {
		for fieldIdx, cell := range row {
			err = convBuilder.Set(fieldIdx, rowIdx, cell)
			if err != nil {
				log.Fatal(err)
			}
		}
	}
	convBuilder.Frame.Name = "Converted"

	st, _ := convBuilder.Frame.StringTable(-1, -1)
	fmt.Println(st)

}
Output:

Name: Converted
Dimensions: 3 Fields by 3 Rows
+----------------+--------------------+-------------------------------+
| Name: Animal   | Name: Weight (lbs) | Name: Time                    |
| Labels:        | Labels:            | Labels:                       |
| Type: []string | Type: []float64    | Type: []time.Time             |
+----------------+--------------------+-------------------------------+
| sloth          | 3.5                | 2020-04-04 15:32:47 +0000 UTC |
| sloth          | 5.5                | 2020-04-05 15:32:47 +0000 UTC |
| sloth          | 7                  | 2020-04-06 15:32:47 +0000 UTC |
+----------------+--------------------+-------------------------------+

func (*FrameInputConverter) Set

func (fic *FrameInputConverter) Set(fieldIdx, rowIdx int, val interface{}) error

Set sets val a FieldIdx and rowIdx of the frame. If the corresponding FieldConverter's Converter is not nil, then the Converter function is called before setting the value (otherwise Frame.Set is called directly). If an error is returned from the Converter function this function returns that error. Like Frame.Set and Field.Set, it will panic if fieldIdx or rowIdx are out of range.

type FrameJSONCache

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

FrameJSONCache holds a byte representation of the schema separate from the data. Methods of FrameJSON are not goroutine-safe.

func FrameToJSONCache

func FrameToJSONCache(frame *Frame) (FrameJSONCache, error)

FrameToJSON creates an object that holds schema and data independently. This is useful for explicit control between the data and schema. For standard json serialization use `json.Marshal(frame)`

NOTE: the format should be considered experimental until grafarg 8 is released.

func (*FrameJSONCache) Bytes

func (f *FrameJSONCache) Bytes(args FrameInclude) []byte

Bytes can return a subset of the cached frame json. Note that requesting a section that was not serialized on creation will return an empty value

func (*FrameJSONCache) MarshalJSON

func (f *FrameJSONCache) MarshalJSON() ([]byte, error)

MarshalJSON marshals Frame to JSON.

func (*FrameJSONCache) SameSchema

func (f *FrameJSONCache) SameSchema(dst *FrameJSONCache) bool

SameSchema checks if both structures have the same schema

type FrameMeta

type FrameMeta struct {
	// Type asserts that the frame matches a known type structure.
	Type FrameType `json:"type,omitempty"`

	// TypeVersion is the version of the Type property. Versions greater than 0.0 correspond to the dataplane
	// contract documentation https://grafarg.github.io/dataplane/contract/.
	TypeVersion FrameTypeVersion `json:"typeVersion"`

	// Path is a browsable path on the datasource.
	Path string `json:"path,omitempty"`

	// PathSeparator defines the separator pattern to decode a hierarchy. The default separator is '/'.
	PathSeparator string `json:"pathSeparator,omitempty"`

	// Custom datasource specific values.
	Custom interface{} `json:"custom,omitempty"`

	// Stats is an array of query result statistics.
	Stats []QueryStat `json:"stats,omitempty"`

	// Notices provide additional information about the data in the Frame that
	// Grafarg can display to the user in the user interface.
	Notices []Notice `json:"notices,omitempty"`

	// Channel is the path to a stream in grafarg live that has real-time updates for this data.
	Channel string `json:"channel,omitempty"`

	// PreferredVisualization is currently used to show results in Explore only in preferred visualisation option.
	PreferredVisualization VisType `json:"preferredVisualisationType,omitempty"`

	// PreferredVisualizationPluginId sets the panel plugin id to use to render the data when using Explore. If
	// the plugin cannot be found will fall back to PreferredVisualization.
	PreferredVisualizationPluginID string `json:"preferredVisualisationPluginId,omitempty"`

	// ExecutedQueryString is the raw query sent to the underlying system. All macros and templating
	// have been applied.  When metadata contains this value, it will be shown in the query inspector.
	ExecutedQueryString string `json:"executedQueryString,omitempty"`

	// Optionally identify which topic the frame should be assigned to.
	// A value specified in the response will override what the request asked for.
	DataTopic DataTopic `json:"dataTopic,omitempty"`
}

FrameMeta matches: https://github.com/famarker/grafarg/blob/master/packages/grafarg-data/src/types/data.ts#L11 NOTE -- in javascript this can accept any `[key: string]: any;` however this interface only exposes the values we want to be exposed

func FrameMetaFromJSON

func FrameMetaFromJSON(jsonStr string) (*FrameMeta, error)

FrameMetaFromJSON creates a QueryResultMeta from a json string

type FrameType

type FrameType string

A FrameType string, when present in a frame's metadata, asserts that the frame's structure conforms to the FrameType's specification. This property is currently optional, so FrameType may be FrameTypeUnknown even if the properties of the Frame correspond to a defined FrameType.

const FrameTypeDirectoryListing FrameType = "directory-listing"

FrameTypeDirectoryListing represents the items in a directory field[0]:

  • name
  • new paths can be constructed from the parent path + separator + name

field[1]:

  • media-type
  • when "directory" it can be nested
const FrameTypeLogLines FrameType = "log-lines"

FrameTypeLogLines is documented in the Logs Format in the Data Plane Contract.

const FrameTypeNumericLong FrameType = "numeric-long"

FrameTypeNumericLong is documented in the Numeric Long Format in the Data Plane Contract.

const FrameTypeNumericMulti FrameType = "numeric-multi"

FrameTypeNumericMulti is documented in the Numeric Multi Format in the Data Plane Contract.

const FrameTypeNumericWide FrameType = "numeric-wide"

FrameTypeNumericWide is documented in the Numeric Wide Format in the Data Plane Contract.

const FrameTypeTable FrameType = "table"

FrameTypeTable represents an arbitrary table structure with no constraints.

const FrameTypeTimeSeriesLong FrameType = "timeseries-long"

FrameTypeTimeSeriesLong uses string fields to define dimensions and is documented in Time Series Long Format in the Data Plane Contract. There is additional documentation in the Developer Data Frame Documentation on Long Format.

const FrameTypeTimeSeriesMany FrameType = "timeseries-many"

FrameTypeTimeSeriesMany is the same as "Wide" with exactly one numeric value field.

Deprecated: use FrameTypeTimeSeriesMulti instead.

const FrameTypeTimeSeriesMulti FrameType = "timeseries-multi"

FrameTypeTimeSeriesMulti is documented in the Time Series Multi Format in the Data Plane Contract. This replaces FrameTypeTimeSeriesMany.

const FrameTypeTimeSeriesWide FrameType = "timeseries-wide"

FrameTypeTimeSeriesWide uses labels on fields to define dimensions and is documented in Time Series Wide Format in the Data Plane Contract. There is additional documentation in the Developer Data Frame Documentation on the Wide Format.

const FrameTypeUnknown FrameType = ""

FrameTypeUnknown indicates that we do not know the frame type

func FrameTypes

func FrameTypes() []FrameType

FrameTypes returns a slice of all known frame types

func (FrameType) IsKnownType

func (p FrameType) IsKnownType() bool

IsKnownType checks if the value is a known structure

func (FrameType) IsLogs

func (p FrameType) IsLogs() bool

func (FrameType) IsNumeric

func (p FrameType) IsNumeric() bool

IsNumeric checks if the FrameType is KindNumeric.

func (FrameType) IsTimeSeries

func (p FrameType) IsTimeSeries() bool

IsTimeSeries checks if the FrameType is KindTimeSeries

func (FrameType) Kind

func (p FrameType) Kind() FrameTypeKind

Kind returns the FrameTypeKind from the FrameType.

type FrameTypeKind

type FrameTypeKind string

FrameTypeKind represents the Kind a particular FrameType falls into. See Kinds and Formats in the data plane documentation.

const KindLogs FrameTypeKind = "logs"

KindLogs means the FrameType's Kind is logs. See [Data Plane Logs Kind].

const KindNumeric FrameTypeKind = "numeric"

KindNumeric means the FrameType's Kind is numeric. See Data Plane Numeric Kind.

const KindTimeSeries FrameTypeKind = "timeseries"

KindTimeSeries means the FrameType's Kind is time series. See Data Plane Time Series Kind.

const KindUnknown FrameTypeKind = ""

type FrameTypeVersion

type FrameTypeVersion [2]uint

FrameType is a 2 number version (Major / Minor).

func ParseFrameTypeVersion

func ParseFrameTypeVersion(s string) (FrameTypeVersion, error)

ParseFrameTypeVersion parses a canonical representation of a FrameTypeVersion (e.g. "0.0") from a string. Taken from github.com/famarker/thema

func (FrameTypeVersion) Greater

func (sv FrameTypeVersion) Greater(osv FrameTypeVersion) bool

func (FrameTypeVersion) IsZero

func (sv FrameTypeVersion) IsZero() bool

func (FrameTypeVersion) Less

func (sv FrameTypeVersion) Less(osv FrameTypeVersion) bool

func (FrameTypeVersion) String

func (sv FrameTypeVersion) String() string

type Framer

type Framer interface {
	Frames() (Frames, error)
}

Framer is simply an object that can be converted to Grafarg data frames. This interface allows us to interact with types that represent data source objects without having to convert them to data frames first.

type Frames

type Frames []*Frame

Frames is a slice of Frame pointers. It is the main data container within a backend.DataResponse. There should be no `nil` entries in the Frames slice (making them pointers was a mistake).

func UnmarshalArrowFrames

func UnmarshalArrowFrames(bFrames [][]byte) (Frames, error)

UnmarshalArrowFrames decodes a slice of Arrow encoded frames to Frames ([]*Frame) by calling the UnmarshalArrow function on each encoded frame. If an error occurs Frames will be nil. See Frames.UnMarshalArrow() for the inverse operation.

func (Frames) MarshalArrow

func (frames Frames) MarshalArrow() ([][]byte, error)

MarshalArrow encodes Frames into a slice of []byte using *Frame's MarshalArrow method on each Frame. If an error occurs [][]byte will be nil. See UnmarshalArrowFrames for the inverse operation.

func (*Frames) MarshalJSON

func (frames *Frames) MarshalJSON() ([]byte, error)

func (*Frames) UnmarshalJSON

func (frames *Frames) UnmarshalJSON(b []byte) error

UnmarshalJSON allows unmarshalling Frame from JSON.

type InspectType

type InspectType int

InspectType is a type for the Inspect property of a Notice.

const (
	// InspectTypeNone is no suggestion for a tab of the panel editor in Grafarg's user interface.
	InspectTypeNone InspectType = iota

	// InspectTypeMeta suggests the "meta" tab of the panel editor in Grafarg's user interface.
	InspectTypeMeta

	// InspectTypeError suggests the "error" tab of the panel editor in Grafarg's user interface.
	InspectTypeError

	// InspectTypeData suggests the "data" tab of the panel editor in Grafarg's user interface.
	InspectTypeData

	// InspectTypeStats suggests the "stats" tab of the panel editor in Grafarg's user interface.
	InspectTypeStats
)

func (InspectType) String

func (n InspectType) String() string
type InternalDataLink struct {
	Query              any                         `json:"query,omitempty"`
	DatasourceUID      string                      `json:"datasourceUid,omitempty"`
	DatasourceName     string                      `json:"datasourceName,omitempty"`
	ExplorePanelsState *ExplorePanelsState         `json:"panelsState,omitempty"`
	Transformations    *[]LinkTransformationConfig `json:"transformations,omitempty"`
	Range              *TimeRange                  `json:"timeRange,omitempty"`
}

InternalDataLink definition to allow Explore links to be constructed in the backend

type Labels

type Labels map[string]string

Labels are used to add metadata to an object. The JSON will always be sorted keys

func LabelsFromString

func LabelsFromString(s string) (Labels, error)

LabelsFromString() parses string into a Label object. Input string needs to follow the k=v convention, e.g. `{service="users-directory"}`, "method=GET", or real JSON

func (Labels) Contains

func (l Labels) Contains(arg Labels) bool

Contains returns true if all k=v pairs of the argument are in the receiver.

func (Labels) Copy

func (l Labels) Copy() Labels

Copy returns a copy of the labels.

func (Labels) Equals

func (l Labels) Equals(arg Labels) bool

Equals returns true if the argument has the same k=v pairs as the receiver.

func (Labels) Fingerprint

func (l Labels) Fingerprint() Fingerprint

Fingerprint calculates a 64-bit FNV-1 hash of the labels. Labels are sorted by key to make sure the hash is stable.

func (Labels) MarshalJSON

func (l Labels) MarshalJSON() ([]byte, error)

MarshalJSON marshals Labels to JSON.

func (Labels) String

func (l Labels) String() string

String() turns labels into string, and will sort the kv pairs by keys e.g. Labels{"b":"valueB", "a": "valueA"} -> {"a=valueA, b=valueB"}

type LinkTransformationConfig

type LinkTransformationConfig struct {
	Type       SupportedTransformationTypes `json:"type,omitempty"`
	Field      string                       `json:"field,omitempty"`
	Expression string                       `json:"expression,omitempty"`
	MapValue   string                       `json:"mapValue,omitempty"`
}

type Notice

type Notice struct {
	// Severity is the severity level of the notice: info, warning, or error.
	Severity NoticeSeverity `json:"severity,omitempty"`

	// Text is freeform descriptive text for the notice.
	Text string `json:"text"`

	// Link is an optional link for display in the user interface and can be an
	// absolute URL or a path relative to Grafarg's root url.
	Link string `json:"link,omitempty"`

	// Inspect is an optional suggestion for which tab to display in the panel inspector
	// in Grafarg's User interface. Can be meta, error, data, or stats.
	Inspect InspectType `json:"inspect,omitempty"`
}

Notice provides a structure for presenting notifications in Grafarg's user interface.

type NoticeSeverity

type NoticeSeverity int

NoticeSeverity is a type for the Severity property of a Notice.

const (
	// NoticeSeverityInfo is informational severity.
	NoticeSeverityInfo NoticeSeverity = iota

	// NoticeSeverityWarning is warning severity.
	NoticeSeverityWarning

	// NoticeSeverityError is error severity.
	NoticeSeverityError
)

func (NoticeSeverity) MarshalJSON

func (n NoticeSeverity) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (NoticeSeverity) String

func (n NoticeSeverity) String() string

func (*NoticeSeverity) UnmarshalJSON

func (n *NoticeSeverity) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

type QueryStat

type QueryStat struct {
	FieldConfig

	Value float64 `json:"value"`
}

QueryStat is used for storing arbitrary statistics metadata related to a query and its result, e.g. total request time, data processing time. The embedded FieldConfig's display name must be set. It corresponds to the QueryResultMetaStat on the frontend (https://github.com/famarker/grafarg/blob/master/packages/grafarg-data/src/types/data.ts#L53).

type RangeValueMapper

type RangeValueMapper struct {
	From   *ConfFloat64       `json:"from,omitempty"`
	To     *ConfFloat64       `json:"to,omitempty"`
	Result ValueMappingResult `json:"result"`
}

type SpecialValueMapper

type SpecialValueMapper struct {
	Match  SpecialValueMatch  `json:"match"`
	Result ValueMappingResult `json:"result"`
}

type SpecialValueMatch

type SpecialValueMatch string
const (
	SpecialValueTrue       SpecialValueMatch = "true"
	SpecialValueFalse      SpecialValueMatch = "false"
	SpecialValueNull       SpecialValueMatch = "null"
	SpecialValueNaN        SpecialValueMatch = "nan"
	SpecialValueNullAndNaN SpecialValueMatch = "null+nan"
	SpecialValueEmpty      SpecialValueMatch = "empty"
)

type SupportedTransformationTypes

type SupportedTransformationTypes string
const (
	Regex  SupportedTransformationTypes = "regex"
	Logfmt SupportedTransformationTypes = "logfmt"
)

type Threshold

type Threshold struct {
	Value ConfFloat64 `json:"value,omitempty"` // First value is always -Infinity serialize to null
	Color string      `json:"color,omitempty"`
	State string      `json:"state,omitempty"`
}

Threshold a single step on the threshold list

func NewThreshold

func NewThreshold(value float64, color, state string) Threshold

NewThreshold Creates a new Threshold object

type ThresholdsConfig

type ThresholdsConfig struct {
	Mode ThresholdsMode `json:"mode"`

	// Must be sorted by 'value', first value is always -Infinity
	Steps []Threshold `json:"steps"`
}

ThresholdsConfig setup thresholds

type ThresholdsMode

type ThresholdsMode string

ThresholdsMode absolute or percentage

const (
	// ThresholdsModeAbsolute pick thresholds based on absolute value
	ThresholdsModeAbsolute ThresholdsMode = "absolute"

	// ThresholdsModePercentage the threshold is relative to min/max
	ThresholdsModePercentage ThresholdsMode = "percentage"
)

type TimeRange

type TimeRange struct {
	From time.Time `json:"from,omitempty"`
	To   time.Time `json:"to,omitempty"`
}

Redefining this to avoid an import cycle

type TimeSeriesSchema

type TimeSeriesSchema struct {
	Type           TimeSeriesType // the type of series, as determinted by frame.TimeSeriesSchema()
	TimeIndex      int            // Field index of the time series index
	TimeIsNullable bool           // true if the time index is nullable (of *time.Time)
	ValueIndices   []int          // Field indices of value columns (All fields excluding string fields and the time index)
	FactorIndices  []int          // Field indices of string, *string, bool, or *bool Fields
}

TimeSeriesSchema is information about a Frame's schema. It is populated from the Frame's TimeSeriesSchema() method.

type TimeSeriesType deprecated

type TimeSeriesType int

TimeSeriesType represents the type of time series the schema can be treated as (if any).

Deprecated: this type will be replaced with FrameType and FrameType#IsTimeSeries()

const (
	// TimeSeriesTypeNot means this Frame is not a valid time series. This means it lacks at least
	// one of a time Field and another (value) Field.
	TimeSeriesTypeNot TimeSeriesType = iota

	// TimeSeriesTypeLong means this Frame can be treated as a "Long" time series.
	//
	// A Long series has one or more string Fields, disregards Labels on Fields, and generally
	// repeated time values in the time index.
	TimeSeriesTypeLong

	// TimeSeriesTypeWide means this Frame can be treated as a "Wide" time series.
	//
	// A Wide series has no string fields, should not have repeated time values, and generally
	// uses labels.
	TimeSeriesTypeWide
)

TODO: Create and link to Grafarg documentation on Long vs Wide

func (TimeSeriesType) String

func (t TimeSeriesType) String() string

type ValueMapper

type ValueMapper map[string]ValueMappingResult

ValueMapper converts one set of strings to another

type ValueMapping

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

ValueMapping allows mapping input values to text and color

type ValueMappingResult

type ValueMappingResult struct {
	Text  string `json:"text,omitempty"`
	Color string `json:"color,omitempty"`
	Index int    `json:"index,omitempty"` // just used ofr ui ordering
}

ValueMappingResult is the results from mapping a value

type ValueMappings

type ValueMappings []ValueMapping

func (ValueMappings) MarshalJSON

func (m ValueMappings) MarshalJSON() ([]byte, error)

MarshalJSON writes the results as json

func (*ValueMappings) UnmarshalJSON

func (m *ValueMappings) UnmarshalJSON(b []byte) error

UnmarshalJSON will read JSON into the appropriate go types

type VisType

type VisType string

VisType is used to indicate how the data should be visualized in explore.

Directories

Path Synopsis
Package converters provides data.FieldConverters commonly used by plugins.
Package converters provides data.FieldConverters commonly used by plugins.
Package framestruct provides functions to convert from any type to *data.Frame or data.Frames
Package framestruct provides functions to convert from any type to *data.Frame or data.Frames
Package sqlutil provides multiple utilities for working with SQL data sources.
Package sqlutil provides multiple utilities for working with SQL data sources.
utils
jsoniter
Package jsoniter wraps json-iterator/go's Iterator methods with error returns so linting can catch unchecked errors.
Package jsoniter wraps json-iterator/go's Iterator methods with error returns so linting can catch unchecked errors.

Jump to

Keyboard shortcuts

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