Separate RuleGraph from LineGraph

pull/3904/head
Andrew Watkins 2018-07-13 16:09:04 -07:00
parent 5ee0f5771a
commit bf5157b530
6 changed files with 138 additions and 86 deletions

View File

@ -17,6 +17,7 @@ import {
import {ColorString, ColorNumber} from 'src/types/colors'
interface Props {
axes: Axes
type: CellType
source: Source
autoRefresh: number
@ -24,7 +25,6 @@ interface Props {
timeRange: TimeRange
queryConfigs: QueryConfig[]
editQueryStatus: () => void
axes: Axes
tableOptions: TableOptions
timeFormat: string
decimalPlaces: DecimalPlaces

View File

@ -1,71 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import buildInfluxQLQuery from 'utils/influxql'
import AutoRefresh from 'shared/components/AutoRefresh'
import LineGraph from 'shared/components/LineGraph'
import TimeRangeDropdown from 'shared/components/TimeRangeDropdown'
import underlayCallback from 'src/kapacitor/helpers/ruleGraphUnderlay'
const RefreshingLineGraph = AutoRefresh(LineGraph)
import {LINE_COLORS_RULE_GRAPH} from 'src/shared/constants/graphColorPalettes'
const {shape, string, func} = PropTypes
const RuleGraph = ({
query,
source,
timeRange: {lower},
timeRange,
rule,
onChooseTimeRange,
}) => {
const autoRefreshMs = 30000
const queryText = buildInfluxQLQuery({lower}, query)
const queries = [{host: source.links.proxy, text: queryText}]
if (!queryText) {
return (
<div className="rule-builder--graph-empty">
<p>
Select a <strong>Time-Series</strong> to preview on a graph
</p>
</div>
)
}
return (
<div className="rule-builder--graph">
<div className="rule-builder--graph-options">
<p>Preview Data from</p>
<TimeRangeDropdown
onChooseTimeRange={onChooseTimeRange}
selected={timeRange}
preventCustomTimeRange={true}
/>
</div>
<RefreshingLineGraph
source={source}
queries={queries}
isGraphFilled={false}
ruleValues={rule.values}
autoRefresh={autoRefreshMs}
colors={LINE_COLORS_RULE_GRAPH}
underlayCallback={underlayCallback(rule)}
/>
</div>
)
}
RuleGraph.propTypes = {
source: shape({
links: shape({
proxy: string.isRequired,
}).isRequired,
}).isRequired,
query: shape({}).isRequired,
rule: shape({}).isRequired,
timeRange: shape({}).isRequired,
onChooseTimeRange: func.isRequired,
}
export default RuleGraph

View File

@ -0,0 +1,127 @@
// Libraries
import React, {PureComponent, CSSProperties} from 'react'
import TimeSeries from 'src/shared/components/time_series/TimeSeries'
// Components
import Dygraph from 'src/shared/components/Dygraph'
import TimeRangeDropdown from 'src/shared/components/TimeRangeDropdown'
// Utils
import buildInfluxQLQuery from 'src/utils/influxql'
import buildQueries from 'src/utils/buildQueriesForGraphs'
import underlayCallback from 'src/kapacitor/helpers/ruleGraphUnderlay'
import {timeSeriesToDygraph} from 'src/utils/timeSeriesTransformers'
// Constants
import {LINE_COLORS_RULE_GRAPH} from 'src/shared/constants/graphColorPalettes'
// Types
import {Source, AlertRule, QueryConfig, Query, TimeRange} from 'src/types'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
source: Source
query: QueryConfig
rule: AlertRule
timeRange: TimeRange
onChooseTimeRange: (tR: TimeRange) => void
}
@ErrorHandling
class RuleGraph extends PureComponent<Props> {
public render() {
const {source, onChooseTimeRange, timeRange, rule} = this.props
if (!this.queryText) {
return (
<div className="rule-builder--graph-empty">
<p>
Select a <strong>Time-Series</strong> to preview on a graph
</p>
</div>
)
}
return (
<div className="rule-builder--graph">
<div className="rule-builder--graph-options">
<p>Preview Data from</p>
<TimeRangeDropdown
onChooseTimeRange={onChooseTimeRange}
selected={timeRange}
preventCustomTimeRange={true}
/>
</div>
<div className="dygraph graph--hasYLabel" style={this.style}>
<TimeSeries source={source} queries={this.queries}>
{data => {
const {labels, timeSeries, dygraphSeries} = timeSeriesToDygraph(
data.timeSeries,
'rule-builder'
)
return (
<Dygraph
labels={labels}
staticLegend={false}
isGraphFilled={false}
ruleValues={rule.values}
options={this.options}
timeRange={timeRange}
queries={this.queries}
timeSeries={timeSeries}
dygraphSeries={dygraphSeries}
colors={LINE_COLORS_RULE_GRAPH}
containerStyle={this.containerStyle}
underlayCallback={underlayCallback(rule)}
/>
)
}}
</TimeSeries>
</div>
</div>
)
}
private get options() {
return {
rightGap: 0,
yRangePad: 10,
labelsKMB: true,
fillGraph: true,
axisLabelWidth: 60,
animatedZooms: true,
drawAxesAtZero: true,
axisLineColor: '#383846',
gridLineColor: '#383846',
connectSeparatedPoints: true,
}
}
private get containerStyle(): CSSProperties {
return {
width: 'calc(100% - 32px)',
height: 'calc(100% - 16px)',
position: 'absolute',
top: '8px',
}
}
private get style(): CSSProperties {
return {height: '100%'}
}
private get queryText(): string {
const {timeRange, query} = this.props
const lower = timeRange.lower
return buildInfluxQLQuery({lower}, query)
}
private get queries(): Query[] {
const {query, timeRange} = this.props
return buildQueries([query], timeRange)
}
}
export default RuleGraph

View File

@ -71,6 +71,7 @@ interface Props {
setResolution?: (w: number) => void
onZoom?: (timeRange: TimeRange) => void
mode?: string
underlayCallback?: () => void
}
interface State {
@ -102,6 +103,7 @@ class Dygraph extends Component<Props, State> {
staticLegend: false,
setResolution: () => {},
handleSetHoverTime: () => {},
underlayCallback: () => {},
}
private graphRef: React.RefObject<HTMLDivElement>
@ -125,6 +127,7 @@ class Dygraph extends Component<Props, State> {
labels,
axes: {y, y2},
isGraphFilled: fillGraph,
underlayCallback,
} = this.props
const timeSeries = this.timeSeries
@ -157,6 +160,7 @@ class Dygraph extends Component<Props, State> {
zoomCallback: (lower: number, upper: number) =>
this.handleZoom(lower, upper),
drawCallback: () => this.handleDraw(),
underlayCallback,
highlightCircleSize: 3,
}
@ -191,6 +195,7 @@ class Dygraph extends Component<Props, State> {
axes: {y, y2},
options,
type,
underlayCallback,
} = this.props
const dygraph = this.dygraph
@ -237,6 +242,7 @@ class Dygraph extends Component<Props, State> {
colors: LINE_COLORS,
series: this.colorDygraphSeries,
plotter: type === CellType.Bar ? barPlotter : null,
underlayCallback,
}
dygraph.updateOptions(updateOptions)

View File

@ -19,14 +19,7 @@ import {
import {ColorString} from 'src/types/colors'
import {DecimalPlaces} from 'src/types/dashboards'
import {TimeSeriesServerResponse} from 'src/types/series'
import {
Query,
Axes,
RuleValues,
TimeRange,
RemoteDataState,
CellType,
} from 'src/types'
import {Query, Axes, TimeRange, RemoteDataState, CellType} from 'src/types'
interface Props {
axes: Axes
@ -34,7 +27,6 @@ interface Props {
queries: Query[]
timeRange: TimeRange
colors: ColorString[]
ruleValues?: RuleValues
loading: RemoteDataState
decimalPlaces: DecimalPlaces
data: TimeSeriesServerResponse[]
@ -96,7 +88,6 @@ class LineGraph extends PureComponent<LineGraphProps> {
queries,
timeRange,
cellHeight,
ruleValues,
staticLegend,
decimalPlaces,
handleSetHoverTime,
@ -105,7 +96,6 @@ class LineGraph extends PureComponent<LineGraphProps> {
const {labels, timeSeries, dygraphSeries} = this.timeSeries
const options = {
labels,
rightGap: 0,
yRangePad: 10,
labelsKMB: true,
@ -133,7 +123,6 @@ class LineGraph extends PureComponent<LineGraphProps> {
options={options}
timeRange={timeRange}
timeSeries={timeSeries}
ruleValues={ruleValues}
staticLegend={staticLegend}
dygraphSeries={dygraphSeries}
isGraphFilled={this.isGraphFilled}

View File

@ -20,11 +20,11 @@ interface RenderProps {
}
interface Props {
inView: boolean
source: Source
queries: Query[]
templates: Template[]
children: (r: RenderProps) => JSX.Element
inView?: boolean
templates?: Template[]
}
interface State {
@ -36,6 +36,7 @@ interface State {
class TimeSeries extends Component<Props, State> {
public static defaultProps = {
inView: true,
templates: [],
}
constructor(props: Props) {