diff --git a/ui/src/shared/components/LineGraph.js b/ui/src/shared/components/LineGraph.js index b6886322b3..21680ce2e3 100644 --- a/ui/src/shared/components/LineGraph.js +++ b/ui/src/shared/components/LineGraph.js @@ -1,67 +1,20 @@ -import React, {PropTypes} from 'react' +import React, {PropTypes, Component} from 'react' import Dygraph from 'shared/components/Dygraph' -import classnames from 'classnames' import shallowCompare from 'react-addons-shallow-compare' +import SingleStat from 'src/shared/components/SingleStat' import timeSeriesToDygraph from 'utils/timeSeriesToDygraph' -import lastValues from 'shared/parsing/lastValues' -const {array, arrayOf, bool, func, number, shape, string} = PropTypes +import {SINGLE_STAT_LINE_COLORS} from 'src/shared/graphs/helpers' -const SMALL_CELL_HEIGHT = 1 - -export default React.createClass({ - displayName: 'LineGraph', - propTypes: { - data: arrayOf(shape({}).isRequired).isRequired, - axes: shape({ - y: shape({ - bounds: array, - label: string, - }), - y2: shape({ - bounds: array, - label: string, - }), - }), - title: string, - isFetchingInitially: bool, - isRefreshing: bool, - underlayCallback: func, - isGraphFilled: bool, - isBarGraph: bool, - overrideLineColors: array, - queries: arrayOf(shape({}).isRequired).isRequired, - showSingleStat: bool, - displayOptions: shape({ - stepPlot: bool, - stackedGraph: bool, - }), - activeQueryIndex: number, - ruleValues: shape({}), - timeRange: shape({ - lower: string.isRequired, - }), - isInDataExplorer: bool, - synchronizer: func, - setResolution: func, - cellHeight: number, - cell: shape({}), - onZoom: func, - resizeCoords: shape(), - }, - - getDefaultProps() { - return { - underlayCallback: () => {}, - isGraphFilled: true, - overrideLineColors: null, - } - }, +class LineGraph extends Component { + constructor(props) { + super(props) + } shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState) - }, + } componentWillMount() { const {data, activeQueryIndex, isInDataExplorer} = this.props @@ -70,7 +23,7 @@ export default React.createClass({ activeQueryIndex, isInDataExplorer ) - }, + } componentWillUpdate(nextProps) { const {data, activeQueryIndex} = this.props @@ -84,132 +37,144 @@ export default React.createClass({ nextProps.isInDataExplorer ) } - }, + } render() { const { data, axes, cell, - isFetchingInitially, - isRefreshing, - isGraphFilled, - isBarGraph, - overrideLineColors, title, + onZoom, queries, - underlayCallback, - showSingleStat, - displayOptions, - ruleValues, - synchronizer, timeRange, cellHeight, - onZoom, + ruleValues, + isBarGraph, resizeCoords, + synchronizer, + isRefreshing, + isGraphFilled, + showSingleStat, + displayOptions, + underlayCallback, + overrideLineColors, + isFetchingInitially, } = this.props + const {labels, timeSeries, dygraphSeries} = this._timeSeries // If data for this graph is being fetched for the first time, show a graph-wide spinner. if (isFetchingInitially) { - return ( -
-
-
- ) + return } const options = { - labels, - connectSeparatedPoints: true, - labelsKMB: true, - axisLineColor: '#383846', - gridLineColor: '#383846', + ...displayOptions, title, + labels, rightGap: 0, yRangePad: 10, + labelsKMB: true, + underlayCallback, axisLabelWidth: 60, drawAxesAtZero: true, - underlayCallback, - ...displayOptions, - } - - const singleStatOptions = { - ...options, - highlightSeriesOpts: { - strokeWidth: 1.5, - }, - } - const singleStatLineColors = [ - '#7A65F2', - '#FFD255', - '#7CE490', - '#F95F53', - '#4591ED', - '#B1B6FF', - '#FFF6B8', - '#C6FFD0', - '#6BDFFF', - ] - - let roundedValue - if (showSingleStat) { - const lastValue = lastValues(data)[1] - - const precision = 100.0 - roundedValue = Math.round(+lastValue * precision) / precision + axisLineColor: '#383846', + gridLineColor: '#383846', + connectSeparatedPoints: true, } const lineColors = showSingleStat - ? singleStatLineColors + ? SINGLE_STAT_LINE_COLORS : overrideLineColors return (
- {isRefreshing ? this.renderSpinner() : null} + {isRefreshing ? : null} {showSingleStat - ?
- - - {roundedValue} - - -
+ ? : null}
) - }, + } +} - renderSpinner() { - return ( -
-
-
-
-
- ) - }, -}) +const GraphLoadingDots = () => +
+
+
+
+
+ +const GraphSpinner = () => +
+
+
+ +const {array, arrayOf, bool, func, number, shape, string} = PropTypes + +LineGraph.defaultProps = { + underlayCallback: () => {}, + isGraphFilled: true, + overrideLineColors: null, +} + +LineGraph.propTypes = { + axes: shape({ + y: shape({ + bounds: array, + label: string, + }), + y2: shape({ + bounds: array, + label: string, + }), + }), + title: string, + isFetchingInitially: bool, + isRefreshing: bool, + underlayCallback: func, + isGraphFilled: bool, + isBarGraph: bool, + overrideLineColors: array, + showSingleStat: bool, + displayOptions: shape({ + stepPlot: bool, + stackedGraph: bool, + }), + activeQueryIndex: number, + ruleValues: shape({}), + timeRange: shape({ + lower: string.isRequired, + }), + isInDataExplorer: bool, + synchronizer: func, + setResolution: func, + cellHeight: number, + cell: shape(), + onZoom: func, + resizeCoords: shape(), + queries: arrayOf(shape({}).isRequired).isRequired, + data: arrayOf(shape({}).isRequired).isRequired, +} + +export default LineGraph diff --git a/ui/src/shared/components/SingleStat.js b/ui/src/shared/components/SingleStat.js index ea95137ed1..5b6bcf9698 100644 --- a/ui/src/shared/components/SingleStat.js +++ b/ui/src/shared/components/SingleStat.js @@ -1,28 +1,20 @@ -import React, {PropTypes} from 'react' +import React, {PropTypes, Component} from 'react' import classnames from 'classnames' import shallowCompare from 'react-addons-shallow-compare' import lastValues from 'shared/parsing/lastValues' -const SMALL_CELL_HEIGHT = 1 - -export default React.createClass({ - displayName: 'LineGraph', - propTypes: { - data: PropTypes.arrayOf(PropTypes.shape({})).isRequired, - title: PropTypes.string, - isFetchingInitially: PropTypes.bool, - cellHeight: PropTypes.number, - }, +import {SMALL_CELL_HEIGHT} from 'src/shared/graphs/helpers' +class SingleStat extends Component { shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState) - }, + } render() { - const {data, cellHeight} = this.props + const {data, cellHeight, isFetchingInitially} = this.props // If data for this graph is being fetched for the first time, show a graph-wide spinner. - if (this.props.isFetchingInitially) { + if (isFetchingInitially) { return (

@@ -46,5 +38,15 @@ export default React.createClass({

) - }, -}) + } +} + +const {arrayOf, bool, number, shape} = PropTypes + +SingleStat.propTypes = { + data: arrayOf(shape()).isRequired, + isFetchingInitially: bool, + cellHeight: number, +} + +export default SingleStat diff --git a/ui/src/shared/graphs/helpers.js b/ui/src/shared/graphs/helpers.js index cef1945b81..e210d36f58 100644 --- a/ui/src/shared/graphs/helpers.js +++ b/ui/src/shared/graphs/helpers.js @@ -17,6 +17,20 @@ export const LINE_COLORS = [ '#a0725b', ] +export const SMALL_CELL_HEIGHT = 1 + +export const SINGLE_STAT_LINE_COLORS = [ + '#7A65F2', + '#FFD255', + '#7CE490', + '#F95F53', + '#4591ED', + '#B1B6FF', + '#FFF6B8', + '#C6FFD0', + '#6BDFFF', +] + export const darkenColor = colorStr => { // Defined in dygraph-utils.js const color = Dygraphs.toRGB_(colorStr)