From 1a5b8001750b1d04c0d2799832b6b4b52ad59c19 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Tue, 10 Jul 2018 11:24:46 -0700 Subject: [PATCH] Add decimal place options to single-stat and line plus single stat --- ui/src/dashboards/components/AxesOptions.tsx | 29 +++++++++++++-- .../dashboards/components/DisplayOptions.tsx | 1 + .../components/GraphOptionsDecimalPlaces.tsx | 35 ++++++++++++++----- .../components/SingleStatOptions.tsx | 34 ++++++++++++++---- ui/src/shared/components/LineGraph.tsx | 4 +++ ui/src/shared/components/RefreshingGraph.js | 18 +++++----- ui/src/shared/components/SingleStat.tsx | 28 ++++++++++----- 7 files changed, 116 insertions(+), 33 deletions(-) diff --git a/ui/src/dashboards/components/AxesOptions.tsx b/ui/src/dashboards/components/AxesOptions.tsx index 3bdcf80ba8..9294595df7 100644 --- a/ui/src/dashboards/components/AxesOptions.tsx +++ b/ui/src/dashboards/components/AxesOptions.tsx @@ -6,6 +6,7 @@ import Input from 'src/dashboards/components/DisplayOptionsInput' import {Tabber, Tab} from 'src/dashboards/components/Tabber' import FancyScrollbar from 'src/shared/components/FancyScrollbar' import LineGraphColorSelector from 'src/shared/components/LineGraphColorSelector' +import GraphOptionsDecimalPlaces from 'src/dashboards/components/GraphOptionsDecimalPlaces' import { AXES_SCALE_OPTIONS, @@ -13,9 +14,13 @@ import { } from 'src/dashboards/constants/cellEditor' import {GRAPH_TYPES} from 'src/dashboards/graphics/graph' -import {updateAxes} from 'src/dashboards/actions/cellEditorOverlay' +import { + updateAxes, + changeDecimalPlaces, +} from 'src/dashboards/actions/cellEditorOverlay' import {ErrorHandling} from 'src/shared/decorators/errors' -import {Axes} from 'src/types' +import {Axes, CellType} from 'src/types' +import {DecimalPlaces} from 'src/types/dashboards' const {LINEAR, LOG, BASE_2, BASE_10} = AXES_SCALE_OPTIONS const getInputMin = scale => (scale === LOG ? '0' : null) @@ -25,6 +30,8 @@ interface Props { axes: Axes staticLegend: boolean defaultYLabel: string + onUpdateDecimalPlaces: () => void + decimalPlaces: DecimalPlaces handleUpdateAxes: (axes: Axes) => void onToggleStaticLegend: (x: boolean) => (e: MouseEvent) => void } @@ -152,6 +159,7 @@ class AxesOptions extends PureComponent { onClickTab={this.handleSetScale(LOG)} /> + {this.decimalPlaces} { ) } + private get decimalPlaces(): JSX.Element { + const {onUpdateDecimalPlaces, decimalPlaces, type} = this.props + + if (type !== CellType.LinePlusSingleStat) { + return null + } + + return ( + + ) + } + private handleSetPrefixSuffix = e => { const {handleUpdateAxes, axes} = this.props const {prefix, suffix} = e.target.form @@ -247,6 +271,7 @@ const mstp = ({ const mdtp = { handleUpdateAxes: updateAxes, + onUpdateDecimalPlaces: changeDecimalPlaces, } export default connect(mstp, mdtp)(AxesOptions) diff --git a/ui/src/dashboards/components/DisplayOptions.tsx b/ui/src/dashboards/components/DisplayOptions.tsx index c82c6a59e9..7e03cb24ed 100644 --- a/ui/src/dashboards/components/DisplayOptions.tsx +++ b/ui/src/dashboards/components/DisplayOptions.tsx @@ -80,6 +80,7 @@ class DisplayOptions extends PureComponent { ) diff --git a/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx b/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx index 0a1c8c390d..c1f11e6264 100644 --- a/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx +++ b/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx @@ -9,6 +9,7 @@ interface Props extends DecimalPlaces { } const fixedValueString = 'fixed' +const defaultPlaceholder = 'unlimited' @ErrorHandling class GraphOptionsDecimalPlaces extends PureComponent { @@ -16,7 +17,7 @@ class GraphOptionsDecimalPlaces extends PureComponent { super(props) } - public onSetValue = (valueFromSelector: string): void => { + public handleSetValue = (valueFromSelector: string): void => { let digits let isEnforced if (valueFromSelector === fixedValueString) { @@ -36,22 +37,40 @@ class GraphOptionsDecimalPlaces extends PureComponent { } public render() { - const {digits, isEnforced} = this.props return (
) } + + private get placeholder(): string { + const {isEnforced, digits} = this.props + + if (!isEnforced) { + return defaultPlaceholder + } + + return `${digits}` + } + + private get value(): string { + const {isEnforced, digits} = this.props + if (!isEnforced) { + return '' + } + + return `${digits}` + } } export default GraphOptionsDecimalPlaces diff --git a/ui/src/dashboards/components/SingleStatOptions.tsx b/ui/src/dashboards/components/SingleStatOptions.tsx index ea7dd32f82..60640ccc09 100644 --- a/ui/src/dashboards/components/SingleStatOptions.tsx +++ b/ui/src/dashboards/components/SingleStatOptions.tsx @@ -4,15 +4,22 @@ import {connect} from 'react-redux' import FancyScrollbar from 'src/shared/components/FancyScrollbar' import ThresholdsList from 'src/shared/components/ThresholdsList' import ThresholdsListTypeToggle from 'src/shared/components/ThresholdsListTypeToggle' +import GraphOptionsDecimalPlaces from 'src/dashboards/components/GraphOptionsDecimalPlaces' -import {updateAxes} from 'src/dashboards/actions/cellEditorOverlay' +import { + updateAxes, + changeDecimalPlaces, +} from 'src/dashboards/actions/cellEditorOverlay' import {ErrorHandling} from 'src/shared/decorators/errors' import {Axes} from 'src/types' +import {DecimalPlaces} from 'src/types/dashboards' interface Props { - handleUpdateAxes: (axes: Axes) => void axes: Axes + decimalPlaces: DecimalPlaces onResetFocus: () => void + onUpdateAxes: (axes: Axes) => void + onUpdateDecimalPlaces: (decimalPlaces: DecimalPlaces) => void } @ErrorHandling @@ -23,6 +30,7 @@ class SingleStatOptions extends PureComponent { y: {prefix, suffix}, }, onResetFocus, + decimalPlaces, } = this.props return ( @@ -54,6 +62,11 @@ class SingleStatOptions extends PureComponent { maxLength={5} /> + @@ -61,27 +74,34 @@ class SingleStatOptions extends PureComponent { ) } + private handleDecimalPlacesChange = (decimalPlaces: DecimalPlaces) => { + const {onUpdateDecimalPlaces} = this.props + onUpdateDecimalPlaces(decimalPlaces) + } + private handleUpdatePrefix = e => { - const {handleUpdateAxes, axes} = this.props + const {onUpdateAxes, axes} = this.props const newAxes = {...axes, y: {...axes.y, prefix: e.target.value}} - handleUpdateAxes(newAxes) + onUpdateAxes(newAxes) } private handleUpdateSuffix = e => { - const {handleUpdateAxes, axes} = this.props + const {onUpdateAxes, axes} = this.props const newAxes = {...axes, y: {...axes.y, suffix: e.target.value}} - handleUpdateAxes(newAxes) + onUpdateAxes(newAxes) } } const mstp = ({cellEditorOverlay}) => ({ axes: cellEditorOverlay.cell.axes, + decimalPlaces: cellEditorOverlay.cell.decimalPlaces, }) const mdtp = { - handleUpdateAxes: updateAxes, + onUpdateAxes: updateAxes, + onUpdateDecimalPlaces: changeDecimalPlaces, } export default connect(mstp, mdtp)(SingleStatOptions) diff --git a/ui/src/shared/components/LineGraph.tsx b/ui/src/shared/components/LineGraph.tsx index e773365480..3028435476 100644 --- a/ui/src/shared/components/LineGraph.tsx +++ b/ui/src/shared/components/LineGraph.tsx @@ -11,6 +11,7 @@ import { import {ErrorHandlingWith} from 'src/shared/decorators/errors' import InvalidData from 'src/shared/components/InvalidData' import {Query, Axes, RuleValues, TimeRange} from 'src/types' +import {DecimalPlaces} from 'src/types/dashboards' import {ColorString} from 'src/types/colors' import {Data} from 'src/types/dygraphs' @@ -48,6 +49,7 @@ interface Props { data: Data queries: Query[] colors: ColorString[] + decimalPlaces: DecimalPlaces underlayCallback?: () => void setResolution: () => void handleSetHoverTime: () => void @@ -109,6 +111,7 @@ class LineGraph extends PureComponent { showSingleStat, displayOptions, staticLegend, + decimalPlaces, underlayCallback, isFetchingInitially, handleSetHoverTime, @@ -167,6 +170,7 @@ class LineGraph extends PureComponent { prefix={this.prefix} suffix={this.suffix} cellHeight={cellHeight} + decimalPlaces={decimalPlaces} isFetchingInitially={isFetchingInitially} /> )} diff --git a/ui/src/shared/components/RefreshingGraph.js b/ui/src/shared/components/RefreshingGraph.js index 4db1956908..497b3058b1 100644 --- a/ui/src/shared/components/RefreshingGraph.js +++ b/ui/src/shared/components/RefreshingGraph.js @@ -32,13 +32,13 @@ const RefreshingGraph = ({ cellID, queries, source, - tableOptions, templates, timeRange, cellHeight, autoRefresh, fieldOptions, timeFormat, + tableOptions, decimalPlaces, onSetResolution, resizerTopHeight, @@ -62,18 +62,19 @@ const RefreshingGraph = ({ if (type === 'single-stat') { return ( ) @@ -149,6 +150,7 @@ const RefreshingGraph = ({ cellHeight={cellHeight} autoRefresh={autoRefresh} isBarGraph={type === 'bar'} + decimalPlaces={decimalPlaces} staticLegend={staticLegend} displayOptions={displayOptions} editQueryStatus={editQueryStatus} diff --git a/ui/src/shared/components/SingleStat.tsx b/ui/src/shared/components/SingleStat.tsx index 4260688317..95fc2fc701 100644 --- a/ui/src/shared/components/SingleStat.tsx +++ b/ui/src/shared/components/SingleStat.tsx @@ -7,12 +7,13 @@ import {SMALL_CELL_HEIGHT} from 'src/shared/graphs/helpers' import {DYGRAPH_CONTAINER_V_MARGIN} from 'src/shared/constants' import {generateThresholdsListHexs} from 'src/shared/constants/colorOperations' import {ColorString} from 'src/types/colors' -import {CellType} from 'src/types/dashboards' +import {CellType, DecimalPlaces} from 'src/types/dashboards' import {Data} from 'src/types/dygraphs' import {ErrorHandling} from 'src/shared/decorators/errors' interface Props { isFetchingInitially: boolean + decimalPlaces: DecimalPlaces cellHeight: number colors: ColorString[] prefix?: string @@ -59,21 +60,32 @@ class SingleStat extends PureComponent { return `${prefix}${this.roundedLastValue}${suffix}` } - private get roundedLastValue(): string { + private get lastValue(): number { const {data} = this.props const {lastValues, series} = getLastValues(data) const firstAlphabeticalSeriesName = _.sortBy(series)[0] - const firstAlphabeticalindex = _.indexOf( + const firstAlphabeticalIndex = _.indexOf( series, firstAlphabeticalSeriesName ) - const lastValue = lastValues[firstAlphabeticalindex] - const HUNDRED = 100.0 - const roundedValue = Math.round(+lastValue * HUNDRED) / HUNDRED - const localeFormatted = roundedValue.toLocaleString() - return `${localeFormatted}` + return lastValues[firstAlphabeticalIndex] + } + + private get roundedLastValue(): string { + const {decimalPlaces} = this.props + let roundedValue = `${this.lastValue}` + + if (decimalPlaces.isEnforced) { + roundedValue = this.lastValue.toFixed(decimalPlaces.digits) + } + + return this.formatToLocale(+roundedValue) + } + + private formatToLocale(n: number): string { + return n.toLocaleString() } private get containerStyle(): CSSProperties {