From 11d0ecac8b01e05bc886fe1e893a1074f55fca07 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 24 Jul 2017 15:01:23 -0700 Subject: [PATCH] WIP encorporate new shape for yRanges => axes --- .../components/CellEditorOverlay.js | 29 ++++++++----- .../dashboards/components/DisplayOptions.js | 11 ++--- ui/src/dashboards/components/Ranger.js | 26 +++++++----- ui/src/data_explorer/components/VisView.js | 41 ++++--------------- .../data_explorer/components/Visualization.js | 12 ++++-- ui/src/shared/components/AutoRefresh.js | 12 ++++-- ui/src/shared/components/Dygraph.js | 32 ++++++++++----- ui/src/shared/components/LineGraph.js | 21 ++++++---- ui/src/shared/components/RefreshingGraph.js | 11 ++--- ui/src/shared/parsing/getRangeForDygraph.js | 8 +++- 10 files changed, 107 insertions(+), 96 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index caaa71355..ae97b8d83 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -35,7 +35,7 @@ class CellEditorOverlay extends Component { this.handleEditRawText = ::this.handleEditRawText this.handleSetRange = ::this.handleSetRange - const {cell: {name, type, queries, yRanges}} = props + const {cell: {name, type, queries, axes}} = props const queriesWorkingDraft = _.cloneDeep( queries.map(({queryConfig}) => ({...queryConfig, id: uuid.v4()})) @@ -47,9 +47,7 @@ class CellEditorOverlay extends Component { queriesWorkingDraft, activeQueryIndex: 0, isDisplayOptionsTabOpen: false, - yRanges: { - y: yRanges && yRanges.y ? yRanges.y : ['', ''], - }, + axes, } } @@ -82,9 +80,12 @@ class CellEditorOverlay extends Component { handleSetRange(e) { const {min, max} = e.target.form + this.setState({ - yRanges: { - y: [min.value, max.value], + axes: { + y: { + bounds: [min.value, max.value], + }, }, }) e.preventDefault() @@ -108,7 +109,7 @@ class CellEditorOverlay extends Component { queriesWorkingDraft, cellWorkingType: type, cellWorkingName: name, - yRanges, + axes, } = this.state const {cell} = this.props @@ -125,7 +126,13 @@ class CellEditorOverlay extends Component { } }) - this.props.onSave({...cell, name, type, queries, yRanges}) + this.props.onSave({ + ...cell, + name, + type, + queries, + axes, + }) } handleSelectGraphType(graphType) { @@ -174,7 +181,7 @@ class CellEditorOverlay extends Component { cellWorkingType, isDisplayOptionsTabOpen, queriesWorkingDraft, - yRanges, + axes, } = this.state const queryActions = { @@ -205,7 +212,7 @@ class CellEditorOverlay extends Component { cellType={cellWorkingType} cellName={cellWorkingName} editQueryStatus={editQueryStatus} - yRanges={yRanges} + axes={axes} views={[]} />
@@ -221,7 +228,7 @@ class CellEditorOverlay extends Component { selectedGraphType={cellWorkingType} onSelectGraphType={this.handleSelectGraphType} onSetRange={this.handleSetRange} - yRanges={yRanges} + axes={axes} /> :
- +
-const {array, func, shape, string} = PropTypes +const {func, shape, string} = PropTypes DisplayOptions.propTypes = { selectedGraphType: string.isRequired, onSelectGraphType: func.isRequired, onSetRange: func.isRequired, - yRanges: shape({ - y: array, - y2: array, - }).isRequired, + axes: shape({}).isRequired, } export default DisplayOptions diff --git a/ui/src/dashboards/components/Ranger.js b/ui/src/dashboards/components/Ranger.js index c97375688..c550fa393 100644 --- a/ui/src/dashboards/components/Ranger.js +++ b/ui/src/dashboards/components/Ranger.js @@ -1,29 +1,34 @@ import React, {PropTypes} from 'react' +import _ from 'lodash' -const Ranger = ({onSetRange, yRanges}) => +const Ranger = ({onSetRange, axes}) =>
Y Axis Controls
- +
- + @@ -35,9 +40,10 @@ const {array, func, shape} = PropTypes Ranger.propTypes = { onSetRange: func.isRequired, - yRanges: shape({ - y: array, - y2: array, + axes: shape({ + y: shape({ + bounds: array, + }), }).isRequired, } diff --git a/ui/src/data_explorer/components/VisView.js b/ui/src/data_explorer/components/VisView.js index a32063cd5..036d554c1 100644 --- a/ui/src/data_explorer/components/VisView.js +++ b/ui/src/data_explorer/components/VisView.js @@ -1,23 +1,18 @@ import React, {PropTypes} from 'react' import Table from './Table' -import AutoRefresh from 'shared/components/AutoRefresh' -import LineGraph from 'shared/components/LineGraph' -import SingleStat from 'shared/components/SingleStat' -const RefreshingLineGraph = AutoRefresh(LineGraph) -const RefreshingSingleStat = AutoRefresh(SingleStat) +import RefreshingGraph from 'shared/components/RefreshingGraph' const VisView = ({ + axes, view, queries, - yRanges, cellType, templates, autoRefresh, heightPixels, editQueryStatus, activeQueryIndex, - isInDataExplorer, }) => { const activeQuery = queries[activeQueryIndex] const defaultQuery = queries[0] @@ -41,42 +36,23 @@ const VisView = ({ ) } - if (cellType === 'single-stat') { - return ( - - ) - } - - const displayOptions = { - stepPlot: cellType === 'line-stepplot', - stackedGraph: cellType === 'line-stacked', - } - return ( - ) } -const {arrayOf, bool, func, number, shape, string} = PropTypes +const {arrayOf, func, number, shape, string} = PropTypes VisView.propTypes = { view: string.isRequired, - yRanges: shape(), + axes: shape().isRequired, queries: arrayOf(shape()).isRequired, cellType: string, templates: arrayOf(shape()), @@ -84,7 +60,6 @@ VisView.propTypes = { heightPixels: number, editQueryStatus: func.isRequired, activeQueryIndex: number, - isInDataExplorer: bool, } export default VisView diff --git a/ui/src/data_explorer/components/Visualization.js b/ui/src/data_explorer/components/Visualization.js index c03c5a23f..472900904 100644 --- a/ui/src/data_explorer/components/Visualization.js +++ b/ui/src/data_explorer/components/Visualization.js @@ -6,7 +6,7 @@ import VisView from 'src/data_explorer/components/VisView' import {GRAPH, TABLE} from 'shared/constants' import _ from 'lodash' -const {arrayOf, bool, func, number, shape, string} = PropTypes +const {array, arrayOf, bool, func, number, shape, string} = PropTypes const META_QUERY_REGEX = /^show/i const Visualization = React.createClass({ @@ -26,7 +26,11 @@ const Visualization = React.createClass({ heightPixels: number, editQueryStatus: func.isRequired, views: arrayOf(string).isRequired, - yRanges: shape(), + axes: shape({ + y: shape({ + bounds: array, + }), + }), }, contextTypes: { @@ -77,9 +81,9 @@ const Visualization = React.createClass({ render() { const { + axes, views, height, - yRanges, cellType, cellName, timeRange, @@ -118,7 +122,7 @@ const Visualization = React.createClass({ > { text: string, }).isRequired ).isRequired, - yRanges: shape({ - y: arrayOf(string), - y2: arrayOf(string), + axes: shape({ + bounds: shape({ + y: array, + y2: array, + }), }), editQueryStatus: func, }, @@ -173,7 +176,8 @@ const AutoRefresh = ComposedComponent => { } if ( - this._noResultsForQuery(timeSeries) || !this.state.lastQuerySuccessful + this._noResultsForQuery(timeSeries) || + !this.state.lastQuerySuccessful ) { return this.renderNoResults() } diff --git a/ui/src/shared/components/Dygraph.js b/ui/src/shared/components/Dygraph.js index 07381d756..8b80312c4 100644 --- a/ui/src/shared/components/Dygraph.js +++ b/ui/src/shared/components/Dygraph.js @@ -54,7 +54,7 @@ export default class Dygraph extends Component { const timeSeries = this.getTimeSeries() // dygraphSeries is a legend label and its corresponding y-axis e.g. {legendLabel1: 'y', legendLabel2: 'y2'}; const { - ranges, + axes, dygraphSeries, ruleValues, overrideLineColors, @@ -71,6 +71,9 @@ export default class Dygraph extends Component { finalLineColors = LINE_COLORS } + const yAxis = _.get(axes, ['y', 'bounds'], [null, null]) + const y2Axis = _.get(axes, ['y2', 'bounds'], undefined) + const defaultOptions = { plugins: [ new Dygraphs.Plugins.Crosshair({ @@ -92,10 +95,10 @@ export default class Dygraph extends Component { series: dygraphSeries, axes: { y: { - valueRange: getRange(timeSeries, ranges && ranges.y, ruleValues), + valueRange: getRange(timeSeries, yAxis, ruleValues), }, y2: { - valueRange: getRange(timeSeries, ranges && ranges.y2), + valueRange: getRange(timeSeries, y2Axis), }, }, highlightSeriesOpts: { @@ -235,7 +238,7 @@ export default class Dygraph extends Component { componentDidUpdate() { const { labels, - ranges, + axes, options, dygraphSeries, ruleValues, @@ -249,16 +252,19 @@ export default class Dygraph extends Component { ) } + const y = _.get(axes, ['y', 'bounds'], [null, null]) + const y2 = _.get(axes, ['y2', 'bounds'], undefined) const timeSeries = this.getTimeSeries() + const updateOptions = { labels, file: timeSeries, axes: { y: { - valueRange: getRange(timeSeries, ranges && ranges.y, ruleValues), + valueRange: getRange(timeSeries, y, ruleValues), }, y2: { - valueRange: getRange(timeSeries, ranges && ranges.y2), + valueRange: getRange(timeSeries, y2), }, }, stepPlot: options.stepPlot, @@ -343,7 +349,7 @@ export default class Dygraph extends Component { isAscending={isAscending} onSnip={this.handleSnipLabel} onSort={this.handleSortLegend} - legendRef={el => this.legendRef = el} + legendRef={el => (this.legendRef = el)} onInputChange={this.handleLegendInputChange} onToggleFilter={this.handleToggleFilter} /> @@ -359,12 +365,16 @@ export default class Dygraph extends Component { } } -const {array, arrayOf, func, bool, shape, string} = PropTypes +const {array, bool, func, shape, string} = PropTypes Dygraph.propTypes = { - ranges: shape({ - y: arrayOf(string), - y2: arrayOf(string), + axes: shape({ + y: shape({ + bounds: array, + }), + y2: shape({ + bounds: array, + }), }), timeSeries: array.isRequired, labels: array.isRequired, diff --git a/ui/src/shared/components/LineGraph.js b/ui/src/shared/components/LineGraph.js index 3d6af1b4f..e92d4dfe8 100644 --- a/ui/src/shared/components/LineGraph.js +++ b/ui/src/shared/components/LineGraph.js @@ -15,9 +15,13 @@ export default React.createClass({ displayName: 'LineGraph', propTypes: { data: arrayOf(shape({}).isRequired).isRequired, - yRanges: shape({ - y: arrayOf(string), - y2: arrayOf(string), + axes: shape({ + y: shape({ + bounds: array, + }), + y2: shape({ + bounds: array, + }), }), title: string, isFetchingInitially: bool, @@ -67,7 +71,8 @@ export default React.createClass({ componentWillUpdate(nextProps) { const {data, activeQueryIndex} = this.props if ( - data !== nextProps.data || activeQueryIndex !== nextProps.activeQueryIndex + data !== nextProps.data || + activeQueryIndex !== nextProps.activeQueryIndex ) { this._timeSeries = timeSeriesToDygraph( nextProps.data, @@ -80,7 +85,7 @@ export default React.createClass({ render() { const { data, - yRanges, + axes, isFetchingInitially, isRefreshing, isGraphFilled, @@ -159,6 +164,7 @@ export default React.createClass({ > {isRefreshing ? this.renderSpinner() : null} - {roundedValue} + + {roundedValue} +
: null} diff --git a/ui/src/shared/components/RefreshingGraph.js b/ui/src/shared/components/RefreshingGraph.js index 746f77c44..56e43857f 100644 --- a/ui/src/shared/components/RefreshingGraph.js +++ b/ui/src/shared/components/RefreshingGraph.js @@ -15,7 +15,7 @@ const RefreshingGraph = ({ type, queries, cellHeight, - yRanges, + axes, }) => { if (type === 'single-stat') { return ( @@ -43,7 +43,7 @@ const RefreshingGraph = ({ isBarGraph={type === 'bar'} displayOptions={displayOptions} synchronizer={synchronizer} - yRanges={yRanges} + axes={axes} /> ) } @@ -59,11 +59,8 @@ RefreshingGraph.propTypes = { synchronizer: func, type: string.isRequired, queries: arrayOf(shape()).isRequired, - cellHeight: number.isRequired, - yRanges: shape({ - y: arrayOf(string), - y2: arrayOf(string), - }), + cellHeight: number, + axes: shape(), } export default RefreshingGraph diff --git a/ui/src/shared/parsing/getRangeForDygraph.js b/ui/src/shared/parsing/getRangeForDygraph.js index 2f2561e1b..1e505718b 100644 --- a/ui/src/shared/parsing/getRangeForDygraph.js +++ b/ui/src/shared/parsing/getRangeForDygraph.js @@ -1,8 +1,12 @@ const PADDING_FACTOR = 0.1 const considerZero = (userNumber, number) => { - if (typeof userNumber === 'number') { - return userNumber + if (userNumber === '') { + return null + } + + if (userNumber) { + return +userNumber } return number