Documentation ¶
Overview ¶
Package data provides data structures that Grafana recognizes.
The Frame object represents a Grafana 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 Grafana frontend package the @grafana/data package (https://github.com/grafana/grafana/tree/master/packages/grafana-data).
Index ¶
- Variables
- func FrameTestCompareOptions() []cmp.Option
- func FramesToBytesSlice(frames []*Frame) ([][]byte, error)
- func MarshalArrow(f *Frame) ([]byte, error)
- func Replace(frame *Frame, fieldIdx int, replacer *StringFieldReplacer) error
- func ValidFieldType(t interface{}) bool
- type ConfFloat64
- type Converter
- type DataLink
- type Field
- func (f *Field) Append(i interface{})
- func (f *Field) At(idx int) interface{}
- func (f *Field) ConcreteAt(idx int) (val interface{}, ok bool)
- func (f *Field) CopyAt(idx int) interface{}
- func (f *Field) Extend(i int)
- func (f *Field) FloatAt(idx int) (float64, error)
- func (f *Field) Len() int
- func (f *Field) Nullable() bool
- func (f *Field) PointerAt(idx int) interface{}
- func (f *Field) Set(idx int, val interface{})
- func (f *Field) SetConfig(conf *FieldConfig) *Field
- func (f *Field) Type() FieldType
- type FieldConfig
- type FieldConverter
- type FieldType
- type Fields
- type Frame
- func BytesSliceToFrames(bFrames [][]byte) ([]*Frame, error)
- func LongToWide(longFrame *Frame) (*Frame, error)
- func NewFrame(name string, fields ...*Field) *Frame
- func NewFrameOfFieldTypes(name string, fieldLen int, fTypes ...FieldType) *Frame
- func NewFromSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, map[int]SQLStringConverter, error)
- func UnmarshalArrow(b []byte) (*Frame, error)
- func WideToLong(wideFrame *Frame) (*Frame, error)
- func (f *Frame) AppendRow(vals ...interface{})
- func (f *Frame) AppendRowSafe(vals ...interface{}) error
- func (f *Frame) AppendWarning(message string, details string)
- func (f *Frame) At(fieldIdx int, rowIdx int) interface{}
- func (f *Frame) ConcreteAt(fieldIdx int, rowIdx int) (val interface{}, ok bool)
- func (f *Frame) CopyAt(fieldIdx int, rowIdx int) interface{}
- func (f *Frame) EmptyCopy() *Frame
- func (f *Frame) Extend(i int)
- func (f *Frame) FilterRowsByField(fieldIdx int, filter func(i interface{}) (bool, error)) (*Frame, error)
- func (f *Frame) FloatAt(fieldIdx int, rowIdx int) (float64, error)
- func (f *Frame) RowCopy(rowIdx int) []interface{}
- func (f *Frame) RowLen() (int, error)
- func (f *Frame) Rows() int
- func (f *Frame) Set(fieldIdx int, rowIdx int, val interface{})
- func (f *Frame) SetFieldNames(names ...string) error
- func (f *Frame) String() string
- func (f *Frame) StringTable(maxFields, maxRows int) (string, error)
- func (f *Frame) TimeSeriesSchema() (tsSchema TimeSeriesSchema)
- func (f *Frame) TypeIndices(fTypes ...FieldType) []int
- type FrameInputConverter
- type FrameMeta
- type Labels
- type MappingType
- type NullValueMode
- type SQLStringConverter
- type StringFieldReplacer
- type Threshold
- type ThresholdsConfig
- type ThresholdsMode
- type TimeSeriesSchema
- type TimeSeriesType
- type ValueMapping
- type Warning
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var AsStringFieldConverter = FieldConverter{ OutputFieldType: FieldTypeString, Converter: asStringConverter, }
AsStringFieldConverter will always return a string a regardless of the input. This is done with fmt.Sprintf which uses reflection.
Functions ¶
func FrameTestCompareOptions ¶
FrameTestCompareOptions returns go-cmp testing options to allow testing of Frame equivelnce. 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.
func FramesToBytesSlice ¶ added in v0.35.0
FramesToBytesSlice encodes a slice of Frames into a slice of []byte.
func MarshalArrow ¶
MarshalArrow converts the Frame to an arrow table and returns a byte representation of that table.
func Replace ¶
func Replace(frame *Frame, fieldIdx int, replacer *StringFieldReplacer) error
Replace will replace a *string Vector of the specified Field's index using the StringFieldReplacer.
Example ¶
package main import ( "fmt" "strconv" "github.com/grafana/grafana-plugin-sdk-go/data" ) func main() { i := 0 getString := func() *string { i++ s := strconv.Itoa(i) return &s } frame := data.NewFrame("Before", data.NewField("string", nil, []*string{getString(), getString()})) fmt.Println(frame.String()) // Before intReplacer := &data.StringFieldReplacer{ VectorType: []*int64{}, ReplaceFunc: func(in *string) (interface{}, error) { if in == nil { return nil, nil } v, err := strconv.ParseInt(*in, 10, 64) if err != nil { return nil, err } return &v, nil }, } err := data.Replace(frame, 0, intReplacer) if err != nil { // return err } frame.Name = "After" fmt.Println(frame.String()) // After }
Output: Name: Before Dimensions: 1 Fields by 2 Rows +-----------------+ | Name: string | | Labels: | | Type: []*string | +-----------------+ | 1 | | 2 | +-----------------+ Name: After Dimensions: 1 Fields by 2 Rows +----------------+ | Name: string | | Labels: | | Type: []*int64 | +----------------+ | 1 | | 2 | +----------------+
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 ¶ added in v0.36.0
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 ¶
type DataLink struct { Title string `json:"title,omitempty"` TargetBlank bool `json:"targetBlank,omitempty"` URL string `json:"url,omitempty"` }
DataLink define what
type Field ¶
type Field struct { Name string Config *FieldConfig Labels Labels // contains filtered or unexported fields }
Field represents a typed column of data within a Frame. The data in the Field is a not exported, so methods on the Field are used to to manipulate its data.
func NewField ¶
NewField returns a instance of *Field.
Supported types for values are: []int8, []*int8, []int16, []*int16, []int32, []*int32, []int64, []*int64, []uint8, []*uint8, []uint16, []*uint16, []uint32, []*uint32, []uint64, []*uint64, []float32, []*float32, []float64, []*float64, []string, []*string, []bool, []*bool, []time.Time, and []*time.Time.
If an unsupported values type is passed, NewField will panic.
func NewFieldFromFieldType ¶
NewFieldFromFieldType creates a new Field of the given pType of length n.
func (*Field) At ¶
At returns the the element at index idx of the Field. It will panic if idx is out of range.
func (*Field) ConcreteAt ¶
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 ¶
CopyAt returns a copy of the value of the specified index idx. It will panic if idx is out of range.
func (*Field) FloatAt ¶ added in v0.31.0
FloatAt returns a float64 at the specified index idx. 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.
func (*Field) PointerAt ¶
PointerAt returns a pointer to the value at idx of the Field. It will panic if idx is out of range.
func (*Field) Set ¶
Set sets the Field's value at index idx to val. It will panic if idx is out of range.
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.
type FieldConfig ¶
type FieldConfig struct { Title string `json:"title,omitempty"` Filterable *bool `json:"filterable,omitempty"` // indicates if the Field's data can be filtered by additional calls. // 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 // Convert input values into a display string Mappings []ValueMapping `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"` // Used when reducing field values NullValueMode NullValueMode `json:"nullValueMode,omitempty"` // The behavior when clicking on a result Links []DataLink `json:"links,omitempty"` // Alternative to empty string NoValue string `json:"noValue,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 convenance 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 convenance 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 convenance 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 convenance function since the Min property is a pointer.
type FieldConverter ¶ added in v0.36.0
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 ( // FieldTypeInt8 indicates the underlying primitive is a []int8. FieldTypeInt8 FieldType = iota // 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 []int8. FieldTypeUint8 // FieldTypeNullableUint8 indicates the underlying primitive is a []*int8. 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 )
func NumericFieldTypes ¶
func NumericFieldTypes() []FieldType
NumericFieldTypes returns a slice of FieldTypes that are numeric.
func (FieldType) ItemTypeString ¶
ItemTypeString returns the string representation of the type of element within in the vector
type Frame ¶
Frame represents a columnar storage with optional labels. Each Field in Fields represents a column, all Fields must be of the same the length.
func BytesSliceToFrames ¶ added in v0.35.0
BytesSliceToFrames decodes a slice of encoded Arrow frames to a slice of *Frame.
func LongToWide ¶
LongToWide converts a Long formated 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 Fields in the longFrame become Labels on the Fields of wideFrame. The name of each string 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.
An error is returned if any of the following are true: The input frame is not a long formated 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 ¶
NewFrame returns a new instance of a Frame.
Example ¶
package main import ( "fmt" "math" "time" "github.com/grafana/grafana-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}), ) fmt.Println(frame.String()) }
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 ¶ added in v0.36.0
NewFrameOfFieldTypes returns a Frame where the Fields are initalized to the corresponding field type in fTypes. Each Field will be of length FieldLen.
func NewFromSQLRows ¶
func NewFromSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, map[int]SQLStringConverter, error)
NewFromSQLRows returns a new Frame populated with the data from rows. The Field Vector types will be Vectors of pointer types, []*T, if the SQL column is nullable or if the nullable property is unknown. Otherwise, they will be []T types.
Fields will be named to match name of the SQL columns and the SQL column names must be unique (https://github.com/grafana/grafana-plugin-sdk-go/issues/59).
All the types must be supported by the Frame or a SQLStringConverter will be created and the resulting Field Vector type will be of type []*string.
The SQLStringConverter's ConversionFunc will be applied to matching rows if it is not nil. Additionally, if the SQLStringConverter's Replacer is not nil, the replacement will be performed. A map of Field/Column index to the corresponding SQLStringConverter is returned so what conversions were done can be inspected.
Example ¶
package main import ( "database/sql" "github.com/grafana/grafana-plugin-sdk-go/data" ) func main() { aQuery := "SELECT * FROM GoodData" db, err := sql.Open("fancySql", "fancysql://user:pass@localhost:1433") if err != nil { // return err } defer db.Close() rows, err := db.Query(aQuery) if err != nil { // return err } defer rows.Close() frame, mappings, err := data.NewFromSQLRows(rows) if err != nil { // return err } _, _ = frame, mappings }
Output:
func UnmarshalArrow ¶
UnmarshalArrow converts a byte representation of an arrow table to a Frame
func WideToLong ¶
WideToLong converts a Wide formated time series Frame to a Long formated 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.
An error is returned if any of the following are true: The input frame is not a wide formated 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) 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 initalized or AppendRow will panic. The number of arguments must match the number of Fields in the Frame and each type must coorespond to the Field type or AppendRow will panic.
func (*Frame) AppendRowSafe ¶
AppendRowSafe adds a new row to the Frame by appending to each each element of vals to the corresponding Field in the data. It has the some constraints as AppendRow but will return an error under those conditions instead of panicing.
func (*Frame) AppendWarning ¶
AppendWarning adds warnings to the data frame.
func (*Frame) At ¶
At returns the value of the specified fieldIdx and rowIdx. It will panic if either the fieldIdx or rowIdx are out of range.
func (*Frame) ConcreteAt ¶
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 pointer type, and is nil, then the zero value is returned and ok will be false.
func (*Frame) CopyAt ¶
CopyAt returns a copy of the value of the specified fieldIdx and rowIdx. It will panic if either the fieldIdx or rowIdx are out of range.
func (*Frame) EmptyCopy ¶ added in v0.28.0
EmptyCopy returns a copy of Frame f but with Fields of zero length, and no copy of the FieldConfigs, Metadata, or Warnings.
func (*Frame) FilterRowsByField ¶ added in v0.28.0
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 ¶ added in v0.31.0
FloatAt returns a float64 representation of value of the specified fieldIdx and rowIdx as per Field.FloatAt(). It will panic if either the fieldIdx or rowIdx are out of range.
func (*Frame) RowCopy ¶ added in v0.28.0
RowCopy returns an interface slice that contains the values of each Field for the given rowIdx.
func (*Frame) RowLen ¶
RowLen returns the the length of the Frame Fields. If the Length of all the Fields is not the same then error is returned. If the Frame's Fields are nil an error is returned.
func (*Frame) Set ¶
Set set the val to the specified fieldIdx and rowIdx. It will panic if either the fieldIdx or rowIdx are out of range.
func (*Frame) SetFieldNames ¶ added in v0.36.0
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) StringTable ¶ added in v0.32.0
StringTable prints a human readable table of the Frame. The table's width is limited to maxFields and the length is limited to maxRows. If the width or length is excceded then last column or row displays "..." as the contents.
func (*Frame) TimeSeriesSchema ¶
func (f *Frame) TimeSeriesSchema() (tsSchema TimeSeriesSchema)
TimeSeriesSchema returns the TimeSeriesSchema of the frame. The TimeSeriesSchema's Type value will be TimeSeriesNot if it is not a time series.
func (*Frame) TypeIndices ¶
TypeIndices returns a slice of Field index positions for the given fTypes.
type FrameInputConverter ¶ added in v0.36.0
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 ¶ added in v0.36.0
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/grafana/grafana-plugin-sdk-go/data" ) 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{ []string{"sloth", "3.5", "1586014367"}, []string{"sloth", "5.5", "1586100767"}, []string{"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", val) } 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", val) } 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 = data.AsStringFieldConverter } 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" fmt.Println(convBuilder.Frame.String()) }
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 ¶ added in v0.36.0
func (fcb *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 FrameMeta ¶ added in v0.35.0
type FrameMeta struct { // Datasource specific values Custom map[string]interface{} `json:"custom,omitempty"` // Stats is TODO Stats interface{} `json:"stats,omitempty"` // Notices is TODO Notices interface{} `json:"notices,omitempty"` }
FrameMeta matches: https://github.com/grafana/grafana/blob/master/packages/grafana-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 ¶ added in v0.35.0
FrameMetaFromJSON creates a QueryResultMeta from a json string
type Labels ¶
Labels are used to add metadata to an object.
func LabelsFromString ¶
LabelsFromString parses the output of Labels.String() into a Labels object. It probably has some flaws.
func (Labels) Contains ¶
Contains returns true if all k=v pairs of the argument are in the receiver.
type MappingType ¶
type MappingType int8
MappingType value or range
const ( // ValueToText map a value to text ValueToText MappingType = iota + 1 // RangeToText map a range to text RangeToText )
type NullValueMode ¶
type NullValueMode string
NullValueMode say how the UI should show null values
const ( // NullValueModeNull displays null values NullValueModeNull NullValueMode = "null" // NullValueModeIgnore sets the display to ignore null values NullValueModeIgnore NullValueMode = "connected" // NullValueModeAsZero set the display show null values as zero NullValueModeAsZero NullValueMode = "null as zero" )
type SQLStringConverter ¶
type SQLStringConverter struct { // Name is an optional property that can be used to identify a converter Name string InputScanKind reflect.Kind // reflect.Type might better or worse option? InputTypeName string // Conversion func may be nil to do no additional operations on the string conversion. ConversionFunc func(in *string) (*string, error) // If the Replacer is not nil, the replacement will be performed. Replacer *StringFieldReplacer }
SQLStringConverter can be used to store types not supported by a Frame into a *string. When scanning, if a SQL's row's InputScanType's Kind and InputScanKind match that returned by the sql response, then the conversion func will be run on the row.
Example ¶
package main import ( "reflect" "strconv" "github.com/grafana/grafana-plugin-sdk-go/data" ) func main() { _ = data.SQLStringConverter{ Name: "BIGINT to *int64", InputScanKind: reflect.Struct, InputTypeName: "BIGINT", Replacer: &data.StringFieldReplacer{ VectorType: []*int64{}, ReplaceFunc: func(in *string) (interface{}, error) { if in == nil { return nil, nil } v, err := strconv.ParseInt(*in, 10, 64) if err != nil { return nil, err } return &v, nil }, }, } }
Output:
type StringFieldReplacer ¶
type StringFieldReplacer struct { VectorType interface{} ReplaceFunc func(in *string) (interface{}, error) }
StringFieldReplacer is used to replace a *string Field in a Frame. The type returned by the ReplaceFunc must match the type of elements of VectorType. Both properties must be non-nil.
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 ¶
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 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 or *string Fields }
TimeSeriesSchema is information about a Frame's schema. It is populated from the Frame's TimeSeriesSchema() method.
type TimeSeriesType ¶
type TimeSeriesType int
TimeSeriesType represents the type of time series the schema can be treated as (if any).
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 Grafana documentation on Long vs Wide
func (TimeSeriesType) String ¶
func (t TimeSeriesType) String() string
type ValueMapping ¶
type ValueMapping struct { ID int16 `json:"id"` Operator string `json:"operator"` Text string `json:"title"` Type MappingType `json:"type"` // Only valid for MappingType == ValueMap Value string `json:"value,omitempty"` // Only valid for MappingType == RangeMap From string `json:"from,omitempty"` To string `json:"to,omitempty"` }
ValueMapping convert input value to something else
type Warning ¶
type Warning struct { // Short message (typically shown in the header) Message string `json:"message,omitempty"` // longer error message, shown in the body Details string `json:"details,omitempty"` }
Warning contains information about problems in a data.
func WarningsFromJSON ¶
WarningsFromJSON creates a *Warning from a json string.