diff --git a/public/app/plugins/panel/gauge/Thresholds.tsx b/public/app/plugins/panel/gauge/Thresholds.tsx index 81b2fe0fd7a..b1bfcd66fdc 100644 --- a/public/app/plugins/panel/gauge/Thresholds.tsx +++ b/public/app/plugins/panel/gauge/Thresholds.tsx @@ -5,6 +5,7 @@ import { Label } from '../../../core/components/Label/Label'; interface State { thresholds: Threshold[]; + userAddedThresholds: number; } export default class Thresholds extends PureComponent, State> { @@ -13,21 +14,34 @@ export default class Thresholds extends PureComponent { - this.setState(prevState => ({ - thresholds: [...prevState.thresholds, { label: 'T1', value: 0, canRemove: true }], - })); + onAddThreshold = index => { + const newThresholds = this.state.thresholds.map(threshold => { + if (threshold.index >= index) { + threshold = { ...threshold, index: threshold.index + 1 }; + } + + return threshold; + }); + + const userAddedThresholds = this.state.userAddedThresholds + 1; + + this.setState({ + thresholds: this.sortThresholds([...newThresholds, { index: index, label: '', value: 0, canRemove: true }]), + userAddedThresholds: userAddedThresholds, + }); }; onRemoveThreshold = threshold => { this.setState(prevState => ({ thresholds: prevState.thresholds.filter(t => t !== threshold), + userAddedThresholds: prevState.userAddedThresholds - 1, })); }; @@ -45,36 +59,148 @@ export default class Thresholds extends PureComponent { - const newThresholds = this.state.thresholds.map(currentThreshold => { - if (currentThreshold === threshold) { - currentThreshold = { ...currentThreshold, label: event.target.value }; - } - - return currentThreshold; - }); - - this.setState({ - thresholds: newThresholds, - }); - }; - onBlur = () => { - this.sortThresholds(); + this.setState(prevState => ({ + thresholds: this.sortThresholds(prevState.thresholds), + })); this.props.onChange({ ...this.props.options, thresholds: this.state.thresholds }); }; - sortThresholds = () => { - console.log('sort'); - this.setState(prevState => ({ - thresholds: prevState.thresholds.sort((t1, t2) => t1.value - t2.value), - })); + sortThresholds = thresholds => { + return thresholds.sort((t1, t2) => { + return t1.index - t2.index; + }); }; - render() { + getIndicatorColor(index) { + const { userAddedThresholds } = this.state; + + if (index === 0) { + return 'green'; + } else if (index < userAddedThresholds) { + return 'yellow'; + } + + return 'red'; + } + + renderNoThresholds() { const { thresholds } = this.state; + return [ +
+ this.onChangeThresholdValue(event, thresholds[0])} + value={thresholds[0].value} + /> + +
, +
+
this.onAddThreshold(1)} + style={{ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: '36px', + height: '36px', + backgroundColor: 'green', + }} + > + +
+ +
, +
+ this.onChangeThresholdValue(event, thresholds[1])} + value={thresholds[1].value} + /> + +
, + ]; + } + + renderThresholds() { + const { thresholds } = this.state; + return thresholds.map((threshold, index) => { + return ( +
+ this.onChangeThresholdValue(event, threshold)} + value={threshold.value} + onBlur={this.onBlur} + /> + {threshold.canRemove ? ( +
this.onRemoveThreshold(threshold)} + style={{ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: '36px', + height: '36px', + }} + > + +
+ ) : ( + + )} +
+ ); + }); + } + + insertAtIndex(index) { + const { userAddedThresholds } = this.state; + + if (userAddedThresholds === 0) { + return 1; + } else if (index === userAddedThresholds) { + return index - 1; + } else if (index > 0) { + return index + 1; + } + + return -1; + } + + renderIndicator() { + const { userAddedThresholds } = this.state; + + const indicators = userAddedThresholds + 1; + + const sections = []; + + for (let i = 0; i < indicators; i++) { + sections.push( +
this.onAddThreshold(this.insertAtIndex(i))} + style={{ + width: '100%', + height: `calc(100%/${indicators})`, + cursor: 'pointer', + background: this.getIndicatorColor(i), + }} + /> + ); + } + + return sections; + } + + render() { + const { userAddedThresholds } = this.state; + return (
Thresholds
@@ -84,44 +210,12 @@ export default class Thresholds extends PureComponent -
- {thresholds.map((threshold, index) => { - return ( -
- {!threshold.canRemove ? ( - - ) : ( - this.onChangeThresholdLabel(event, threshold)} - value={threshold.label} - /> - )} - this.onChangeThresholdValue(event, threshold)} - onBlur={this.onBlur} - /> - {threshold.canRemove && ( - this.onRemoveThreshold(threshold)}> - - - )} -
- ); - })} -
- - - + - -
+ > + {this.renderIndicator()} +
+
+ {userAddedThresholds === 0 ? this.renderNoThresholds() : this.renderThresholds()}
diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index 48ec9d4ae1e..049b07973de 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -30,6 +30,7 @@ export interface PanelMenuItem { } export interface Threshold { + index: number; label: string; value: number; color?: string; diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index d4a95fe1fac..22db9a24ecf 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -103,6 +103,7 @@ @import 'components/add_data_source.scss'; @import 'components/page_loader'; @import 'components/unit-picker'; +@import 'components/thresholds'; // PAGES @import 'pages/login'; diff --git a/public/sass/components/_thresholds.scss b/public/sass/components/_thresholds.scss new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/public/sass/components/_thresholds.scss @@ -0,0 +1 @@ +