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 { 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