import React, { FC, ReactNode } from 'react'; import { Alert, Button, ButtonGroup, Table } from 'reactstrap'; import SeriesName from './SeriesName'; import { Metric, Histogram } from '../../types/types'; import moment from 'moment'; import HistogramChart from './HistogramChart'; 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 }) => { const [scale, setScale] = React.useState<'linear' | 'exponential'>('exponential'); 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]} {s.histogram && ( <>
Total count: {s.histogram[1].count} Sum: {s.histogram[1].sum}
x-axis scale:
{histogramTable(s.histogram[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 ( {histogramTable(h[1])} @{{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}
); }; const leftDelim = (br: number): string => (br === 3 || br === 1 ? '[' : '('); const rightDelim = (br: number): string => (br === 3 || br === 0 ? ']' : ')'); export const bucketRangeString = ([boundaryRule, leftBoundary, rightBoundary, _]: [ number, string, string, string ]): string => { return `${leftDelim(boundaryRule)}${leftBoundary} -> ${rightBoundary}${rightDelim(boundaryRule)}`; }; export const histogramTable = (h: Histogram): ReactNode => ( {h.buckets?.map((b, i) => ( ))}
Histogram Sample
Range Count
{bucketRangeString(b)} {b[3]}
); export default DataTable;