diff --git a/packages/grafana-ui/src/types/data.ts b/packages/grafana-ui/src/types/data.ts index ab177eb8888..69d5261ba3c 100644 --- a/packages/grafana-ui/src/types/data.ts +++ b/packages/grafana-ui/src/types/data.ts @@ -50,14 +50,29 @@ export enum NullValueMode { /** View model projection of many time series */ export type TimeSeriesVMs = TimeSeriesVM[]; +export enum ColumnType { + time = 'time', // or date + number = 'number', + string = 'string', + boolean = 'boolean', + other = 'other', // Object, Array, etc +} + export interface Column { text: string; // The column name - type?: 'time' | 'number' | 'string' | 'object'; // not used anywhere? can we remove? - filterable?: boolean; // currently only set by elasticsearch, and used in the table panel + type?: ColumnType; + filterable?: boolean; unit?: string; + dateFormat?: string; // Source data format +} + +export interface Tags { + [key: string]: string; } export interface TableData { + name?: string; columns: Column[]; - rows: any[]; + rows: any[][]; + tags?: Tags; } diff --git a/packages/grafana-ui/src/utils/processTableData.ts b/packages/grafana-ui/src/utils/processTableData.ts index 013c714d62d..dc1582e1f39 100644 --- a/packages/grafana-ui/src/utils/processTableData.ts +++ b/packages/grafana-ui/src/utils/processTableData.ts @@ -1,10 +1,11 @@ // Libraries import isNumber from 'lodash/isNumber'; +import isString from 'lodash/isString'; + import Papa, { ParseError, ParseMeta } from 'papaparse'; // Types -import { TableData, Column, TimeSeries } from '../types'; -import { isString } from 'util'; +import { TableData, Column, TimeSeries, ColumnType } from '../types'; // Subset of all parse options export interface TableParseOptions { @@ -132,6 +133,7 @@ export function parseCSV(text: string, options?: TableParseOptions, details?: Ta function convertTimeSeriesToTableData(timeSeries: TimeSeries): TableData { return { + name: timeSeries.target, columns: [ { text: timeSeries.target || 'Value', @@ -139,7 +141,7 @@ function convertTimeSeriesToTableData(timeSeries: TimeSeries): TableData { }, { text: 'Time', - type: 'time', + type: ColumnType.time, unit: 'dateTimeAsIso', }, ], @@ -161,8 +163,8 @@ export const guessColumnTypes = (table: TableData): TableData => { changed = true; return { ...column, - type: 'time', - } as Column; + type: ColumnType.time, + }; } } @@ -170,18 +172,18 @@ export const guessColumnTypes = (table: TableData): TableData => { for (let i = 0; i < table.rows.length; i++) { const v = table.rows[i][index]; if (v !== null) { - let type; + let type: ColumnType | undefined; if (isNumber(v)) { - type = 'number'; + type = ColumnType.number; } else if (isString(v)) { - type = 'string'; + type = ColumnType.string; } if (type) { changed = true; return { ...column, type, - } as Column; + }; } break; } diff --git a/public/app/plugins/datasource/graphite/func_editor.ts b/public/app/plugins/datasource/graphite/func_editor.ts index f2522f2ab18..25c007fcb19 100644 --- a/public/app/plugins/datasource/graphite/func_editor.ts +++ b/public/app/plugins/datasource/graphite/func_editor.ts @@ -183,8 +183,9 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) { } let paramValue = templateSrv.highlightVariablesAsHtml(func.params[index]); + const hasValue = paramValue !== null && paramValue !== undefined; - const last = index >= func.params.length - 1 && param.optional && !paramValue; + const last = index >= func.params.length - 1 && param.optional && !hasValue; if (last && param.multiple) { paramValue = '+'; } @@ -197,7 +198,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) { '' + - (paramValue || ' ') + + (hasValue ? paramValue : ' ') + '' ); const $input = $(paramTemplate); diff --git a/public/app/plugins/datasource/influxdb/influx_series.ts b/public/app/plugins/datasource/influxdb/influx_series.ts index 10c1584f488..fedeffca942 100644 --- a/public/app/plugins/datasource/influxdb/influx_series.ts +++ b/public/app/plugins/datasource/influxdb/influx_series.ts @@ -1,5 +1,6 @@ import _ from 'lodash'; import TableModel from 'app/core/table_model'; +import { ColumnType } from '@grafana/ui'; export default class InfluxSeries { series: any; @@ -156,7 +157,7 @@ export default class InfluxSeries { // 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: 'time' }); + table.columns.push({ text: 'Time', type: ColumnType.time }); j++; } _.each(_.keys(series.tags), key => { diff --git a/public/app/plugins/datasource/prometheus/result_transformer.ts b/public/app/plugins/datasource/prometheus/result_transformer.ts index b0fab2564eb..5815d10adcf 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; import TableModel from 'app/core/table_model'; -import { TimeSeries } from '@grafana/ui'; +import { TimeSeries, ColumnType } from '@grafana/ui'; export class ResultTransformer { constructor(private templateSrv) {} @@ -98,7 +98,7 @@ export class ResultTransformer { // Sort metric labels, create columns for them and record their index const sortedLabels = _.keys(metricLabels).sort(); - table.columns.push({ text: 'Time', type: 'time' }); + table.columns.push({ text: 'Time', type: ColumnType.time }); _.each(sortedLabels, (label, labelIndex) => { metricLabels[label] = labelIndex + 1; table.columns.push({ text: label, filterable: true }); diff --git a/public/app/plugins/panel/singlestat2/SingleStatPanel.tsx b/public/app/plugins/panel/singlestat2/SingleStatPanel.tsx index eb121f9e44a..2c151b09525 100644 --- a/public/app/plugins/panel/singlestat2/SingleStatPanel.tsx +++ b/public/app/plugins/panel/singlestat2/SingleStatPanel.tsx @@ -4,7 +4,7 @@ import React, { PureComponent, CSSProperties } from 'react'; // Types import { SingleStatOptions, SingleStatBaseOptions } from './types'; -import { DisplayValue, PanelProps, processTimeSeries, NullValueMode, guessColumnTypes } from '@grafana/ui'; +import { DisplayValue, PanelProps, processTimeSeries, NullValueMode, guessColumnTypes, ColumnType } from '@grafana/ui'; import { config } from 'app/core/config'; import { getDisplayProcessor } from '@grafana/ui'; import { ProcessedValuesRepeater } from './ProcessedValuesRepeater'; @@ -25,13 +25,13 @@ export const getSingleStatValues = (props: PanelProps): D }); const values: DisplayValue[] = []; - data.forEach(t => { - const table = guessColumnTypes(t); + for (let t = 0; t < data.length; t++) { + const table = guessColumnTypes(data[t]); for (let i = 0; i < table.columns.length; i++) { const column = table.columns[i]; // Show all columns that are not 'time' - if (column.type === 'number') { + if (column.type === ColumnType.number) { const series = processTimeSeries({ data: [table], xColumn: i, @@ -43,7 +43,7 @@ export const getSingleStatValues = (props: PanelProps): D values.push(processor(value)); } } - }); + } if (values.length === 0) { throw { message: 'Could not find numeric data' };