Commit 92c73036 by Torkel Ödegaard

Refactoring bar gauge

parent a27c55b5
// Library // Library
import React, { PureComponent } from 'react'; import React, { PureComponent, CSSProperties } from 'react';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
// Utils // Utils
...@@ -65,7 +65,7 @@ export class BarGauge extends PureComponent<Props> { ...@@ -65,7 +65,7 @@ export class BarGauge extends PureComponent<Props> {
}; };
} }
getValueStyles(value: string, color: string) { getValueStyles(value: string, color: string): CSSProperties {
const { width } = this.props; const { width } = this.props;
const guess = width / value.length; const guess = width / value.length;
...@@ -77,16 +77,28 @@ export class BarGauge extends PureComponent<Props> { ...@@ -77,16 +77,28 @@ export class BarGauge extends PureComponent<Props> {
}; };
} }
renderHorizontalBar(valueStyles: React.CSSProperties, valueFormatted: string, barStyles: React.CSSProperties) { renderVerticalBar(valueFormatted: string, valuePercent: number) {
const { height, width } = this.props; const { height, width } = this.props;
const containerStyles = { const maxHeight = width * 0.8;
const barHeight = Math.max(valuePercent * maxHeight, 0);
const colors = this.getColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
const containerStyles: CSSProperties = {
width: `${width}px`, width: `${width}px`,
height: `${height}px`, height: `${height}px`,
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'flex-end', justifyContent: 'flex-end',
} as React.CSSProperties; };
const barStyles: CSSProperties = {
height: `${barHeight}px`,
width: `${width}px`,
backgroundColor: colors.bar,
borderTop: `1px solid ${colors.border}`,
};
return ( return (
<div style={containerStyles}> <div style={containerStyles}>
...@@ -98,22 +110,31 @@ export class BarGauge extends PureComponent<Props> { ...@@ -98,22 +110,31 @@ export class BarGauge extends PureComponent<Props> {
); );
} }
renderVerticalBar(valueFormatted: string, barStyles: React.CSSProperties) { renderHorizontalBar(valueFormatted: string, valuePercent: number) {
const { height, width } = this.props; const { height, width } = this.props;
const maxWidth = width - 0.8;
const barWidth = Math.max(valuePercent * maxWidth, 0);
const colors = this.getColors(); const colors = this.getColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
const containerStyles = { valueStyles.marginLeft = '8px';
const containerStyles: CSSProperties = {
width: `${width}px`, width: `${width}px`,
height: `${height}px`, height: `${height}px`,
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
marginBottom: '8px', marginBottom: '8px',
} as React.CSSProperties; };
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
Object.assign(valueStyles, { marginLeft: '8px' }); const barStyles = {
height: `${height}px`,
width: `${barWidth}px`,
backgroundColor: colors.bar,
borderRight: `1px solid ${colors.border}`,
};
return ( return (
<div style={containerStyles}> <div style={containerStyles}>
...@@ -126,40 +147,18 @@ export class BarGauge extends PureComponent<Props> { ...@@ -126,40 +147,18 @@ export class BarGauge extends PureComponent<Props> {
} }
render() { render() {
const { height, width, maxValue, minValue, orientation, unit, decimals } = this.props; const { maxValue, minValue, orientation, unit, decimals } = this.props;
const numericValue = this.getNumericValue(); const numericValue = this.getNumericValue();
const barMaxHeight = height * 0.8; // 20% for value & name
const barMaxWidth = width * 0.8;
const valuePercent = numericValue / (maxValue - minValue); const valuePercent = numericValue / (maxValue - minValue);
const barHeight = Math.max(valuePercent * barMaxHeight, 0);
const barWidth = Math.max(valuePercent * barMaxWidth, 0);
const formatFunc = getValueFormat(unit); const formatFunc = getValueFormat(unit);
const valueFormatted = formatFunc(numericValue, decimals); const valueFormatted = formatFunc(numericValue, decimals);
const colors = this.getColors();
const valueStyles = this.getValueStyles(valueFormatted, colors.value);
const vertical = orientation === 'vertical'; 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 return vertical
? this.renderVerticalBar(valueFormatted, barStyles) ? this.renderVerticalBar(valueFormatted, valuePercent)
: this.renderHorizontalBar(valueStyles, valueFormatted, barStyles); : this.renderHorizontalBar(valueFormatted, valuePercent);
} }
} }
......
...@@ -15,51 +15,58 @@ interface Props { ...@@ -15,51 +15,58 @@ interface Props {
orientation?: string; orientation?: string;
} }
const SPACE_BETWEEN = 10;
export class VizRepeater extends PureComponent<Props> { export class VizRepeater extends PureComponent<Props> {
render() { getOrientation() {
const { children, orientation, height, values, width } = this.props; const { orientation, width, height } = this.props;
const vizContainerWidth = (1 / values.length) * 100; if (!orientation) {
const vizContainerHeight = (1 / values.length) * 100; if (width > height) {
const repeatingVizWidth = Math.floor(width / values.length) - 10; // make Gauge slightly smaller than panel. return 'horizontal';
const repeatingVizHeight = Math.floor(height / values.length) - 10; } else {
return 'vertical';
}
}
const horizontalVisualization = { return orientation;
display: 'flex', }
height: height,
width: `${vizContainerWidth}%`,
};
const verticalVisualization = { render() {
const { children, height, values, width } = this.props;
const orientation = this.getOrientation();
const itemStyles: React.CSSProperties = {
display: 'flex', display: 'flex',
width: width,
height: `${vizContainerHeight}%`,
}; };
const repeaterStyle = { const repeaterStyle: React.CSSProperties = {
display: 'flex', display: 'flex',
flexDirection: orientation === 'vertical' || height > width ? 'column' : 'row', };
} as React.CSSProperties;
let vizContainerStyle = {};
let vizWidth = width;
let vizHeight = height; let vizHeight = height;
let vizWidth = width;
if ((orientation && orientation === 'horizontal') || width > height) { if (orientation === 'horizontal') {
vizContainerStyle = horizontalVisualization; repeaterStyle.flexDirection = 'column';
vizWidth = repeatingVizWidth; itemStyles.margin = `${SPACE_BETWEEN / 2}px 0`;
vizWidth = width;
vizHeight = height / values.length - SPACE_BETWEEN;
} else {
repeaterStyle.flexDirection = 'row';
itemStyles.margin = `0 ${SPACE_BETWEEN / 2}px`;
vizHeight = height;
vizWidth = width / values.length - SPACE_BETWEEN;
} }
if ((orientation && orientation === 'vertical') || height > width) { itemStyles.width = `${vizWidth}px`;
vizContainerStyle = verticalVisualization; itemStyles.height = `${vizHeight}px`;
vizHeight = repeatingVizHeight;
}
return ( return (
<div style={repeaterStyle}> <div style={repeaterStyle}>
{values.map((valueInfo, index) => { {values.map((valueInfo, index) => {
return ( return (
<div key={index} style={vizContainerStyle}> <div key={index} style={itemStyles}>
{children({ vizHeight, vizWidth, valueInfo })} {children({ vizHeight, vizWidth, valueInfo })}
</div> </div>
); );
......
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