mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
StatPanel: ColorMode, GraphMode & JustifyMode changes (#20680)
* StatPanel: Options rethink * Changed options to string based * -Fixed tests * Refactoring moving files * Refactoring alignment factors * Added alignment factors * Added basic test * Added unit test for layout * Font size handling * Font sizing works * Progress on sizing * Updated * Minor update * Updated * Updated * Removed line option * updated * Updated * Updated * Updated * Highlight last point * Fixed tests * Code refactoring and cleanup * updated * Updated snapshot
This commit is contained in:
@@ -4,36 +4,23 @@ import React, { PureComponent } from 'react';
|
||||
// Services & Utils
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
import { BarGauge, BarGaugeAlignmentFactors, VizRepeater, DataLinksContextMenu } from '@grafana/ui';
|
||||
import { BarGauge, VizRepeater, DataLinksContextMenu } from '@grafana/ui';
|
||||
import { BarGaugeOptions } from './types';
|
||||
import { getFieldDisplayValues, FieldDisplay, PanelProps } from '@grafana/data';
|
||||
import {
|
||||
getFieldDisplayValues,
|
||||
FieldDisplay,
|
||||
PanelProps,
|
||||
getDisplayValueAlignmentFactors,
|
||||
DisplayValueAlignmentFactors,
|
||||
} from '@grafana/data';
|
||||
import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
|
||||
export class BarGaugePanel extends PureComponent<PanelProps<BarGaugeOptions>> {
|
||||
findMaximumInput = (values: FieldDisplay[], width: number, height: number): BarGaugeAlignmentFactors => {
|
||||
const info: BarGaugeAlignmentFactors = {
|
||||
title: '',
|
||||
text: '',
|
||||
};
|
||||
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const v = values[i].display;
|
||||
if (v.text && v.text.length > info.text.length) {
|
||||
info.text = v.text;
|
||||
}
|
||||
|
||||
if (v.title && v.title.length > info.title.length) {
|
||||
info.title = v.title;
|
||||
}
|
||||
}
|
||||
return info;
|
||||
};
|
||||
|
||||
renderValue = (
|
||||
value: FieldDisplay,
|
||||
width: number,
|
||||
height: number,
|
||||
alignmentFactors: BarGaugeAlignmentFactors
|
||||
alignmentFactors: DisplayValueAlignmentFactors
|
||||
): JSX.Element => {
|
||||
const { options } = this.props;
|
||||
const { field, display } = value;
|
||||
@@ -87,7 +74,7 @@ export class BarGaugePanel extends PureComponent<PanelProps<BarGaugeOptions>> {
|
||||
return (
|
||||
<VizRepeater
|
||||
source={data}
|
||||
getAlignmentFactors={this.findMaximumInput}
|
||||
getAlignmentFactors={getDisplayValueAlignmentFactors}
|
||||
getValues={this.getValues}
|
||||
renderValue={this.renderValue}
|
||||
renderCounter={renderCounter}
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
import { FieldDisplayOptions, FieldConfig, DataLink, PanelEditorProps } from '@grafana/data';
|
||||
|
||||
import { Threshold, ValueMapping } from '@grafana/data';
|
||||
import { BarGaugeOptions, orientationOptions, displayModes } from './types';
|
||||
import { BarGaugeOptions, displayModes } from './types';
|
||||
import { orientationOptions } from '../gauge/types';
|
||||
import {
|
||||
getDataLinksVariableSuggestions,
|
||||
getCalculationValueDataLinksVariableSuggestions,
|
||||
|
||||
@@ -12,11 +12,6 @@ export const displayModes: Array<SelectableValue<string>> = [
|
||||
{ value: 'basic', label: 'Basic' },
|
||||
];
|
||||
|
||||
export const orientationOptions: Array<SelectableValue<VizOrientation>> = [
|
||||
{ value: VizOrientation.Horizontal, label: 'Horizontal' },
|
||||
{ value: VizOrientation.Vertical, label: 'Vertical' },
|
||||
];
|
||||
|
||||
export const defaults: BarGaugeOptions = {
|
||||
displayMode: 'lcd',
|
||||
orientation: VizOrientation.Horizontal,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { VizOrientation, FieldDisplayOptions } from '@grafana/data';
|
||||
import { VizOrientation, FieldDisplayOptions, SelectableValue } from '@grafana/data';
|
||||
import { SingleStatBaseOptions } from '@grafana/ui/src/components/SingleStatShared/SingleStatBaseOptions';
|
||||
import { standardFieldDisplayOptions } from '../stat/types';
|
||||
|
||||
@@ -11,6 +11,12 @@ export const standardGaugeFieldOptions: FieldDisplayOptions = {
|
||||
...standardFieldDisplayOptions,
|
||||
};
|
||||
|
||||
export const orientationOptions: Array<SelectableValue<VizOrientation>> = [
|
||||
{ value: VizOrientation.Auto, label: 'Auto' },
|
||||
{ value: VizOrientation.Horizontal, label: 'Horizontal' },
|
||||
{ value: VizOrientation.Vertical, label: 'Vertical' },
|
||||
];
|
||||
|
||||
export const defaults: GaugeOptions = {
|
||||
showThresholdMarkers: true,
|
||||
showThresholdLabels: false,
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// Libraries
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
// Components
|
||||
import { Switch } from '@grafana/ui';
|
||||
|
||||
// Types
|
||||
import { SparklineOptions } from './types';
|
||||
|
||||
interface Props {
|
||||
options: SparklineOptions;
|
||||
onChange: (options: SparklineOptions) => void;
|
||||
}
|
||||
|
||||
export class SparklineEditor extends PureComponent<Props> {
|
||||
onToggleShow = () => this.props.onChange({ ...this.props.options, show: !this.props.options.show });
|
||||
|
||||
render() {
|
||||
const { show } = this.props.options;
|
||||
|
||||
return <Switch label="Graph" labelClass="width-8" checked={show} onChange={this.onToggleShow} />;
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,41 @@ import { config } from 'app/core/config';
|
||||
|
||||
// Types
|
||||
import { StatPanelOptions } from './types';
|
||||
import { VizRepeater, BigValue, DataLinksContextMenu, BigValueSparkline } from '@grafana/ui';
|
||||
import { PanelProps, getFieldDisplayValues, FieldDisplay } from '@grafana/data';
|
||||
import { VizRepeater, BigValue, DataLinksContextMenu, BigValueSparkline, BigValueGraphMode } from '@grafana/ui';
|
||||
|
||||
import {
|
||||
PanelProps,
|
||||
getFieldDisplayValues,
|
||||
FieldDisplay,
|
||||
ReducerID,
|
||||
getDisplayValueAlignmentFactors,
|
||||
DisplayValueAlignmentFactors,
|
||||
VizOrientation,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
|
||||
export class StatPanel extends PureComponent<PanelProps<StatPanelOptions>> {
|
||||
renderValue = (value: FieldDisplay, width: number, height: number): JSX.Element => {
|
||||
renderValue = (
|
||||
value: FieldDisplay,
|
||||
width: number,
|
||||
height: number,
|
||||
alignmentFactors: DisplayValueAlignmentFactors
|
||||
): JSX.Element => {
|
||||
const { timeRange, options } = this.props;
|
||||
let sparkline: BigValueSparkline | undefined;
|
||||
|
||||
if (value.sparkline) {
|
||||
sparkline = {
|
||||
...options.sparkline,
|
||||
data: value.sparkline,
|
||||
minX: timeRange.from.valueOf(),
|
||||
maxX: timeRange.to.valueOf(),
|
||||
};
|
||||
|
||||
const calc = options.fieldOptions.calcs[0];
|
||||
if (calc === ReducerID.last) {
|
||||
sparkline.highlightIndex = sparkline.data.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -31,7 +50,10 @@ export class StatPanel extends PureComponent<PanelProps<StatPanelOptions>> {
|
||||
<BigValue
|
||||
value={value.display}
|
||||
sparkline={sparkline}
|
||||
displayMode={options.displayMode}
|
||||
colorMode={options.colorMode}
|
||||
graphMode={options.graphMode}
|
||||
justifyMode={options.justifyMode}
|
||||
alignmentFactors={alignmentFactors}
|
||||
width={width}
|
||||
height={height}
|
||||
theme={config.theme}
|
||||
@@ -52,22 +74,39 @@ export class StatPanel extends PureComponent<PanelProps<StatPanelOptions>> {
|
||||
replaceVariables,
|
||||
theme: config.theme,
|
||||
data: data.series,
|
||||
sparkline: options.sparkline.show,
|
||||
sparkline: options.graphMode !== BigValueGraphMode.None,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { height, width, options, data, renderCounter } = this.props;
|
||||
const { height, options, width, data, renderCounter } = this.props;
|
||||
|
||||
return (
|
||||
<VizRepeater
|
||||
getValues={this.getValues}
|
||||
getAlignmentFactors={getDisplayValueAlignmentFactors}
|
||||
renderValue={this.renderValue}
|
||||
width={width}
|
||||
height={height}
|
||||
source={data}
|
||||
renderCounter={renderCounter}
|
||||
orientation={options.orientation}
|
||||
orientation={getOrientation(width, height, options.orientation)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stat panel custom auto orientation
|
||||
*/
|
||||
function getOrientation(width: number, height: number, orientation: VizOrientation): VizOrientation {
|
||||
if (orientation !== VizOrientation.Auto) {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
if (width / height > 2) {
|
||||
return VizOrientation.Vertical;
|
||||
} else {
|
||||
return VizOrientation.Horizontal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ import {
|
||||
|
||||
import { Threshold, ValueMapping, FieldConfig, DataLink, PanelEditorProps, FieldDisplayOptions } from '@grafana/data';
|
||||
|
||||
import { StatPanelOptions, SparklineOptions, displayModes } from './types';
|
||||
import { SparklineEditor } from './SparklineEditor';
|
||||
import { StatPanelOptions, colorModes, graphModes, justifyModes } from './types';
|
||||
import { orientationOptions } from '../gauge/types';
|
||||
|
||||
import {
|
||||
getDataLinksVariableSuggestions,
|
||||
getCalculationValueDataLinksVariableSuggestions,
|
||||
@@ -45,13 +46,10 @@ export class StatPanelEditor extends PureComponent<PanelEditorProps<StatPanelOpt
|
||||
fieldOptions,
|
||||
});
|
||||
|
||||
onSparklineChanged = (sparkline: SparklineOptions) =>
|
||||
this.props.onOptionsChange({
|
||||
...this.props.options,
|
||||
sparkline,
|
||||
});
|
||||
|
||||
onDisplayModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
|
||||
onColorModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, colorMode: value });
|
||||
onGraphModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, graphMode: value });
|
||||
onJustifyModeChanged = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, justifyMode: value });
|
||||
onOrientationChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, orientation: value });
|
||||
|
||||
onDefaultsChange = (field: FieldConfig) => {
|
||||
this.onDisplayOptionsChanged({
|
||||
@@ -81,16 +79,45 @@ export class StatPanelEditor extends PureComponent<PanelEditorProps<StatPanelOpt
|
||||
<PanelOptionsGroup title="Display">
|
||||
<FieldDisplayEditor onChange={this.onDisplayOptionsChanged} value={fieldOptions} labelWidth={8} />
|
||||
<div className="form-field">
|
||||
<FormLabel width={8}>Display mode</FormLabel>
|
||||
<FormLabel width={8}>Orientation</FormLabel>
|
||||
<Select
|
||||
width={12}
|
||||
options={displayModes}
|
||||
defaultValue={displayModes[0]}
|
||||
onChange={this.onDisplayModeChange}
|
||||
value={displayModes.find(item => item.value === options.displayMode)}
|
||||
options={orientationOptions}
|
||||
defaultValue={orientationOptions[0]}
|
||||
onChange={this.onOrientationChange}
|
||||
value={orientationOptions.find(item => item.value === options.orientation)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<FormLabel width={8}>Color</FormLabel>
|
||||
<Select
|
||||
width={12}
|
||||
options={colorModes}
|
||||
defaultValue={colorModes[0]}
|
||||
onChange={this.onColorModeChanged}
|
||||
value={colorModes.find(item => item.value === options.colorMode)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<FormLabel width={8}>Graph</FormLabel>
|
||||
<Select
|
||||
width={12}
|
||||
options={graphModes}
|
||||
defaultValue={graphModes[0]}
|
||||
onChange={this.onGraphModeChanged}
|
||||
value={graphModes.find(item => item.value === options.graphMode)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<FormLabel width={8}>Justify</FormLabel>
|
||||
<Select
|
||||
width={12}
|
||||
options={justifyModes}
|
||||
defaultValue={justifyModes[0]}
|
||||
onChange={this.onJustifyModeChanged}
|
||||
value={justifyModes.find(item => item.value === options.justifyMode)}
|
||||
/>
|
||||
</div>
|
||||
<SparklineEditor options={options.sparkline} onChange={this.onSparklineChanged} />
|
||||
</PanelOptionsGroup>
|
||||
|
||||
<PanelOptionsGroup title="Field">
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
import { SingleStatBaseOptions, BigValueDisplayMode } from '@grafana/ui';
|
||||
import { SingleStatBaseOptions, BigValueColorMode, BigValueGraphMode, BigValueJustifyMode } from '@grafana/ui';
|
||||
import { VizOrientation, ReducerID, FieldDisplayOptions, SelectableValue } from '@grafana/data';
|
||||
|
||||
export interface SparklineOptions {
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
// Structure copied from angular
|
||||
export interface StatPanelOptions extends SingleStatBaseOptions {
|
||||
sparkline: SparklineOptions;
|
||||
displayMode: BigValueDisplayMode;
|
||||
graphMode: BigValueGraphMode;
|
||||
colorMode: BigValueColorMode;
|
||||
justifyMode: BigValueJustifyMode;
|
||||
}
|
||||
|
||||
export const displayModes: Array<SelectableValue<BigValueDisplayMode>> = [
|
||||
{ value: BigValueDisplayMode.Classic, label: 'Classic' },
|
||||
{ value: BigValueDisplayMode.Vibrant, label: 'Vibrant' },
|
||||
{ value: BigValueDisplayMode.Vibrant2, label: 'Vibrant 2' },
|
||||
export const colorModes: Array<SelectableValue<BigValueColorMode>> = [
|
||||
{ value: BigValueColorMode.Value, label: 'Value' },
|
||||
{ value: BigValueColorMode.Background, label: 'Background' },
|
||||
];
|
||||
|
||||
export const graphModes: Array<SelectableValue<BigValueGraphMode>> = [
|
||||
{ value: BigValueGraphMode.None, label: 'None' },
|
||||
{ value: BigValueGraphMode.Area, label: 'Area graph' },
|
||||
];
|
||||
|
||||
export const justifyModes: Array<SelectableValue<BigValueJustifyMode>> = [
|
||||
{ value: BigValueJustifyMode.Auto, label: 'Auto' },
|
||||
{ value: BigValueJustifyMode.Center, label: 'Center' },
|
||||
];
|
||||
|
||||
export const standardFieldDisplayOptions: FieldDisplayOptions = {
|
||||
@@ -33,10 +39,9 @@ export const standardFieldDisplayOptions: FieldDisplayOptions = {
|
||||
};
|
||||
|
||||
export const defaults: StatPanelOptions = {
|
||||
sparkline: {
|
||||
show: true,
|
||||
},
|
||||
displayMode: BigValueDisplayMode.Vibrant,
|
||||
graphMode: BigValueGraphMode.Area,
|
||||
colorMode: BigValueColorMode.Value,
|
||||
justifyMode: BigValueJustifyMode.Auto,
|
||||
fieldOptions: standardFieldDisplayOptions,
|
||||
orientation: VizOrientation.Auto,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user