mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Gauge: convert tests to RTL (#49251)
* Move logic into utils file, add EXTREMELY basic RTL test * initialise array with value
This commit is contained in:
parent
4a61f4111f
commit
b864442717
@ -11,9 +11,6 @@ exports[`no enzyme tests`] = {
|
||||
"packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx:3129955645": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Gauge/Gauge.test.tsx:2525939157": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Graph/Graph.test.tsx:1664091255": [
|
||||
[0, 17, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { shallow } from 'enzyme';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { ThresholdsMode, FieldConfig, FieldColorModeId } from '@grafana/data';
|
||||
@ -11,71 +11,33 @@ jest.mock('jquery', () => ({
|
||||
plot: jest.fn(),
|
||||
}));
|
||||
|
||||
const setup = (propOverrides?: FieldConfig) => {
|
||||
const field: FieldConfig = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
color: {
|
||||
mode: FieldColorModeId.Thresholds,
|
||||
},
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [{ value: -Infinity, color: '#7EB26D' }],
|
||||
},
|
||||
};
|
||||
Object.assign(field, propOverrides);
|
||||
|
||||
const props: Props = {
|
||||
showThresholdMarkers: true,
|
||||
showThresholdLabels: false,
|
||||
field,
|
||||
width: 300,
|
||||
height: 300,
|
||||
value: {
|
||||
text: '25',
|
||||
numeric: 25,
|
||||
},
|
||||
theme: getTheme(),
|
||||
};
|
||||
|
||||
const wrapper = shallow(<Gauge {...props} />);
|
||||
const instance = wrapper.instance() as Gauge;
|
||||
|
||||
return {
|
||||
instance,
|
||||
wrapper,
|
||||
};
|
||||
const field: FieldConfig = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
color: {
|
||||
mode: FieldColorModeId.Thresholds,
|
||||
},
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [{ value: -Infinity, color: '#7EB26D' }],
|
||||
},
|
||||
};
|
||||
|
||||
describe('Get thresholds formatted', () => {
|
||||
it('should return first thresholds color for min and max', () => {
|
||||
const { instance } = setup({
|
||||
thresholds: { mode: ThresholdsMode.Absolute, steps: [{ value: -Infinity, color: '#7EB26D' }] },
|
||||
});
|
||||
const props: Props = {
|
||||
showThresholdMarkers: true,
|
||||
showThresholdLabels: false,
|
||||
field,
|
||||
width: 300,
|
||||
height: 300,
|
||||
value: {
|
||||
text: '25',
|
||||
numeric: 25,
|
||||
},
|
||||
theme: getTheme(),
|
||||
};
|
||||
|
||||
expect(instance.getFormattedThresholds(2)).toEqual([
|
||||
{ value: 0, color: '#7EB26D' },
|
||||
{ value: 100, color: '#7EB26D' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should get the correct formatted values when thresholds are added', () => {
|
||||
const { instance } = setup({
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{ value: -Infinity, color: '#7EB26D' },
|
||||
{ value: 50, color: '#EAB839' },
|
||||
{ value: 75, color: '#6ED0E0' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(instance.getFormattedThresholds(2)).toEqual([
|
||||
{ value: 0, color: '#7EB26D' },
|
||||
{ value: 50, color: '#7EB26D' },
|
||||
{ value: 75, color: '#EAB839' },
|
||||
{ value: 100, color: '#6ED0E0' },
|
||||
]);
|
||||
describe('Gauge', () => {
|
||||
it('should render without blowing up', () => {
|
||||
expect(() => render(<Gauge {...props} />)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
@ -8,17 +8,14 @@ import {
|
||||
ThresholdsMode,
|
||||
GAUGE_DEFAULT_MAXIMUM,
|
||||
GAUGE_DEFAULT_MINIMUM,
|
||||
getActiveThreshold,
|
||||
Threshold,
|
||||
getColorForTheme,
|
||||
FieldColorModeId,
|
||||
FALLBACK_COLOR,
|
||||
TextDisplayOptions,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { Themeable } from '../../types';
|
||||
import { calculateFontSize } from '../../utils/measureText';
|
||||
|
||||
import { calculateGaugeAutoProps, DEFAULT_THRESHOLDS, getFormattedThresholds } from './utils';
|
||||
|
||||
export interface Props extends Themeable {
|
||||
height: number;
|
||||
field: FieldConfig;
|
||||
@ -40,13 +37,7 @@ export class Gauge extends PureComponent<Props> {
|
||||
field: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{ value: -Infinity, color: 'green' },
|
||||
{ value: 80, color: 'red' },
|
||||
],
|
||||
},
|
||||
thresholds: DEFAULT_THRESHOLDS,
|
||||
},
|
||||
};
|
||||
|
||||
@ -58,48 +49,6 @@ export class Gauge extends PureComponent<Props> {
|
||||
this.draw();
|
||||
}
|
||||
|
||||
getFormattedThresholds(decimals: number): Threshold[] {
|
||||
const { field, theme, value } = this.props;
|
||||
|
||||
if (field.color?.mode !== FieldColorModeId.Thresholds) {
|
||||
return [{ value: field.min ?? GAUGE_DEFAULT_MINIMUM, color: value.color ?? FALLBACK_COLOR }];
|
||||
}
|
||||
|
||||
const thresholds = field.thresholds ?? Gauge.defaultProps.field?.thresholds!;
|
||||
const isPercent = thresholds.mode === ThresholdsMode.Percentage;
|
||||
const steps = thresholds.steps;
|
||||
|
||||
let min = field.min ?? GAUGE_DEFAULT_MINIMUM;
|
||||
let max = field.max ?? GAUGE_DEFAULT_MAXIMUM;
|
||||
|
||||
if (isPercent) {
|
||||
min = 0;
|
||||
max = 100;
|
||||
}
|
||||
|
||||
const first = getActiveThreshold(min, steps);
|
||||
const last = getActiveThreshold(max, steps);
|
||||
const formatted: Threshold[] = [];
|
||||
formatted.push({ value: +min.toFixed(decimals), color: getColorForTheme(first.color, theme) });
|
||||
let skip = true;
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (skip) {
|
||||
if (first === step) {
|
||||
skip = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const prev = steps[i - 1];
|
||||
formatted.push({ value: step.value, color: getColorForTheme(prev!.color, theme) });
|
||||
if (step === last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
formatted.push({ value: +max.toFixed(decimals), color: getColorForTheme(last.color, theme) });
|
||||
return formatted;
|
||||
}
|
||||
|
||||
draw() {
|
||||
const { field, showThresholdLabels, showThresholdMarkers, width, height, theme, value } = this.props;
|
||||
|
||||
@ -157,7 +106,7 @@ export class Gauge extends PureComponent<Props> {
|
||||
layout: { margin: 0, thresholdWidth: 0, vMargin: 0 },
|
||||
cell: { border: { width: 0 } },
|
||||
threshold: {
|
||||
values: this.getFormattedThresholds(decimals),
|
||||
values: getFormattedThresholds(decimals, field, value, theme),
|
||||
label: {
|
||||
show: showThresholdLabels,
|
||||
margin: thresholdMarkersWidth + 1,
|
||||
@ -240,23 +189,3 @@ export class Gauge extends PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface GaugeAutoProps {
|
||||
titleFontSize: number;
|
||||
gaugeHeight: number;
|
||||
showLabel: boolean;
|
||||
}
|
||||
|
||||
function calculateGaugeAutoProps(width: number, height: number, title: string | undefined): GaugeAutoProps {
|
||||
const showLabel = title !== null && title !== undefined;
|
||||
const titleFontSize = Math.min((width * 0.15) / 1.5, 20); // 20% of height * line-height, max 40px
|
||||
const titleHeight = titleFontSize * 1.5;
|
||||
const availableHeight = showLabel ? height - titleHeight : height;
|
||||
const gaugeHeight = Math.min(availableHeight, width);
|
||||
|
||||
return {
|
||||
showLabel,
|
||||
gaugeHeight,
|
||||
titleFontSize,
|
||||
};
|
||||
}
|
||||
|
55
packages/grafana-ui/src/components/Gauge/utils.test.ts
Normal file
55
packages/grafana-ui/src/components/Gauge/utils.test.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { FieldColorModeId, FieldConfig, ThresholdsMode } from '@grafana/data';
|
||||
|
||||
import { getTheme } from '../../themes';
|
||||
|
||||
import { getFormattedThresholds } from './utils';
|
||||
|
||||
describe('getFormattedThresholds', () => {
|
||||
const value = {
|
||||
text: '25',
|
||||
numeric: 25,
|
||||
};
|
||||
const theme = getTheme();
|
||||
let field: FieldConfig;
|
||||
|
||||
beforeEach(() => {
|
||||
field = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
color: {
|
||||
mode: FieldColorModeId.Thresholds,
|
||||
},
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [{ value: -Infinity, color: '#7EB26D' }],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('should return first thresholds color for min and max', () => {
|
||||
field.thresholds = { mode: ThresholdsMode.Absolute, steps: [{ value: -Infinity, color: '#7EB26D' }] };
|
||||
|
||||
expect(getFormattedThresholds(2, field, value, theme)).toEqual([
|
||||
{ value: 0, color: '#7EB26D' },
|
||||
{ value: 100, color: '#7EB26D' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should get the correct formatted values when thresholds are added', () => {
|
||||
field.thresholds = {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{ value: -Infinity, color: '#7EB26D' },
|
||||
{ value: 50, color: '#EAB839' },
|
||||
{ value: 75, color: '#6ED0E0' },
|
||||
],
|
||||
};
|
||||
|
||||
expect(getFormattedThresholds(2, field, value, theme)).toEqual([
|
||||
{ value: 0, color: '#7EB26D' },
|
||||
{ value: 50, color: '#7EB26D' },
|
||||
{ value: 75, color: '#EAB839' },
|
||||
{ value: 100, color: '#6ED0E0' },
|
||||
]);
|
||||
});
|
||||
});
|
86
packages/grafana-ui/src/components/Gauge/utils.ts
Normal file
86
packages/grafana-ui/src/components/Gauge/utils.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {
|
||||
DisplayValue,
|
||||
FALLBACK_COLOR,
|
||||
FieldColorModeId,
|
||||
FieldConfig,
|
||||
GAUGE_DEFAULT_MAXIMUM,
|
||||
GAUGE_DEFAULT_MINIMUM,
|
||||
getActiveThreshold,
|
||||
getColorForTheme,
|
||||
GrafanaTheme,
|
||||
Threshold,
|
||||
ThresholdsConfig,
|
||||
ThresholdsMode,
|
||||
} from '@grafana/data';
|
||||
|
||||
interface GaugeAutoProps {
|
||||
titleFontSize: number;
|
||||
gaugeHeight: number;
|
||||
showLabel: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_THRESHOLDS: ThresholdsConfig = {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{ value: -Infinity, color: 'green' },
|
||||
{ value: 80, color: 'red' },
|
||||
],
|
||||
};
|
||||
|
||||
export function calculateGaugeAutoProps(width: number, height: number, title: string | undefined): GaugeAutoProps {
|
||||
const showLabel = title !== null && title !== undefined;
|
||||
const titleFontSize = Math.min((width * 0.15) / 1.5, 20); // 20% of height * line-height, max 40px
|
||||
const titleHeight = titleFontSize * 1.5;
|
||||
const availableHeight = showLabel ? height - titleHeight : height;
|
||||
const gaugeHeight = Math.min(availableHeight, width);
|
||||
|
||||
return {
|
||||
showLabel,
|
||||
gaugeHeight,
|
||||
titleFontSize,
|
||||
};
|
||||
}
|
||||
|
||||
export function getFormattedThresholds(
|
||||
decimals: number,
|
||||
field: FieldConfig,
|
||||
value: DisplayValue,
|
||||
theme: GrafanaTheme
|
||||
): Threshold[] {
|
||||
if (field.color?.mode !== FieldColorModeId.Thresholds) {
|
||||
return [{ value: field.min ?? GAUGE_DEFAULT_MINIMUM, color: value.color ?? FALLBACK_COLOR }];
|
||||
}
|
||||
|
||||
const thresholds = field.thresholds ?? DEFAULT_THRESHOLDS;
|
||||
const isPercent = thresholds.mode === ThresholdsMode.Percentage;
|
||||
const steps = thresholds.steps;
|
||||
|
||||
let min = field.min ?? GAUGE_DEFAULT_MINIMUM;
|
||||
let max = field.max ?? GAUGE_DEFAULT_MAXIMUM;
|
||||
|
||||
if (isPercent) {
|
||||
min = 0;
|
||||
max = 100;
|
||||
}
|
||||
|
||||
const first = getActiveThreshold(min, steps);
|
||||
const last = getActiveThreshold(max, steps);
|
||||
const formatted: Threshold[] = [{ value: +min.toFixed(decimals), color: getColorForTheme(first.color, theme) }];
|
||||
let skip = true;
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (skip) {
|
||||
if (first === step) {
|
||||
skip = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const prev = steps[i - 1];
|
||||
formatted.push({ value: step.value, color: getColorForTheme(prev!.color, theme) });
|
||||
if (step === last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
formatted.push({ value: +max.toFixed(decimals), color: getColorForTheme(last.color, theme) });
|
||||
return formatted;
|
||||
}
|
Loading…
Reference in New Issue
Block a user