Skip to content

Commit

Permalink
fix(ui): enable selecting more columns in line visualizations
Browse files Browse the repository at this point in the history
Closes #14153
  • Loading branch information
chnn committed Jun 24, 2019
1 parent ffce990 commit 1d7521e
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 89 deletions.
10 changes: 7 additions & 3 deletions ui/src/shared/components/ScatterContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import GraphLoadingDots from 'src/shared/components/GraphLoadingDots'

// Utils
import {useVisDomainSettings} from 'src/shared/utils/useVisDomainSettings'
import {getFormatter, chooseXColumn, chooseYColumn} from 'src/shared/utils/vis'
import {
getFormatter,
defaultXColumn,
defaultYColumn,
} from 'src/shared/utils/vis'

// Constants
import {VIS_THEME} from 'src/shared/constants'
Expand Down Expand Up @@ -47,8 +51,8 @@ const ScatterContainer: FunctionComponent<Props> = ({
const fillColumns = storedFill || []
const symbolColumns = storedSymbol || []

const xColumn = storedXColumn || chooseXColumn(table)
const yColumn = storedYColumn || chooseYColumn(table)
const xColumn = storedXColumn || defaultXColumn(table)
const yColumn = storedYColumn || defaultYColumn(table)

const columnKeys = table.columnKeys

Expand Down
8 changes: 4 additions & 4 deletions ui/src/shared/components/XYContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
geomToInterpolation,
filterNoisyColumns,
parseBounds,
chooseXColumn,
chooseYColumn,
defaultXColumn,
defaultYColumn,
} from 'src/shared/utils/vis'

// Constants
Expand Down Expand Up @@ -59,8 +59,8 @@ const XYContainer: FunctionComponent<Props> = ({
const storedXDomain = useMemo(() => parseBounds(xBounds), [xBounds])
const storedYDomain = useMemo(() => parseBounds(yBounds), [yBounds])

const xColumn = storedXColumn || chooseXColumn(table)
const yColumn = storedYColumn || chooseYColumn(table)
const xColumn = storedXColumn || defaultXColumn(table)
const yColumn = storedYColumn || defaultYColumn(table)

const columnKeys = table.columnKeys

Expand Down
96 changes: 79 additions & 17 deletions ui/src/shared/utils/vis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,32 +105,94 @@ export const extent = (xs: number[]): [number, number] | null => {
return [low, high]
}

export const chooseXColumn = (table: Table): string | null => {
const columnKeys = new Set(table.columnKeys)
export const checkResultsLength = (giraffeResult: FromFluxResult): boolean => {
return get(giraffeResult, 'table.length', 0) > 0
}

export const getNumericColumns = (table: Table): string[] => {
const numericColumnKeys = table.columnKeys.filter(k => {
if (k === 'result' || k === 'table') {
return false
}

const columnType = table.getColumnType(k)

return columnType === 'time' || columnType === 'number'
})

if (columnKeys.has('_time')) {
return '_time'
return numericColumnKeys
}

export const getGroupableColumns = (table: Table): string[] => {
const invalidGroupColumns = new Set(['_value', '_time', 'table'])
const groupableColumns = table.columnKeys.filter(
name => !invalidGroupColumns.has(name)
)

return groupableColumns
}

/*
Previously we would automatically select an x and y column setting for an
`XYView` based on the current Flux response. We then added support for an
explicit x and y column setting by adding `xColumn` and `yColumn` fields to
the `XYView`.
We did not migrate existing views when adding the fields, so the fields are
considered optional. Thus to resolve the correct x and y column selections
for an `XYView`, we need to:
1. Use the `xColumn` and `yColumn` fields if they exist
2. Fall back to automatically selecting and x and y column if not
A `null` result from this function indicates that no valid selection could be
made.
*/
export const defaultXColumn = (
table: Table,
preferredColumnKey?: string
): string | null => {
const validColumnKeys = getNumericColumns(table)

if (validColumnKeys.includes(preferredColumnKey)) {
return preferredColumnKey
}

if (columnKeys.has('_stop')) {
return '_stop'
for (const key of ['_time', '_stop', '_start']) {
if (validColumnKeys.includes(key)) {
return key
}
}

if (columnKeys.has('_start')) {
return '_start'
if (validColumnKeys.length) {
return validColumnKeys[0]
}

return null
}

export const chooseYColumn = (table: Table): string | null => {
return table.columnKeys.find(
k =>
k.startsWith('_value') &&
(table.getColumnType(k) === 'number' || table.getColumnType(k) === 'time')
)
}
/*
See `defaultXColumn`.
*/
export const defaultYColumn = (
table: Table,
preferredColumnKey?: string
): string | null => {
const validColumnKeys = getNumericColumns(table)

if (validColumnKeys.includes(preferredColumnKey)) {
return preferredColumnKey
}

export const checkResultsLength = (giraffeResult: FromFluxResult): boolean => {
return get(giraffeResult, 'table.length', 0) > 0
for (const key of validColumnKeys) {
if (key.startsWith('_value')) {
return key
}
}

if (validColumnKeys.length) {
return validColumnKeys[0]
}

return null
}
83 changes: 18 additions & 65 deletions ui/src/timeMachine/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {fromFlux, Table} from '@influxdata/giraffe'

// Utils
import {parseResponse} from 'src/shared/parsing/flux/response'
import {chooseYColumn, chooseXColumn} from 'src/shared/utils/vis'
import {
defaultXColumn,
defaultYColumn,
getNumericColumns as getNumericColumnsUtil,
getGroupableColumns as getGroupableColumnsUtil,
} from 'src/shared/utils/vis'

// Types
import {
Expand Down Expand Up @@ -47,92 +52,40 @@ export const getVisTable = (
return {table, fluxGroupKeyUnion}
}

const getNumericColumnsMemoized = memoizeOne(
(table: Table): string[] => {
const columnKeys = table.columnKeys
return columnKeys.reduce((numericColumns, key) => {
const columnType = table.getColumnType(key)
const columnName = table.getColumnName(key)
if (
(columnType === 'number' || columnType === 'time') &&
columnName !== 'result' &&
columnName !== 'table'
) {
numericColumns.push(columnName)
}
return numericColumns
}, [])
}
)
const getNumericColumnsMemoized = memoizeOne(getNumericColumnsUtil)

export const getNumericColumns = (state: AppState): string[] => {
const {table} = getVisTable(state)

return getNumericColumnsMemoized(table)
}

const getGroupableColumnsMemoized = memoizeOne(
(table: Table): string[] => {
const invalidGroupColumns = new Set(['_value', '_time', 'table'])
const groupableColumns = table.columnKeys.filter(
name => !invalidGroupColumns.has(name)
)

return groupableColumns
}
)
const getGroupableColumnsMemoized = memoizeOne(getGroupableColumnsUtil)

export const getGroupableColumns = (state: AppState): string[] => {
const {table} = getVisTable(state)

return getGroupableColumnsMemoized(table)
}

const selectXYColumn = (
validColumns: string[],
preference: string,
defaultSelection: string
): string => {
if (preference && validColumns.includes(preference)) {
return preference
}

return defaultSelection
}

const getXColumnSelectionMemoized = memoizeOne(selectXYColumn)

const getYColumnSelectionMemoized = memoizeOne(selectXYColumn)

export const getXColumnSelection = (state: AppState): string => {
const validXColumns = getNumericColumns(state)

const preference = get(getActiveTimeMachine(state), 'view.properties.xColumn')

const {table} = getVisTable(state)
const defaultSelection = chooseXColumn(table)

return getXColumnSelectionMemoized(
validXColumns,
preference,
defaultSelection
const preferredXColumnKey = get(
getActiveTimeMachine(state),
'view.properties.xColumn'
)

return defaultXColumn(table, preferredXColumnKey)
}

export const getYColumnSelection = (state: AppState): string => {
const validYColumns = getNumericColumns(state)

const preference = get(getActiveTimeMachine(state), 'view.properties.yColumn')

const {table} = getVisTable(state)

const defaultSelection = chooseYColumn(table)

return getYColumnSelectionMemoized(
validYColumns,
preference,
defaultSelection
const preferredYColumnKey = get(
getActiveTimeMachine(state),
'view.properties.yColumn'
)

return defaultYColumn(table, preferredYColumnKey)
}

const getGroupableColumnSelection = (
Expand Down

0 comments on commit 1d7521e

Please sign in to comment.