mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #14909 from grafana/hugoh/move-valuemappings-to-ui-components
Move ValueMappings to UI Components
This commit is contained in:
commit
ff8592d1fe
@ -1,5 +1,5 @@
|
|||||||
import React, { SFC, ReactNode } from 'react';
|
import React, { SFC, ReactNode } from 'react';
|
||||||
import { Tooltip } from '@grafana/ui';
|
import { Tooltip } from '../Tooltip/Tooltip';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tooltip?: string;
|
tooltip?: string;
|
@ -1,22 +1,23 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { MappingType, RangeMap, Select, ValueMap } from '@grafana/ui';
|
|
||||||
|
|
||||||
import { Label } from 'app/core/components/Label/Label';
|
import { MappingType, ValueMapping } from '../../types/panel';
|
||||||
|
import { Label } from '../Label/Label';
|
||||||
|
import { Select } from '../Select/Select';
|
||||||
|
|
||||||
interface Props {
|
export interface Props {
|
||||||
mapping: ValueMap | RangeMap;
|
valueMapping: ValueMapping;
|
||||||
updateMapping: (mapping) => void;
|
updateValueMapping: (valueMapping: ValueMapping) => void;
|
||||||
removeMapping: () => void;
|
removeValueMapping: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
from: string;
|
from?: string;
|
||||||
id: number;
|
id: number;
|
||||||
operator: string;
|
operator: string;
|
||||||
text: string;
|
text: string;
|
||||||
to: string;
|
to?: string;
|
||||||
type: MappingType;
|
type: MappingType;
|
||||||
value: string;
|
value?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mappingOptions = [
|
const mappingOptions = [
|
||||||
@ -25,36 +26,34 @@ const mappingOptions = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default class MappingRow extends PureComponent<Props, State> {
|
export default class MappingRow extends PureComponent<Props, State> {
|
||||||
constructor(props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = { ...props.valueMapping };
|
||||||
...props.mapping,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMappingValueChange = event => {
|
onMappingValueChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({ value: event.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMappingFromChange = event => {
|
onMappingFromChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ from: event.target.value });
|
this.setState({ from: event.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMappingToChange = event => {
|
onMappingToChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ to: event.target.value });
|
this.setState({ to: event.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMappingTextChange = event => {
|
onMappingTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ text: event.target.value });
|
this.setState({ text: event.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMappingTypeChange = mappingType => {
|
onMappingTypeChange = (mappingType: MappingType) => {
|
||||||
this.setState({ type: mappingType });
|
this.setState({ type: mappingType });
|
||||||
};
|
};
|
||||||
|
|
||||||
updateMapping = () => {
|
updateMapping = () => {
|
||||||
this.props.updateMapping({ ...this.state });
|
this.props.updateValueMapping({ ...this.state } as ValueMapping);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderRow() {
|
renderRow() {
|
||||||
@ -136,7 +135,7 @@ export default class MappingRow extends PureComponent<Props, State> {
|
|||||||
</div>
|
</div>
|
||||||
{this.renderRow()}
|
{this.renderRow()}
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
<button onClick={this.props.removeMapping} className="gf-form-label gf-form-label--btn">
|
<button onClick={this.props.removeValueMapping} className="gf-form-label gf-form-label--btn">
|
||||||
<i className="fa fa-times" />
|
<i className="fa fa-times" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
@ -1,27 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { GaugeOptions, MappingType, PanelOptionsProps } from '@grafana/ui';
|
|
||||||
import { defaultProps } from 'app/plugins/panel/gauge/GaugePanelOptions';
|
|
||||||
|
|
||||||
import ValueMappings from './ValueMappings';
|
import { ValueMappingsEditor, Props } from './ValueMappingsEditor';
|
||||||
|
import { MappingType } from '../../types/panel';
|
||||||
|
|
||||||
const setup = (propOverrides?: object) => {
|
const setup = (propOverrides?: object) => {
|
||||||
const props: PanelOptionsProps<GaugeOptions> = {
|
const props: Props = {
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
options: {
|
valueMappings: [
|
||||||
...defaultProps.options,
|
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
||||||
mappings: [
|
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
||||||
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
],
|
||||||
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(props, propOverrides);
|
Object.assign(props, propOverrides);
|
||||||
|
|
||||||
const wrapper = shallow(<ValueMappings {...props} />);
|
const wrapper = shallow(<ValueMappingsEditor {...props} />);
|
||||||
|
|
||||||
const instance = wrapper.instance() as ValueMappings;
|
const instance = wrapper.instance() as ValueMappingsEditor;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
instance,
|
instance,
|
||||||
@ -40,18 +36,20 @@ describe('Render', () => {
|
|||||||
describe('On remove mapping', () => {
|
describe('On remove mapping', () => {
|
||||||
it('Should remove mapping with id 0', () => {
|
it('Should remove mapping with id 0', () => {
|
||||||
const { instance } = setup();
|
const { instance } = setup();
|
||||||
|
|
||||||
instance.onRemoveMapping(1);
|
instance.onRemoveMapping(1);
|
||||||
|
|
||||||
expect(instance.state.mappings).toEqual([
|
expect(instance.state.valueMappings).toEqual([
|
||||||
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove mapping with id 1', () => {
|
it('should remove mapping with id 1', () => {
|
||||||
const { instance } = setup();
|
const { instance } = setup();
|
||||||
|
|
||||||
instance.onRemoveMapping(2);
|
instance.onRemoveMapping(2);
|
||||||
|
|
||||||
expect(instance.state.mappings).toEqual([
|
expect(instance.state.valueMappings).toEqual([
|
||||||
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@ -67,7 +65,7 @@ describe('Next id to add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should default to 1', () => {
|
it('should default to 1', () => {
|
||||||
const { instance } = setup({ options: { ...defaultProps.options } });
|
const { instance } = setup({ valueMappings: [] });
|
||||||
|
|
||||||
expect(instance.state.nextIdToAdd).toEqual(1);
|
expect(instance.state.nextIdToAdd).toEqual(1);
|
||||||
});
|
});
|
@ -1,33 +1,39 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { GaugeOptions, PanelOptionsProps, MappingType, RangeMap, ValueMap, PanelOptionsGroup } from '@grafana/ui';
|
|
||||||
|
|
||||||
import MappingRow from './MappingRow';
|
import MappingRow from './MappingRow';
|
||||||
|
import { MappingType, ValueMapping } from '../../types/panel';
|
||||||
|
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
valueMappings: ValueMapping[];
|
||||||
|
onChange: (valueMappings: ValueMapping[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
mappings: Array<ValueMap | RangeMap>;
|
valueMappings: ValueMapping[];
|
||||||
nextIdToAdd: number;
|
nextIdToAdd: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ValueMappings extends PureComponent<PanelOptionsProps<GaugeOptions>, State> {
|
export class ValueMappingsEditor extends PureComponent<Props, State> {
|
||||||
constructor(props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const mappings = props.options.mappings;
|
const mappings = props.valueMappings;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
mappings: mappings || [],
|
valueMappings: mappings,
|
||||||
nextIdToAdd: mappings.length > 0 ? this.getMaxIdFromMappings(mappings) : 1,
|
nextIdToAdd: mappings.length > 0 ? this.getMaxIdFromValueMappings(mappings) : 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxIdFromMappings(mappings) {
|
getMaxIdFromValueMappings(mappings: ValueMapping[]) {
|
||||||
return Math.max.apply(null, mappings.map(mapping => mapping.id).map(m => m)) + 1;
|
return Math.max.apply(null, mappings.map(mapping => mapping.id).map(m => m)) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addMapping = () =>
|
addMapping = () =>
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
mappings: [
|
valueMappings: [
|
||||||
...prevState.mappings,
|
...prevState.valueMappings,
|
||||||
{
|
{
|
||||||
id: prevState.nextIdToAdd,
|
id: prevState.nextIdToAdd,
|
||||||
operator: '',
|
operator: '',
|
||||||
@ -41,23 +47,23 @@ export default class ValueMappings extends PureComponent<PanelOptionsProps<Gauge
|
|||||||
nextIdToAdd: prevState.nextIdToAdd + 1,
|
nextIdToAdd: prevState.nextIdToAdd + 1,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
onRemoveMapping = id => {
|
onRemoveMapping = (id: number) => {
|
||||||
this.setState(
|
this.setState(
|
||||||
prevState => ({
|
prevState => ({
|
||||||
mappings: prevState.mappings.filter(m => {
|
valueMappings: prevState.valueMappings.filter(m => {
|
||||||
return m.id !== id;
|
return m.id !== id;
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
() => {
|
() => {
|
||||||
this.props.onChange({ ...this.props.options, mappings: this.state.mappings });
|
this.props.onChange(this.state.valueMappings);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateGauge = mapping => {
|
updateGauge = (mapping: ValueMapping) => {
|
||||||
this.setState(
|
this.setState(
|
||||||
prevState => ({
|
prevState => ({
|
||||||
mappings: prevState.mappings.map(m => {
|
valueMappings: prevState.valueMappings.map(m => {
|
||||||
if (m.id === mapping.id) {
|
if (m.id === mapping.id) {
|
||||||
return { ...mapping };
|
return { ...mapping };
|
||||||
}
|
}
|
||||||
@ -66,24 +72,24 @@ export default class ValueMappings extends PureComponent<PanelOptionsProps<Gauge
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
() => {
|
() => {
|
||||||
this.props.onChange({ ...this.props.options, mappings: this.state.mappings });
|
this.props.onChange(this.state.valueMappings);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { mappings } = this.state;
|
const { valueMappings } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelOptionsGroup title="Value Mappings">
|
<PanelOptionsGroup title="Value Mappings">
|
||||||
<div>
|
<div>
|
||||||
{mappings.length > 0 &&
|
{valueMappings.length > 0 &&
|
||||||
mappings.map((mapping, index) => (
|
valueMappings.map((valueMapping, index) => (
|
||||||
<MappingRow
|
<MappingRow
|
||||||
key={`${mapping.text}-${index}`}
|
key={`${valueMapping.text}-${index}`}
|
||||||
mapping={mapping}
|
valueMapping={valueMapping}
|
||||||
updateMapping={this.updateGauge}
|
updateValueMapping={this.updateGauge}
|
||||||
removeMapping={() => this.onRemoveMapping(mapping.id)}
|
removeValueMapping={() => this.onRemoveMapping(valueMapping.id)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
@ -7,7 +7,9 @@ exports[`Render should render component 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<MappingRow
|
<MappingRow
|
||||||
key="Ok-0"
|
key="Ok-0"
|
||||||
mapping={
|
removeValueMapping={[Function]}
|
||||||
|
updateValueMapping={[Function]}
|
||||||
|
valueMapping={
|
||||||
Object {
|
Object {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"operator": "",
|
"operator": "",
|
||||||
@ -16,12 +18,12 @@ exports[`Render should render component 1`] = `
|
|||||||
"value": "20",
|
"value": "20",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeMapping={[Function]}
|
|
||||||
updateMapping={[Function]}
|
|
||||||
/>
|
/>
|
||||||
<MappingRow
|
<MappingRow
|
||||||
key="Meh-1"
|
key="Meh-1"
|
||||||
mapping={
|
removeValueMapping={[Function]}
|
||||||
|
updateValueMapping={[Function]}
|
||||||
|
valueMapping={
|
||||||
Object {
|
Object {
|
||||||
"from": "21",
|
"from": "21",
|
||||||
"id": 2,
|
"id": 2,
|
||||||
@ -31,8 +33,6 @@ exports[`Render should render component 1`] = `
|
|||||||
"type": 2,
|
"type": 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeMapping={[Function]}
|
|
||||||
updateMapping={[Function]}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
@ -6,3 +6,4 @@
|
|||||||
@import 'PanelOptionsGroup/PanelOptionsGroup';
|
@import 'PanelOptionsGroup/PanelOptionsGroup';
|
||||||
@import 'PanelOptionsGrid/PanelOptionsGrid';
|
@import 'PanelOptionsGrid/PanelOptionsGrid';
|
||||||
@import 'ColorPicker/ColorPicker';
|
@import 'ColorPicker/ColorPicker';
|
||||||
|
@import 'ValueMappingsEditor/ValueMappingsEditor';
|
||||||
|
@ -2,6 +2,7 @@ export { DeleteButton } from './DeleteButton/DeleteButton';
|
|||||||
export { Tooltip } from './Tooltip/Tooltip';
|
export { Tooltip } from './Tooltip/Tooltip';
|
||||||
export { Portal } from './Portal/Portal';
|
export { Portal } from './Portal/Portal';
|
||||||
export { CustomScrollbar } from './CustomScrollbar/CustomScrollbar';
|
export { CustomScrollbar } from './CustomScrollbar/CustomScrollbar';
|
||||||
|
export { Label } from './Label/Label';
|
||||||
|
|
||||||
// Select
|
// Select
|
||||||
export { Select, AsyncSelect, SelectOptionItem } from './Select/Select';
|
export { Select, AsyncSelect, SelectOptionItem } from './Select/Select';
|
||||||
@ -18,3 +19,4 @@ export { GfFormLabel } from './GfFormLabel/GfFormLabel';
|
|||||||
export { Graph } from './Graph/Graph';
|
export { Graph } from './Graph/Graph';
|
||||||
export { PanelOptionsGroup } from './PanelOptionsGroup/PanelOptionsGroup';
|
export { PanelOptionsGroup } from './PanelOptionsGroup/PanelOptionsGroup';
|
||||||
export { PanelOptionsGrid } from './PanelOptionsGrid/PanelOptionsGrid';
|
export { PanelOptionsGrid } from './PanelOptionsGrid/PanelOptionsGrid';
|
||||||
|
export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { RangeMap, Threshold, ValueMap } from './panel';
|
|
||||||
|
|
||||||
export interface GaugeOptions {
|
|
||||||
baseColor: string;
|
|
||||||
decimals: number;
|
|
||||||
mappings: Array<RangeMap | ValueMap>;
|
|
||||||
maxValue: number;
|
|
||||||
minValue: number;
|
|
||||||
prefix: string;
|
|
||||||
showThresholdLabels: boolean;
|
|
||||||
showThresholdMarkers: boolean;
|
|
||||||
stat: string;
|
|
||||||
suffix: string;
|
|
||||||
thresholds: Threshold[];
|
|
||||||
unit: string;
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
export * from './series';
|
export * from './series';
|
||||||
export * from './time';
|
export * from './time';
|
||||||
export * from './panel';
|
export * from './panel';
|
||||||
export * from './gauge';
|
|
||||||
|
@ -56,6 +56,8 @@ interface BaseMap {
|
|||||||
type: MappingType;
|
type: MappingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ValueMapping = ValueMap | RangeMap;
|
||||||
|
|
||||||
export interface ValueMap extends BaseMap {
|
export interface ValueMap extends BaseMap {
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Select, Label } from '@grafana/ui';
|
||||||
|
|
||||||
import { Label } from 'app/core/components/Label/Label';
|
|
||||||
import { Select } from '@grafana/ui';
|
|
||||||
import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
|
import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
|
||||||
import { DashboardSearchHit } from 'app/types';
|
import { DashboardSearchHit } from 'app/types';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { SFC } from 'react';
|
import React, { SFC } from 'react';
|
||||||
import { Label } from 'app/core/components/Label/Label';
|
import { Label } from '@grafana/ui';
|
||||||
|
|
||||||
import { Switch } from '../../../core/components/Switch/Switch';
|
import { Switch } from '../../../core/components/Switch/Switch';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { Label } from '@grafana/ui';
|
||||||
|
|
||||||
import { Label } from 'app/core/components/Label/Label';
|
|
||||||
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
|
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
|
||||||
import { updateTeam } from './state/actions';
|
import { updateTeam } from './state/actions';
|
||||||
import { getRouteParamsId } from 'app/core/selectors/location';
|
import { getRouteParamsId } from 'app/core/selectors/location';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { GaugeOptions, PanelOptionsProps, PanelOptionsGroup } from '@grafana/ui';
|
import { PanelOptionsProps, PanelOptionsGroup, Label } from '@grafana/ui';
|
||||||
|
|
||||||
import { Switch } from 'app/core/components/Switch/Switch';
|
import { Switch } from 'app/core/components/Switch/Switch';
|
||||||
import { Label } from '../../../core/components/Label/Label';
|
import { GaugeOptions } from './types';
|
||||||
|
|
||||||
export default class GaugeOptionsEditor extends PureComponent<PanelOptionsProps<GaugeOptions>> {
|
export default class GaugeOptionsEditor extends PureComponent<PanelOptionsProps<GaugeOptions>> {
|
||||||
onToggleThresholdLabels = () =>
|
onToggleThresholdLabels = () =>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { GaugeOptions, PanelProps, NullValueMode } from '@grafana/ui';
|
import { PanelProps, NullValueMode } from '@grafana/ui';
|
||||||
|
|
||||||
import { getTimeSeriesVMs } from 'app/viz/state/timeSeries';
|
import { getTimeSeriesVMs } from 'app/viz/state/timeSeries';
|
||||||
import Gauge from 'app/viz/Gauge';
|
import Gauge from 'app/viz/Gauge';
|
||||||
|
import { GaugeOptions } from './types';
|
||||||
|
|
||||||
interface Props extends PanelProps<GaugeOptions> {}
|
interface Props extends PanelProps<GaugeOptions> {}
|
||||||
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import {
|
import {
|
||||||
BasicGaugeColor,
|
BasicGaugeColor,
|
||||||
GaugeOptions,
|
|
||||||
PanelOptionsProps,
|
PanelOptionsProps,
|
||||||
ThresholdsEditor,
|
ThresholdsEditor,
|
||||||
Threshold,
|
Threshold,
|
||||||
PanelOptionsGrid,
|
PanelOptionsGrid,
|
||||||
|
ValueMappingsEditor,
|
||||||
|
ValueMapping,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import ValueOptions from 'app/plugins/panel/gauge/ValueOptions';
|
import ValueOptions from 'app/plugins/panel/gauge/ValueOptions';
|
||||||
import ValueMappings from 'app/plugins/panel/gauge/ValueMappings';
|
|
||||||
import GaugeOptionsEditor from './GaugeOptionsEditor';
|
import GaugeOptionsEditor from './GaugeOptionsEditor';
|
||||||
|
import { GaugeOptions } from './types';
|
||||||
|
|
||||||
export const defaultProps = {
|
export const defaultProps = {
|
||||||
options: {
|
options: {
|
||||||
@ -24,7 +25,7 @@ export const defaultProps = {
|
|||||||
decimals: 0,
|
decimals: 0,
|
||||||
stat: 'avg',
|
stat: 'avg',
|
||||||
unit: 'none',
|
unit: 'none',
|
||||||
mappings: [],
|
valueMappings: [],
|
||||||
thresholds: [],
|
thresholds: [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -32,7 +33,17 @@ export const defaultProps = {
|
|||||||
export default class GaugePanelOptions extends PureComponent<PanelOptionsProps<GaugeOptions>> {
|
export default class GaugePanelOptions extends PureComponent<PanelOptionsProps<GaugeOptions>> {
|
||||||
static defaultProps = defaultProps;
|
static defaultProps = defaultProps;
|
||||||
|
|
||||||
onThresholdsChanged = (thresholds: Threshold[]) => this.props.onChange({ ...this.props.options, thresholds });
|
onThresholdsChanged = (thresholds: Threshold[]) =>
|
||||||
|
this.props.onChange({
|
||||||
|
...this.props.options,
|
||||||
|
thresholds,
|
||||||
|
});
|
||||||
|
|
||||||
|
onValueMappingsChanged = (valueMappings: ValueMapping[]) =>
|
||||||
|
this.props.onChange({
|
||||||
|
...this.props.options,
|
||||||
|
valueMappings,
|
||||||
|
});
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { onChange, options } = this.props;
|
const { onChange, options } = this.props;
|
||||||
@ -44,7 +55,7 @@ export default class GaugePanelOptions extends PureComponent<PanelOptionsProps<G
|
|||||||
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={options.thresholds} />
|
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={options.thresholds} />
|
||||||
</PanelOptionsGrid>
|
</PanelOptionsGrid>
|
||||||
|
|
||||||
<ValueMappings onChange={onChange} options={options} />
|
<ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={options.valueMappings} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { GaugeOptions, PanelOptionsProps, PanelOptionsGroup } from '@grafana/ui';
|
import { PanelOptionsProps, PanelOptionsGroup, Label, Select } from '@grafana/ui';
|
||||||
|
|
||||||
import { Label } from 'app/core/components/Label/Label';
|
|
||||||
import { Select} from '@grafana/ui';
|
|
||||||
import UnitPicker from 'app/core/components/Select/UnitPicker';
|
import UnitPicker from 'app/core/components/Select/UnitPicker';
|
||||||
|
import { GaugeOptions } from './types';
|
||||||
|
|
||||||
const statOptions = [
|
const statOptions = [
|
||||||
{ value: 'min', label: 'Min' },
|
{ value: 'min', label: 'Min' },
|
||||||
|
@ -1,2 +1,16 @@
|
|||||||
|
import { Threshold, ValueMapping } from '@grafana/ui';
|
||||||
|
|
||||||
|
export interface GaugeOptions {
|
||||||
|
baseColor: string;
|
||||||
|
decimals: number;
|
||||||
|
valueMappings: ValueMapping[];
|
||||||
|
maxValue: number;
|
||||||
|
minValue: number;
|
||||||
|
prefix: string;
|
||||||
|
showThresholdLabels: boolean;
|
||||||
|
showThresholdMarkers: boolean;
|
||||||
|
stat: string;
|
||||||
|
suffix: string;
|
||||||
|
thresholds: Threshold[];
|
||||||
|
unit: string;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ const setup = (propOverrides?: object) => {
|
|||||||
const props: Props = {
|
const props: Props = {
|
||||||
baseColor: BasicGaugeColor.Green,
|
baseColor: BasicGaugeColor.Green,
|
||||||
maxValue: 100,
|
maxValue: 100,
|
||||||
mappings: [],
|
valueMappings: [],
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
prefix: '',
|
prefix: '',
|
||||||
showThresholdMarkers: true,
|
showThresholdMarkers: true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { BasicGaugeColor, Threshold, TimeSeriesVMs, RangeMap, ValueMap, MappingType } from '@grafana/ui';
|
import { BasicGaugeColor, Threshold, TimeSeriesVMs, MappingType, ValueMapping } from '@grafana/ui';
|
||||||
|
|
||||||
import config from '../core/config';
|
import config from '../core/config';
|
||||||
import kbn from '../core/utils/kbn';
|
import kbn from '../core/utils/kbn';
|
||||||
@ -9,7 +9,7 @@ export interface Props {
|
|||||||
baseColor: string;
|
baseColor: string;
|
||||||
decimals: number;
|
decimals: number;
|
||||||
height: number;
|
height: number;
|
||||||
mappings: Array<RangeMap | ValueMap>;
|
valueMappings: ValueMapping[];
|
||||||
maxValue: number;
|
maxValue: number;
|
||||||
minValue: number;
|
minValue: number;
|
||||||
prefix: string;
|
prefix: string;
|
||||||
@ -29,7 +29,7 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
baseColor: BasicGaugeColor.Green,
|
baseColor: BasicGaugeColor.Green,
|
||||||
maxValue: 100,
|
maxValue: 100,
|
||||||
mappings: [],
|
valueMappings: [],
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
prefix: '',
|
prefix: '',
|
||||||
showThresholdMarkers: true,
|
showThresholdMarkers: true,
|
||||||
@ -64,20 +64,17 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
return {
|
return { rangeMap, valueMap };
|
||||||
rangeMap,
|
|
||||||
valueMap,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
formatValue(value) {
|
formatValue(value) {
|
||||||
const { decimals, mappings, prefix, suffix, unit } = this.props;
|
const { decimals, valueMappings, prefix, suffix, unit } = this.props;
|
||||||
|
|
||||||
const formatFunc = kbn.valueFormats[unit];
|
const formatFunc = kbn.valueFormats[unit];
|
||||||
const formattedValue = formatFunc(value, decimals);
|
const formattedValue = formatFunc(value, decimals);
|
||||||
|
|
||||||
if (mappings.length > 0) {
|
if (valueMappings.length > 0) {
|
||||||
const { rangeMap, valueMap } = this.formatWithMappings(mappings, formattedValue);
|
const { rangeMap, valueMap } = this.formatWithMappings(valueMappings, formattedValue);
|
||||||
|
|
||||||
if (valueMap) {
|
if (valueMap) {
|
||||||
return `${prefix} ${valueMap} ${suffix}`;
|
return `${prefix} ${valueMap} ${suffix}`;
|
||||||
@ -148,10 +145,7 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
color: index === 0 ? threshold.color : thresholds[index].color,
|
color: index === 0 ? threshold.color : thresholds[index].color,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
{
|
{ value: maxValue, color: thresholds.length > 0 ? BasicGaugeColor.Red : baseColor },
|
||||||
value: maxValue,
|
|
||||||
color: thresholds.length > 0 ? BasicGaugeColor.Red : baseColor,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
@ -184,19 +178,14 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
formatter: () => {
|
formatter: () => {
|
||||||
return this.formatValue(value);
|
return this.formatValue(value);
|
||||||
},
|
},
|
||||||
font: {
|
font: { size: fontSize, family: '"Helvetica Neue", Helvetica, Arial, sans-serif' },
|
||||||
size: fontSize,
|
|
||||||
family: '"Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const plotSeries = {
|
const plotSeries = { data: [[0, value]] };
|
||||||
data: [[0, value]],
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$.plot(this.canvasElement, [plotSeries], options);
|
$.plot(this.canvasElement, [plotSeries], options);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// DEPENDENCIES
|
// DEPENDENCIES
|
||||||
@import '../../node_modules/react-table/react-table.css';
|
@import '../../node_modules/react-table/react-table.css';
|
||||||
|
|
||||||
// VENDOR
|
// VENDOR
|
||||||
@ -97,7 +97,6 @@
|
|||||||
@import 'components/add_data_source.scss';
|
@import 'components/add_data_source.scss';
|
||||||
@import 'components/page_loader';
|
@import 'components/page_loader';
|
||||||
@import 'components/toggle_button_group';
|
@import 'components/toggle_button_group';
|
||||||
@import 'components/value-mappings';
|
|
||||||
@import 'components/popover-box';
|
@import 'components/popover-box';
|
||||||
|
|
||||||
// LOAD @grafana/ui components
|
// LOAD @grafana/ui components
|
||||||
|
Loading…
Reference in New Issue
Block a user