Merge pull request #4486 from influxdata/flux/table-invalid-date
Update Vis Types to not assume there is always a timepull/4490/head
commit
ee10dc6175
|
@ -80,15 +80,17 @@ const updateMaxWidths = (
|
|||
}
|
||||
|
||||
const columnLabel = topRow[c]
|
||||
const isTimeColumn =
|
||||
columnLabel === DEFAULT_INFLUXQL_TIME_FIELD.internalName ||
|
||||
columnLabel === DEFAULT_FLUX_TIME_FIELD.internalName
|
||||
|
||||
const isTimeRow =
|
||||
topRow[0] === DEFAULT_INFLUXQL_TIME_FIELD.internalName ||
|
||||
topRow[0] === DEFAULT_FLUX_TIME_FIELD.internalName
|
||||
|
||||
const useTimeWidth =
|
||||
(columnLabel === DEFAULT_INFLUXQL_TIME_FIELD.internalName &&
|
||||
verticalTimeAxis &&
|
||||
!isTopRow) ||
|
||||
(!verticalTimeAxis &&
|
||||
isTopRow &&
|
||||
topRow[0] === DEFAULT_INFLUXQL_TIME_FIELD.internalName &&
|
||||
c !== 0)
|
||||
(isTimeColumn && verticalTimeAxis && !isTopRow) ||
|
||||
(!verticalTimeAxis && isTopRow && isTimeRow && c !== 0)
|
||||
|
||||
const currentWidth = useTimeWidth
|
||||
? timeFormatWidth
|
||||
|
@ -110,23 +112,12 @@ const updateMaxWidths = (
|
|||
return maxWidths
|
||||
}
|
||||
|
||||
export const getTimeField = (
|
||||
fieldOptions: FieldOption[],
|
||||
dataType: DataType
|
||||
): FieldOption => {
|
||||
export const getDefaultTimeField = (dataType: DataType): FieldOption => {
|
||||
if (dataType === DataType.flux) {
|
||||
return (
|
||||
fieldOptions.find(
|
||||
f => f.internalName === DEFAULT_FLUX_TIME_FIELD.internalName
|
||||
) || DEFAULT_FLUX_TIME_FIELD
|
||||
)
|
||||
return DEFAULT_FLUX_TIME_FIELD
|
||||
}
|
||||
|
||||
return (
|
||||
fieldOptions.find(
|
||||
f => f.internalName === DEFAULT_INFLUXQL_TIME_FIELD.internalName
|
||||
) || DEFAULT_INFLUXQL_TIME_FIELD
|
||||
)
|
||||
return DEFAULT_INFLUXQL_TIME_FIELD
|
||||
}
|
||||
|
||||
export const computeFieldOptions = (
|
||||
|
@ -134,18 +125,16 @@ export const computeFieldOptions = (
|
|||
sortedLabels: SortedLabel[],
|
||||
dataType: DataType
|
||||
): FieldOption[] => {
|
||||
const timeField = getTimeField(existingFieldOptions, dataType)
|
||||
const defaultTimeField = getDefaultTimeField(dataType)
|
||||
|
||||
let astNames = [timeField]
|
||||
let astNames = dataType === DataType.influxQL ? [defaultTimeField] : []
|
||||
sortedLabels.forEach(({label}) => {
|
||||
if (label !== timeField.internalName) {
|
||||
const field: FieldOption = {
|
||||
internalName: label,
|
||||
displayName: '',
|
||||
visible: true,
|
||||
}
|
||||
astNames = [...astNames, field]
|
||||
const field: FieldOption = {
|
||||
internalName: label,
|
||||
displayName: '',
|
||||
visible: true,
|
||||
}
|
||||
astNames = [...astNames, field]
|
||||
})
|
||||
|
||||
const intersection = existingFieldOptions.filter(f => {
|
||||
|
|
|
@ -5,6 +5,7 @@ import {manager} from 'src/worker/JobManager'
|
|||
|
||||
import getLastValues from 'src/shared/parsing/lastValues'
|
||||
import Gauge from 'src/shared/components/Gauge'
|
||||
import InvalidData from 'src/shared/components/InvalidData'
|
||||
|
||||
import {DEFAULT_GAUGE_COLORS} from 'src/shared/constants/thresholds'
|
||||
import {stringifyColorValues} from 'src/shared/constants/colorOperations'
|
||||
|
@ -33,6 +34,7 @@ interface State {
|
|||
values: number[]
|
||||
series: string[]
|
||||
}
|
||||
isValidData: boolean
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -46,7 +48,7 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
||||
this.state = {}
|
||||
this.state = {isValidData: true}
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
|
@ -70,6 +72,14 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
|
||||
public render() {
|
||||
const {colors, prefix, suffix, decimalPlaces} = this.props
|
||||
if (!this.state.isValidData) {
|
||||
return <InvalidData />
|
||||
}
|
||||
|
||||
if (!this.state.lastValues) {
|
||||
return <h3 className="graph-spinner" />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="single-stat">
|
||||
<Gauge
|
||||
|
@ -115,8 +125,9 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
private async dataToLastValues() {
|
||||
const {data, dataType} = this.props
|
||||
|
||||
let lastValues
|
||||
let isValidData = true
|
||||
try {
|
||||
let lastValues
|
||||
if (dataType === DataType.flux) {
|
||||
lastValues = await manager.fluxTablesToSingleStat(data as FluxTable[])
|
||||
} else if (dataType === DataType.influxQL) {
|
||||
|
@ -126,11 +137,10 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
if (!this.isComponentMounted) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setState({lastValues})
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
isValidData = false
|
||||
}
|
||||
this.setState({lastValues, isValidData})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Libraries
|
||||
import React, {PureComponent, CSSProperties} from 'react'
|
||||
import _ from 'lodash'
|
||||
import Dygraph from 'src/shared/components/Dygraph'
|
||||
import {withRouter, RouteComponentProps} from 'react-router'
|
||||
|
||||
|
@ -83,25 +84,30 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
|
|||
data: TimeSeriesServerResponse[] | FluxTable[],
|
||||
dataType: DataType
|
||||
) {
|
||||
let timeSeries
|
||||
try {
|
||||
const timeSeries = await this.convertToDygraphData(data, dataType)
|
||||
timeSeries = await this.convertToDygraphData(data, dataType)
|
||||
|
||||
this.isValidData = await manager.validateDygraphData(
|
||||
timeSeries.timeSeries
|
||||
)
|
||||
if (!this.isComponentMounted) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setState({timeSeries})
|
||||
this.isValidData = await manager.validateDygraphData(
|
||||
timeSeries.timeSeries
|
||||
)
|
||||
} catch (err) {
|
||||
this.isValidData = false
|
||||
}
|
||||
|
||||
this.setState({timeSeries})
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps: LineGraphProps) {
|
||||
if (nextProps.loading === RemoteDataState.Done) {
|
||||
this.parseTimeSeries(nextProps.data, nextProps.dataType)
|
||||
public componentDidUpdate(prevProps: LineGraphProps) {
|
||||
const isDataChanged =
|
||||
prevProps.data.length !== this.props.data.length ||
|
||||
!_.isEqual(_.get(prevProps, 'data.0.id'), _.get(this.props, 'data.0.id'))
|
||||
|
||||
if (this.props.loading === RemoteDataState.Done && isDataChanged) {
|
||||
this.parseTimeSeries(this.props.data, this.props.dataType)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +115,6 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
|
|||
if (!this.isValidData) {
|
||||
return <InvalidData />
|
||||
}
|
||||
|
||||
const {
|
||||
data,
|
||||
axes,
|
||||
|
|
|
@ -4,6 +4,8 @@ import getLastValues from 'src/shared/parsing/lastValues'
|
|||
import _ from 'lodash'
|
||||
import {manager} from 'src/worker/JobManager'
|
||||
|
||||
import InvalidData from 'src/shared/components/InvalidData'
|
||||
|
||||
import {SMALL_CELL_HEIGHT} from 'src/shared/graphs/helpers'
|
||||
import {DYGRAPH_CONTAINER_V_MARGIN} from 'src/shared/constants'
|
||||
import {generateThresholdsListHexs} from 'src/shared/constants/colorOperations'
|
||||
|
@ -32,6 +34,7 @@ interface State {
|
|||
values: number[]
|
||||
series: string[]
|
||||
}
|
||||
isValidData: boolean
|
||||
}
|
||||
|
||||
const NOOP = () => {}
|
||||
|
@ -49,7 +52,7 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
||||
this.state = {}
|
||||
this.state = {isValidData: true}
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
|
@ -72,6 +75,9 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
if (!this.state.isValidData) {
|
||||
return <InvalidData />
|
||||
}
|
||||
if (!this.state.lastValues) {
|
||||
return <h3 className="graph-spinner" />
|
||||
}
|
||||
|
@ -223,8 +229,9 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
private async dataToLastValues() {
|
||||
const {data, dataType} = this.props
|
||||
|
||||
let lastValues
|
||||
let isValidData = true
|
||||
try {
|
||||
let lastValues
|
||||
if (dataType === DataType.flux) {
|
||||
lastValues = await manager.fluxTablesToSingleStat(data as FluxTable[])
|
||||
} else if (dataType === DataType.influxQL) {
|
||||
|
@ -234,11 +241,10 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
if (!this.isComponentMounted) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setState({lastValues})
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
isValidData = false
|
||||
}
|
||||
this.setState({lastValues, isValidData})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,12 @@ import {MultiGrid, PropsMultiGrid} from 'src/shared/components/MultiGrid'
|
|||
import {bindActionCreators} from 'redux'
|
||||
import {fastReduce} from 'src/utils/fast'
|
||||
import {timeSeriesToTableGraph} from 'src/utils/timeSeriesTransformers'
|
||||
import {computeFieldOptions} from 'src/dashboards/utils/tableGraph'
|
||||
import {
|
||||
computeFieldOptions,
|
||||
getDefaultTimeField,
|
||||
} from 'src/dashboards/utils/tableGraph'
|
||||
import {updateFieldOptions} from 'src/shared/actions/visualizations'
|
||||
import {QueryUpdateState} from 'src/shared/actions/queries'
|
||||
import {
|
||||
DEFAULT_INFLUXQL_TIME_FIELD,
|
||||
DEFAULT_FLUX_TIME_FIELD,
|
||||
} from 'src/dashboards/constants'
|
||||
import {
|
||||
ASCENDING,
|
||||
DESCENDING,
|
||||
|
@ -95,16 +94,12 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
||||
const defaultTimeField =
|
||||
props.dataType === DataType.flux
|
||||
? DEFAULT_FLUX_TIME_FIELD
|
||||
: DEFAULT_INFLUXQL_TIME_FIELD
|
||||
|
||||
const sortField: string = _.get(
|
||||
this.props,
|
||||
'tableOptions.sortBy.internalName',
|
||||
defaultTimeField.internalName
|
||||
''
|
||||
)
|
||||
|
||||
this.state = {
|
||||
shouldResize: false,
|
||||
data: [[]],
|
||||
|
@ -208,14 +203,18 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
let sortField: string = _.get(
|
||||
this.props,
|
||||
['tableOptions', 'sortBy', 'internalName'],
|
||||
this.defaultTimeField.internalName
|
||||
''
|
||||
)
|
||||
const isValidSortField = !!fieldOptions.find(
|
||||
f => f.internalName === sortField
|
||||
)
|
||||
|
||||
if (!isValidSortField) {
|
||||
sortField = this.defaultTimeField.internalName
|
||||
sortField = _.get(
|
||||
this.defaultTimeField,
|
||||
'internalName',
|
||||
_.get(fieldOptions, '0.internalName', '')
|
||||
)
|
||||
}
|
||||
|
||||
const sort: Sort = {field: sortField, direction: DEFAULT_SORT_DIRECTION}
|
||||
|
@ -246,7 +245,7 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
decimalPlaces
|
||||
)
|
||||
|
||||
const isTimeVisible = _.get(this.timeField, 'visible', true)
|
||||
const isTimeVisible = _.get(this.timeField, 'visible', false)
|
||||
|
||||
this.setState(
|
||||
{
|
||||
|
@ -312,12 +311,17 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
f => f.internalName === sortField
|
||||
)
|
||||
|
||||
const defaultTimeField = getDefaultTimeField(dataType)
|
||||
|
||||
if (!isValidSortField) {
|
||||
const defaultTimeField =
|
||||
dataType === DataType.flux
|
||||
? DEFAULT_FLUX_TIME_FIELD
|
||||
: DEFAULT_INFLUXQL_TIME_FIELD
|
||||
sortField = defaultTimeField.internalName
|
||||
const timeField = fieldOptions.find(
|
||||
f => f.internalName === defaultTimeField.internalName
|
||||
)
|
||||
sortField = _.get(
|
||||
timeField,
|
||||
'internalName',
|
||||
_.get(fieldOptions, '0.internalName', '')
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -349,12 +353,9 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
let isTimeVisible = this.state.isTimeVisible
|
||||
if (_.includes(updatedProps, 'fieldOptions')) {
|
||||
const timeField = _.find(nextProps.fieldOptions, f => {
|
||||
if (dataType === DataType.flux) {
|
||||
return f.internalName === DEFAULT_FLUX_TIME_FIELD.internalName
|
||||
}
|
||||
return f.internalName === DEFAULT_INFLUXQL_TIME_FIELD.internalName
|
||||
return f.internalName === defaultTimeField.internalName
|
||||
})
|
||||
isTimeVisible = _.get(timeField, 'visible', this.state.isTimeVisible)
|
||||
isTimeVisible = _.get(timeField, 'visible', false)
|
||||
}
|
||||
|
||||
if (!this.isComponentMounted) {
|
||||
|
@ -601,11 +602,7 @@ class TableGraph extends PureComponent<Props, State> {
|
|||
private get defaultTimeField(): FieldOption {
|
||||
const {dataType} = this.props
|
||||
|
||||
if (dataType === DataType.flux) {
|
||||
return DEFAULT_FLUX_TIME_FIELD
|
||||
}
|
||||
|
||||
return DEFAULT_INFLUXQL_TIME_FIELD
|
||||
return getDefaultTimeField(dataType)
|
||||
}
|
||||
|
||||
private get timeFieldIndex(): number {
|
||||
|
|
Loading…
Reference in New Issue