@grafana/data#FieldType TypeScript Examples

The following examples show how to use @grafana/data#FieldType. 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 getTextAlign(field: Field): TextAlignProperty {
  if (field.config.custom) {
    const custom = field.config.custom as TableFieldOptions;

    switch (custom.align) {
      case 'right':
        return 'right';
      case 'left':
        return 'left';
      case 'center':
        return 'center';
    }
  }

  if (field.type === FieldType.number) {
    return 'right';
  }

  return 'left';
}
Example #2
Source File: utils.test.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
function getData() {
  const data = new MutableDataFrame({
    fields: [
      { name: 'Time', type: FieldType.time, values: [] },
      {
        name: 'Value',
        type: FieldType.number,
        values: [],
        config: {
          custom: {
            width: 100,
          },
        },
      },
      {
        name: 'Message',
        type: FieldType.string,
        values: [],
        config: {
          custom: {
            align: 'center',
          },
        },
      },
    ],
  });
  return data;
}
Example #3
Source File: utils.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
export function feedToDataFrame(feed: RssFeed): DataFrame {
  const date = new ArrayVector<number>([]);
  const title = new ArrayVector<string>([]);
  const link = new ArrayVector<string>([]);
  const content = new ArrayVector<string>([]);

  for (const item of feed.items) {
    const val = dateTime(item.pubDate);

    try {
      date.buffer.push(val.valueOf());
      title.buffer.push(item.title);
      link.buffer.push(item.link);

      if (item.content) {
        const body = item.content.replace(/<\/?[^>]+(>|$)/g, '');
        content.buffer.push(body);
      }
    } catch (err) {
      console.warn('Error reading news item:', err, item);
    }
  }

  return {
    fields: [
      { name: 'date', type: FieldType.time, config: { title: 'Date' }, values: date },
      { name: 'title', type: FieldType.string, config: {}, values: title },
      { name: 'link', type: FieldType.string, config: {}, values: link },
      { name: 'content', type: FieldType.string, config: {}, values: content },
    ],
    length: date.length,
  };
}
Example #4
Source File: utils.test.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
cSeries = toDataFrame({
  fields: [
    { name: 'time', type: FieldType.time, values: [100, 300] },
    {
      name: 'value',
      type: FieldType.number,
      values: [30, 30],
      config: { color: { mode: FieldColorMode.Fixed, fixedColor: 'yellow' } },
    },
  ],
})
Example #5
Source File: utils.test.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
bSeries = toDataFrame({
  fields: [
    { name: 'time', type: FieldType.time, values: [100, 200, 300] },
    {
      name: 'value',
      type: FieldType.number,
      values: [30, 60, 30],
      config: { color: { mode: FieldColorMode.Fixed, fixedColor: 'blue' } },
    },
  ],
})
Example #6
Source File: utils.test.ts    From grafana-chinese with Apache License 2.0 7 votes vote down vote up
aSeries = toDataFrame({
  fields: [
    { name: 'time', type: FieldType.time, values: [100, 200, 300] },
    {
      name: 'value',
      type: FieldType.number,
      values: [10, 20, 10],
      config: { color: { mode: FieldColorMode.Fixed, fixedColor: 'red' } },
    },
  ],
})
Example #7
Source File: live_streams.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getLegacyStream(target: LegacyTarget): Observable<DataFrame[]> {
    let stream = this.streams[target.url];

    if (stream) {
      return stream;
    }

    const data = new CircularDataFrame({ capacity: target.size });
    data.addField({ name: 'ts', type: FieldType.time, config: { title: 'Time' } });
    data.addField({ name: 'line', type: FieldType.string }).labels = parseLabels(target.query);
    data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line
    data.addField({ name: 'id', type: FieldType.string });

    stream = webSocket(target.url).pipe(
      finalize(() => {
        delete this.streams[target.url];
      }),

      map((response: LokiLegacyStreamResponse) => {
        appendLegacyResponseToBufferedData(response, data);
        return [data];
      })
    );
    this.streams[target.url] = stream;

    return stream;
  }
Example #8
Source File: live_streams.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getStream(target: LegacyTarget): Observable<DataFrame[]> {
    let stream = this.streams[target.url];

    if (stream) {
      return stream;
    }

    const data = new CircularDataFrame({ capacity: target.size });
    data.addField({ name: 'ts', type: FieldType.time, config: { title: 'Time' } });
    data.addField({ name: 'tsNs', type: FieldType.time, config: { title: 'Time ns' } });
    data.addField({ name: 'line', type: FieldType.string }).labels = parseLabels(target.query);
    data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line
    data.addField({ name: 'id', type: FieldType.string });

    stream = webSocket(target.url).pipe(
      finalize(() => {
        delete this.streams[target.url];
      }),

      map((response: LokiTailResponse) => {
        appendResponseToBufferedData(response, data);
        return [data];
      })
    );
    this.streams[target.url] = stream;

    return stream;
  }
Example #9
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs dataFrame with supplied fields and other data. Also makes sure it is properly reversed if needed.
 */
function constructDataFrame(
  times: ArrayVector<string>,
  timesNs: ArrayVector<string>,
  lines: ArrayVector<string>,
  uids: ArrayVector<string>,
  labels: Labels,
  reverse?: boolean,
  refId?: string
) {
  const dataFrame = {
    refId,
    fields: [
      { name: 'ts', type: FieldType.time, config: { title: 'Time' }, values: times }, // Time
      { name: 'line', type: FieldType.string, config: {}, values: lines, labels }, // Line
      { name: 'id', type: FieldType.string, config: {}, values: uids },
      { name: 'tsNs', type: FieldType.time, config: { title: 'Time ns' }, values: timesNs }, // Time
    ],
    length: times.length,
  };

  if (reverse) {
    const mutableDataFrame = new MutableDataFrame(dataFrame);
    mutableDataFrame.reverse();
    return mutableDataFrame;
  }

  return dataFrame;
}
Example #10
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function appendResponseToBufferedData(response: LokiTailResponse, data: MutableDataFrame) {
  // Should we do anything with: response.dropped_entries?

  const streams: LokiStreamResult[] = response.streams;
  if (!streams || !streams.length) {
    return;
  }

  let baseLabels: Labels = {};
  for (const f of data.fields) {
    if (f.type === FieldType.string) {
      if (f.labels) {
        baseLabels = f.labels;
      }
      break;
    }
  }

  for (const stream of streams) {
    // Find unique labels
    const unique = findUniqueLabels(stream.stream, baseLabels);
    const allLabelsString = Object.entries(stream.stream)
      .map(([key, val]) => `${key}="${val}"`)
      .sort()
      .join('');

    // Add each line
    for (const [ts, line] of stream.values) {
      data.values.ts.add(new Date(parseInt(ts.substr(0, ts.length - 6), 10)).toISOString());
      data.values.tsNs.add(ts);
      data.values.line.add(line);
      data.values.labels.add(unique);
      data.values.id.add(createUid(ts, allLabelsString, line));
    }
  }
}
Example #11
Source File: DebugSection.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
function makeDebugFields(derivedFields: DerivedFieldConfig[], debugText: string): DebugField[] {
  return derivedFields
    .filter(field => field.name && field.matcherRegex)
    .map(field => {
      try {
        const testMatch = debugText.match(field.matcherRegex);
        const value = testMatch && testMatch[1];
        let link;

        if (field.url && value) {
          link = getLinksFromLogsField(
            {
              name: '',
              type: FieldType.string,
              values: new ArrayVector([value]),
              config: {
                links: [{ title: '', url: field.url }],
              },
            },
            0
          )[0];
        }

        return {
          name: field.name,
          value: value || '<no match>',
          href: link && link.href,
        } as DebugField;
      } catch (error) {
        return {
          name: field.name,
          error,
        } as DebugField;
      }
    });
}
Example #12
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 #13
Source File: BarGauge.test.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
function getProps(propOverrides?: Partial<Props>): Props {
  const field: Partial<Field> = {
    type: FieldType.number,
    config: {
      min: 0,
      max: 100,
      thresholds: {
        mode: ThresholdsMode.Absolute,
        steps: [
          { value: -Infinity, color: 'green' },
          { value: 70, color: 'orange' },
          { value: 90, color: 'red' },
        ],
      },
    },
  };
  const theme = getTheme();
  field.display = getDisplayProcessor({ field, theme });

  const props: Props = {
    displayMode: BarGaugeDisplayMode.Basic,
    field: field.config!,
    display: field.display!,
    height: 300,
    width: 300,
    value: field.display(25),
    theme,
    orientation: VizOrientation.Horizontal,
  };

  Object.assign(props, propOverrides);
  return props;
}
Example #14
Source File: ResultProcessor.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function isTimeSeries(frame: DataFrame): boolean {
  if (frame.fields.length === 2) {
    if (frame.fields[1].type === FieldType.time) {
      return true;
    }
  }

  return false;
}
Example #15
Source File: elastic_response.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
createEmptyDataFrame = (
  propNames: string[],
  timeField: string,
  logMessageField?: string,
  logLevelField?: string
): MutableDataFrame => {
  const series = new MutableDataFrame({ fields: [] });

  series.addField({
    name: timeField,
    type: FieldType.time,
  });

  if (logMessageField) {
    series.addField({
      name: logMessageField,
      type: FieldType.string,
    }).parse = (v: any) => {
      return v || '';
    };
  } else {
    series.addField({
      name: '_source',
      type: FieldType.string,
    }).parse = (v: any) => {
      return JSON.stringify(v, null, 2);
    };
  }

  if (logLevelField) {
    series.addField({
      name: 'level',
      type: FieldType.string,
    }).parse = (v: any) => {
      return v || '';
    };
  }

  const fieldNames = series.fields.map(field => field.name);

  for (const propName of propNames) {
    // Do not duplicate fields. This can mean that we will shadow some fields.
    if (fieldNames.includes(propName)) {
      continue;
    }

    series.addField({
      name: propName,
      type: FieldType.string,
    }).parse = (v: any) => {
      return v || '';
    };
  }

  return series;
}
Example #16
Source File: influx_series.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
getTable() {
    const table = new TableModel();
    let i, j;

    if (this.series.length === 0) {
      return table;
    }

    _.each(this.series, (series: any, seriesIndex: number) => {
      if (seriesIndex === 0) {
        j = 0;
        // Check that the first column is indeed 'time'
        if (series.columns[0] === 'time') {
          // Push this now before the tags and with the right type
          table.columns.push({ text: 'Time', type: FieldType.time });
          j++;
        }
        _.each(_.keys(series.tags), key => {
          table.columns.push({ text: key });
        });
        for (; j < series.columns.length; j++) {
          table.columns.push({ text: series.columns[j] });
        }
      }

      if (series.values) {
        for (i = 0; i < series.values.length; i++) {
          const values = series.values[i];
          const reordered = [values[0]];
          if (series.tags) {
            for (const key in series.tags) {
              if (series.tags.hasOwnProperty(key)) {
                reordered.push(series.tags[key]);
              }
            }
          }
          for (j = 1; j < values.length; j++) {
            reordered.push(values[j]);
          }
          table.rows.push(reordered);
        }
      }
    });

    return table;
  }
Example #17
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 #18
Source File: runStreams.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export function runLogsStream(
  target: TestDataQuery,
  query: StreamingQuery,
  req: DataQueryRequest<TestDataQuery>
): Observable<DataQueryResponse> {
  return new Observable<DataQueryResponse>(subscriber => {
    const streamId = `logs-${req.panelId}-${target.refId}`;
    const maxDataPoints = req.maxDataPoints || 1000;

    const data = new CircularDataFrame({
      append: 'tail',
      capacity: maxDataPoints,
    });
    data.refId = target.refId;
    data.name = target.alias || 'Logs ' + target.refId;
    data.addField({ name: 'time', type: FieldType.time });
    data.addField({ name: 'line', type: FieldType.string });

    const { speed } = query;

    let timeoutId: any = null;

    const pushNextEvent = () => {
      data.values.time.add(Date.now());
      data.values.line.add(getRandomLine());

      subscriber.next({
        data: [data],
        key: streamId,
      });

      timeoutId = setTimeout(pushNextEvent, speed);
    };

    // Send first event in 5ms
    setTimeout(pushNextEvent, 5);

    return () => {
      console.log('unsubscribing to stream ' + streamId);
      clearTimeout(timeoutId);
    };
  });
}
Example #19
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
/**
 * Transform LokiResponse data and appends it to MutableDataFrame. Used for streaming where the dataFrame can be
 * a CircularDataFrame creating a fixed size rolling buffer.
 * TODO: Probably could be unified with the logStreamToDataFrame function.
 * @param response
 * @param data Needs to have ts, line, labels, id as fields
 */
export function appendLegacyResponseToBufferedData(response: LokiLegacyStreamResponse, data: MutableDataFrame) {
  // Should we do anything with: response.dropped_entries?

  const streams: LokiLegacyStreamResult[] = response.streams;
  if (!streams || !streams.length) {
    return;
  }

  let baseLabels: Labels = {};
  for (const f of data.fields) {
    if (f.type === FieldType.string) {
      if (f.labels) {
        baseLabels = f.labels;
      }
      break;
    }
  }

  for (const stream of streams) {
    // Find unique labels
    const labels = parseLabels(stream.labels);
    const unique = findUniqueLabels(labels, baseLabels);

    // Add each line
    for (const entry of stream.entries) {
      const ts = entry.ts || entry.timestamp;
      data.values.ts.add(ts);
      data.values.line.add(entry.line);
      data.values.labels.add(unique);
      data.values.id.add(createUid(ts, stream.labels, entry.line));
    }
  }
}
Example #20
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export function lokiResultsToTableModel(
  lokiResults: Array<LokiMatrixResult | LokiVectorResult>,
  resultCount: number,
  refId: string,
  valueWithRefId?: boolean
): TableModel {
  if (!lokiResults || lokiResults.length === 0) {
    return new TableModel();
  }

  // Collect all labels across all metrics
  const metricLabels: Set<string> = new Set<string>(
    lokiResults.reduce((acc, cur) => acc.concat(Object.keys(cur.metric)), [])
  );

  // Sort metric labels, create columns for them and record their index
  const sortedLabels = [...metricLabels.values()].sort();
  const table = new TableModel();
  table.columns = [
    { text: 'Time', type: FieldType.time },
    ...sortedLabels.map(label => ({ text: label, filterable: true })),
    { text: resultCount > 1 || valueWithRefId ? `Value #${refId}` : 'Value', type: FieldType.time },
  ];

  // Populate rows, set value to empty string when label not present.
  lokiResults.forEach(series => {
    const newSeries: LokiMatrixResult = {
      metric: series.metric,
      values: (series as LokiVectorResult).value
        ? [(series as LokiVectorResult).value]
        : (series as LokiMatrixResult).values,
    };

    if (!newSeries.values) {
      return;
    }

    if (!newSeries.metric) {
      table.rows.concat(newSeries.values.map(([a, b]) => [a * 1000, parseFloat(b)]));
    } else {
      table.rows.push(
        ...newSeries.values.map(([a, b]) => [
          a * 1000,
          ...sortedLabels.map(label => newSeries.metric[label] || ''),
          parseFloat(b),
        ])
      );
    }
  });

  return table;
}
Example #21
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
enhanceDataFrame = (dataFrame: DataFrame, config: LokiOptions | null): void => {
  if (!config) {
    return;
  }

  const derivedFields = config.derivedFields ?? [];
  if (!derivedFields.length) {
    return;
  }

  const fields = derivedFields.reduce((acc, field) => {
    const config: FieldConfig = {};
    if (field.url) {
      config.links = [
        {
          url: field.url,
          title: '',
        },
      ];
    }
    const dataFrameField = {
      name: field.name,
      type: FieldType.string,
      config,
      values: new ArrayVector<string>([]),
    };

    acc[field.name] = dataFrameField;
    return acc;
  }, {} as Record<string, any>);

  const view = new DataFrameView(dataFrame);
  view.forEachRow((row: { line: string }) => {
    for (const field of derivedFields) {
      const logMatch = row.line.match(field.matcherRegex);
      fields[field.name].values.add(logMatch && logMatch[1]);
    }
  });

  dataFrame.fields = [...dataFrame.fields, ...Object.values(fields)];
}
Example #22
Source File: result_transformer.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
transformMetricDataToTable(md: any, resultCount: number, refId: string, valueWithRefId?: boolean): TableModel {
    const table = new TableModel();
    table.refId = refId;

    let i: number, j: number;
    const metricLabels: { [key: string]: number } = {};

    if (!md || md.length === 0) {
      return table;
    }

    // Collect all labels across all metrics
    _.each(md, series => {
      for (const label in series.metric) {
        if (!metricLabels.hasOwnProperty(label)) {
          metricLabels[label] = 1;
        }
      }
    });

    // Sort metric labels, create columns for them and record their index
    const sortedLabels = _.keys(metricLabels).sort();
    table.columns.push({ text: 'Time', type: FieldType.time });
    _.each(sortedLabels, (label, labelIndex) => {
      metricLabels[label] = labelIndex + 1;
      table.columns.push({ text: label, filterable: true });
    });
    const valueText = resultCount > 1 || valueWithRefId ? `Value #${refId}` : 'Value';
    table.columns.push({ text: valueText });

    // Populate rows, set value to empty string when label not present.
    _.each(md, series => {
      if (series.value) {
        series.values = [series.value];
      }
      if (series.values) {
        for (i = 0; i < series.values.length; i++) {
          const values = series.values[i];
          const reordered: any = [values[0] * 1000];
          if (series.metric) {
            for (j = 0; j < sortedLabels.length; j++) {
              const label = sortedLabels[j];
              if (series.metric.hasOwnProperty(label)) {
                reordered.push(series.metric[label]);
              } else {
                reordered.push('');
              }
            }
          }
          reordered.push(parseFloat(values[1]));
          table.rows.push(reordered);
        }
      }
    });

    return table;
  }
Example #23
Source File: runStreams.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
export function runSignalStream(
  target: TestDataQuery,
  query: StreamingQuery,
  req: DataQueryRequest<TestDataQuery>
): Observable<DataQueryResponse> {
  return new Observable<DataQueryResponse>(subscriber => {
    const streamId = `signal-${req.panelId}-${target.refId}`;
    const maxDataPoints = req.maxDataPoints || 1000;

    const data = new CircularDataFrame({
      append: 'tail',
      capacity: maxDataPoints,
    });
    data.refId = target.refId;
    data.name = target.alias || 'Signal ' + target.refId;
    data.addField({ name: 'time', type: FieldType.time });
    data.addField({ name: 'value', type: FieldType.number });

    const { spread, speed, bands, noise } = query;

    for (let i = 0; i < bands; i++) {
      const suffix = bands > 1 ? ` ${i + 1}` : '';
      data.addField({ name: 'Min' + suffix, type: FieldType.number });
      data.addField({ name: 'Max' + suffix, type: FieldType.number });
    }

    let value = Math.random() * 100;
    let timeoutId: any = null;

    const addNextRow = (time: number) => {
      value += (Math.random() - 0.5) * spread;

      let idx = 0;
      data.fields[idx++].values.add(time);
      data.fields[idx++].values.add(value);

      let min = value;
      let max = value;

      for (let i = 0; i < bands; i++) {
        min = min - Math.random() * noise;
        max = max + Math.random() * noise;

        data.fields[idx++].values.add(min);
        data.fields[idx++].values.add(max);
      }
    };

    // Fill the buffer on init
    if (true) {
      let time = Date.now() - maxDataPoints * speed;
      for (let i = 0; i < maxDataPoints; i++) {
        addNextRow(time);
        time += speed;
      }
    }

    const pushNextEvent = () => {
      addNextRow(Date.now());
      subscriber.next({
        data: [data],
        key: streamId,
      });

      timeoutId = setTimeout(pushNextEvent, speed);
    };

    // Send first event in 5ms
    setTimeout(pushNextEvent, 5);

    return () => {
      console.log('unsubscribing to stream ' + streamId);
      clearTimeout(timeoutId);
    };
  });
}
Example #24
Source File: link_srv.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
getDataFrameVars = (dataFrames: DataFrame[]) => {
  let numeric: Field = undefined;
  let title: Field = undefined;
  const suggestions: VariableSuggestion[] = [];
  const keys: KeyValue<true> = {};

  for (const df of dataFrames) {
    for (const f of df.fields) {
      if (keys[f.name]) {
        continue;
      }

      suggestions.push({
        value: `__data.fields[${f.name}]`,
        label: `${f.name}`,
        documentation: `Formatted value for ${f.name} on the same row`,
        origin: VariableOrigin.Fields,
      });

      keys[f.name] = true;

      if (!numeric && f.type === FieldType.number) {
        numeric = f;
      }

      if (!title && f.config.title && f.config.title !== f.name) {
        title = f;
      }
    }
  }

  if (suggestions.length) {
    suggestions.push({
      value: `__data.fields[0]`,
      label: `Select by index`,
      documentation: `Enter the field order`,
      origin: VariableOrigin.Fields,
    });
  }

  if (numeric) {
    suggestions.push({
      value: `__data.fields[${numeric.name}].numeric`,
      label: `Show numeric value`,
      documentation: `the numeric field value`,
      origin: VariableOrigin.Fields,
    });
    suggestions.push({
      value: `__data.fields[${numeric.name}].text`,
      label: `Show text value`,
      documentation: `the text value`,
      origin: VariableOrigin.Fields,
    });
  }

  if (title) {
    suggestions.push({
      value: `__data.fields[${title.config.title}]`,
      label: `Select by title`,
      documentation: `Use the title to pick the field`,
      origin: VariableOrigin.Fields,
    });
  }

  return suggestions;
}
Example #25
Source File: data_processor.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
getSeriesList(options: Options): TimeSeries[] {
    const list: TimeSeries[] = [];
    const { dataList, range } = options;

    if (!dataList || !dataList.length) {
      return list;
    }

    for (let i = 0; i < dataList.length; i++) {
      const series = dataList[i];
      const { timeField } = getTimeField(series);
      if (!timeField) {
        continue;
      }

      const seriesName = series.name ? series.name : series.refId;
      for (let j = 0; j < series.fields.length; j++) {
        const field = series.fields[j];
        if (field.type !== FieldType.number) {
          continue;
        }

        let name = field.config && field.config.title ? field.config.title : field.name;

        if (seriesName && dataList.length > 0 && name !== seriesName) {
          name = seriesName + ' ' + name;
        }

        const datapoints = [];
        for (let r = 0; r < series.length; r++) {
          datapoints.push([field.values.get(r), timeField.values.get(r)]);
        }
        list.push(this.toTimeSeries(field, name, i, j, datapoints, list.length, range));
      }
    }

    // Merge all the rows if we want to show a histogram
    if (this.panel.xaxis.mode === 'histogram' && !this.panel.stack && list.length > 1) {
      const first = list[0];
      first.alias = first.aliasEscaped = 'Count';
      for (let i = 1; i < list.length; i++) {
        first.datapoints = first.datapoints.concat(list[i].datapoints);
      }
      return [first];
    }

    return list;
  }
Example #26
Source File: ResultProcessor.test.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
testContext = (options: any = {}) => {
  const timeSeries = toDataFrame({
    name: 'A-series',
    refId: 'A',
    fields: [
      { name: 'A-series', type: FieldType.number, values: [4, 5, 6] },
      { name: 'time', type: FieldType.time, values: [100, 200, 300] },
    ],
  });

  const table = toDataFrame({
    name: 'table-res',
    refId: 'A',
    fields: [
      { name: 'value', type: FieldType.number, values: [4, 5, 6] },
      { name: 'time', type: FieldType.time, values: [100, 200, 300] },
      { name: 'message', type: FieldType.string, values: ['this is a message', 'second message', 'third'] },
    ],
  });

  const emptyTable = toDataFrame({ name: 'empty-table', refId: 'A', fields: [] });

  const defaultOptions = {
    mode: ExploreMode.Metrics,
    dataFrames: [timeSeries, table, emptyTable],
    graphResult: [] as TimeSeries[],
    tableResult: new TableModel(),
    logsResult: { hasUniqueLabels: false, rows: [] as LogRowModel[] },
  };

  const combinedOptions = { ...defaultOptions, ...options };

  const state = ({
    mode: combinedOptions.mode,
    graphResult: combinedOptions.graphResult,
    tableResult: combinedOptions.tableResult,
    logsResult: combinedOptions.logsResult,
    queryIntervals: { intervalMs: 10 },
  } as any) as ExploreItemState;

  const resultProcessor = new ResultProcessor(state, combinedOptions.dataFrames, 60000, 'utc');

  return {
    dataFrames: combinedOptions.dataFrames,
    resultProcessor,
  };
}
Example #27
Source File: graph.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
onPlotClick(event: JQueryEventObject, pos: any, item: any) {
    const scrollContextElement = this.elem.closest('.view') ? this.elem.closest('.view').get()[0] : null;
    const contextMenuSourceItem = item;

    if (this.panel.xaxis.mode !== 'time') {
      // Skip if panel in histogram or series mode
      return;
    }

    if ((pos.ctrlKey || pos.metaKey) && (this.dashboard.meta.canEdit || this.dashboard.meta.canMakeEditable)) {
      // Skip if range selected (added in "plotselected" event handler)
      if (pos.x !== pos.x1) {
        return;
      }
      setTimeout(() => {
        this.eventManager.updateTime({ from: pos.x, to: null });
      }, 100);
      return;
    } else {
      this.tooltip.clear(this.plot);
      let linksSupplier: LinkModelSupplier<FieldDisplay>;

      if (item) {
        // pickup y-axis index to know which field's config to apply
        const yAxisConfig = this.panel.yaxes[item.series.yaxis.n === 2 ? 1 : 0];
        const dataFrame = this.ctrl.dataList[item.series.dataFrameIndex];
        const field = dataFrame.fields[item.series.fieldIndex];
        const dataIndex = this.getDataIndexWithNullValuesCorrection(item, dataFrame);

        let links = this.panel.options.dataLinks || [];
        if (field.config.links && field.config.links.length) {
          // Append the configured links to the panel datalinks
          links = [...links, ...field.config.links];
        }
        const fieldConfig = {
          decimals: yAxisConfig.decimals,
          links,
        };
        const fieldDisplay = getDisplayProcessor({
          field: { config: fieldConfig, type: FieldType.number },
          theme: getCurrentTheme(),
        })(field.values.get(dataIndex));
        linksSupplier = links.length
          ? getFieldLinksSupplier({
              display: fieldDisplay,
              name: field.name,
              view: new DataFrameView(dataFrame),
              rowIndex: dataIndex,
              colIndex: item.series.fieldIndex,
              field: fieldConfig,
            })
          : undefined;
      }

      this.scope.$apply(() => {
        // Setting nearest CustomScrollbar element as a scroll context for graph context menu
        this.contextMenu.setScrollContextElement(scrollContextElement);
        this.contextMenu.setSource(contextMenuSourceItem);
        this.contextMenu.setMenuItemsSupplier(this.getContextMenuItemsSupplier(pos, linksSupplier) as any);
        this.contextMenu.toggleMenu(pos);
      });
    }
  }
Example #28
Source File: Table.story.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
function buildData(theme: GrafanaTheme, overrides: ConfigOverrideRule[]): DataFrame {
  const data = new MutableDataFrame({
    fields: [
      { name: 'Time', type: FieldType.time, values: [] }, // The time field
      {
        name: 'Quantity',
        type: FieldType.number,
        values: [],
        config: {
          decimals: 0,
          custom: {
            align: 'center',
          },
        },
      },
      { name: 'Status', type: FieldType.string, values: [] }, // The time field
      {
        name: 'Value',
        type: FieldType.number,
        values: [],
        config: {
          decimals: 2,
        },
      },
      {
        name: 'Progress',
        type: FieldType.number,
        values: [],
        config: {
          unit: 'percent',
          custom: {
            width: 100,
          },
        },
      },
    ],
  });

  for (let i = 0; i < 1000; i++) {
    data.appendRow([
      new Date().getTime(),
      Math.random() * 2,
      Math.random() > 0.7 ? 'Active' : 'Cancelled',
      Math.random() * 100,
      Math.random() * 100,
    ]);
  }

  return applyFieldOverrides({
    data: [data],
    fieldOptions: {
      overrides,
      defaults: {},
    },
    theme,
    replaceVariables: (value: string) => value,
  })[0];
}
Example #29
Source File: GraphWithLegend.story.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
series: GraphSeriesXY[] = [
  {
    data: [
      [1546372800000, 10],
      [1546376400000, 20],
      [1546380000000, 10],
    ],
    color: 'red',
    isVisible: true,
    label: 'A-series',
    seriesIndex: 0,
    timeField: {
      type: FieldType.time,
      name: 'time',
      values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
      config: {},
    },
    valueField: {
      type: FieldType.number,
      name: 'a-series',
      values: new ArrayVector([10, 20, 10]),
      config: {
        color: {
          mode: FieldColorMode.Fixed,
          fixedColor: 'red',
        },
      },
    },
    timeStep: 3600000,
    yAxis: {
      index: 1,
    },
  },
  {
    data: [
      [1546372800000, 20],
      [1546376400000, 30],
      [1546380000000, 40],
    ],
    color: 'blue',
    isVisible: true,
    label: 'B-series',
    seriesIndex: 1,
    timeField: {
      type: FieldType.time,
      name: 'time',
      values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
      config: {},
    },
    valueField: {
      type: FieldType.number,
      name: 'b-series',
      values: new ArrayVector([20, 30, 40]),
      config: {
        color: {
          mode: FieldColorMode.Fixed,
          fixedColor: 'blue',
        },
      },
    },
    timeStep: 3600000,
    yAxis: {
      index: 1,
    },
  },
]