diff --git a/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx new file mode 100644 index 00000000000..e944fae1924 --- /dev/null +++ b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx @@ -0,0 +1,56 @@ +import { Component } from 'react'; +import { TimeSeriesVMs } from '../../types'; + +interface RenderProps { + vizWidth: number; + vizHeight: number; + vizContainerStyle: React.CSSProperties; +} + +interface Props { + children: (renderProps: RenderProps) => JSX.Element | JSX.Element[]; + height: number; + width: number; + timeSeries: TimeSeriesVMs; +} + +export class VizRepeater extends Component { + render() { + const { children, 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 horizontalPanels = { + display: 'inline-block', + height: height, + width: `${singleStatWidth}%`, + }; + + const verticalPanels = { + display: 'block', + width: width, + height: `${singleStatHeight}%`, + }; + + let vizContainerStyle = {}; + let vizWidth = width; + let vizHeight = height; + + if (width > height) { + vizContainerStyle = horizontalPanels; + vizWidth = repeatingGaugeWidth; + } else if (height > width) { + vizContainerStyle = verticalPanels; + vizHeight = repeatingGaugeHeight; + } + + return children({ + vizHeight, + vizWidth, + vizContainerStyle, + }); + } +} diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index 2cdf3ffe6f6..b23bbe3784b 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -27,3 +27,4 @@ export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult'; export { Gauge } from './Gauge/Gauge'; export { Graph } from './Graph/Graph'; export { BarGauge } from './BarGauge/BarGauge'; +export { VizRepeater } from './VizRepeater/VizRepeater'; diff --git a/packages/grafana-ui/src/types/data.ts b/packages/grafana-ui/src/types/data.ts index 1e4ccba3948..2239ec3c523 100644 --- a/packages/grafana-ui/src/types/data.ts +++ b/packages/grafana-ui/src/types/data.ts @@ -48,10 +48,7 @@ export enum NullValueMode { } /** View model projection of many time series */ -export interface TimeSeriesVMs { - [index: number]: TimeSeriesVM; - length: number; -} +export type TimeSeriesVMs = TimeSeriesVM[]; interface Column { text: string; diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index 7be347563fd..4381338d640 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -6,7 +6,7 @@ import { processTimeSeries } from '@grafana/ui'; import { config } from 'app/core/config'; // Components -import { Gauge } from '@grafana/ui'; +import { Gauge, VizRepeater } from '@grafana/ui'; // Types import { GaugeOptions } from './types'; @@ -15,51 +15,6 @@ import { PanelProps, NullValueMode } from '@grafana/ui/src/types'; interface Props extends PanelProps {} export class GaugePanel extends PureComponent { - renderMultipleGauge(timeSeries) { - const { options, height, width } = this.props; - const { stat } = options.valueOptions; - - return timeSeries.map((series, index) => { - 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 horizontalPanels = { - display: 'inline-block', - height: height, - width: `${singleStatWidth}%`, - }; - - const verticalPanels = { - display: 'block', - width: width, - height: `${singleStatHeight}%`, - }; - - let style = {}; - let gaugeWidth = width; - let gaugeHeight = height; - - if (width > height) { - style = horizontalPanels; - gaugeWidth = repeatingGaugeWidth; - } else if (height > width) { - style = verticalPanels; - gaugeHeight = repeatingGaugeHeight; - } - - const value = stat !== 'name' ? series.stats[stat] : series.label; - - return ( -
- {this.renderGauge(value, gaugeWidth, gaugeHeight)} -
{series.label}
-
- ); - }); - } - renderGauge(value, width, height) { const { onInterpolate, options } = this.props; const { valueOptions } = options; @@ -101,7 +56,8 @@ export class GaugePanel extends PureComponent { } render() { - const { panelData } = this.props; + const { panelData, options, height, width } = this.props; + const { stat } = options.valueOptions; if (panelData.timeSeries) { const timeSeries = processTimeSeries({ @@ -110,7 +66,21 @@ export class GaugePanel extends PureComponent { }); if (timeSeries.length > 1) { - return this.renderMultipleGauge(timeSeries); + return ( + + {({ vizHeight, vizWidth, vizContainerStyle }) => { + return timeSeries.map((series, index) => { + const value = stat !== 'name' ? series.stats[stat] : series.label; + + return ( +
+ {this.renderGauge(value, vizWidth, vizHeight)} +
+ ); + }); + }} +
+ ); } else if (timeSeries.length > 0) { return this.renderSingleGauge(timeSeries); } else { diff --git a/public/app/plugins/panel/gauge/types.ts b/public/app/plugins/panel/gauge/types.ts index d6f2b8ab251..6922538c210 100644 --- a/public/app/plugins/panel/gauge/types.ts +++ b/public/app/plugins/panel/gauge/types.ts @@ -31,5 +31,5 @@ export const defaults: GaugeOptions = { unit: 'none', }, valueMappings: [], - thresholds: [{ index: 1, value: 80, color: 'red' }, { index: 0, value: -Infinity, color: 'green' }], + thresholds: [{ index: 0, value: -Infinity, color: 'green' }, { index: 1, value: 80, color: 'red' }], };