Browse Source

first draft of repeater component

Peter Holmberg 6 years ago
parent
commit
4c5c162045

+ 56 - 0
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<Props> {
+  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,
+    });
+  }
+}

+ 1 - 0
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';

+ 1 - 4
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;

+ 18 - 48
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<GaugeOptions> {}
 
 export class GaugePanel extends PureComponent<Props> {
-  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 (
-        <div className="singlestat-panel" key={`${timeSeries.label}-${index}`} style={style}>
-          {this.renderGauge(value, gaugeWidth, gaugeHeight)}
-          <div style={{ textAlign: 'center' }}>{series.label}</div>
-        </div>
-      );
-    });
-  }
-
   renderGauge(value, width, height) {
     const { onInterpolate, options } = this.props;
     const { valueOptions } = options;
@@ -101,7 +56,8 @@ export class GaugePanel extends PureComponent<Props> {
   }
 
   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<Props> {
       });
 
       if (timeSeries.length > 1) {
-        return this.renderMultipleGauge(timeSeries);
+        return (
+          <VizRepeater timeSeries={timeSeries} width={width} height={height}>
+            {({ vizHeight, vizWidth, vizContainerStyle }) => {
+              return timeSeries.map((series, index) => {
+                const value = stat !== 'name' ? series.stats[stat] : series.label;
+
+                return (
+                  <div className="singlestat-panel" key={`${series.label}-${index}`} style={vizContainerStyle}>
+                    {this.renderGauge(value, vizWidth, vizHeight)}
+                  </div>
+                );
+              });
+            }}
+          </VizRepeater>
+        );
       } else if (timeSeries.length > 0) {
         return this.renderSingleGauge(timeSeries);
       } else {

+ 1 - 1
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' }],
 };