Skip to content

Commit

Permalink
feat(y_axis_domain): updated y-axis domain settings to allow min OR m…
Browse files Browse the repository at this point in the history
…ax values to be set.
  • Loading branch information
asalem1 committed May 11, 2020
1 parent bdc882f commit 99904d8
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 38 deletions.
38 changes: 12 additions & 26 deletions ui/src/shared/components/AutoDomainInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,32 @@ interface MinMaxInputsProps {
initialMin: string
initialMax: string
onSetMinMax: (minMax: [number, number]) => void
onSetErrorMessage: (errorMessage: string) => void
}

const MinMaxInputs: SFC<MinMaxInputsProps> = ({
initialMin,
initialMax,
onSetMinMax,
onSetErrorMessage,
}) => {
const [minInput, setMinInput] = useOneWayState(initialMin)
const [maxInput, setMaxInput] = useOneWayState(initialMax)

const emitIfValid = () => {
const newMin = parseFloat(minInput)
const newMax = parseFloat(maxInput)

let newMin = parseFloat(minInput)
let newMax = parseFloat(maxInput)
if (isNaN(newMin)) {
onSetErrorMessage('Must supply a valid minimum value')
return
newMin = null
}

if (isNaN(newMax)) {
onSetErrorMessage('Must supply a valid maximum value')
return
}

if (newMin >= newMax) {
onSetErrorMessage('Minium value must be less than maximum')
return
newMax = null
}

if (initialMin === minInput && initialMax === maxInput) {
// Only emit the change event if an actual change has occurred
return
}

onSetErrorMessage('')
onSetMinMax([newMin, newMax])
}

Expand Down Expand Up @@ -98,28 +87,26 @@ const AutoDomainInput: SFC<AutoDomainInputProps> = ({
label = 'Set Domain',
}) => {
const [showInputs, setShowInputs] = useState(!!domain)
const [errorMessage, setErrorMessage] = useState('')

const handleChooseAuto = () => {
setShowInputs(false)
setErrorMessage('')
onSetDomain(null)
}

const handleChooseCustom = () => {
setShowInputs(true)
setErrorMessage('')
}

const initialMin = domain ? String(domain[0]) : ''
const initialMax = domain ? String(domain[1]) : ''
const formatDomainValue = (value: null | number): string => {
return value === null ? '' : String(value)
}
const initialMin =
domain && Array.isArray(domain) ? formatDomainValue(domain[0]) : ''
const initialMax =
domain && Array.isArray(domain) ? formatDomainValue(domain[1]) : ''

return (
<Form.Element
label={label}
errorMessage={errorMessage}
className="auto-domain-input"
>
<Form.Element label={label} className="auto-domain-input">
<Grid>
<Grid.Row>
<Grid.Column widthXS={Columns.Twelve}>
Expand Down Expand Up @@ -153,7 +140,6 @@ const AutoDomainInput: SFC<AutoDomainInputProps> = ({
initialMin={initialMin}
initialMax={initialMax}
onSetMinMax={onSetDomain}
onSetErrorMessage={setErrorMessage}
/>
</Grid.Row>
)}
Expand Down
7 changes: 5 additions & 2 deletions ui/src/shared/components/HeatmapPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import EmptyGraphMessage from 'src/shared/components/EmptyGraphMessage'
import GraphLoadingDots from 'src/shared/components/GraphLoadingDots'

// Utils
import {useVisDomainSettings} from 'src/shared/utils/useVisDomainSettings'
import {
useVisDomainSettings,
useVisYDomainSettings,
} from 'src/shared/utils/useVisDomainSettings'
import {getFormatter} from 'src/shared/utils/vis'

// Constants
Expand Down Expand Up @@ -65,7 +68,7 @@ const HeatmapPlot: FunctionComponent<Props> = ({
timeRange
)

const [yDomain, onSetYDomain, onResetYDomain] = useVisDomainSettings(
const [yDomain, onSetYDomain, onResetYDomain] = useVisYDomainSettings(
storedYDomain,
table.getColumn(yColumn, 'number')
)
Expand Down
7 changes: 5 additions & 2 deletions ui/src/shared/components/ScatterPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import EmptyGraphMessage from 'src/shared/components/EmptyGraphMessage'
import GraphLoadingDots from 'src/shared/components/GraphLoadingDots'

// Utils
import {useVisDomainSettings} from 'src/shared/utils/useVisDomainSettings'
import {
useVisDomainSettings,
useVisYDomainSettings,
} from 'src/shared/utils/useVisDomainSettings'
import {
getFormatter,
defaultXColumn,
Expand Down Expand Up @@ -77,7 +80,7 @@ const ScatterPlot: FunctionComponent<Props> = ({
timeRange
)

const [yDomain, onSetYDomain, onResetYDomain] = useVisDomainSettings(
const [yDomain, onSetYDomain, onResetYDomain] = useVisYDomainSettings(
storedYDomain,
table.getColumn(yColumn, 'number')
)
Expand Down
11 changes: 7 additions & 4 deletions ui/src/shared/components/XYPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import EmptyGraphMessage from 'src/shared/components/EmptyGraphMessage'
import GraphLoadingDots from 'src/shared/components/GraphLoadingDots'

// Utils
import {useVisDomainSettings} from 'src/shared/utils/useVisDomainSettings'
import {
useVisDomainSettings,
useVisYDomainSettings,
} from 'src/shared/utils/useVisDomainSettings'
import {
getFormatter,
geomToInterpolation,
filterNoisyColumns,
parseBounds,
parseYBounds,
defaultXColumn,
defaultYColumn,
} from 'src/shared/utils/vis'
Expand Down Expand Up @@ -83,8 +87,7 @@ const XYPlot: FunctionComponent<Props> = ({
theme,
}) => {
const storedXDomain = useMemo(() => parseBounds(xBounds), [xBounds])
const storedYDomain = useMemo(() => parseBounds(yBounds), [yBounds])

const storedYDomain = useMemo(() => parseYBounds(yBounds), [yBounds])
const xColumn = storedXColumn || defaultXColumn(table)
const yColumn = storedYColumn || defaultYColumn(table)

Expand Down Expand Up @@ -130,7 +133,7 @@ const XYPlot: FunctionComponent<Props> = ({
return table.getColumn(yColumn, 'number')
}, [table, yColumn, position])

const [yDomain, onSetYDomain, onResetYDomain] = useVisDomainSettings(
const [yDomain, onSetYDomain, onResetYDomain] = useVisYDomainSettings(
storedYDomain,
memoizedYColumnData
)
Expand Down
39 changes: 39 additions & 0 deletions ui/src/shared/utils/useVisDomainSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,42 @@ export const useVisDomainSettings = (

return [domain, setDomain, resetDomain]
}

export const getRemainingRange = (
data: NumericColumnData = [],
timeRange: TimeRange | null,
storedDomain: number[]
) => {
const range = extent((data as number[]) || [])
if (range && range.length >= 2) {
const startTime = getStartTime(timeRange)
const endTime = getEndTime(timeRange)
const start = storedDomain[0]
? storedDomain[0]
: Math.min(startTime, range[0])
const end = storedDomain[1] ? storedDomain[1] : Math.max(endTime, range[1])
return [start, end]
}
return range
}

export const useVisYDomainSettings = (
storedDomain: number[],
data: NumericColumnData,
timeRange: TimeRange | null = null
) => {
const initialDomain = useMemo(() => {
if (storedDomain === null || storedDomain.every(val => val === null)) {
return getValidRange(data, timeRange)
}
if (storedDomain.includes(null)) {
return getRemainingRange(data, timeRange, storedDomain)
}
return storedDomain
}, [storedDomain, data])

const [domain, setDomain] = useOneWayState(initialDomain)
const resetDomain = () => setDomain(initialDomain)

return [domain, setDomain, resetDomain]
}
12 changes: 12 additions & 0 deletions ui/src/shared/utils/vis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ export const parseBounds = (
return [+bounds[0], +bounds[1]]
}

export const parseYBounds = (
bounds: Axis['bounds']
): [number | null, number | null] | null => {
if (!bounds || (!bounds[0] && !bounds[1])) {
return null
}

const min = isNaN(parseInt(bounds[0])) ? null : parseInt(bounds[0])
const max = isNaN(parseInt(bounds[1])) ? null : parseInt(bounds[1])
return [min, max]
}

export const extent = (xs: number[]): [number, number] | null => {
if (!xs || !xs.length) {
return null
Expand Down
13 changes: 9 additions & 4 deletions ui/src/timeMachine/components/view_options/LineOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
} from 'src/timeMachine/actions'

// Utils
import {parseBounds} from 'src/shared/utils/vis'
import {parseYBounds} from 'src/shared/utils/vis'
import {
getXColumnSelection,
getYColumnSelection,
Expand Down Expand Up @@ -202,14 +202,19 @@ class LineOptions extends PureComponent<Props> {
}

private get yDomain(): [number, number] {
return parseBounds(this.props.axes.y.bounds)
return parseYBounds(this.props.axes.y.bounds)
}

private setBoundValues = (value: number | null): string | null => {
return value === null ? null : String(value)
}

private handleSetYDomain = (yDomain: [number, number]): void => {
let bounds: [string, string] | [null, null]
let bounds: [string | null, string | null]

if (yDomain) {
bounds = [String(yDomain[0]), String(yDomain[1])]
const [min, max] = yDomain
bounds = [this.setBoundValues(min), this.setBoundValues(max)]
} else {
bounds = [null, null]
}
Expand Down

0 comments on commit 99904d8

Please sign in to comment.