mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
adding threshold
This commit is contained in:
@@ -2,17 +2,14 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import Thresholds from './Thresholds';
|
||||
import { defaultProps, OptionsProps } from './module';
|
||||
import { BasicGaugeColor, PanelOptionsProps } from '../../../types';
|
||||
import { PanelOptionsProps } from 'app/types';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: PanelOptionsProps<OptionsProps> = {
|
||||
onChange: jest.fn(),
|
||||
options: {
|
||||
...defaultProps.options,
|
||||
thresholds: [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: 'Max', value: 100, canRemove: false },
|
||||
],
|
||||
thresholds: [],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -22,124 +19,55 @@ const setup = (propOverrides?: object) => {
|
||||
};
|
||||
|
||||
describe('Add threshold', () => {
|
||||
it('should add threshold between min and max', () => {
|
||||
it('should add threshold', () => {
|
||||
const instance = setup();
|
||||
|
||||
instance.onAddThreshold(1);
|
||||
instance.onAddThreshold(0);
|
||||
|
||||
expect(instance.state.thresholds).toEqual([
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: '', value: 50, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 2, label: 'Max', value: 100, canRemove: false },
|
||||
]);
|
||||
expect(instance.state.thresholds).toEqual([{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }]);
|
||||
});
|
||||
|
||||
it('should add threshold between min and added threshold', () => {
|
||||
it('should add another threshold above a first', () => {
|
||||
const instance = setup({
|
||||
options: {
|
||||
...defaultProps.options,
|
||||
thresholds: [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: '', value: 50, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 2, label: 'Max', value: 100, canRemove: false },
|
||||
],
|
||||
thresholds: [{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }],
|
||||
},
|
||||
});
|
||||
|
||||
instance.onAddThreshold(1);
|
||||
|
||||
expect(instance.state.thresholds).toEqual([
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: '', value: 25, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 2, label: '', value: 50, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
{ index: 0, value: 50, color: 'rgb(127, 115, 64)' },
|
||||
{ index: 1, value: 75, color: 'rgb(170, 95, 61)' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Add at index', () => {
|
||||
it('should return 1, no added thresholds', () => {
|
||||
const instance = setup();
|
||||
|
||||
const result = instance.insertAtIndex(1);
|
||||
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return 1, one added threshold', () => {
|
||||
const instance = setup();
|
||||
instance.state = {
|
||||
baseColor: BasicGaugeColor.Green,
|
||||
thresholds: [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false },
|
||||
{ index: 1, label: '', value: 50, canRemove: true },
|
||||
{ index: 2, label: 'Max', value: 100, canRemove: false },
|
||||
],
|
||||
};
|
||||
|
||||
const result = instance.insertAtIndex(1);
|
||||
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return 2, two added thresholds', () => {
|
||||
const instance = setup({
|
||||
options: {
|
||||
thresholds: [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false },
|
||||
{ index: 1, label: '', value: 25, canRemove: true },
|
||||
{ index: 2, label: '', value: 50, canRemove: true },
|
||||
{ index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const result = instance.insertAtIndex(2);
|
||||
|
||||
expect(result).toEqual(2);
|
||||
});
|
||||
|
||||
it('should return 2, one added threshold', () => {
|
||||
const instance = setup();
|
||||
instance.state = {
|
||||
baseColor: BasicGaugeColor.Green,
|
||||
thresholds: [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false },
|
||||
{ index: 1, label: '', value: 50, canRemove: true },
|
||||
{ index: 2, label: 'Max', value: 100, canRemove: false },
|
||||
],
|
||||
};
|
||||
|
||||
const result = instance.insertAtIndex(2);
|
||||
|
||||
expect(result).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('change threshold value', () => {
|
||||
it('should update value and resort rows', () => {
|
||||
const instance = setup();
|
||||
const mockThresholds = [
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: '', value: 50, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 2, label: '', value: 75, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
];
|
||||
|
||||
instance.state = {
|
||||
baseColor: BasicGaugeColor.Green,
|
||||
thresholds: mockThresholds,
|
||||
};
|
||||
|
||||
const mockEvent = { target: { value: 78 } };
|
||||
|
||||
instance.onChangeThresholdValue(mockEvent, mockThresholds[1]);
|
||||
|
||||
expect(instance.state.thresholds).toEqual([
|
||||
{ index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
{ index: 1, label: '', value: 78, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 2, label: '', value: 75, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
{ index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
]);
|
||||
});
|
||||
});
|
||||
// describe('change threshold value', () => {
|
||||
// it('should update value and resort rows', () => {
|
||||
// const instance = setup();
|
||||
// const mockThresholds = [
|
||||
// { index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
// { index: 1, label: '', value: 50, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
// { index: 2, label: '', value: 75, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
// { index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
// ];
|
||||
//
|
||||
// instance.state = {
|
||||
// baseColor: BasicGaugeColor.Green,
|
||||
// thresholds: mockThresholds,
|
||||
// };
|
||||
//
|
||||
// const mockEvent = { target: { value: 78 } };
|
||||
//
|
||||
// instance.onChangeThresholdValue(mockEvent, mockThresholds[1]);
|
||||
//
|
||||
// expect(instance.state.thresholds).toEqual([
|
||||
// { index: 0, label: 'Min', value: 0, canRemove: false, color: 'rgba(50, 172, 45, 0.97)' },
|
||||
// { index: 1, label: '', value: 78, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
// { index: 2, label: '', value: 75, canRemove: true, color: 'rgba(237, 129, 40, 0.89)' },
|
||||
// { index: 3, label: 'Max', value: 100, canRemove: false },
|
||||
// ]);
|
||||
// });
|
||||
// });
|
||||
|
||||
@@ -14,14 +14,17 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
thresholds: [{ value: 50, canRemove: true, color: '#f2f2f2', index: 0, label: '' }],
|
||||
thresholds: props.options.thresholds,
|
||||
baseColor: props.options.baseColor,
|
||||
};
|
||||
}
|
||||
|
||||
onAddThreshold = index => {
|
||||
const { maxValue, minValue } = this.props.options;
|
||||
const { thresholds } = this.state;
|
||||
|
||||
console.log('add at index:', index);
|
||||
|
||||
const newThresholds = thresholds.map(threshold => {
|
||||
if (threshold.index >= index) {
|
||||
threshold = { ...threshold, index: threshold.index + 1 };
|
||||
@@ -31,17 +34,27 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
|
||||
});
|
||||
|
||||
// Setting value to a value between the previous thresholds
|
||||
const value = newThresholds[index].value - (newThresholds[index].value - newThresholds[index - 1].value) / 2;
|
||||
let value;
|
||||
|
||||
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
|
||||
const color = tinycolor.mix(thresholds[index - 1].color, thresholds[index].color, 50).toRgbString();
|
||||
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, BasicGaugeColor.Red, 50).toRgbString();
|
||||
}
|
||||
|
||||
this.setState(
|
||||
{
|
||||
thresholds: this.sortThresholds([
|
||||
...newThresholds,
|
||||
{ index: index, label: '', value: value, canRemove: true, color: color },
|
||||
]),
|
||||
thresholds: this.sortThresholds([...newThresholds, { index: index, value: value, color: color }]),
|
||||
},
|
||||
() => this.updateGauge()
|
||||
);
|
||||
@@ -106,32 +119,10 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
|
||||
|
||||
sortThresholds = thresholds => {
|
||||
return thresholds.sort((t1, t2) => {
|
||||
return t1.value - t2.value;
|
||||
return t2.value - t1.value;
|
||||
});
|
||||
};
|
||||
|
||||
getIndicatorColor = index => {
|
||||
const { thresholds } = this.state;
|
||||
|
||||
if (index === 0) {
|
||||
return thresholds[0].color;
|
||||
}
|
||||
|
||||
return index < thresholds.length ? thresholds[index].color : BasicGaugeColor.Red;
|
||||
};
|
||||
|
||||
insertAtIndex(index) {
|
||||
const { thresholds } = this.state;
|
||||
|
||||
// If thresholds.length is greater or equal to 3
|
||||
// it means a user has added one threshold
|
||||
if (thresholds.length < 3 || index < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
renderThresholds() {
|
||||
const { thresholds } = this.state;
|
||||
|
||||
@@ -170,20 +161,25 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
|
||||
|
||||
return thresholds.map((t, i) => {
|
||||
return (
|
||||
<div
|
||||
key={`${t.value}-${i}`}
|
||||
className="indicator-section"
|
||||
style={{
|
||||
height: '50%',
|
||||
}}
|
||||
>
|
||||
<div key={`${t.value}-${i}`} className="indicator-section">
|
||||
<div
|
||||
onClick={() => this.onAddThreshold(this.insertAtIndex(1))}
|
||||
onClick={() => this.onAddThreshold(t.index + 1)}
|
||||
style={{
|
||||
height: '100%',
|
||||
background: this.getIndicatorColor(i),
|
||||
height: '50%',
|
||||
backgroundColor: t.color,
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{t.index}
|
||||
</div>
|
||||
<div
|
||||
onClick={() => this.onAddThreshold(t.index)}
|
||||
style={{
|
||||
height: '50%',
|
||||
backgroundColor: t.color,
|
||||
}}
|
||||
>
|
||||
{t.index}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -193,8 +189,8 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
|
||||
return (
|
||||
<div className="indicator-section" style={{ height: '100%' }}>
|
||||
<div
|
||||
onClick={() => this.onAddThreshold(1)}
|
||||
style={{ height: '50px', backgroundColor: this.props.options.baseColor }}
|
||||
onClick={() => this.onAddThreshold(0)}
|
||||
style={{ height: '100%', backgroundColor: this.props.options.baseColor }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -31,10 +31,8 @@ export interface PanelMenuItem {
|
||||
|
||||
export interface Threshold {
|
||||
index: number;
|
||||
label: string;
|
||||
value: number;
|
||||
color?: string;
|
||||
canRemove: boolean;
|
||||
}
|
||||
|
||||
export enum MappingType {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.threshold-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 5px 0;
|
||||
margin-top: 3px;
|
||||
padding: 5px;
|
||||
|
||||
&::before {
|
||||
@@ -95,6 +95,7 @@
|
||||
|
||||
.indicator-section {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user