mirror of https://github.com/grafana/grafana
parent
2d5fd7fdfd
commit
83d1eb87e5
@ -0,0 +1,59 @@ |
||||
// Library
|
||||
import React, { PureComponent } from 'react'; |
||||
|
||||
// Utils
|
||||
import { getValueFormat } from '../../utils'; |
||||
|
||||
// Types
|
||||
import { Themeable, TimeSeriesValue } from '../../types'; |
||||
|
||||
export interface Props extends Themeable { |
||||
height: number; |
||||
unit: string; |
||||
width: number; |
||||
value: TimeSeriesValue; |
||||
prefix: string; |
||||
suffix: string; |
||||
maxValue: number; |
||||
minValue: number; |
||||
} |
||||
|
||||
export class BarGauge extends PureComponent<Props> { |
||||
static defaultProps = { |
||||
maxValue: 100, |
||||
minValue: 0, |
||||
unit: 'none', |
||||
}; |
||||
|
||||
getNumericValue(): number { |
||||
if (Number.isFinite(this.props.value as number)) { |
||||
return this.props.value as number; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
render() { |
||||
const { height, width, maxValue, minValue, unit } = this.props; |
||||
|
||||
const numericValue = this.getNumericValue(); |
||||
const barMaxHeight = height * 0.8; // 20% for value & name
|
||||
const valuePercent = numericValue / (maxValue - minValue); |
||||
const barHeight = valuePercent * barMaxHeight; |
||||
|
||||
const formatFunc = getValueFormat(unit); |
||||
const valueFormatted = formatFunc(numericValue); |
||||
|
||||
return ( |
||||
<div className="bar-gauge" style={{ width: `${width}px`, height: `${height}px` }}> |
||||
<div className="bar-gauge__value">{valueFormatted}</div> |
||||
<div |
||||
style={{ |
||||
height: `${barHeight}px`, |
||||
width: `${width}px`, |
||||
backgroundColor: 'rgba(200,0,0,0.3)', |
||||
}} |
||||
/> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
.bar-gauge { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: flex-end; |
||||
} |
||||
|
||||
.bar-gauge__value { |
||||
text-align: center; |
||||
} |
@ -0,0 +1,56 @@ |
||||
// Libraries
|
||||
import React, { PureComponent } from 'react'; |
||||
|
||||
// Services & Utils
|
||||
import { processTimeSeries, ThemeContext } from '@grafana/ui'; |
||||
|
||||
// Components
|
||||
import { BarGauge } from '@grafana/ui'; |
||||
|
||||
// Types
|
||||
import { BarGaugeOptions } from './types'; |
||||
import { PanelProps, NullValueMode, TimeSeriesValue } from '@grafana/ui/src/types'; |
||||
|
||||
interface Props extends PanelProps<BarGaugeOptions> {} |
||||
|
||||
export class BarGaugePanel extends PureComponent<Props> { |
||||
render() { |
||||
const { panelData, width, height, onInterpolate, options } = this.props; |
||||
|
||||
const prefix = onInterpolate(options.prefix); |
||||
const suffix = onInterpolate(options.suffix); |
||||
|
||||
let value: TimeSeriesValue; |
||||
|
||||
if (panelData.timeSeries) { |
||||
const vmSeries = processTimeSeries({ |
||||
timeSeries: panelData.timeSeries, |
||||
nullValueMode: NullValueMode.Null, |
||||
}); |
||||
|
||||
if (vmSeries[0]) { |
||||
value = vmSeries[0].stats[options.stat]; |
||||
} else { |
||||
value = null; |
||||
} |
||||
} else if (panelData.tableData) { |
||||
value = panelData.tableData.rows[0].find(prop => prop > 0); |
||||
} |
||||
|
||||
return ( |
||||
<ThemeContext.Consumer> |
||||
{theme => ( |
||||
<BarGauge |
||||
value={value} |
||||
{...this.props.options} |
||||
width={width} |
||||
height={height} |
||||
prefix={prefix} |
||||
suffix={suffix} |
||||
theme={theme} |
||||
/> |
||||
)} |
||||
</ThemeContext.Consumer> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
import { BarGaugePanel } from './BarGaugePanel'; |
||||
import { PanelDefaults } from './types'; |
||||
|
||||
export { BarGaugePanel as Panel, PanelDefaults }; |
@ -0,0 +1,15 @@ |
||||
{ |
||||
"type": "panel", |
||||
"name": "Bar Gauge", |
||||
"id": "bargauge", |
||||
|
||||
"dataFormats": ["time_series"], |
||||
|
||||
"info": { |
||||
"author": { |
||||
"name": "Grafana Project", |
||||
"url": "https://grafana.com" |
||||
}, |
||||
"logos": {} |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
export interface BarGaugeOptions { |
||||
minValue: number; |
||||
maxValue: number; |
||||
prefix: string; |
||||
stat: string; |
||||
suffix: string; |
||||
unit: string; |
||||
} |
||||
|
||||
export const PanelDefaults: BarGaugeOptions = { |
||||
minValue: 0, |
||||
maxValue: 100, |
||||
prefix: '', |
||||
suffix: '', |
||||
stat: 'avg', |
||||
unit: 'none', |
||||
}; |
@ -1,4 +1,5 @@ |
||||
import GaugePanelOptions, { defaultProps } from './GaugePanelOptions'; |
||||
import { GaugePanelOptions } from './GaugePanelOptions'; |
||||
import { GaugePanel } from './GaugePanel'; |
||||
import { PanelDefaults } from './types'; |
||||
|
||||
export { GaugePanel as Panel, GaugePanelOptions as PanelOptions, defaultProps as PanelDefaults }; |
||||
export { GaugePanel as Panel, GaugePanelOptions as PanelOptions, PanelDefaults }; |
||||
|
Loading…
Reference in new issue