Skip to content

Commit 3135ab8

Browse files
authored
feat: requery with a tighter window period upon zoom-in (#4834)
1 parent 065a0ef commit 3135ab8

File tree

4 files changed

+245
-30
lines changed

4 files changed

+245
-30
lines changed

src/variables/selectors/index.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import {get} from 'lodash'
55
import {getActiveQuery} from 'src/timeMachine/selectors'
66
import {getRangeVariable} from 'src/variables/utils/getTimeRangeVars'
77
import {getTimeRange, getTimeRangeWithTimezone} from 'src/dashboards/selectors'
8-
import {getWindowPeriodVariableFromVariables} from 'src/variables/utils/getWindowVars'
8+
import {
9+
getWindowPeriodVariableForZoomRequery,
10+
getWindowPeriodVariableFromVariables,
11+
} from 'src/variables/utils/getWindowVars'
912
import {
1013
TIME_RANGE_START,
1114
TIME_RANGE_STOP,
@@ -134,6 +137,23 @@ export const getAllVariables = (
134137
return vars
135138
}
136139

140+
export const getAllVariablesForZoomRequery = (
141+
state: AppState,
142+
contextID?: string
143+
): Variable[] => {
144+
const vars = getUserVariableNames(state, contextID || currentContext(state))
145+
.concat([TIME_RANGE_START, TIME_RANGE_STOP, WINDOW_PERIOD])
146+
.map(variableID => {
147+
if (variableID === WINDOW_PERIOD) {
148+
return getWindowPeriodVariableForZoomRequery()
149+
}
150+
return getVariable(state, variableID)
151+
})
152+
.filter(v => !!v)
153+
154+
return vars
155+
}
156+
137157
export const sortVariablesByName = (variables: Variable[]): Variable[] =>
138158
variables.sort((a, b) =>
139159
a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1

src/variables/utils/getWindowVars.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
buildUsedVarsOption,
88
buildVarsOption,
99
} from 'src/variables/utils/buildVarsOption'
10+
1011
// Constants
1112
import {WINDOW_PERIOD} from 'src/variables/constants'
1213

@@ -17,6 +18,7 @@ import {SELECTABLE_TIME_RANGES} from 'src/shared/constants/timeRanges'
1718

1819
const DESIRED_POINTS_PER_GRAPH = 360
1920
const FALLBACK_WINDOW_PERIOD = 15000
21+
const FINEST_WINDOW_PERIOD_PRECISION = 1000
2022

2123
/*
2224
Compute the `v.windowPeriod` variable assignment for a query.
@@ -190,3 +192,16 @@ export const getWindowPeriodVariableFromVariables = (
190192

191193
return [windowPeriodVariable]
192194
}
195+
196+
export const getWindowPeriodVariableForZoomRequery = (): Variable => ({
197+
orgID: '',
198+
id: WINDOW_PERIOD,
199+
name: WINDOW_PERIOD,
200+
arguments: {
201+
type: 'system',
202+
values: [FINEST_WINDOW_PERIOD_PRECISION],
203+
},
204+
status: RemoteDataState.Done,
205+
labels: [],
206+
selected: [],
207+
})

src/visualization/types/Graph/view.tsx

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Libraries
2-
import React, {FC, useMemo, useContext} from 'react'
2+
import React, {FC, useMemo, useContext, useState, useEffect} from 'react'
33
import {useDispatch, useSelector} from 'react-redux'
44
import {
55
Config,
@@ -29,7 +29,13 @@ import {DEFAULT_LINE_COLORS} from 'src/shared/constants/graphColorPalettes'
2929
import {INVALID_DATA_COPY} from 'src/visualization/constants'
3030

3131
// Types
32-
import {AppState, ResourceType, View, XYViewProperties} from 'src/types'
32+
import {
33+
AppState,
34+
InternalFromFluxResult,
35+
ResourceType,
36+
View,
37+
XYViewProperties,
38+
} from 'src/types'
3339
import {VisualizationProps} from 'src/visualization'
3440

3541
// Utils
@@ -40,6 +46,8 @@ import {useStaticLegend} from 'src/visualization/utils/useStaticLegend'
4046
import {
4147
useVisXDomainSettings,
4248
useVisYDomainSettings,
49+
useZoomRequeryXDomainSettings,
50+
useZoomRequeryYDomainSettings,
4351
} from 'src/visualization/utils/useVisDomainSettings'
4452
import {
4553
geomToInterpolation,
@@ -70,6 +78,15 @@ const XYPlot: FC<Props> = ({
7078
annotations,
7179
cellID,
7280
}) => {
81+
const [resultState, setResultState] = useState(result)
82+
const [preZoomResult, setPreZoomResult] = useState<InternalFromFluxResult>(
83+
null
84+
)
85+
86+
useEffect(() => {
87+
setResultState(result)
88+
}, [result])
89+
7390
const {theme, timeZone} = useContext(AppSettingContext)
7491
const axisTicksOptions = useAxisTicksGenerator(properties)
7592
const tooltipOpacity = useLegendOpacity(properties.legendOpacity)
@@ -98,11 +115,12 @@ const XYPlot: FC<Props> = ({
98115
const storedYDomain = useMemo(() => parseYBounds(properties.axes.y.bounds), [
99116
properties.axes.y.bounds,
100117
])
101-
const columnKeys = Object.keys(result.table.columns)
102-
const xColumn = properties.xColumn || defaultXColumn(result.table, '_time')
118+
const columnKeys = Object.keys(resultState.table.columns)
119+
const xColumn =
120+
properties.xColumn || defaultXColumn(resultState.table, '_time')
103121
const yColumn =
104122
(columnKeys.includes(properties.yColumn) && properties.yColumn) ||
105-
defaultYColumn(result.table)
123+
defaultYColumn(resultState.table)
106124

107125
const isValidView =
108126
xColumn &&
@@ -119,44 +137,80 @@ const XYPlot: FC<Props> = ({
119137

120138
const interpolation = geomToInterpolation(properties.geom)
121139

122-
const groupKey = useMemo(() => [...result.fluxGroupKeyUnion, 'result'], [
123-
result,
140+
const groupKey = useMemo(() => [...resultState.fluxGroupKeyUnion, 'result'], [
141+
resultState,
124142
])
125143

126-
const [xDomain, onSetXDomain, onResetXDomain] = useVisXDomainSettings(
127-
storedXDomain,
128-
result.table.getColumn(xColumn, 'number'),
129-
timeRange
130-
)
131-
132144
const memoizedYColumnData = useMemo(() => {
133145
if (properties.position === 'stacked') {
134146
const {lineData} = lineTransform(
135-
result.table,
147+
resultState.table,
136148
xColumn,
137149
yColumn,
138150
groupKey,
139151
colorHexes,
140152
properties.position
141153
)
142-
const [fillColumn] = createGroupIDColumn(result.table, groupKey)
154+
const [fillColumn] = createGroupIDColumn(resultState.table, groupKey)
143155
return getDomainDataFromLines(lineData, [...fillColumn], DomainLabel.Y)
144156
}
145157

146-
return result.table.getColumn(yColumn, 'number')
158+
return resultState.table.getColumn(yColumn, 'number')
147159
}, [
148-
result.table,
160+
resultState.table,
149161
xColumn,
150162
yColumn,
151163
groupKey,
152164
colorHexes,
153165
properties.position,
154166
])
155167

156-
const [yDomain, onSetYDomain, onResetYDomain] = useVisYDomainSettings(
157-
storedYDomain,
158-
memoizedYColumnData
159-
)
168+
let useXDomainSettings = ({storedDomain, parsedResult, timeRange}) =>
169+
useVisXDomainSettings(
170+
storedDomain,
171+
parsedResult.table.getColumn(xColumn, 'number'),
172+
timeRange
173+
)
174+
let useYDomainSettings = options => {
175+
const {storedDomain} = options
176+
return useVisYDomainSettings(storedDomain, memoizedYColumnData)
177+
}
178+
179+
if (isFlagEnabled('zoomRequery')) {
180+
useXDomainSettings = ({storedDomain, parsedResult, timeRange}) =>
181+
useZoomRequeryXDomainSettings({
182+
parsedResult,
183+
setResult: setResultState,
184+
preZoomResult,
185+
setPreZoomResult,
186+
query: properties?.queries?.[0]?.text ?? '',
187+
storedDomain,
188+
data: parsedResult.table.getColumn(xColumn, 'number'),
189+
timeRange,
190+
})
191+
useYDomainSettings = ({storedDomain, parsedResult}) =>
192+
useZoomRequeryYDomainSettings({
193+
parsedResult,
194+
setResult: setResultState,
195+
preZoomResult,
196+
setPreZoomResult,
197+
query: properties?.queries?.[0]?.text ?? '',
198+
storedDomain,
199+
data: memoizedYColumnData,
200+
})
201+
}
202+
203+
const [xDomain, onSetXDomain, onResetXDomain] = useXDomainSettings({
204+
storedDomain: storedXDomain,
205+
parsedResult: resultState,
206+
timeRange,
207+
})
208+
209+
const [yDomain, onSetYDomain, onResetYDomain] = useYDomainSettings({
210+
storedDomain: storedYDomain,
211+
parsedResult: resultState,
212+
timeRange,
213+
})
160214

161215
const legendColumns = filterNoisyColumns(
162216
properties.position === 'stacked'
@@ -168,18 +222,18 @@ const XYPlot: FC<Props> = ({
168222
`_${LINE_COUNT}`,
169223
]
170224
: [...groupKey, xColumn, yColumn],
171-
result.table
225+
resultState.table
172226
)
173227

174-
const xFormatter = getFormatter(result.table.getColumnType(xColumn), {
228+
const xFormatter = getFormatter(resultState.table.getColumnType(xColumn), {
175229
prefix: properties.axes.x.prefix,
176230
suffix: properties.axes.x.suffix,
177231
base: properties.axes.x.base,
178232
timeZone,
179233
timeFormat: properties.timeFormat,
180234
})
181235

182-
const yFormatter = getFormatter(result.table.getColumnType(yColumn), {
236+
const yFormatter = getFormatter(resultState.table.getColumnType(yColumn), {
183237
prefix: properties.axes.y.prefix,
184238
suffix: properties.axes.y.suffix,
185239
base: properties.axes.y.base,
@@ -197,7 +251,7 @@ const XYPlot: FC<Props> = ({
197251

198252
if (isFlagEnabled('graphColorMapping')) {
199253
const memoizedGetColorMappingObjects = memoizeOne(getColorMappingObjects)
200-
const [, fillColumnMap] = createGroupIDColumn(result.table, groupKey)
254+
const [, fillColumnMap] = createGroupIDColumn(resultState.table, groupKey)
201255
const {
202256
colorMappingForGiraffe,
203257
colorMappingForIDPE,
@@ -218,7 +272,7 @@ const XYPlot: FC<Props> = ({
218272

219273
const config: Config = {
220274
...currentTheme,
221-
table: result.table,
275+
table: resultState.table,
222276
xAxisLabel: properties.axes.x.label,
223277
yAxisLabel: properties.axes.y.label,
224278
xDomain,

0 commit comments

Comments
 (0)