1import { ThresholdsConfig } from './thresholds';
2import { ValueMapping } from './valueMapping';
3import { QueryResultBase, Labels, NullValueMode } from './data';
4import { DisplayProcessor, DisplayValue } from './displayValue';
5import { DataLink, LinkModel } from './dataLink';
6import { Vector } from './vector';
7import { FieldColor } from './fieldColor';
8import { ScopedVars } from './ScopedVars';
9
10/** @public */
11export enum FieldType {
12  time = 'time', // or date
13  number = 'number',
14  string = 'string',
15  boolean = 'boolean',
16  // Used to detect that the value is some kind of trace data to help with the visualisation and processing.
17  trace = 'trace',
18  other = 'other', // Object, Array, etc
19}
20
21/**
22 * @public
23 * Every property is optional
24 *
25 * Plugins may extend this with additional properties. Something like series overrides
26 */
27export interface FieldConfig<TOptions = any> {
28  /**
29   * The display value for this field.  This supports template variables blank is auto
30   */
31  displayName?: string;
32
33  /**
34   * This can be used by data sources that return and explicit naming structure for values and labels
35   * When this property is configured, this value is used rather than the default naming strategy.
36   */
37  displayNameFromDS?: string;
38
39  /**
40   * Human readable field metadata
41   */
42  description?: string;
43
44  /**
45   * An explict path to the field in the datasource.  When the frame meta includes a path,
46   * This will default to `${frame.meta.path}/${field.name}
47   *
48   * When defined, this value can be used as an identifier within the datasource scope, and
49   * may be used to update the results
50   */
51  path?: string;
52
53  /**
54   * True if data source can write a value to the path.  Auth/authz are supported separately
55   */
56  writeable?: boolean;
57
58  /**
59   * True if data source field supports ad-hoc filters
60   */
61  filterable?: boolean;
62
63  // Numeric Options
64  unit?: string;
65  decimals?: number | null; // Significant digits (for display)
66  min?: number | null;
67  max?: number | null;
68
69  // Convert input values into a display string
70  mappings?: ValueMapping[];
71
72  // Map numeric values to states
73  thresholds?: ThresholdsConfig;
74
75  // Map values to a display color
76  color?: FieldColor;
77
78  // Used when reducing field values
79  nullValueMode?: NullValueMode;
80
81  // The behavior when clicking on a result
82  links?: DataLink[];
83
84  // Alternative to empty string
85  noValue?: string;
86
87  // Panel Specific Values
88  custom?: TOptions;
89}
90
91/** @public */
92export interface ValueLinkConfig {
93  /**
94   * Result of field reduction
95   */
96  calculatedValue?: DisplayValue;
97  /**
98   * Index of the value row within Field. Should be provided only when value is not a result of a reduction
99   */
100  valueRowIndex?: number;
101}
102
103export interface Field<T = any, V = Vector<T>> {
104  /**
105   * Name of the field (column)
106   */
107  name: string;
108  /**
109   *  Field value type (string, number, etc)
110   */
111  type: FieldType;
112  /**
113   *  Meta info about how field and how to display it
114   */
115  config: FieldConfig;
116  values: V; // The raw field values
117  labels?: Labels;
118
119  /**
120   * Cached values with appropriate display and id values
121   */
122  state?: FieldState | null;
123
124  /**
125   * Convert text to the field value
126   */
127  parse?: (value: any) => T;
128
129  /**
130   * Convert a value for display
131   */
132  display?: DisplayProcessor;
133
134  /**
135   * Get value data links with variables interpolated
136   */
137  getLinks?: (config: ValueLinkConfig) => Array<LinkModel<Field>>;
138}
139
140/** @alpha */
141export interface FieldState {
142  /**
143   * An appropriate name for the field (does not include frame info)
144   */
145  displayName?: string | null;
146
147  /**
148   * Cache of reduced values
149   */
150  calcs?: FieldCalcs;
151
152  /**
153   * The numeric range for values in this field.  This value will respect the min/max
154   * set in field config, or when set to `auto` this will have the min/max for all data
155   * in the response
156   */
157  range?: NumericRange;
158
159  /**
160   * Appropriate values for templating
161   */
162  scopedVars?: ScopedVars;
163
164  /**
165   * Series index is index for this field in a larger data set that can span multiple DataFrames
166   * Useful for assigning color to series by looking up a color in a palette using this index
167   */
168  seriesIndex?: number;
169
170  /**
171   * Location of this field within the context frames results
172   *
173   * @internal -- we will try to make this unnecessary
174   */
175  origin?: DataFrameFieldIndex;
176}
177
178/** @public */
179export interface NumericRange {
180  min?: number | null;
181  max?: number | null;
182  delta: number;
183}
184
185export interface DataFrame extends QueryResultBase {
186  name?: string;
187  fields: Field[]; // All fields of equal length
188
189  // The number of rows
190  length: number;
191}
192
193/**
194 * @public
195 * Like a field, but properties are optional and values may be a simple array
196 */
197export interface FieldDTO<T = any> {
198  name: string; // The column name
199  type?: FieldType;
200  config?: FieldConfig;
201  values?: Vector<T> | T[]; // toJSON will always be T[], input could be either
202  labels?: Labels;
203}
204
205/**
206 * @public
207 * Like a DataFrame, but fields may be a FieldDTO
208 */
209export interface DataFrameDTO extends QueryResultBase {
210  name?: string;
211  fields: Array<FieldDTO | Field>;
212}
213
214export interface FieldCalcs extends Record<string, any> {}
215
216export const TIME_SERIES_VALUE_FIELD_NAME = 'Value';
217export const TIME_SERIES_TIME_FIELD_NAME = 'Time';
218export const TIME_SERIES_METRIC_FIELD_NAME = 'Metric';
219
220/**
221 * Describes where a specific data frame field is located within a
222 * dataset of type DataFrame[]
223 *
224 * @internal -- we will try to make this unnecessary
225 */
226export interface DataFrameFieldIndex {
227  frameIndex: number;
228  fieldIndex: number;
229}
230