Merge pull request #3159 from influxdata/chore/crosshair-performance

Chore/crosshair performance
pull/10616/head
Andrew Watkins 2018-04-10 14:33:37 -07:00 committed by GitHub
commit a8b3926296
15 changed files with 172 additions and 187 deletions

View File

@ -186,6 +186,13 @@ export const editTemplateVariableValues = (
},
})
export const setHoverTime = hoverTime => ({
type: 'SET_HOVER_TIME',
payload: {
hoverTime,
},
})
// Async Action Creators
export const getDashboardsAsync = () => async dispatch => {

View File

@ -25,8 +25,6 @@ const Dashboard = ({
showTemplateControlBar,
setScrollTop,
inView,
onSetHoverTime,
hoverTime,
}) => {
const cells = dashboard.cells.map(cell => {
const dashboardCell = {
@ -67,8 +65,6 @@ const Dashboard = ({
timeRange={timeRange}
autoRefresh={autoRefresh}
manualRefresh={manualRefresh}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
onDeleteCell={onDeleteCell}
onPositionChange={onPositionChange}
templates={templatesIncludingDashTime}
@ -116,8 +112,6 @@ Dashboard.propTypes = {
onPositionChange: func,
onDeleteCell: func,
onSummonOverlayTechnologies: func,
hoverTime: string,
onSetHoverTime: func,
source: shape({
links: shape({
proxy: string,

View File

@ -18,7 +18,6 @@ import ManualRefresh from 'src/shared/components/ManualRefresh'
import {errorThrown as errorThrownAction} from 'shared/actions/errors'
import {notify as notifyAction} from 'shared/actions/notifications'
import idNormalizer, {TYPE_ID} from 'src/normalizers/id'
import {NULL_HOVER_TIME} from 'src/shared/constants/tableGraph'
import * as dashboardActionCreators from 'src/dashboards/actions'
import * as annotationActions from 'shared/actions/annotations'
@ -58,12 +57,9 @@ class DashboardPage extends Component {
zoomedTimeRange: {zoomedLower: null, zoomedUpper: null},
scrollTop: 0,
windowHeight: window.innerHeight,
hoverTime: NULL_HOVER_TIME,
}
}
dygraphs = []
async componentDidMount() {
const {
params: {dashboardID},
@ -279,10 +275,6 @@ class DashboardPage extends Component {
this.props.errorThrown(error)
}
handleSetHoverTime = hoverTime => {
this.setState({hoverTime})
}
handleToggleTempVarControls = () => {
this.props.templateControlBarVisibilityToggled()
}
@ -296,7 +288,7 @@ class DashboardPage extends Component {
}
render() {
const {zoomedTimeRange, hoverTime} = this.state
const {zoomedTimeRange} = this.state
const {zoomedLower, zoomedUpper} = zoomedTimeRange
const {
source,
@ -441,8 +433,6 @@ class DashboardPage extends Component {
manualRefresh={manualRefresh}
onZoom={this.handleZoomedTimeRange}
onAddCell={this.handleAddCell}
hoverTime={hoverTime}
onSetHoverTime={this.handleSetHoverTime}
inPresentationMode={inPresentationMode}
onPositionChange={this.handleUpdatePosition}
onSelectTemplate={this.handleSelectTemplate}

View File

@ -1,5 +1,6 @@
import _ from 'lodash'
import {timeRanges} from 'shared/data/timeRanges'
import {NULL_HOVER_TIME} from 'src/shared/constants/tableGraph'
const {lower, upper} = timeRanges.find(tr => tr.lower === 'now() - 1h')
@ -8,6 +9,7 @@ const initialState = {
timeRange: {lower, upper},
isEditMode: false,
cellQueryStatus: {queryID: null, status: null},
hoverTime: NULL_HOVER_TIME,
}
import {
@ -312,6 +314,12 @@ export default function ui(state = initialState, action) {
return {...state, dashboards}
}
case 'SET_HOVER_TIME': {
const {hoverTime} = action.payload
return {...state, hoverTime}
}
}
return state

View File

@ -7,27 +7,27 @@ import AnnotationSpan from 'shared/components/AnnotationSpan'
import * as schema from 'shared/schemas'
const Annotation = ({
dygraph,
annotation,
mode,
lastUpdated,
dygraph,
dWidth,
annotation,
staticLegendHeight,
}) => (
<div>
{annotation.startTime === annotation.endTime ? (
<AnnotationPoint
lastUpdated={lastUpdated}
annotation={annotation}
mode={mode}
dygraph={dygraph}
annotation={annotation}
dWidth={dWidth}
staticLegendHeight={staticLegendHeight}
/>
) : (
<AnnotationSpan
lastUpdated={lastUpdated}
annotation={annotation}
mode={mode}
dygraph={dygraph}
annotation={annotation}
dWidth={dWidth}
staticLegendHeight={staticLegendHeight}
/>
)}
@ -38,7 +38,7 @@ const {number, shape, string} = PropTypes
Annotation.propTypes = {
mode: string,
lastUpdated: number,
dWidth: number,
annotation: schema.annotation.isRequired,
dygraph: shape({}).isRequired,
staticLegendHeight: number,

View File

@ -19,22 +19,10 @@ import {
import {visibleAnnotations} from 'src/shared/annotations/helpers'
class Annotations extends Component {
state = {
lastUpdated: null,
}
componentDidMount() {
this.props.annotationsRef(this)
}
heartbeat = () => {
this.setState({lastUpdated: Date.now()})
}
render() {
const {lastUpdated} = this.state
const {
mode,
dWidth,
dygraph,
isTempHovering,
handleUpdateAnnotation,
@ -45,53 +33,56 @@ class Annotations extends Component {
staticLegendHeight,
} = this.props
const annotations = visibleAnnotations(
dygraph,
this.props.annotations
).filter(a => a.id !== TEMP_ANNOTATION.id)
const tempAnnotation = this.props.annotations.find(
a => a.id === TEMP_ANNOTATION.id
)
return (
<div className="annotations-container">
{mode === ADDING &&
tempAnnotation && (
this.tempAnnotation && (
<NewAnnotation
dygraph={dygraph}
tempAnnotation={tempAnnotation}
isTempHovering={isTempHovering}
tempAnnotation={this.tempAnnotation}
staticLegendHeight={staticLegendHeight}
onUpdateAnnotation={handleUpdateAnnotation}
onDismissAddingAnnotation={handleDismissAddingAnnotation}
onAddingAnnotationSuccess={handleAddingAnnotationSuccess}
onUpdateAnnotation={handleUpdateAnnotation}
isTempHovering={isTempHovering}
onMouseEnterTempAnnotation={handleMouseEnterTempAnnotation}
onMouseLeaveTempAnnotation={handleMouseLeaveTempAnnotation}
staticLegendHeight={staticLegendHeight}
/>
)}
{annotations.map(a => (
{this.annotations.map(a => (
<Annotation
key={a.id}
mode={mode}
annotation={a}
dygraph={dygraph}
dWidth={dWidth}
staticLegendHeight={staticLegendHeight}
lastUpdated={lastUpdated}
/>
))}
</div>
)
}
get annotations() {
return visibleAnnotations(
this.props.dygraph,
this.props.annotations
).filter(a => a.id !== TEMP_ANNOTATION.id)
}
get tempAnnotation() {
return this.props.annotations.find(a => a.id === TEMP_ANNOTATION.id)
}
}
const {arrayOf, bool, func, number, shape, string} = PropTypes
Annotations.propTypes = {
annotations: arrayOf(schema.annotation),
dygraph: shape({}),
dygraph: shape({}).isRequired,
dWidth: number.isRequired,
mode: string,
isTempHovering: bool,
annotationsRef: func,
handleUpdateAnnotation: func.isRequired,
handleDismissAddingAnnotation: func.isRequired,
handleAddingAnnotationSuccess: func.isRequired,

View File

@ -1,36 +1,48 @@
import React, {Component} from 'react'
import React, {PureComponent} from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'shared/constants'
import {NULL_HOVER_TIME} from 'shared/constants/tableGraph'
import classnames from 'classnames'
class Crosshair extends PureComponent {
shouldCompnentUpdate(nextProps) {
return this.props.hoverTime !== nextProps.hoverTime
}
class Crosshair extends Component {
render() {
const {dygraph, staticLegendHeight, hoverTime} = this.props
const crosshairLeft = Math.round(
Math.max(-1000, dygraph.toDomXCoord(hoverTime)) || -1000 + 1
)
const crosshairHeight = `calc(100% - ${staticLegendHeight +
DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
const crosshairHidden = hoverTime === NULL_HOVER_TIME
return (
<div className="crosshair-container">
<div
className={classnames('crosshair', {
hidden: crosshairHidden,
hidden: this.isHidden,
})}
style={{
left: crosshairLeft,
height: crosshairHeight,
left: this.crosshairLeft,
height: this.crosshairHeight,
zIndex: 1999,
}}
/>
</div>
)
}
get crosshairLeft() {
const {dygraph, hoverTime} = this.props
return Math.round(
Math.max(-1000, dygraph.toDomXCoord(hoverTime)) || -1000 + 1
)
}
get crosshairHeight() {
return `calc(100% - ${this.props.staticLegendHeight +
DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
}
get isHidden() {
return this.props.hoverTime === NULL_HOVER_TIME
}
}
const {number, shape, string} = PropTypes

View File

@ -23,7 +23,6 @@ import {
LABEL_WIDTH,
CHAR_PIXELS,
barPlotter,
highlightSeriesOpts,
} from 'src/shared/graphs/helpers'
import {getLineColorsHexes} from 'src/shared/constants/graphColorPalettes'
@ -49,21 +48,20 @@ class Dygraph extends Component {
options,
} = this.props
const timeSeries = this.getTimeSeries()
const timeSeries = this.timeSeries
const graphRef = this.graphRef
let defaultOptions = {
fillGraph,
logscale: y.scale === LOG,
colors: this.getLineColors(),
series: this.colorDygraphSeries(),
plugins: [new Dygraphs.Plugins.Crosshair({direction: 'vertical'})],
colors: this.lineColors,
series: this.colorDygraphSeries,
axes: {
y: {
valueRange: this.getYRange(timeSeries),
axisLabelFormatter: (yval, __, opts) =>
numberValueFormatter(yval, opts, y.prefix, y.suffix),
axisLabelWidth: this.getLabelWidth(),
axisLabelWidth: this.labelWidth,
labelsKMB: y.base === BASE_10,
labelsKMG2: y.base === BASE_2,
},
@ -71,7 +69,6 @@ class Dygraph extends Component {
valueRange: getRange(timeSeries, y2.bounds),
},
},
highlightSeriesOpts,
zoomCallback: (lower, upper) => this.handleZoom(lower, upper),
}
@ -79,11 +76,6 @@ class Dygraph extends Component {
defaultOptions = {
...defaultOptions,
plotter: barPlotter,
plugins: [],
highlightSeriesOpts: {
...highlightSeriesOpts,
highlightCircleSize: 0,
},
}
}
@ -130,7 +122,7 @@ class Dygraph extends Component {
)
}
const timeSeries = this.getTimeSeries()
const timeSeries = this.timeSeries
const updateOptions = {
...options,
@ -143,7 +135,7 @@ class Dygraph extends Component {
valueRange: this.getYRange(timeSeries),
axisLabelFormatter: (yval, __, opts) =>
numberValueFormatter(yval, opts, y.prefix, y.suffix),
axisLabelWidth: this.getLabelWidth(),
axisLabelWidth: this.labelWidth,
labelsKMB: y.base === BASE_10,
labelsKMG2: y.base === BASE_2,
},
@ -151,10 +143,9 @@ class Dygraph extends Component {
valueRange: getRange(timeSeries, y2.bounds),
},
},
colors: this.getLineColors(),
series: this.colorDygraphSeries(),
colors: this.lineColors,
series: this.colorDygraphSeries,
plotter: isBarGraph ? barPlotter : null,
drawCallback: this.annotationsRef.heartbeat,
}
dygraph.updateOptions(updateOptions)
@ -192,7 +183,7 @@ class Dygraph extends Component {
onZoom(this.formatTimeRange(lower), this.formatTimeRange(upper))
}
colorDygraphSeries = () => {
get colorDygraphSeries() {
const {dygraphSeries, colors, overrideLineColors} = this.props
const numSeries = Object.keys(dygraphSeries).length
const dygraphSeriesKeys = Object.keys(dygraphSeries).sort()
@ -221,32 +212,15 @@ class Dygraph extends Component {
return `${clamped}`
}
handleMouseMove = e => {
if (this.props.onSetHoverTime) {
const newTime = this.eventToTimestamp(e)
this.props.onSetHoverTime(newTime)
}
this.setState({isHoveringThisGraph: true})
}
handleMouseOut = () => {
if (this.props.onSetHoverTime) {
this.props.onSetHoverTime(NULL_HOVER_TIME)
}
this.setState({isHoveringThisGraph: false})
}
handleHideLegend = () => {
this.setState({isHidden: true})
}
getLineColors = () => {
get lineColors() {
return [...(this.props.overrideLineColors || LINE_COLORS)]
}
getLabelWidth = () => {
get labelWidth() {
const {axes: {y}} = this.props
return (
LABEL_WIDTH +
@ -255,7 +229,7 @@ class Dygraph extends Component {
)
}
getTimeSeries = () => {
get timeSeries() {
const {timeSeries} = this.props
// Avoid 'Can't plot empty data set' errors by falling back to a
// default dataset that's valid for Dygraph.
@ -288,31 +262,37 @@ class Dygraph extends Component {
return date.toISOString()
}
deselectCrosshair = () => {
const plugins = this.dygraph.plugins_
const crosshair = plugins.find(
({plugin}) => plugin.toString() === 'Crosshair Plugin'
)
handleMouseMove = e => {
const newTime = this.eventToTimestamp(e)
this.props.handleSetHoverTime(newTime)
if (!crosshair || this.props.isBarGraph) {
return
}
this.setState({isHoveringThisGraph: true})
}
crosshair.plugin.deselect()
handleMouseLeave = () => {
this.props.handleSetHoverTime(NULL_HOVER_TIME)
this.setState({isHoveringThisGraph: false})
}
handleShowLegend = () => {
this.setState({isHidden: false})
}
handleAnnotationsRef = ref => (this.annotationsRef = ref)
handleReceiveStaticLegendHeight = staticLegendHeight => {
this.setState({staticLegendHeight})
}
get areAnnotationsVisible() {
if (!this.dygraph) {
return false
}
const [start, end] = this.dygraph && this.dygraph.xAxisRange()
return !!start && !!end
}
render() {
const {isHidden, staticLegendHeight, isHoveringThisGraph} = this.state
const {isHidden, staticLegendHeight} = this.state
const {staticLegend, children, hoverTime} = this.props
const nestedGraph = (children && children.length && children[0]) || children
let dygraphStyle = {...this.props.containerStyle, zIndex: '2'}
@ -327,12 +307,12 @@ class Dygraph extends Component {
}
return (
<div className="dygraph-child" onMouseLeave={this.deselectCrosshair}>
{this.dygraph && (
<div className="dygraph-child" onMouseLeave={this.handleMouseLeave}>
{this.areAnnotationsVisible && (
<div className="dygraph-addons">
<Annotations
dygraph={this.dygraph}
annotationsRef={this.handleAnnotationsRef}
dWidth={this.dygraph.width_}
staticLegendHeight={staticLegendHeight}
/>
<DygraphLegend
@ -341,13 +321,11 @@ class Dygraph extends Component {
onHide={this.handleHideLegend}
onShow={this.handleShowLegend}
/>
{!isHoveringThisGraph && (
<Crosshair
dygraph={this.dygraph}
staticLegendHeight={staticLegendHeight}
hoverTime={hoverTime}
/>
)}
<Crosshair
dygraph={this.dygraph}
staticLegendHeight={staticLegendHeight}
hoverTime={hoverTime}
/>
</div>
)}
<div
@ -357,12 +335,12 @@ class Dygraph extends Component {
}}
className="dygraph-child-container"
style={dygraphStyle}
onMouseMove={this.handleMouseMove}
onMouseMove={_.throttle(this.handleMouseMove, 100)}
onMouseOut={this.handleMouseOut}
/>
{staticLegend && (
<StaticLegend
dygraphSeries={this.colorDygraphSeries()}
dygraphSeries={this.colorDygraphSeries}
dygraph={this.dygraph}
handleReceiveStaticLegendHeight={
this.handleReceiveStaticLegendHeight
@ -397,12 +375,14 @@ Dygraph.defaultProps = {
overrideLineColors: null,
dygraphRef: () => {},
onZoom: () => {},
handleSetHoverTime: () => {},
staticLegend: {
type: null,
},
}
Dygraph.propTypes = {
handleSetHoverTime: func,
axes: shape({
y: shape({
bounds: array,
@ -435,7 +415,6 @@ Dygraph.propTypes = {
lower: string.isRequired,
}),
hoverTime: string,
onSetHoverTime: func,
setResolution: func,
dygraphRef: func,
onZoom: func,

View File

@ -60,8 +60,6 @@ const Layout = (
onStopAddAnnotation,
onSummonOverlayTechnologies,
grabDataForDownload,
hoverTime,
onSetHoverTime,
},
{source: defaultSource}
) => (
@ -90,8 +88,6 @@ const Layout = (
timeRange={timeRange}
templates={templates}
autoRefresh={autoRefresh}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
manualRefresh={manualRefresh}
onStopAddAnnotation={onStopAddAnnotation}
grabDataForDownload={grabDataForDownload}
@ -149,8 +145,6 @@ const propTypes = {
onEditCell: func,
onDeleteCell: func,
onSummonOverlayTechnologies: func,
hoverTime: string,
onSetHoverTime: func,
isStatusPage: bool,
isEditable: bool,
onCancelEditCell: func,

View File

@ -74,8 +74,6 @@ class LayoutRenderer extends Component {
onDeleteCell,
onCancelEditCell,
onSummonOverlayTechnologies,
hoverTime,
onSetHoverTime,
} = this.props
const {rowHeight, resizeCoords} = this.state
@ -130,8 +128,6 @@ class LayoutRenderer extends Component {
autoRefresh={autoRefresh}
resizeCoords={resizeCoords}
onDeleteCell={onDeleteCell}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
manualRefresh={manualRefresh}
onCancelEditCell={onCancelEditCell}
onStopAddAnnotation={this.handleStopAddAnnotation}
@ -186,8 +182,6 @@ LayoutRenderer.propTypes = {
onEditCell: func,
onDeleteCell: func,
onSummonOverlayTechnologies: func,
hoverTime: string,
onSetHoverTime: func,
isStatusPage: bool,
isEditable: bool,
onCancelEditCell: func,

View File

@ -44,6 +44,7 @@ class LineGraph extends Component {
colors,
onZoom,
queries,
hoverTime,
timeRange,
cellHeight,
ruleValues,
@ -58,8 +59,7 @@ class LineGraph extends Component {
underlayCallback,
overrideLineColors,
isFetchingInitially,
hoverTime,
onSetHoverTime,
handleSetHoverTime,
} = this.props
const {labels, timeSeries, dygraphSeries} = this._timeSeries
@ -101,20 +101,20 @@ class LineGraph extends Component {
<Dygraph
cell={cell}
axes={axes}
colors={colors}
onZoom={onZoom}
labels={labels}
hoverTime={hoverTime}
queries={queries}
options={options}
timeRange={timeRange}
isBarGraph={isBarGraph}
timeSeries={timeSeries}
ruleValues={ruleValues}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
resizeCoords={resizeCoords}
dygraphSeries={dygraphSeries}
setResolution={setResolution}
colors={colors}
handleSetHoverTime={handleSetHoverTime}
overrideLineColors={overrideLineColors}
containerStyle={containerStyle}
staticLegend={staticLegend}
@ -170,6 +170,8 @@ LineGraph.propTypes = {
label: string,
}),
}),
hoverTime: string,
handleSetHoverTime: func,
title: string,
isFetchingInitially: bool,
isRefreshing: bool,
@ -189,8 +191,6 @@ LineGraph.propTypes = {
lower: string.isRequired,
}),
isInDataExplorer: bool,
hoverTime: string,
onSetHoverTime: func,
setResolution: func,
cellHeight: number,
cell: shape(),

View File

@ -1,7 +1,9 @@
import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import {emptyGraphCopy} from 'src/shared/copy/cell'
import {bindActionCreators} from 'redux'
import AutoRefresh from 'shared/components/AutoRefresh'
import LineGraph from 'shared/components/LineGraph'
@ -10,6 +12,7 @@ import GaugeChart from 'shared/components/GaugeChart'
import TableGraph from 'shared/components/TableGraph'
import {colorsStringSchema} from 'shared/schemas'
import {setHoverTime} from 'src/dashboards/actions'
const RefreshingLineGraph = AutoRefresh(LineGraph)
const RefreshingSingleStat = AutoRefresh(SingleStat)
@ -24,6 +27,7 @@ const RefreshingGraph = ({
onZoom,
cellID,
queries,
hoverTime,
tableOptions,
templates,
timeRange,
@ -34,9 +38,8 @@ const RefreshingGraph = ({
manualRefresh, // when changed, re-mounts the component
resizeCoords,
editQueryStatus,
handleSetHoverTime,
grabDataForDownload,
hoverTime,
onSetHoverTime,
}) => {
const prefix = (axes && axes.y.prefix) || ''
const suffix = (axes && axes.y.suffix) || ''
@ -87,19 +90,19 @@ const RefreshingGraph = ({
if (type === 'table') {
return (
<RefreshingTableGraph
cellID={cellID}
colors={colors}
inView={inView}
hoverTime={hoverTime}
key={manualRefresh}
queries={queries}
templates={templates}
autoRefresh={autoRefresh}
cellHeight={cellHeight}
resizerTopHeight={resizerTopHeight}
resizeCoords={resizeCoords}
cellID={cellID}
tableOptions={tableOptions}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
inView={inView}
resizerTopHeight={resizerTopHeight}
handleSetHoverTime={handleSetHoverTime}
/>
)
}
@ -120,14 +123,14 @@ const RefreshingGraph = ({
templates={templates}
timeRange={timeRange}
autoRefresh={autoRefresh}
isBarGraph={type === 'bar'}
hoverTime={hoverTime}
onSetHoverTime={onSetHoverTime}
isBarGraph={type === 'bar'}
resizeCoords={resizeCoords}
staticLegend={staticLegend}
displayOptions={displayOptions}
editQueryStatus={editQueryStatus}
grabDataForDownload={grabDataForDownload}
handleSetHoverTime={handleSetHoverTime}
showSingleStat={type === 'line-plus-single-stat'}
/>
)
@ -142,8 +145,6 @@ RefreshingGraph.propTypes = {
autoRefresh: number.isRequired,
manualRefresh: number,
templates: arrayOf(shape()),
hoverTime: string,
onSetHoverTime: func,
type: string.isRequired,
cellHeight: number,
resizerTopHeight: number,
@ -158,6 +159,8 @@ RefreshingGraph.propTypes = {
cellID: string,
inView: bool,
tableOptions: shape({}),
hoverTime: string.isRequired,
handleSetHoverTime: func.isRequired,
}
RefreshingGraph.defaultProps = {
@ -166,4 +169,13 @@ RefreshingGraph.defaultProps = {
inView: true,
}
export default RefreshingGraph
const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
mode,
hoverTime: dashboardUI.hoverTime,
})
const mapDispatchToProps = dispatch => ({
handleSetHoverTime: bindActionCreators(setHoverTime, dispatch),
})
export default connect(mapStateToProps, mapDispatchToProps)(RefreshingGraph)

View File

@ -131,16 +131,16 @@ class TableGraph extends Component {
}
handleHover = (columnIndex, rowIndex) => () => {
const {onSetHoverTime, tableOptions: {verticalTimeAxis}} = this.props
const {handleSetHoverTime, tableOptions: {verticalTimeAxis}} = this.props
const {sortedTimeVals} = this.state
if (verticalTimeAxis && rowIndex === 0) {
return
}
if (onSetHoverTime) {
if (handleSetHoverTime) {
const hoverTime = verticalTimeAxis
? sortedTimeVals[rowIndex]
: sortedTimeVals[columnIndex]
onSetHoverTime(hoverTime.toString())
handleSetHoverTime(hoverTime.toString())
}
this.setState({
hoveredColumnIndex: columnIndex,
@ -149,8 +149,8 @@ class TableGraph extends Component {
}
handleMouseLeave = () => {
if (this.props.onSetHoverTime) {
this.props.onSetHoverTime(NULL_HOVER_TIME)
if (this.props.handleSetHoverTime) {
this.props.handleSetHoverTime(NULL_HOVER_TIME)
this.setState({
hoveredColumnIndex: NULL_ARRAY_INDEX,
hoveredRowIndex: NULL_ARRAY_INDEX,
@ -300,7 +300,7 @@ class TableGraph extends Component {
style={cellStyle}
className={cellClass}
onClick={isFieldName ? this.handleClickFieldName(cellData) : null}
onMouseOver={this.handleHover(columnIndex, rowIndex)}
onMouseOver={_.throttle(this.handleHover(columnIndex, rowIndex), 100)}
title={cellContents}
>
{cellContents}
@ -407,7 +407,7 @@ TableGraph.propTypes = {
fixFirstColumn: bool,
}),
hoverTime: string,
onSetHoverTime: func,
handleSetHoverTime: func,
colors: colorsStringSchema,
}

View File

@ -190,10 +190,6 @@ export const OPTIONS = {
highlightSeriesBackgroundColor: 'rgb(41, 41, 51)',
}
export const highlightSeriesOpts = {
highlightCircleSize: 5,
}
export const hasherino = (str, len) =>
str
.split('')

View File

@ -4,19 +4,27 @@ import queryString from 'query-string'
import {enablePresentationMode} from 'src/shared/actions/app'
import {templateVariablesSelectedByName} from 'src/dashboards/actions'
export const queryStringConfig = () => next => action => {
next(action)
const qs = queryString.parse(window.location.search)
export const queryStringConfig = () => {
let prevPath
return next => action => {
next(action)
const qs = queryString.parse(window.location.search)
// Presentation Mode
if (qs.present === 'true') {
next(enablePresentationMode())
}
// Presentation Mode
if (qs.present === 'true') {
next(enablePresentationMode())
}
// Select Template Variable By Name
const dashboardRegex = /\/sources\/(\d+?)\/dashboards\/(\d+?)/
if (dashboardRegex.test(window.location.pathname)) {
const dashboardID = window.location.pathname.match(dashboardRegex)[2]
next(templateVariablesSelectedByName(+dashboardID, qs))
// Select Template Variable By Name
const dashboardRegex = /\/sources\/(\d+?)\/dashboards\/(\d+?)/
if (dashboardRegex.test(window.location.pathname)) {
const currentPath = window.location.pathname
const dashboardID = currentPath.match(dashboardRegex)[2]
if (currentPath !== prevPath) {
next(templateVariablesSelectedByName(+dashboardID, qs))
}
prevPath = currentPath
}
}
}