From a431efa0da03bdf4d6f89f50563dba471e03c7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Mon, 14 Jan 2019 13:50:06 +0100 Subject: [PATCH] Refactored logic in ThresholdEditor --- .../ThresholdsEditor.test.tsx | 59 +++++++++++++++---- .../ThresholdsEditor/ThresholdsEditor.tsx | 43 +++++++------- 2 files changed, 67 insertions(+), 35 deletions(-) diff --git a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx index 14f84e00f80..30a7c8fc257 100644 --- a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx @@ -15,25 +15,56 @@ const setup = (propOverrides?: object) => { return shallow().instance() as ThresholdsEditor; }; +describe('Initialization', () => { + it('should add a base threshold if missing', () => { + const instance = setup(); + + expect(instance.state.thresholds).toEqual([{ index: 0, value: -Infinity, color: '#7EB26D' }]); + }); +}); + describe('Add threshold', () => { it('should add threshold', () => { const instance = setup(); - instance.onAddThreshold(0); + instance.onAddThreshold(1); - expect(instance.state.thresholds).toEqual([{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }]); + expect(instance.state.thresholds).toEqual([ + { index: 1, value: 50, color: '#EAB839' }, + { index: 0, value: -Infinity, color: '#7EB26D' }, + ]); }); it('should add another threshold above a first', () => { const instance = setup({ - thresholds: [{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }], + thresholds: [{ index: 0, value: -Infinity, color: '#7EB26D' }, { index: 1, value: 50, color: '#EAB839' }], }); - instance.onAddThreshold(1); + instance.onAddThreshold(2); expect(instance.state.thresholds).toEqual([ - { index: 1, value: 75, color: 'rgb(170, 95, 61)' }, - { index: 0, value: 50, color: 'rgb(127, 115, 64)' }, + { index: 2, value: 75, color: '#6ED0E0' }, + { index: 1, value: 50, color: '#EAB839' }, + { index: 0, value: -Infinity, color: '#7EB26D' }, + ]); + }); + + it('should add another threshold between first and second index', () => { + const instance = setup({ + thresholds: [ + { index: 0, value: -Infinity, color: '#7EB26D' }, + { index: 1, value: 50, color: '#EAB839' }, + { index: 2, value: 75, color: '#6ED0E0' }, + ], + }); + + instance.onAddThreshold(2); + + expect(instance.state.thresholds).toEqual([ + { index: 3, value: 75, color: '#EF843C' }, + { index: 2, value: 62.5, color: '#6ED0E0' }, + { index: 1, value: 50, color: '#EAB839' }, + { index: 0, value: -Infinity, color: '#7EB26D' }, ]); }); }); @@ -41,23 +72,25 @@ describe('Add threshold', () => { describe('change threshold value', () => { it('should update value and resort rows', () => { const instance = setup(); - const mockThresholds = [ - { index: 0, value: 50, color: 'rgba(237, 129, 40, 0.89)' }, - { index: 1, value: 75, color: 'rgba(237, 129, 40, 0.89)' }, + const thresholds = [ + { index: 0, value: -Infinity, color: '#7EB26D' }, + { index: 1, value: 50, color: '#EAB839' }, + { index: 2, value: 75, color: '#6ED0E0' }, ]; instance.state = { baseColor: BasicGaugeColor.Green, - thresholds: mockThresholds, + thresholds, }; const mockEvent = { target: { value: 78 } }; - instance.onChangeThresholdValue(mockEvent, mockThresholds[0]); + instance.onChangeThresholdValue(mockEvent, thresholds[1]); expect(instance.state.thresholds).toEqual([ - { index: 0, value: 78, color: 'rgba(237, 129, 40, 0.89)' }, - { index: 1, value: 75, color: 'rgba(237, 129, 40, 0.89)' }, + { index: 0, value: -Infinity, color: '#7EB26D' }, + { index: 1, value: 78, color: '#EAB839' }, + { index: 2, value: 75, color: '#6ED0E0' }, ]); }); }); diff --git a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx index c635b9cb4f5..50986bac5d6 100644 --- a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx @@ -1,9 +1,10 @@ import React, { PureComponent } from 'react'; -import tinycolor, { ColorInput } from 'tinycolor2'; +// import tinycolor, { ColorInput } from 'tinycolor2'; import { Threshold, BasicGaugeColor } from '../../types'; import { ColorPicker } from '../ColorPicker/ColorPicker'; import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup'; +import { colors } from '../../utils'; export interface Props { thresholds: Threshold[]; @@ -19,43 +20,41 @@ export class ThresholdsEditor extends PureComponent { constructor(props: Props) { super(props); - this.state = { thresholds: props.thresholds, baseColor: BasicGaugeColor.Green }; + const thresholds: Threshold[] = + props.thresholds.length > 0 ? props.thresholds : [{ index: 0, value: -Infinity, color: colors[0] }]; + this.state = { thresholds, baseColor: BasicGaugeColor.Green }; } onAddThreshold = (index: number) => { - const maxValue = 100; // hardcoded for now before we add the base threshold - const minValue = 0; // hardcoded for now before we add the base threshold const { thresholds } = this.state; + const maxValue = 100; + const minValue = 0; + + if (index === 0) { + return; + } const newThresholds = thresholds.map(threshold => { if (threshold.index >= index) { + const index = threshold.index + 1; threshold = { ...threshold, - index: threshold.index + 1, + index, + color: colors[index], }; } - return threshold; }); // Setting value to a value between the previous thresholds - let value; + const beforeThreshold = newThresholds.filter(threshold => threshold.index === index - 1)[0]; + const afterThreshold = newThresholds.filter(threshold => threshold.index === index + 1)[0]; + const beforeThresholdValue = beforeThreshold !== undefined ? Math.max(beforeThreshold.value, minValue) : minValue; + const afterThresholdValue = afterThreshold !== undefined ? Math.min(afterThreshold.value, maxValue) : maxValue; + const value = afterThresholdValue - (afterThresholdValue - beforeThresholdValue) / 2; - if (index === 0 && thresholds.length === 0) { - value = maxValue - (maxValue - minValue) / 2; - } else if (index === 0 && thresholds.length > 0) { - value = newThresholds[index + 1].value - (newThresholds[index + 1].value - minValue) / 2; - } else if (index > newThresholds[newThresholds.length - 1].index) { - value = maxValue - (maxValue - newThresholds[index - 1].value) / 2; - } - - // Set a color that lies between the previous thresholds - let color; - if (index === 0 && thresholds.length === 0) { - color = tinycolor.mix(BasicGaugeColor.Green, BasicGaugeColor.Red, 50).toRgbString(); - } else { - color = tinycolor.mix(thresholds[index - 1].color as ColorInput, BasicGaugeColor.Red, 50).toRgbString(); - } + // Set a color + const color = colors[index]; this.setState( {