@grafana/data#DataFrame TypeScript Examples

The following examples show how to use @grafana/data#DataFrame. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
export function getColumns(data: DataFrame, availableWidth: number, columnMinWidth: number): Column[] {
  const columns: Column[] = [];
  let fieldCountWithoutWidth = data.fields.length;

  for (const field of data.fields) {
    const fieldTableOptions = (field.config.custom || {}) as TableFieldOptions;
    if (fieldTableOptions.width) {
      availableWidth -= fieldTableOptions.width;
      fieldCountWithoutWidth -= 1;
    }

    const Cell = getCellComponent(fieldTableOptions.displayMode);

    columns.push({
      Cell,
      Header: field.name,
      accessor: field.name,
      width: fieldTableOptions.width,
    });
  }

  // divide up the rest of the space
  const sharedWidth = availableWidth / fieldCountWithoutWidth;
  for (const column of columns) {
    if (!column.width) {
      column.width = Math.max(sharedWidth, columnMinWidth);
    }
  }

  return columns;
}
Example #2
Source File: fetchMetrics.tsx    From grafana-weathermap-panel with Apache License 2.0 6 votes vote down vote up
reqMetricRegion = (region: RegionClass, props: any) => {
  const data: DataFrame[] = [];

  for (const line of props.data.series) {
    if (line.refId === region.mainMetric.refId) {
      data.push(line);
    }
  }
  region.mainMetric.returnQuery = data;
}
Example #3
Source File: link_srv.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getDataLinksVariableSuggestions = (
  dataFrames: DataFrame[],
  scope?: VariableSuggestionsScope
): VariableSuggestion[] => {
  const valueTimeVar = {
    value: `${DataLinkBuiltInVars.valueTime}`,
    label: 'Time',
    documentation: 'Time value of the clicked datapoint (in ms epoch)',
    origin: VariableOrigin.Value,
  };
  const includeValueVars = scope === VariableSuggestionsScope.Values;

  return includeValueVars
    ? [
        ...seriesVars,
        ...getFieldVars(dataFrames),
        ...valueVars,
        valueTimeVar,
        ...getDataFrameVars(dataFrames),
        ...getPanelLinksVariableSuggestions(),
      ]
    : [
        ...seriesVars,
        ...getFieldVars(dataFrames),
        ...getDataFrameVars(dataFrames),
        ...getPanelLinksVariableSuggestions(),
      ];
}
Example #4
Source File: fetchMetrics.tsx    From grafana-weathermap-panel with Apache License 2.0 6 votes vote down vote up
reqMetricAuxRegion = (region: RegionClass, props: any) => {
  for (const metric of region.metrics) {
    const data: DataFrame[] = [];
    for (const line of props.data.series) {
      if (line.refId === metric.refId) {
        data.push(line);
      }
    }
    metric.returnQuery = data;
  }
}
Example #5
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
 * Transforms LokiStreamResult structure into a dataFrame. Used when doing standard queries and newer version of Loki.
 */
export function lokiStreamResultToDataFrame(stream: LokiStreamResult, reverse?: boolean, refId?: string): DataFrame {
  const labels: Labels = stream.stream;
  const labelsString = Object.entries(labels)
    .map(([key, val]) => `${key}="${val}"`)
    .sort()
    .join('');

  const times = new ArrayVector<string>([]);
  const timesNs = new ArrayVector<string>([]);
  const lines = new ArrayVector<string>([]);
  const uids = new ArrayVector<string>([]);

  for (const [ts, line] of stream.values) {
    // num ns epoch in string, we convert it to iso string here so it matches old format
    times.add(new Date(parseInt(ts.substr(0, ts.length - 6), 10)).toISOString());
    timesNs.add(ts);
    lines.add(line);
    uids.add(createUid(ts, labelsString, line));
  }

  return constructDataFrame(times, timesNs, lines, uids, labels, reverse, refId);
}
Example #6
Source File: fetchMetrics.tsx    From grafana-weathermap-panel with Apache License 2.0 6 votes vote down vote up
reqMetricAuxPoint = (point: PointClass, props: any) => {
  for (const metric of point.metrics) {
    const data: DataFrame[] = [];
    for (const line of props.data.series) {
      if (line.refId === metric.refId) {
        data.push(line);
      }
    }
    metric.returnQuery = data;
  }
}
Example #7
Source File: module.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
function getDistinctNames(data: DataFrame[]): DistinctFieldsInfo {
  const distinct: DistinctFieldsInfo = {
    byName: {},
    names: [],
  };
  for (const frame of data) {
    const info: FrameInfo = { frame };
    for (const field of frame.fields) {
      if (field.type === FieldType.time) {
        if (!info.firstTimeField) {
          info.firstTimeField = field;
        }
      } else {
        const f = { field, frame: info };
        if (!distinct.first) {
          distinct.first = f;
        }
        let t = field.config.title;
        if (t && !distinct.byName[t]) {
          distinct.byName[t] = f;
          distinct.names.push(t);
        }
        t = field.name;
        if (t && !distinct.byName[t]) {
          distinct.byName[t] = f;
          distinct.names.push(t);
        }
      }
    }
  }
  return distinct;
}
Example #8
Source File: manageQuery.tsx    From grafana-weathermap-panel with Apache License 2.0 6 votes vote down vote up
/** edit value for select */
  onChangeSelectQuery = (value: SelectableValue<DataFrame>) => {
    const newMainMetric: Metric = this.state.mainMetric;
    newMainMetric.refId = value.value?.refId || '';
    newMainMetric.expr = '';
    this.setState({
      mainMetric: newMainMetric,
      selectQueryDefault: value,
    });
    this.callBack();
  };
Example #9
Source File: module.ts    From mqtt-panel with Apache License 2.0 6 votes vote down vote up
// 6.3+ get typed DataFrame directly
  handleDataFrame(data: DataFrame[]) {
    const values: KeyValue[] = [];

    for (const frame of data) {
      for (let i = 0; i < frame.fields.length; i++) {
        values.push({
          key: frame.fields[i].name,
          value: frame.fields[i].values,
        });
      }
    }

    this.firstValues = values;
  }
Example #10
Source File: heatmap_ctrl.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
// Directly support DataFrame
  onDataFramesReceived(data: DataFrame[]) {
    this.series = this.processor.getSeriesList({ dataList: data, range: this.range }).map(ts => {
      ts.color = null; // remove whatever the processor set
      ts.flotpairs = ts.getFlotPairs(this.panel.nullPointMode);
      return ts;
    });

    this.dataWarning = null;
    const datapointsCount = _.reduce(
      this.series,
      (sum, series) => {
        return sum + series.datapoints.length;
      },
      0
    );

    if (datapointsCount === 0) {
      this.dataWarning = {
        title: 'No data points',
        tip: 'No datapoints returned from data query',
      };
    } else {
      for (const series of this.series) {
        if (series.isOutsideRange) {
          this.dataWarning = {
            title: 'Data points outside time range',
            tip: 'Can be caused by timezone mismatch or missing time filter in query',
          };
          break;
        }
      }
    }

    this.render();
  }
Example #11
Source File: fetchMetrics.tsx    From grafana-weathermap-panel with Apache License 2.0 6 votes vote down vote up
reqMetricPoint = (point: PointClass, props: any) => {
  const data: DataFrame[] = [];
  for (const line of props.data.series) {
    if (line.refId === point.mainMetric.refId) {
      data.push(line);
    }
  }
  point.mainMetric.returnQuery = data;
}
Example #12
Source File: logs_model.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
 * Convert dataFrame into LogsModel which consists of creating separate array of log rows and metrics series. Metrics
 * series can be either already included in the dataFrame or will be computed from the log rows.
 * @param dataFrame
 * @param intervalMs In case there are no metrics series, we use this for computing it from log rows.
 */
export function dataFrameToLogsModel(dataFrame: DataFrame[], intervalMs: number, timeZone: TimeZone): LogsModel {
  const { logSeries, metricSeries } = separateLogsAndMetrics(dataFrame);
  const logsModel = logSeriesToLogsModel(logSeries);

  if (logsModel) {
    if (metricSeries.length === 0) {
      // Create metrics from logs
      logsModel.series = makeSeriesForLogs(logsModel.rows, intervalMs, timeZone);
    } else {
      // We got metrics in the dataFrame so process those
      logsModel.series = getGraphSeriesModel(
        metricSeries,
        timeZone,
        {},
        { showBars: true, showLines: false, showPoints: false },
        {
          asTable: false,
          isVisible: true,
          placement: 'under',
        }
      );
    }

    return logsModel;
  }

  return {
    hasUniqueLabels: false,
    rows: [],
    meta: [],
    series: [],
  };
}
Example #13
Source File: manageAuxiliaryQuery.tsx    From grafana-weathermap-panel with Apache License 2.0 5 votes vote down vote up
private getCurrentQuery = (id: string, isLinkB: boolean): SelectableValue<DataFrame> => {
    let currentQuery: SelectableValue<DataFrame> = [];
    const newAuxiliaryMetrics: Metric[] = this.getAuxiliaryMetrics(false);
    currentQuery = { id: id, label: newAuxiliaryMetrics[parseInt(id, 10)].refId };
    return currentQuery;
  };
Example #14
Source File: elastic_response.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
getLogs(logMessageField?: string, logLevelField?: string): DataQueryResponse {
    const dataFrame: DataFrame[] = [];

    for (let n = 0; n < this.response.responses.length; n++) {
      const response = this.response.responses[n];
      if (response.error) {
        throw this.getErrorFromElasticResponse(this.response, response.error);
      }

      const { propNames, docs } = flattenHits(response.hits.hits);
      if (docs.length > 0) {
        const series = createEmptyDataFrame(propNames, this.targets[0].timeField, logMessageField, logLevelField);

        // Add a row for each document
        for (const doc of docs) {
          if (logLevelField) {
            // Remap level field based on the datasource config. This field is then used in explore to figure out the
            // log level. We may rewrite some actual data in the level field if they are different.
            doc['level'] = doc[logLevelField];
          }

          series.add(doc);
        }

        dataFrame.push(series);
      }

      if (response.aggregations) {
        const aggregations = response.aggregations;
        const target = this.targets[n];
        const tmpSeriesList: any[] = [];
        const table = new TableModel();

        this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0);
        this.trimDatapoints(tmpSeriesList, target);
        this.nameSeries(tmpSeriesList, target);

        for (let y = 0; y < tmpSeriesList.length; y++) {
          const series = toDataFrame(tmpSeriesList[y]);
          dataFrame.push(series);
        }
      }
    }

    return { data: dataFrame };
  }
Example #15
Source File: manageQuery.tsx    From grafana-weathermap-panel with Apache License 2.0 5 votes vote down vote up
/** add all query in select */
  fillSelectQuery = () => {
    const valueSelect: Array<SelectableValue<DataFrame>> = [];
    const newMainMetric: Metric = this.state.mainMetric;

    valueSelect.push({ value: undefined, label: 'No value' });
    for (const line of this.props.data.series) {
      let duplicate = false;
      for (const valueSave of valueSelect) {
        if (valueSave.value?.refId === line.refId) {
          duplicate = true;
          break;
        }
      }
      if (!duplicate) {
        valueSelect.push({ value: line, label: line.refId });
      }
    }
    if (newMainMetric.refId === '') {
      newMainMetric.refId = valueSelect.length > 0 ? valueSelect[0].value?.refId || '' : '';
    }

    const refId: string | undefined = this.state.mainMetric.refId;
    let defaultValue: SelectableValue<DataFrame>;

    defaultValue = { value: undefined, label: 'No value' };
    if (refId) {
      for (const line of valueSelect) {
        if (line.value?.refId === refId) {
          defaultValue = line;
          break;
        }
      }
    }
    this.setState({
      mainMetric: newMainMetric,
      selectQuery: valueSelect,
      selectQueryDefault: defaultValue,
    });
  };
Example #16
Source File: logs_model.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
function isLogsData(series: DataFrame) {
  return series.fields.some(f => f.type === FieldType.time) && series.fields.some(f => f.type === FieldType.string);
}
Example #17
Source File: getGraphSeriesModel.ts    From loudml-grafana-app with MIT License 4 votes vote down vote up
getGraphSeriesModel = (
  dataFrames: DataFrame[],
  timeZone: TimeZone,
  seriesOptions: SeriesOptions,
  graphOptions: GraphOptions,
  legendOptions: GraphLegendEditorLegendOptions,
  fieldOptions?: FieldDisplayOptions
) => {
  const graphs: GraphSeriesXY[] = [];

  const displayProcessor = getDisplayProcessor({
    field: {
      config: {
        unit: fieldOptions?.defaults?.unit,
        decimals: legendOptions.decimals,
      },
    },
  });

  let fieldColumnIndex = -1;
  for (const series of dataFrames) {
    const { timeField } = getTimeField(series);
    if (!timeField) {
      continue;
    }

    for (const field of series.fields) {
      if (field.type !== FieldType.number) {
        continue;
      }
      // Storing index of series field for future inspection
      fieldColumnIndex++;

      // Use external calculator just to make sure it works :)
      const points = getFlotPairs({
        xField: timeField,
        yField: field,
        nullValueMode: NullValueMode.Null,
      });

      if (points.length > 0) {
        const seriesStats = reduceField({ field, reducers: legendOptions.stats });
        let statsDisplayValues: DisplayValue[];

        if (legendOptions.stats) {
          statsDisplayValues = legendOptions.stats.map<DisplayValue>(stat => {
            const statDisplayValue = displayProcessor(seriesStats[stat]);

            return {
              ...statDisplayValue,
              title: stat,
            };
          });
        }

        let color: FieldColor;
        if (seriesOptions[field.name] && seriesOptions[field.name].color) {
          // Case when panel has settings provided via SeriesOptions, i.e. graph panel
          color = {
            mode: FieldColorMode.Fixed,
            fixedColor: seriesOptions[field.name].color,
          };
        } else if (field.config && field.config.color) {
          // Case when color settings are set on field, i.e. Explore logs histogram (see makeSeriesForLogs)
          color = field.config.color;
        } else {
          color = {
            mode: FieldColorMode.Fixed,
            fixedColor: colors[graphs.length % colors.length],
          };
        }

        field.config = fieldOptions
          ? {
              ...field.config,
              unit: fieldOptions.defaults.unit,
              decimals: fieldOptions.defaults.decimals,
              color,
            }
          : { ...field.config, color };

        field.display = getDisplayProcessor({ field });

        // Time step is used to determine bars width when graph is rendered as bar chart
        const timeStep = getSeriesTimeStep(timeField);
        const useMsDateFormat = hasMsResolution(timeField);

        timeField.display = getDisplayProcessor({
          timeZone,
          field: {
            ...timeField,
            type: timeField.type,
            config: {
              unit: `time:${useMsDateFormat ? MS_DATE_TIME_FORMAT : DEFAULT_DATE_TIME_FORMAT}`,
            },
          },
        });

        graphs.push({
          label: field.name,
          data: points,
          color: field.config.color?.fixedColor,
          info: statsDisplayValues,
          isVisible: true,
          yAxis: {
            index: (seriesOptions[field.name] && seriesOptions[field.name].yAxis) || 1,
          },
          // This index is used later on to retrieve appropriate series/time for X and Y axes
          seriesIndex: fieldColumnIndex,
          timeField: { ...timeField },
          valueField: { ...field },
          timeStep,
        });
      }
    }
  }

  return graphs;
}
Example #18
Source File: fieldOverrides.test.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
describe('FieldOverrides', () => {
  beforeAll(() => {
    standardFieldConfigEditorRegistry.setInit(getStandardFieldConfigs);
  });

  const f0 = new MutableDataFrame();
  f0.add({ title: 'AAA', value: 100, value2: 1234 }, true);
  f0.add({ title: 'BBB', value: -20 }, true);
  f0.add({ title: 'CCC', value: 200, value2: 1000 }, true);
  expect(f0.length).toEqual(3);

  // Hardcode the max value
  f0.fields[1].config.max = 0;
  f0.fields[1].config.decimals = 6;

  const src: FieldConfigSource = {
    defaults: {
      unit: 'xyz',
      decimals: 2,
    },
    overrides: [
      {
        matcher: { id: FieldMatcherID.numeric },
        properties: [
          { prop: 'decimals', value: 1 }, // Numeric
          { prop: 'title', value: 'Kittens' }, // Text
        ],
      },
    ],
  };

  it('will merge FieldConfig with default values', () => {
    const field: FieldConfig = {
      min: 0,
      max: 100,
    };
    const f1 = {
      unit: 'ms',
      dateFormat: '', // should be ignored
      max: parseFloat('NOPE'), // should be ignored
      min: null, // should alo be ignored!
    };

    const f: DataFrame = toDataFrame({
      fields: [{ type: FieldType.number, name: 'x', config: field, values: [] }],
    });
    const processed = applyFieldOverrides({
      data: [f],
      standard: standardFieldConfigEditorRegistry,
      fieldOptions: {
        defaults: f1 as FieldConfig,
        overrides: [],
      },
      replaceVariables: v => v,
      theme: getTheme(),
    })[0];
    const out = processed.fields[0].config;

    expect(out.min).toEqual(0);
    expect(out.max).toEqual(100);
    expect(out.unit).toEqual('ms');
  });

  it('will apply field overrides', () => {
    const data = applyFieldOverrides({
      data: [f0], // the frame
      fieldOptions: src as FieldDisplayOptions, // defaults + overrides
      replaceVariables: (undefined as any) as InterpolateFunction,
      theme: (undefined as any) as GrafanaTheme,
    })[0];
    const valueColumn = data.fields[1];
    const config = valueColumn.config;

    // Keep max from the original setting
    expect(config.max).toEqual(0);

    // Don't Automatically pick the min value
    expect(config.min).toEqual(undefined);

    // The default value applied
    expect(config.unit).toEqual('xyz');

    // The default value applied
    expect(config.title).toEqual('Kittens');

    // The override applied
    expect(config.decimals).toEqual(1);
  });

  it('will apply set min/max when asked', () => {
    const data = applyFieldOverrides({
      data: [f0], // the frame
      fieldOptions: src as FieldDisplayOptions, // defaults + overrides
      replaceVariables: (undefined as any) as InterpolateFunction,
      theme: (undefined as any) as GrafanaTheme,
      autoMinMax: true,
    })[0];
    const valueColumn = data.fields[1];
    const config = valueColumn.config;

    // Keep max from the original setting
    expect(config.max).toEqual(0);

    // Don't Automatically pick the min value
    expect(config.min).toEqual(-20);
  });
});