Преглед изворни кода

incorporate torkels feedback

ryan пре 6 година
родитељ
комит
0cfa929d4c

+ 18 - 3
packages/grafana-ui/src/types/data.ts

@@ -50,14 +50,29 @@ export enum NullValueMode {
 /** View model projection of many time series */
 /** View model projection of many time series */
 export type TimeSeriesVMs = TimeSeriesVM[];
 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 {
 export interface Column {
   text: string; // The column name
   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;
   unit?: string;
+  dateFormat?: string; // Source data format
+}
+
+export interface Tags {
+  [key: string]: string;
 }
 }
 
 
 export interface TableData {
 export interface TableData {
+  name?: string;
   columns: Column[];
   columns: Column[];
-  rows: any[];
+  rows: any[][];
+  tags?: Tags;
 }
 }

+ 11 - 9
packages/grafana-ui/src/utils/processTableData.ts

@@ -1,10 +1,11 @@
 // Libraries
 // Libraries
 import isNumber from 'lodash/isNumber';
 import isNumber from 'lodash/isNumber';
+import isString from 'lodash/isString';
+
 import Papa, { ParseError, ParseMeta } from 'papaparse';
 import Papa, { ParseError, ParseMeta } from 'papaparse';
 
 
 // Types
 // Types
-import { TableData, Column, TimeSeries } from '../types';
-import { isString } from 'util';
+import { TableData, Column, TimeSeries, ColumnType } from '../types';
 
 
 // Subset of all parse options
 // Subset of all parse options
 export interface TableParseOptions {
 export interface TableParseOptions {
@@ -132,6 +133,7 @@ export function parseCSV(text: string, options?: TableParseOptions, details?: Ta
 
 
 function convertTimeSeriesToTableData(timeSeries: TimeSeries): TableData {
 function convertTimeSeriesToTableData(timeSeries: TimeSeries): TableData {
   return {
   return {
+    name: timeSeries.target,
     columns: [
     columns: [
       {
       {
         text: timeSeries.target || 'Value',
         text: timeSeries.target || 'Value',
@@ -139,7 +141,7 @@ function convertTimeSeriesToTableData(timeSeries: TimeSeries): TableData {
       },
       },
       {
       {
         text: 'Time',
         text: 'Time',
-        type: 'time',
+        type: ColumnType.time,
         unit: 'dateTimeAsIso',
         unit: 'dateTimeAsIso',
       },
       },
     ],
     ],
@@ -161,8 +163,8 @@ export const guessColumnTypes = (table: TableData): TableData => {
           changed = true;
           changed = true;
           return {
           return {
             ...column,
             ...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++) {
       for (let i = 0; i < table.rows.length; i++) {
         const v = table.rows[i][index];
         const v = table.rows[i][index];
         if (v !== null) {
         if (v !== null) {
-          let type;
+          let type: ColumnType | undefined;
           if (isNumber(v)) {
           if (isNumber(v)) {
-            type = 'number';
+            type = ColumnType.number;
           } else if (isString(v)) {
           } else if (isString(v)) {
-            type = 'string';
+            type = ColumnType.string;
           }
           }
           if (type) {
           if (type) {
             changed = true;
             changed = true;
             return {
             return {
               ...column,
               ...column,
               type,
               type,
-            } as Column;
+            };
           }
           }
           break;
           break;
         }
         }

+ 3 - 2
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]);
           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) {
           if (last && param.multiple) {
             paramValue = '+';
             paramValue = '+';
           }
           }
@@ -197,7 +198,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
             '<a ng-click="" class="graphite-func-param-link' +
             '<a ng-click="" class="graphite-func-param-link' +
               (last ? ' query-part__last' : '') +
               (last ? ' query-part__last' : '') +
               '">' +
               '">' +
-              (paramValue || '&nbsp;') +
+              (hasValue ? paramValue : '&nbsp;') +
               '</a>'
               '</a>'
           );
           );
           const $input = $(paramTemplate);
           const $input = $(paramTemplate);

+ 2 - 1
public/app/plugins/datasource/influxdb/influx_series.ts

@@ -1,5 +1,6 @@
 import _ from 'lodash';
 import _ from 'lodash';
 import TableModel from 'app/core/table_model';
 import TableModel from 'app/core/table_model';
+import { ColumnType } from '@grafana/ui';
 
 
 export default class InfluxSeries {
 export default class InfluxSeries {
   series: any;
   series: any;
@@ -156,7 +157,7 @@ export default class InfluxSeries {
         // Check that the first column is indeed 'time'
         // Check that the first column is indeed 'time'
         if (series.columns[0] === 'time') {
         if (series.columns[0] === 'time') {
           // Push this now before the tags and with the right type
           // 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++;
           j++;
         }
         }
         _.each(_.keys(series.tags), key => {
         _.each(_.keys(series.tags), key => {

+ 2 - 2
public/app/plugins/datasource/prometheus/result_transformer.ts

@@ -1,6 +1,6 @@
 import _ from 'lodash';
 import _ from 'lodash';
 import TableModel from 'app/core/table_model';
 import TableModel from 'app/core/table_model';
-import { TimeSeries } from '@grafana/ui';
+import { TimeSeries, ColumnType } from '@grafana/ui';
 
 
 export class ResultTransformer {
 export class ResultTransformer {
   constructor(private templateSrv) {}
   constructor(private templateSrv) {}
@@ -98,7 +98,7 @@ export class ResultTransformer {
 
 
     // Sort metric labels, create columns for them and record their index
     // Sort metric labels, create columns for them and record their index
     const sortedLabels = _.keys(metricLabels).sort();
     const sortedLabels = _.keys(metricLabels).sort();
-    table.columns.push({ text: 'Time', type: 'time' });
+    table.columns.push({ text: 'Time', type: ColumnType.time });
     _.each(sortedLabels, (label, labelIndex) => {
     _.each(sortedLabels, (label, labelIndex) => {
       metricLabels[label] = labelIndex + 1;
       metricLabels[label] = labelIndex + 1;
       table.columns.push({ text: label, filterable: true });
       table.columns.push({ text: label, filterable: true });

+ 5 - 5
public/app/plugins/panel/singlestat2/SingleStatPanel.tsx

@@ -4,7 +4,7 @@ import React, { PureComponent, CSSProperties } from 'react';
 // Types
 // Types
 import { SingleStatOptions, SingleStatBaseOptions } from './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 { config } from 'app/core/config';
 import { getDisplayProcessor } from '@grafana/ui';
 import { getDisplayProcessor } from '@grafana/ui';
 import { ProcessedValuesRepeater } from './ProcessedValuesRepeater';
 import { ProcessedValuesRepeater } from './ProcessedValuesRepeater';
@@ -25,13 +25,13 @@ export const getSingleStatValues = (props: PanelProps<SingleStatBaseOptions>): D
   });
   });
 
 
   const values: DisplayValue[] = [];
   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++) {
     for (let i = 0; i < table.columns.length; i++) {
       const column = table.columns[i];
       const column = table.columns[i];
 
 
       // Show all columns that are not 'time'
       // Show all columns that are not 'time'
-      if (column.type === 'number') {
+      if (column.type === ColumnType.number) {
         const series = processTimeSeries({
         const series = processTimeSeries({
           data: [table],
           data: [table],
           xColumn: i,
           xColumn: i,
@@ -43,7 +43,7 @@ export const getSingleStatValues = (props: PanelProps<SingleStatBaseOptions>): D
         values.push(processor(value));
         values.push(processor(value));
       }
       }
     }
     }
-  });
+  }
 
 
   if (values.length === 0) {
   if (values.length === 0) {
     throw { message: 'Could not find numeric data' };
     throw { message: 'Could not find numeric data' };