import React, { FC, ReactNode } from 'react'; import { Alert, Table } from 'reactstrap'; import SeriesName from './SeriesName'; import { Metric, Histogram } from '../../types/types'; import moment from 'moment'; export interface DataTableProps { data: | null | { resultType: 'vector'; result: InstantSample[]; } | { resultType: 'matrix'; result: RangeSamples[]; } | { resultType: 'scalar'; result: SampleValue; } | { resultType: 'string'; result: SampleValue; }; useLocalTime: boolean; } interface InstantSample { metric: Metric; value?: SampleValue; histogram?: SampleHistogram; } interface RangeSamples { metric: Metric; values?: SampleValue[]; histograms?: SampleHistogram[]; } type SampleValue = [number, string]; type SampleHistogram = [number, Histogram]; const limitSeries = (series: S[]): S[] => { const maxSeries = 10000; if (series.length > maxSeries) { return series.slice(0, maxSeries); } return series; }; const DataTable: FC = ({ data, useLocalTime }) => { if (data === null) { return No data queried yet; } if (data.result === null || data.result.length === 0) { return Empty query result; } const maxFormattableSize = 1000; let rows: ReactNode[] = []; let limited = false; const doFormat = data.result.length <= maxFormattableSize; switch (data.resultType) { case 'vector': rows = (limitSeries(data.result) as InstantSample[]).map((s: InstantSample, index: number): ReactNode => { return ( {s.value && s.value[1]} ); }); limited = rows.length !== data.result.length; break; case 'matrix': rows = (limitSeries(data.result) as RangeSamples[]).map((s, seriesIdx) => { const valuesAndTimes = s.values ? s.values.map((v, valIdx) => { const printedDatetime = moment.unix(v[0]).toISOString(useLocalTime); return ( {v[1]} @{{v[0]}}
); }) : []; const histogramsAndTimes = s.histograms ? s.histograms.map((h, hisIdx) => { const printedDatetime = moment.unix(h[0]).toISOString(useLocalTime); return ( @{{h[0]}}
); }) : []; return ( {valuesAndTimes} {histogramsAndTimes} ); }); limited = rows.length !== data.result.length; break; case 'scalar': rows.push( scalar {data.result[1]} ); break; case 'string': rows.push( string {data.result[1]} ); break; default: return Unsupported result value type; } return ( <> {limited && ( Warning: Fetched {data.result.length} metrics, only displaying first {rows.length}. )} {!doFormat && ( Notice: Showing more than {maxFormattableSize} series, turning off label formatting for performance reasons. )} {rows}
); }; export interface HistogramStringProps { h?: Histogram; } export const HistogramString: FC = ({ h }) => { if (!h) { return <>; } const buckets: string[] = []; if (h.buckets) { for (const bucket of h.buckets) { const left = bucket[0] === 3 || bucket[0] === 1 ? '[' : '('; const right = bucket[0] === 3 || bucket[0] === 0 ? ']' : ')'; buckets.push(left + bucket[1] + ',' + bucket[2] + right + ':' + bucket[3] + ' '); } } return ( <> {'{'} count:{h.count} sum:{h.sum} {buckets} {'}'} ); }; export default DataTable;