import React from 'react'; import { hot } from 'react-hot-loader'; import colors from 'app/core/utils/colors'; import TimeSeries from 'app/core/time_series2'; import ElapsedTime from './ElapsedTime'; import Legend from './Legend'; import QueryRows from './QueryRows'; import Graph from './Graph'; import Table from './Table'; import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { buildQueryOptions, ensureQueries, generateQueryKey, hasQuery } from './utils/query'; function makeTimeSeriesList(dataList, options) { return dataList.map((seriesData, index) => { const datapoints = seriesData.datapoints || []; const alias = seriesData.target; const colorIndex = index % colors.length; const color = colors[colorIndex]; const series = new TimeSeries({ datapoints: datapoints, alias: alias, color: color, unit: seriesData.unit, }); if (datapoints && datapoints.length > 0) { const last = datapoints[datapoints.length - 1][1]; const from = options.range.from; if (last - from < -10000) { series.isOutsideRange = true; } } return series; }); } interface IExploreState { datasource: any; datasourceError: any; datasourceLoading: any; graphResult: any; latency: number; loading: any; queries: any; requestOptions: any; showingGraph: boolean; showingTable: boolean; tableResult: any; } // @observer export class Explore extends React.Component { datasourceSrv: DatasourceSrv; constructor(props) { super(props); this.state = { datasource: null, datasourceError: null, datasourceLoading: true, graphResult: null, latency: 0, loading: false, queries: ensureQueries(), requestOptions: null, showingGraph: true, showingTable: true, tableResult: null, }; } async componentDidMount() { const datasource = await this.props.datasourceSrv.get(); const testResult = await datasource.testDatasource(); if (testResult.status === 'success') { this.setState({ datasource, datasourceError: null, datasourceLoading: false }); } else { this.setState({ datasource: null, datasourceError: testResult.message, datasourceLoading: false }); } } handleAddQueryRow = index => { const { queries } = this.state; const nextQueries = [ ...queries.slice(0, index + 1), { query: '', key: generateQueryKey() }, ...queries.slice(index + 1), ]; this.setState({ queries: nextQueries }); }; handleChangeQuery = (query, index) => { const { queries } = this.state; const nextQuery = { ...queries[index], query, }; const nextQueries = [...queries]; nextQueries[index] = nextQuery; this.setState({ queries: nextQueries }); }; handleClickGraphButton = () => { this.setState(state => ({ showingGraph: !state.showingGraph })); }; handleClickTableButton = () => { this.setState(state => ({ showingTable: !state.showingTable })); }; handleRemoveQueryRow = index => { const { queries } = this.state; if (queries.length <= 1) { return; } const nextQueries = [...queries.slice(0, index), ...queries.slice(index + 1)]; this.setState({ queries: nextQueries }, () => this.handleSubmit()); }; handleSubmit = () => { const { showingGraph, showingTable } = this.state; if (showingTable) { this.runTableQuery(); } if (showingGraph) { this.runGraphQuery(); } }; async runGraphQuery() { const { datasource, queries } = this.state; if (!hasQuery(queries)) { return; } this.setState({ latency: 0, loading: true, graphResult: null }); const now = Date.now(); const options = buildQueryOptions({ format: 'time_series', interval: datasource.interval, instant: false, now, queries: queries.map(q => q.query), }); try { const res = await datasource.query(options); const result = makeTimeSeriesList(res.data, options); const latency = Date.now() - now; this.setState({ latency, loading: false, graphResult: result, requestOptions: options }); } catch (error) { console.error(error); this.setState({ loading: false, graphResult: error }); } } async runTableQuery() { const { datasource, queries } = this.state; if (!hasQuery(queries)) { return; } this.setState({ latency: 0, loading: true, tableResult: null }); const now = Date.now(); const options = buildQueryOptions({ format: 'table', interval: datasource.interval, instant: true, now, queries: queries.map(q => q.query), }); try { const res = await datasource.query(options); const tableModel = res.data[0]; const latency = Date.now() - now; this.setState({ latency, loading: false, tableResult: tableModel, requestOptions: options }); } catch (error) { console.error(error); this.setState({ loading: false, tableResult: null }); } } request = url => { const { datasource } = this.state; return datasource.metadataRequest(url); }; render() { const { datasource, datasourceError, datasourceLoading, graphResult, latency, loading, queries, requestOptions, showingGraph, showingTable, tableResult, } = this.state; const showingBoth = showingGraph && showingTable; const graphHeight = showingBoth ? '200px' : null; const graphButtonClassName = showingBoth || showingGraph ? 'btn m-r-1' : 'btn btn-inverse m-r-1'; const tableButtonClassName = showingBoth || showingTable ? 'btn m-r-1' : 'btn btn-inverse m-r-1'; return (

Explore

{datasourceLoading ?
Loading datasource...
: null} {datasourceError ?
Error connecting to datasource.
: null} {datasource ? (
{loading || latency ? : null}
{showingGraph ? ( ) : null} {showingGraph ? : null} {showingTable ? : null} ) : null} ); } } export default hot(module)(Explore);