prevent historical graph zoom state from resetting during data updates

This commit is contained in:
Nick Krecklow 2020-06-10 18:42:51 -05:00
parent d33cf682e9
commit 6aeb8b5045
No known key found for this signature in database
GPG Key ID: 5F149FDE156FFA94
3 changed files with 55 additions and 5 deletions

@ -3,7 +3,7 @@ import uPlot from 'uplot'
import { RelativeScale } from './scale' import { RelativeScale } from './scale'
import { formatNumber, formatTimestampSeconds } from './util' import { formatNumber, formatTimestampSeconds } from './util'
import { uPlotTooltipPlugin } from './tooltip' import { uPlotTooltipPlugin, uPlotIsZoomedPlugin } from './plugins'
import { FAVORITE_SERVERS_STORAGE_KEY } from './favorites' import { FAVORITE_SERVERS_STORAGE_KEY } from './favorites'
@ -18,6 +18,7 @@ export class GraphDisplayManager {
this._hasLoadedSettings = false this._hasLoadedSettings = false
this._initEventListenersOnce = false this._initEventListenersOnce = false
this._showOnlyFavorites = false this._showOnlyFavorites = false
this._isPlotZoomed = false
} }
addGraphPoint (timestamp, playerCounts) { addGraphPoint (timestamp, playerCounts) {
@ -49,8 +50,14 @@ export class GraphDisplayManager {
} }
} }
// Paint updated data structure // If not zoomed, paint updated data structure
this._plotInstance.setData(this.getGraphData()) // Otherwise flag the plot data as dirty with repainting to be handled by #handlePlotZoomOut
// This prevents #addGraphPoint calls from resetting the graph's zoom state
if (!this._isPlotZoomed) {
this._plotInstance.setData(this.getGraphData())
} else {
this._isPlotZoomedDataDirty = true
}
} }
loadLocalStorage () { loadLocalStorage () {
@ -244,7 +251,8 @@ export class GraphDisplayManager {
} else { } else {
this._app.tooltip.hide() this._app.tooltip.hide()
} }
}) }),
uPlotIsZoomedPlugin(this.handlePlotZoomIn, this.handlePlotZoomOut)
], ],
...this.getPlotSize(), ...this.getPlotSize(),
cursor: { cursor: {
@ -339,6 +347,21 @@ export class GraphDisplayManager {
this._resizeRequestTimeout = undefined this._resizeRequestTimeout = undefined
} }
handlePlotZoomIn = () => {
this._isPlotZoomed = true
}
handlePlotZoomOut = () => {
this._isPlotZoomed = false
// Test if the data has changed while the plot was zoomed in
if (this._isPlotZoomedDataDirty) {
this._isPlotZoomedDataDirty = false
this._plotInstance.setData(this.getGraphData())
}
}
initEventListeners () { initEventListeners () {
if (!this._initEventListenersOnce) { if (!this._initEventListenersOnce) {
this._initEventListenersOnce = true this._initEventListenersOnce = true
@ -446,6 +469,9 @@ export class GraphDisplayManager {
this._graphData = [] this._graphData = []
this._hasLoadedSettings = false this._hasLoadedSettings = false
this._isPlotZoomed = false
this._isPlotZoomedDataDirty = false
// Fire #clearTimeout if the timeout is currently defined // Fire #clearTimeout if the timeout is currently defined
if (this._resizeRequestTimeout) { if (this._resizeRequestTimeout) {
clearTimeout(this._resizeRequestTimeout) clearTimeout(this._resizeRequestTimeout)

@ -26,3 +26,27 @@ export function uPlotTooltipPlugin (onHover) {
} }
} }
} }
export function uPlotIsZoomedPlugin (onZoomIn, onZoomOut) {
return {
hooks: {
setSelect: u => {
u._zoomPluginIgnoreNextSetScale = true
if (onZoomIn) {
onZoomIn(u)
}
},
setScale: u => {
if (typeof u._zoomPluginIgnoreNextSetScale !== 'boolean') {
return
}
if (u._zoomPluginIgnoreNextSetScale) {
u._zoomPluginIgnoreNextSetScale = false
} else if (onZoomOut) {
onZoomOut(u)
}
}
}
}
}

@ -3,7 +3,7 @@ import uPlot from 'uplot'
import { RelativeScale } from './scale' import { RelativeScale } from './scale'
import { formatNumber, formatTimestampSeconds, formatDate, formatMinecraftServerAddress, formatMinecraftVersions } from './util' import { formatNumber, formatTimestampSeconds, formatDate, formatMinecraftServerAddress, formatMinecraftVersions } from './util'
import { uPlotTooltipPlugin } from './tooltip' import { uPlotTooltipPlugin } from './plugins'
import MISSING_FAVICON from '../images/missing_favicon.svg' import MISSING_FAVICON from '../images/missing_favicon.svg'