Merge pull request #4537 from influxdata/flux/time-range-update

Flux/time range update
pull/4549/head
Iris Scholten 2018-10-04 14:27:57 -07:00 committed by GitHub
commit f25d200b0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 138 additions and 48 deletions

View File

@ -18,13 +18,12 @@ import {TimeMachineContainer} from 'src/shared/utils/TimeMachineContainer'
// Constants
import {HANDLE_VERTICAL} from 'src/shared/constants'
import {QueryUpdateState} from 'src/shared/actions/queries'
import {DEFAULT_AXES} from 'src/dashboards/constants/cellEditor'
// Types
import {buildDefaultYLabel} from 'src/shared/presenters'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {Axes, QueryConfig, CellType} from 'src/types'
import {Axes, QueryConfig, CellType, QueryUpdateState} from 'src/types'
import {
FieldOption,
DecimalPlaces,

View File

@ -12,10 +12,10 @@ import TableGraph from 'src/shared/components/TableGraph'
import {getDeep} from 'src/utils/wrappers'
// Types
import {QueryUpdateState} from 'src/shared/actions/queries'
import {ColorString} from 'src/types/colors'
import {TableOptions, FieldOption, DecimalPlaces} from 'src/types/dashboards'
import {DataType} from 'src/shared/constants'
import {QueryUpdateState} from 'src/types'
interface Props {
data: FluxTable[]

View File

@ -1,4 +0,0 @@
export enum QueryUpdateState {
CEO = 'cellEditorOverlay',
DE = 'dataExplorer',
}

View File

@ -1,8 +1,9 @@
// Libraries
import React, {Component} from 'react'
import _ from 'lodash'
// Constants
import {GAUGE_SPECS} from 'src/shared/constants/gaugeSpecs'
import {
COLOR_TYPE_MIN,
COLOR_TYPE_MAX,
@ -10,8 +11,10 @@ import {
} from 'src/shared/constants/thresholds'
import {MAX_TOLOCALESTRING_VAL} from 'src/dashboards/constants'
// Utils
import {ErrorHandling} from 'src/shared/decorators/errors'
// Types
import {ColorString} from 'src/types/colors'
import {DecimalPlaces} from 'src/types/dashboards'

View File

@ -1,21 +1,28 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
import {manager} from 'src/worker/JobManager'
import getLastValues from 'src/shared/parsing/lastValues'
// Components
import Gauge from 'src/shared/components/Gauge'
import InvalidData from 'src/shared/components/InvalidData'
// Utils
import {manager} from 'src/worker/JobManager'
import {getDataUUID, hasDataChanged} from 'src/shared/graphs/helpers'
import getLastValues from 'src/shared/parsing/lastValues'
import {ErrorHandling} from 'src/shared/decorators/errors'
// Constants
import {DEFAULT_GAUGE_COLORS} from 'src/shared/constants/thresholds'
import {stringifyColorValues} from 'src/shared/constants/colorOperations'
import {DASHBOARD_LAYOUT_ROW_HEIGHT} from 'src/shared/constants'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {DataType} from 'src/shared/constants'
// Types
import {DecimalPlaces} from 'src/types/dashboards'
import {ColorString} from 'src/types/colors'
import {TimeSeriesServerResponse} from 'src/types/series'
import {FluxTable} from 'src/types/flux'
import {DataType} from 'src/shared/constants'
interface Props {
data: TimeSeriesServerResponse[] | FluxTable[]
@ -44,6 +51,7 @@ class GaugeChart extends PureComponent<Props, State> {
}
private isComponentMounted: boolean
private lastUUID: string
constructor(props: Props) {
super(props)
@ -53,13 +61,15 @@ class GaugeChart extends PureComponent<Props, State> {
public async componentDidMount() {
this.isComponentMounted = true
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
await this.dataToLastValues()
}
public async componentDidUpdate(prevProps: Props) {
const isDataChanged =
prevProps.dataType !== this.props.dataType ||
!_.isEqual(prevProps.data, this.props.data)
const isDataChanged = hasDataChanged(prevProps, this.props)
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
if (isDataChanged) {
await this.dataToLastValues()
@ -134,7 +144,10 @@ class GaugeChart extends PureComponent<Props, State> {
lastValues = getLastValues(data as TimeSeriesServerResponse[])
}
if (!this.isComponentMounted) {
if (
!this.isComponentMounted ||
this.lastUUID !== getDataUUID(data, dataType)
) {
return
}
} catch (err) {

View File

@ -16,6 +16,7 @@ import {
} from 'src/utils/timeSeriesTransformers'
import {manager} from 'src/worker/JobManager'
import {fluxTablesToDygraph} from 'src/shared/parsing/flux/dygraph'
import {getDataUUID, hasDataChanged} from 'src/shared/graphs/helpers'
// Types
import {ColorString} from 'src/types/colors'
@ -60,6 +61,7 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
public static defaultProps: Partial<LineGraphProps> = {
staticLegend: false,
}
private latestUUID: string
private isComponentMounted: boolean = false
private isValidData: boolean = true
@ -85,12 +87,16 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
dataType: DataType
) {
let timeSeries
this.latestUUID = getDataUUID(data, dataType)
try {
timeSeries = await this.convertToDygraphData(data, dataType)
const {result, uuid} = await this.convertToDygraphData(data, dataType)
if (!this.isComponentMounted) {
timeSeries = result
if (!this.isComponentMounted || uuid !== this.latestUUID) {
return
}
this.isValidData = await manager.validateDygraphData(
timeSeries.timeSeries
)
@ -102,12 +108,7 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
}
public componentDidUpdate(prevProps: LineGraphProps) {
const isInfluxQLDataChanged =
_.get(prevProps, 'data.0.response.uuid') !==
_.get(this.props, 'data.0.response.uuid')
const isFluxDataChanged =
_.get(prevProps, 'data.0.id') !== _.get(this.props, 'data.0.id')
const isDataChanged = isInfluxQLDataChanged || isFluxDataChanged
const isDataChanged = hasDataChanged(prevProps, this.props)
if (this.props.loading === RemoteDataState.Done && isDataChanged) {
this.parseTimeSeries(this.props.data, this.props.dataType)
@ -239,19 +240,22 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
private async convertToDygraphData(
data: TimeSeriesServerResponse[] | FluxTable[],
dataType: DataType
): Promise<TimeSeriesToDyGraphReturnType> {
): Promise<{result: TimeSeriesToDyGraphReturnType; uuid: string}> {
const {location} = this.props
let result: TimeSeriesToDyGraphReturnType
if (dataType === DataType.influxQL) {
return await timeSeriesToDygraph(
result = await timeSeriesToDygraph(
data as TimeSeriesServerResponse[],
location.pathname
)
}
if (dataType === DataType.flux) {
return await fluxTablesToDygraph(data as FluxTable[])
result = await fluxTablesToDygraph(data as FluxTable[])
}
return {result, uuid: getDataUUID(data, dataType)}
}
}

View File

@ -29,7 +29,6 @@ import {setHoverTime} from 'src/dashboards/actions'
import {notify} from 'src/shared/actions/notifications'
// Types
import {QueryUpdateState} from 'src/shared/actions/queries'
import {ColorString} from 'src/types/colors'
import {
Source,
@ -40,6 +39,7 @@ import {
CellType,
FluxTable,
RemoteDataState,
QueryUpdateState,
} from 'src/types'
import {
TableOptions,

View File

@ -1,20 +1,31 @@
// Libraries
import React, {PureComponent, CSSProperties} from 'react'
import classnames from 'classnames'
import getLastValues from 'src/shared/parsing/lastValues'
import _ from 'lodash'
import {manager} from 'src/worker/JobManager'
// Components
import InvalidData from 'src/shared/components/InvalidData'
import {SMALL_CELL_HEIGHT} from 'src/shared/graphs/helpers'
// Utils
import {manager} from 'src/worker/JobManager'
import {
SMALL_CELL_HEIGHT,
getDataUUID,
hasDataChanged,
} from 'src/shared/graphs/helpers'
import getLastValues from 'src/shared/parsing/lastValues'
import {ErrorHandling} from 'src/shared/decorators/errors'
// Constants
import {DYGRAPH_CONTAINER_V_MARGIN} from 'src/shared/constants'
import {generateThresholdsListHexs} from 'src/shared/constants/colorOperations'
import {DataType} from 'src/shared/constants'
// types
import {ColorString} from 'src/types/colors'
import {CellType, DecimalPlaces} from 'src/types/dashboards'
import {TimeSeriesServerResponse} from 'src/types/series'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {FluxTable} from 'src/types'
import {DataType} from 'src/shared/constants'
interface Props {
decimalPlaces: DecimalPlaces
@ -48,6 +59,7 @@ class SingleStat extends PureComponent<Props, State> {
}
private isComponentMounted: boolean
private lastUUID: string
constructor(props: Props) {
super(props)
@ -57,13 +69,14 @@ class SingleStat extends PureComponent<Props, State> {
public async componentDidMount() {
this.isComponentMounted = true
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
await this.dataToLastValues()
}
public async componentDidUpdate(prevProps: Props) {
const isDataChanged =
prevProps.dataType !== this.props.dataType ||
!_.isEqual(prevProps.data, this.props.data)
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
const isDataChanged = hasDataChanged(prevProps, this.props)
if (isDataChanged) {
await this.dataToLastValues()
@ -238,7 +251,10 @@ class SingleStat extends PureComponent<Props, State> {
lastValues = getLastValues(data as TimeSeriesServerResponse[])
}
if (!this.isComponentMounted) {
if (
!this.isComponentMounted ||
this.lastUUID !== getDataUUID(data, dataType)
) {
return
}
} catch (err) {

View File

@ -1,19 +1,26 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
import classnames from 'classnames'
import {connect} from 'react-redux'
import moment from 'moment'
import {ColumnSizer, SizedColumnProps, AutoSizer} from 'react-virtualized'
// Components
import {MultiGrid, PropsMultiGrid} from 'src/shared/components/MultiGrid'
import InvalidData from 'src/shared/components/InvalidData'
// Utils
import {fastReduce} from 'src/utils/fast'
import {timeSeriesToTableGraph} from 'src/utils/timeSeriesTransformers'
import {
computeFieldOptions,
getDefaultTimeField,
} from 'src/dashboards/utils/tableGraph'
import {QueryUpdateState} from 'src/shared/actions/queries'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {manager} from 'src/worker/JobManager'
// Constants
import {
ASCENDING,
DESCENDING,
@ -24,7 +31,9 @@ import {
DEFAULT_SORT_DIRECTION,
} from 'src/shared/constants/tableGraph'
import {generateThresholdsListHexs} from 'src/shared/constants/colorOperations'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {DataType} from 'src/shared/constants'
// Types
import {
TimeSeriesServerResponse,
TimeSeriesValue,
@ -38,10 +47,7 @@ import {
DecimalPlaces,
Sort,
} from 'src/types/dashboards'
import {FluxTable} from 'src/types'
import {DataType} from 'src/shared/constants'
import {manager} from 'src/worker/JobManager'
import {FluxTable, QueryUpdateState} from 'src/types'
const COLUMN_MIN_WIDTH = 100
const ROW_HEIGHT = 30

View File

@ -28,7 +28,6 @@ import {HANDLE_HORIZONTAL} from 'src/shared/constants'
import {CEOTabs} from 'src/dashboards/constants'
// Types
import {QueryUpdateState} from 'src/shared/actions/queries'
import {
TimeRange,
QueryConfig,
@ -40,6 +39,7 @@ import {
Status,
Query,
QueryType,
QueryUpdateState,
} from 'src/types'
import {SourceOption} from 'src/types/sources'
import {Links, ScriptStatus} from 'src/types/flux'

View File

@ -14,9 +14,9 @@ import {
Query,
Template,
Status,
QueryUpdateState,
} from 'src/types'
import {ColorString, ColorNumber} from 'src/types/colors'
import {QueryUpdateState} from 'src/shared/actions/queries'
import {
TableOptions,
FieldOption,

View File

@ -1,7 +1,19 @@
// Libraries
import _ from 'lodash'
/* eslint-disable no-magic-numbers */
import {toRGB_} from 'dygraphs/src/dygraph-utils'
import {CSSProperties} from 'react'
// Utils
import {getDeep} from 'src/utils/wrappers'
// Constants
import {DataType} from 'src/shared/constants'
// Types
import {FluxTable, TimeRange} from 'src/types'
import {TimeSeriesServerResponse} from 'src/types/series'
export const LINE_COLORS = [
'#00C9FF',
'#9394FF',
@ -169,3 +181,38 @@ export const hasherino = (str, len) =>
export const LABEL_WIDTH = 44
export const CHAR_PIXELS = 7
export const getDataUUID = (
data: TimeSeriesServerResponse[] | FluxTable[],
dataType: DataType
): string => {
if (dataType === DataType.influxQL) {
return getDeep(data, '0.response.uuid', '')
} else {
return getDeep(data, '0.id', '')
}
}
interface DataProps {
data: TimeSeriesServerResponse[] | FluxTable[]
dataType: DataType
timeRange?: TimeRange
}
export const hasDataChanged = (
prevProps: DataProps,
newProps: DataProps
): boolean => {
const isDataTypeChanged = prevProps.dataType !== newProps.dataType
const isDataIDsChanged = !_.isEqual(
getDataUUID(prevProps.data, prevProps.dataType),
getDataUUID(newProps.data, newProps.dataType)
)
const isTimeRangeChanged = !!_.isEqual(
_.get(prevProps, 'timeRange'),
_.get(newProps, 'timeRange')
)
const isDataChanged =
isDataTypeChanged || isDataIDsChanged || isTimeRangeChanged
return isDataChanged
}

View File

@ -36,3 +36,8 @@ export interface VisualizationOptions {
gaugeColors: ColorNumber[]
lineColors: ColorString[]
}
export enum QueryUpdateState {
CEO = 'cellEditorOverlay',
DE = 'dataExplorer',
}

View File

@ -68,7 +68,7 @@ import {
} from './dygraphs'
import {JSONFeedData} from './status'
import {Annotation} from './annotations'
import {WriteDataMode} from './dataExplorer'
import {WriteDataMode, QueryUpdateState} from './dataExplorer'
import {Host, Layout} from './hosts'
export {
@ -143,4 +143,5 @@ export {
Host,
Layout,
QueryType,
QueryUpdateState,
}