package data import ( "fmt" "math" "strconv" ) // FieldConfig represents the display properties for a Field. type FieldConfig struct { // This struct needs to match the frontend component defined in: // https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/dataFrame.ts#L23 // All properties are optional should be omitted from JSON when empty or not set. // DisplayName overrides Grafana default naming, should not be used from a data source DisplayName string `json:"displayName,omitempty"` // DisplayNameFromDS overrides Grafana default naming in a better way that allows users to override it easily. 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"` // 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"` } // ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf // to null. type ConfFloat64 float64 // MarshalJSON fullfills the json.Marshaler interface. func (sf *ConfFloat64) MarshalJSON() ([]byte, error) { if sf == nil || math.IsNaN(float64(*sf)) || math.IsInf(float64(*sf), -1) || math.IsInf(float64(*sf), 1) { return []byte(string(NullValueModeNull)), nil } return []byte(fmt.Sprintf(`%v`, float64(*sf))), nil } // UnmarshalJSON fullfills the json.Unmarshaler interface. func (sf *ConfFloat64) UnmarshalJSON(data []byte) error { s := string(data) if s == string(NullValueModeNull) { return nil } v, err := strconv.ParseFloat(s, 64) if err != nil { return err } cf := ConfFloat64(v) *sf = cf return nil } // 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 (fc *FieldConfig) SetDecimals(v uint16) *FieldConfig { fc.Decimals = &v return fc } // 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. func (fc *FieldConfig) SetMin(v float64) *FieldConfig { cf := ConfFloat64(v) fc.Min = &cf return fc } // 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 (fc *FieldConfig) SetMax(v float64) *FieldConfig { cf := ConfFloat64(v) fc.Max = &cf return fc } // 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 (fc *FieldConfig) SetFilterable(b bool) *FieldConfig { fc.Filterable = &b return fc } // NullValueMode say how the UI should show null values type NullValueMode string 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" ) // MappingType value or range type MappingType int8 const ( // ValueToText map a value to text ValueToText MappingType = iota + 1 // RangeToText map a range to text RangeToText ) // ValueMapping convert input value to something else type ValueMapping struct { ID int16 `json:"id,omitempty"` Text string `json:"text,omitempty"` Type MappingType `json:"type,omitempty"` // 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"` } // DataLink define what type DataLink struct { //revive:disable-line Title string `json:"title,omitempty"` TargetBlank bool `json:"targetBlank,omitempty"` URL string `json:"url,omitempty"` } // ThresholdsConfig setup thresholds type ThresholdsConfig struct { Mode ThresholdsMode `json:"mode"` // Must be sorted by 'value', first value is always -Infinity Steps []Threshold `json:"steps"` } // Threshold a single step on the threshold list 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"` } // NewThreshold Creates a new Threshold object func NewThreshold(value float64, color, state string) Threshold { cf := ConfFloat64(value) return Threshold{ Value: cf, Color: color, State: state, } } // ThresholdsMode absolute or percentage type ThresholdsMode string const ( // ThresholdsModeAbsolute pick thresholds based on absolute value ThresholdsModeAbsolute ThresholdsMode = "absolute" // ThresholdsModePercentage the threshold is relative to min/max ThresholdsModePercentage ThresholdsMode = "percentage" )