Measure plot dimensions for auto group by queries

pull/4668/head
Christopher Henn 2018-10-29 11:18:32 -07:00 committed by Chris Henn
parent fe31ff3475
commit 759758f0e2
3 changed files with 134 additions and 83 deletions

View File

@ -28,6 +28,8 @@ interface Props {
timeFormat: string
decimalPlaces: DecimalPlaces
fieldOptions: FieldOption[]
width: number
height: number
handleSetHoverTime?: (hovertime: string) => void
colors: ColorString[]
editorLocation?: QueryUpdateState
@ -75,6 +77,8 @@ class TimeMachineTables extends PureComponent<Props, State> {
public render() {
const {
width,
height,
colors,
dataType,
timeFormat,
@ -86,7 +90,10 @@ class TimeMachineTables extends PureComponent<Props, State> {
} = this.props
return (
<div className="time-machine-tables">
<div
className="time-machine-tables"
style={{width: `${width}px`, height: `${height}px`}}
>
{this.showSidebar && (
<TableSidebar
data={this.props.data}

View File

@ -2,6 +2,7 @@
import React, {Component} from 'react'
import {connect} from 'react-redux'
import _ from 'lodash'
import {AutoSizer} from 'react-virtualized'
// Components
import LineGraph from 'src/shared/components/LineGraph'
@ -54,9 +55,7 @@ import {
NoteVisibility,
} from 'src/types/dashboards'
import {GrabDataForDownloadHandler} from 'src/types/layout'
import {
TimeSeriesServerResponse,
} from 'src/types/series'
import {TimeSeriesServerResponse} from 'src/types/series'
interface TypeAndData {
dataType: DataType
@ -145,78 +144,103 @@ class RefreshingGraph extends Component<Props> {
}
return (
<AutoRefresh autoRefresh={autoRefresher} manualRefresh={manualRefresh}>
{refreshingUUID => (
<TimeSeries
uuid={refreshingUUID}
source={source}
inView={inView}
queries={this.queries}
timeRange={timeRange}
templates={templates}
fluxASTLink={fluxASTLink}
editQueryStatus={editQueryStatus}
onNotify={onNotify}
grabDataForDownload={grabDataForDownload}
grabFluxData={grabFluxData}
>
{({
timeSeriesInfluxQL,
timeSeriesFlux,
rawFluxData,
loading,
uuid,
errorMessage,
}) => {
if (!this.hasValues(timeSeriesFlux, timeSeriesInfluxQL)) {
if (errorMessage && _.get(queries, '0.text', '').trim()) {
return <InvalidData message={errorMessage} />
}
<AutoSizer>
{({width, height}) => {
if (width === 0) {
return null
}
if (cellNoteVisibility === NoteVisibility.ShowWhenNoData) {
return <MarkdownCell text={cellNote} />
}
if (
this.isFluxQuery &&
!getDeep<string>(source, 'links.flux', null)
) {
return (
<div className="graph-empty">
<p>The current source does not support Flux</p>
</div>
)
}
return (
<div className="graph-empty">
<p>No Results</p>
</div>
)
}
if (showRawFluxData) {
return <RawFluxDataTable csv={rawFluxData} />
}
switch (type) {
case CellType.SingleStat:
return this.singleStat(timeSeriesInfluxQL, timeSeriesFlux)
case CellType.Table:
return this.table(timeSeriesInfluxQL, timeSeriesFlux, uuid)
case CellType.Gauge:
return this.gauge(timeSeriesInfluxQL, timeSeriesFlux)
default:
return this.lineGraph(
return (
<AutoRefresh
autoRefresh={autoRefresher}
manualRefresh={manualRefresh}
>
{refreshingUUID => (
<TimeSeries
uuid={refreshingUUID}
source={source}
inView={inView}
queries={this.queries}
timeRange={timeRange}
xPixels={width}
templates={templates}
fluxASTLink={fluxASTLink}
editQueryStatus={editQueryStatus}
onNotify={onNotify}
grabDataForDownload={grabDataForDownload}
grabFluxData={grabFluxData}
>
{({
timeSeriesInfluxQL,
timeSeriesFlux,
loading
)
}
}}
</TimeSeries>
)}
</AutoRefresh>
rawFluxData,
loading,
uuid,
errorMessage,
}) => {
if (!this.hasValues(timeSeriesFlux, timeSeriesInfluxQL)) {
if (errorMessage && _.get(queries, '0.text', '').trim()) {
return <InvalidData message={errorMessage} />
}
if (
cellNoteVisibility === NoteVisibility.ShowWhenNoData
) {
return <MarkdownCell text={cellNote} />
}
if (
this.isFluxQuery &&
!getDeep<string>(source, 'links.flux', null)
) {
return (
<div className="graph-empty">
<p>The current source does not support Flux</p>
</div>
)
}
return (
<div className="graph-empty">
<p>No Results</p>
</div>
)
}
if (showRawFluxData) {
return <RawFluxDataTable csv={rawFluxData} />
}
switch (type) {
case CellType.SingleStat:
return this.singleStat(
timeSeriesInfluxQL,
timeSeriesFlux
)
case CellType.Table:
return this.table(
timeSeriesInfluxQL,
timeSeriesFlux,
uuid,
width,
height
)
case CellType.Gauge:
return this.gauge(timeSeriesInfluxQL, timeSeriesFlux)
default:
return this.lineGraph(
timeSeriesInfluxQL,
timeSeriesFlux,
loading
)
}
}}
</TimeSeries>
)}
</AutoRefresh>
)
}}
</AutoSizer>
)
}
@ -297,7 +321,9 @@ class RefreshingGraph extends Component<Props> {
private table = (
influxQLData: TimeSeriesServerResponse[],
fluxData: FluxTable[],
uuid: string
uuid: string,
width: number,
height: number
): JSX.Element => {
const {
colors,
@ -319,6 +345,8 @@ class RefreshingGraph extends Component<Props> {
uuid={uuid}
dataType={dataType}
colors={colors}
width={width}
height={height}
key={manualRefresh}
tableOptions={tableOptions}
fieldOptions={fieldOptions}

View File

@ -18,6 +18,7 @@ import {getDeep} from 'src/utils/wrappers'
import {restartable} from 'src/shared/utils/restartable'
import {renderTemplatesInScript} from 'src/flux/helpers/templates'
import {parseResponse} from 'src/shared/parsing/flux/response'
import DefaultDebouncer, {Debouncer} from 'src/shared/utils/debouncer'
import {DEFAULT_X_PIXELS} from 'src/shared/constants'
// Types
@ -35,6 +36,7 @@ import {TimeSeriesServerResponse} from 'src/types/series'
import {GrabDataForDownloadHandler} from 'src/types/layout'
export const DEFAULT_TIME_SERIES = [{response: {results: []}}]
const EXECUTE_QUERIES_DEBOUNCE_MS = 400
interface RenderProps {
timeSeriesInfluxQL: TimeSeriesServerResponse[]
@ -50,6 +52,7 @@ interface Props {
uuid: string
queries: Query[]
timeRange: TimeRange
xPixels?: number
children: (r: RenderProps) => JSX.Element
inView?: boolean
templates?: Template[]
@ -71,8 +74,6 @@ interface State {
errorMessage: string
}
const TEMP_RES = DEFAULT_X_PIXELS // FIXME
const GraphLoadingDots = () => (
<div className="graph-panel__refreshing">
<div />
@ -85,6 +86,7 @@ class TimeSeries extends PureComponent<Props, State> {
public static defaultProps = {
inView: true,
templates: [],
xPixels: DEFAULT_X_PIXELS,
editQueryStatus: () => ({
type: 'NOOP',
payload: {},
@ -109,6 +111,7 @@ class TimeSeries extends PureComponent<Props, State> {
private executeFluxQuery = restartable(executeFluxQuery)
private executeInfluxQLQueries = restartable(executeInfluxQLQueries)
private debouncer: Debouncer = new DefaultDebouncer()
constructor(props: Props) {
super(props)
@ -125,10 +128,14 @@ class TimeSeries extends PureComponent<Props, State> {
}
}
public async componentDidMount() {
public componentDidMount() {
this.executeQueries()
}
public componentWillUnmount() {
this.debouncer.cancelAll()
}
public async componentDidUpdate(prevProps: Props) {
const prevQueries = _.map(prevProps.queries, q => q.text)
const currQueries = _.map(this.props.queries, q => q.text)
@ -137,9 +144,10 @@ class TimeSeries extends PureComponent<Props, State> {
if (
this.props.uuid !== prevProps.uuid ||
queriesDifferent ||
this.state.isFirstFetch
this.state.isFirstFetch ||
this.props.xPixels !== prevProps.xPixels
) {
this.executeQueries()
this.debouncer.call(this.executeQueries, EXECUTE_QUERIES_DEBOUNCE_MS)
}
}
@ -267,14 +275,22 @@ class TimeSeries extends PureComponent<Props, State> {
}
private executeTemplatedFluxQuery = async (latestUUID: string) => {
const {queries, onNotify, source, timeRange, fluxASTLink} = this.props
const {
queries,
onNotify,
source,
timeRange,
fluxASTLink,
xPixels,
} = this.props
const script: string = _.get(queries, '0.text', '')
const renderedScript = await renderTemplatesInScript(
script,
timeRange,
fluxASTLink,
TEMP_RES
xPixels
)
const results = await this.executeFluxQuery(
@ -293,7 +309,7 @@ class TimeSeries extends PureComponent<Props, State> {
private executeInfluxQLWithStatus = async (
latestUUID: string
): Promise<TimeSeriesServerResponse[]> => {
const {source, templates, editQueryStatus, queries} = this.props
const {source, templates, editQueryStatus, queries, xPixels} = this.props
for (const query of queries) {
editQueryStatus(query.id, {loading: true})
@ -303,7 +319,7 @@ class TimeSeries extends PureComponent<Props, State> {
source,
queries,
templates,
TEMP_RES,
xPixels,
latestUUID
)