added orientation option

This commit is contained in:
Peter Holmberg
2019-02-20 15:07:30 +01:00
parent 4c5c162045
commit 2fc136e615
6 changed files with 187 additions and 78 deletions
@@ -21,6 +21,7 @@ const setup = (propOverrides?: object) => {
value: 25,
decimals: 0,
theme: getTheme(),
orientation: 'horizontal',
};
Object.assign(props, propOverrides);
@@ -17,6 +17,7 @@ export interface Props extends Themeable {
value: TimeSeriesValue;
maxValue: number;
minValue: number;
orientation: string;
prefix?: string;
suffix?: string;
decimals?: number;
@@ -28,6 +29,7 @@ export class BarGauge extends PureComponent<Props> {
minValue: 0,
value: 100,
unit: 'none',
orientation: 'horizontal',
thresholds: [],
valueMappings: [],
};
@@ -75,29 +77,19 @@ export class BarGauge extends PureComponent<Props> {
};
}
render() {
const { height, width, maxValue, minValue, unit, decimals } = this.props;
renderHorizontalBar(valueStyles: React.CSSProperties, valueFormatted: string, barStyles: React.CSSProperties) {
const { height, width } = this.props;
const numericValue = this.getNumericValue();
const barMaxHeight = height * 0.8; // 20% for value & name
const valuePercent = numericValue / (maxValue - minValue);
const barHeight = Math.max(valuePercent * barMaxHeight, 0);
const formatFunc = getValueFormat(unit);
const valueFormatted = formatFunc(numericValue, decimals);
const colors = this.getColors();
const containerStyles = { width: `${width}px`, height: `${height}px` };
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
const barStyles = {
height: `${barHeight}px`,
const containerStyles = {
width: `${width}px`,
backgroundColor: colors.bar,
borderTop: `1px solid ${colors.border}`,
};
height: `${height}px`,
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
} as React.CSSProperties;
return (
<div className="bar-gauge" style={containerStyles}>
<div style={containerStyles}>
<div className="bar-gauge__value" style={valueStyles}>
{valueFormatted}
</div>
@@ -105,6 +97,70 @@ export class BarGauge extends PureComponent<Props> {
</div>
);
}
renderVerticalBar(valueFormatted: string, barStyles: React.CSSProperties) {
const { height, width } = this.props;
const colors = this.getColors();
const containerStyles = {
width: `${width}px`,
height: `${height}px`,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginBottom: '8px',
} as React.CSSProperties;
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
Object.assign(valueStyles, { marginLeft: '8px' });
return (
<div style={containerStyles}>
<div style={barStyles} />
<div className="bar-gauge__value" style={valueStyles}>
{valueFormatted}
</div>
</div>
);
}
render() {
const { height, width, maxValue, minValue, orientation, unit, decimals } = this.props;
const numericValue = this.getNumericValue();
const barMaxHeight = height * 0.8; // 20% for value & name
const barMaxWidth = width * 0.8;
const valuePercent = numericValue / (maxValue - minValue);
const barHeight = Math.max(valuePercent * barMaxHeight, 0);
const barWidth = Math.max(valuePercent * barMaxWidth, 0);
const formatFunc = getValueFormat(unit);
const valueFormatted = formatFunc(numericValue, decimals);
const colors = this.getColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
const vertical = orientation === 'vertical';
const horizontalBarStyles = {
height: `${barHeight}px`,
width: `${width}px`,
backgroundColor: colors.bar,
borderTop: `1px solid ${colors.border}`,
};
const verticalBarStyles = {
height: `${height}px`,
width: `${barWidth}px`,
backgroundColor: colors.bar,
borderRight: `1px solid ${colors.border}`,
};
const barStyles = vertical ? verticalBarStyles : horizontalBarStyles;
return vertical
? this.renderVerticalBar(valueFormatted, barStyles)
: this.renderHorizontalBar(valueStyles, valueFormatted, barStyles);
}
}
interface BarColors {
@@ -1,4 +1,4 @@
import { Component } from 'react';
import React, { PureComponent } from 'react';
import { TimeSeriesVMs } from '../../types';
interface RenderProps {
@@ -12,45 +12,55 @@ interface Props {
height: number;
width: number;
timeSeries: TimeSeriesVMs;
orientation?: string;
}
export class VizRepeater extends Component<Props> {
export class VizRepeater extends PureComponent<Props> {
render() {
const { children, height, timeSeries, width } = this.props;
const { children, orientation, height, timeSeries, width } = this.props;
const singleStatWidth = 1 / timeSeries.length * 100;
const singleStatHeight = 1 / timeSeries.length * 100;
const repeatingGaugeWidth = Math.floor(width / timeSeries.length) - 10; // make Gauge slightly smaller than panel.
const repeatingGaugeHeight = Math.floor(height / timeSeries.length) - 10;
const vizContainerWidth = 1 / timeSeries.length * 100;
const vizContainerHeight = 1 / timeSeries.length * 100;
const repeatingVizWidth = Math.floor(width / timeSeries.length) - 10; // make Gauge slightly smaller than panel.
const repeatingVizHeight = Math.floor(height / timeSeries.length) - 10;
const horizontalPanels = {
display: 'inline-block',
const horizontalVisualization = {
height: height,
width: `${singleStatWidth}%`,
width: `${vizContainerWidth}%`,
};
const verticalPanels = {
display: 'block',
const verticalVisualization = {
width: width,
height: `${singleStatHeight}%`,
height: `${vizContainerHeight}%`,
};
const repeaterStyle = {
display: 'flex',
flexDirection: orientation === 'vertical' || height > width ? 'column' : 'row',
} as React.CSSProperties;
let vizContainerStyle = {};
let vizWidth = width;
let vizHeight = height;
if (width > height) {
vizContainerStyle = horizontalPanels;
vizWidth = repeatingGaugeWidth;
} else if (height > width) {
vizContainerStyle = verticalPanels;
vizHeight = repeatingGaugeHeight;
if (orientation === 'horizontal' || width > height) {
vizContainerStyle = horizontalVisualization;
vizWidth = repeatingVizWidth;
}
return children({
vizHeight,
vizWidth,
vizContainerStyle,
});
if (orientation === 'vertical' || height > width) {
vizContainerStyle = verticalVisualization;
vizHeight = repeatingVizHeight;
}
return (
<div style={repeaterStyle}>
{children({
vizHeight,
vizWidth,
vizContainerStyle,
})}
</div>
);
}
}