Commit 72943af4 by Torkel Ödegaard

Refactoring orientation stuff

parent bce6f75f
import React from 'react';
import { shallow } from 'enzyme';
import { BarGauge, Props } from './BarGauge';
import { VizOrientation } from '../../types';
import { getTheme } from '../../themes';
jest.mock('jquery', () => ({
......@@ -21,7 +22,7 @@ const setup = (propOverrides?: object) => {
value: 25,
decimals: 0,
theme: getTheme(),
orientation: 'horizontal',
orientation: VizOrientation.Horizontal,
};
Object.assign(props, propOverrides);
......@@ -39,7 +40,7 @@ describe('Get font color', () => {
it('should get first threshold color when only one threshold', () => {
const { instance } = setup({ thresholds: [{ index: 0, value: -Infinity, color: '#7EB26D' }] });
expect(instance.getColors().value).toEqual('#7EB26D');
expect(instance.getValueColors().value).toEqual('#7EB26D');
});
it('should get the threshold color if value is same as a threshold', () => {
......@@ -51,7 +52,7 @@ describe('Get font color', () => {
],
});
expect(instance.getColors().value).toEqual('#EAB839');
expect(instance.getValueColors().value).toEqual('#EAB839');
});
});
......
......@@ -6,7 +6,7 @@ import tinycolor from 'tinycolor2';
import { getColorFromHexRgbOrName, getValueFormat, getThresholdForValue } from '../../utils';
// Types
import { Themeable, TimeSeriesValue, Threshold, ValueMapping } from '../../types';
import { Themeable, TimeSeriesValue, Threshold, ValueMapping, VizOrientation } from '../../types';
const BAR_SIZE_RATIO = 0.8;
......@@ -19,7 +19,7 @@ export interface Props extends Themeable {
value: TimeSeriesValue;
maxValue: number;
minValue: number;
orientation: string;
orientation: VizOrientation;
prefix?: string;
suffix?: string;
decimals?: number;
......@@ -31,7 +31,7 @@ export class BarGauge extends PureComponent<Props> {
minValue: 0,
value: 100,
unit: 'none',
orientation: 'horizontal',
orientation: VizOrientation.Horizontal,
thresholds: [],
valueMappings: [],
};
......@@ -43,7 +43,7 @@ export class BarGauge extends PureComponent<Props> {
return 0;
}
getColors(): BarColors {
getValueColors(): BarColors {
const { thresholds, theme, value } = this.props;
const activeThreshold = getThresholdForValue(thresholds, value);
......@@ -67,6 +67,28 @@ export class BarGauge extends PureComponent<Props> {
};
}
getCellColor(positionValue: TimeSeriesValue): string {
const { thresholds, theme, value } = this.props;
const activeThreshold = getThresholdForValue(thresholds, positionValue);
if (activeThreshold !== null) {
const color = getColorFromHexRgbOrName(activeThreshold.color, theme.type);
// if we are past real value the cell is not "on"
if (value === null || (positionValue !== null && positionValue > value)) {
return tinycolor(color)
.setAlpha(0.15)
.toRgbString();
} else {
return tinycolor(color)
.setAlpha(0.65)
.toRgbString();
}
}
return 'gray';
}
getValueStyles(value: string, color: string, width: number): CSSProperties {
const guess = width / (value.length * 1.1);
const fontSize = Math.min(Math.max(guess, 14), 40);
......@@ -82,7 +104,7 @@ export class BarGauge extends PureComponent<Props> {
const maxHeight = height * BAR_SIZE_RATIO;
const barHeight = Math.max(valuePercent * maxHeight, 0);
const colors = this.getColors();
const colors = this.getValueColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value, width);
const containerStyles: CSSProperties = {
......@@ -115,7 +137,7 @@ export class BarGauge extends PureComponent<Props> {
const maxWidth = width * BAR_SIZE_RATIO;
const barWidth = Math.max(valuePercent * maxWidth, 0);
const colors = this.getColors();
const colors = this.getValueColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value, width * (1 - BAR_SIZE_RATIO));
valueStyles.marginLeft = '8px';
......@@ -145,6 +167,51 @@ export class BarGauge extends PureComponent<Props> {
);
}
renderHorizontalLCD(valueFormatted: string, valuePercent: number) {
const { height, width, maxValue, minValue } = this.props;
const valueRange = maxValue - minValue;
const maxWidth = width * BAR_SIZE_RATIO;
const cellSpacing = 4;
const cellCount = 30;
const cellWidth = (maxWidth - cellSpacing * cellCount) / cellCount;
const colors = this.getValueColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value, width * (1 - BAR_SIZE_RATIO));
valueStyles.marginLeft = '8px';
const containerStyles: CSSProperties = {
width: `${width}px`,
height: `${height}px`,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
};
const cells: JSX.Element[] = [];
for (let i = 0; i < cellCount; i++) {
const currentValue = (valueRange / cellCount) * i;
const cellColor = this.getCellColor(currentValue);
const cellStyles: CSSProperties = {
width: `${cellWidth}px`,
backgroundColor: cellColor,
marginRight: '4px',
height: `${height}px`,
};
cells.push(<div style={cellStyles} />);
}
return (
<div style={containerStyles}>
{cells}
<div className="bar-gauge__value" style={valueStyles}>
{valueFormatted}
</div>
</div>
);
}
render() {
const { maxValue, minValue, orientation, unit, decimals } = this.props;
......@@ -157,7 +224,7 @@ export class BarGauge extends PureComponent<Props> {
return vertical
? this.renderVerticalBar(valueFormatted, valuePercent)
: this.renderHorizontalBar(valueFormatted, valuePercent);
: this.renderHorizontalLCD(valueFormatted, valuePercent);
}
}
......
import React, { PureComponent } from 'react';
import { SingleStatValueInfo } from '../../types';
import { SingleStatValueInfo, VizOrientation } from '../../types';
interface RenderProps {
vizWidth: number;
......@@ -12,20 +12,20 @@ interface Props {
height: number;
width: number;
values: SingleStatValueInfo[];
orientation?: string;
orientation: VizOrientation;
}
const SPACE_BETWEEN = 10;
export class VizRepeater extends PureComponent<Props> {
getOrientation() {
getOrientation(): VizOrientation {
const { orientation, width, height } = this.props;
if (!orientation) {
if (orientation === VizOrientation.Auto) {
if (width > height) {
return 'horizontal';
return VizOrientation.Vertical;
} else {
return 'vertical';
return VizOrientation.Horizontal;
}
}
......@@ -47,7 +47,7 @@ export class VizRepeater extends PureComponent<Props> {
let vizHeight = height;
let vizWidth = width;
if (orientation === 'horizontal') {
if (orientation === VizOrientation.Horizontal) {
repeaterStyle.flexDirection = 'column';
itemStyles.margin = `${SPACE_BETWEEN / 2}px 0`;
vizWidth = width;
......
......@@ -86,3 +86,9 @@ export interface RangeMap extends BaseMap {
from: string;
to: string;
}
export enum VizOrientation {
Auto = 'auto',
Vertical = 'vertical',
Horizontal = 'horizontal',
}
import { Threshold, SelectOptionItem, ValueMapping } from '@grafana/ui';
import { Threshold, SelectOptionItem, ValueMapping, VizOrientation } from '@grafana/ui';
import { SingleStatValueOptions } from '../gauge/types';
export interface BarGaugeOptions {
minValue: number;
maxValue: number;
orientation: string;
orientation: VizOrientation;
valueOptions: SingleStatValueOptions;
valueMappings: ValueMapping[];
thresholds: Threshold[];
}
export enum OrientationModes {
Vertical = 'vertical',
Horizontal = 'horizontal',
}
export const orientationOptions: SelectOptionItem[] = [
{ value: OrientationModes.Horizontal, label: 'Horizontal' },
{ value: OrientationModes.Vertical, label: 'Vertical' },
{ value: VizOrientation.Horizontal, label: 'Horizontal' },
{ value: VizOrientation.Vertical, label: 'Vertical' },
];
export const defaults: BarGaugeOptions = {
minValue: 0,
maxValue: 100,
orientation: OrientationModes.Horizontal,
orientation: VizOrientation.Horizontal,
valueOptions: {
unit: 'none',
stat: 'avg',
......
......@@ -10,7 +10,7 @@ import { Gauge, VizRepeater } from '@grafana/ui';
// Types
import { GaugeOptions } from './types';
import { PanelProps } from '@grafana/ui/src/types';
import { PanelProps, VizOrientation } from '@grafana/ui/src/types';
interface Props extends PanelProps<GaugeOptions> {}
......@@ -50,7 +50,7 @@ export class GaugePanel extends PureComponent<Props> {
});
return (
<VizRepeater height={height} width={width} values={values} orientation="horizontal">
<VizRepeater height={height} width={width} values={values} orientation={VizOrientation.Auto}>
{({ vizHeight, vizWidth, valueInfo }) => this.renderGauge(valueInfo.value, vizWidth, vizHeight)}
</VizRepeater>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment