mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 02:29:33 +08:00
BarGauge: First bar gauge panel option & some refactoring (#23128)
* First bar gauge panel option * Update doc comments * Minor changes * progress * Fixing typing errors * Minor type updates * Fix that TS! * Bring satisfaction to that beast called typescript Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
@ -15,10 +15,10 @@ export interface NumberFieldConfigSettings {
|
||||
export const numberOverrideProcessor = (
|
||||
value: any,
|
||||
context: FieldOverrideContext,
|
||||
settings: NumberFieldConfigSettings
|
||||
settings?: NumberFieldConfigSettings
|
||||
) => {
|
||||
const v = parseFloat(`${value}`);
|
||||
if (settings.max && v > settings.max) {
|
||||
if (settings && settings.max && v > settings.max) {
|
||||
// ????
|
||||
}
|
||||
return v;
|
||||
@ -29,7 +29,7 @@ export interface DataLinksFieldConfigSettings {}
|
||||
export const dataLinksOverrideProcessor = (
|
||||
value: any,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: DataLinksFieldConfigSettings
|
||||
_settings?: DataLinksFieldConfigSettings
|
||||
) => {
|
||||
return value as DataLink[];
|
||||
};
|
||||
@ -39,7 +39,7 @@ export interface ValueMappingFieldConfigSettings {}
|
||||
export const valueMappingsOverrideProcessor = (
|
||||
value: any,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: ValueMappingFieldConfigSettings
|
||||
_settings?: ValueMappingFieldConfigSettings
|
||||
) => {
|
||||
return value as ValueMapping[]; // !!!! likely not !!!!
|
||||
};
|
||||
@ -51,7 +51,7 @@ export interface SelectFieldConfigSettings<T> {
|
||||
export const selectOverrideProcessor = (
|
||||
value: any,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: SelectFieldConfigSettings<any>
|
||||
_settings?: SelectFieldConfigSettings<any>
|
||||
) => {
|
||||
return value;
|
||||
};
|
||||
@ -65,9 +65,9 @@ export interface StringFieldConfigSettings {
|
||||
export const stringOverrideProcessor = (
|
||||
value: any,
|
||||
context: FieldOverrideContext,
|
||||
settings: StringFieldConfigSettings
|
||||
settings?: StringFieldConfigSettings
|
||||
) => {
|
||||
if (settings.expandTemplateVars && context.replaceVariables) {
|
||||
if (settings && settings.expandTemplateVars && context.replaceVariables) {
|
||||
return context.replaceVariables(value, context.field!.config.scopedVars);
|
||||
}
|
||||
return `${value}`;
|
||||
@ -80,7 +80,7 @@ export interface ThresholdsFieldConfigSettings {
|
||||
export const thresholdsOverrideProcessor = (
|
||||
value: any,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: ThresholdsFieldConfigSettings
|
||||
_settings?: ThresholdsFieldConfigSettings
|
||||
) => {
|
||||
return value as ThresholdsConfig; // !!!! likely not !!!!
|
||||
};
|
||||
@ -90,7 +90,7 @@ export interface UnitFieldConfigSettings {}
|
||||
export const unitOverrideProcessor = (
|
||||
value: boolean,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: UnitFieldConfigSettings
|
||||
_settings?: UnitFieldConfigSettings
|
||||
) => {
|
||||
return value;
|
||||
};
|
||||
@ -98,7 +98,7 @@ export const unitOverrideProcessor = (
|
||||
export const booleanOverrideProcessor = (
|
||||
value: boolean,
|
||||
_context: FieldOverrideContext,
|
||||
_settings: ThresholdsFieldConfigSettings
|
||||
_settings?: ThresholdsFieldConfigSettings
|
||||
) => {
|
||||
return value; // !!!! likely not !!!!
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ describe('PanelPlugin', () => {
|
||||
return <div>Panel</div>;
|
||||
});
|
||||
|
||||
panel.setCustomFieldConfigEditor(builder => {
|
||||
panel.setCustomFieldOptions(builder => {
|
||||
builder.addCustomEditor({
|
||||
id: 'custom',
|
||||
name: 'Custom',
|
||||
@ -31,7 +31,7 @@ describe('PanelPlugin', () => {
|
||||
return <div>Panel</div>;
|
||||
});
|
||||
|
||||
panel.setOptionsEditor(builder => {
|
||||
panel.setPanelOptions(builder => {
|
||||
builder.addCustomEditor({
|
||||
id: 'option',
|
||||
name: 'Option editor',
|
||||
|
@ -110,7 +110,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
||||
* interface ShapePanelOptions {}
|
||||
*
|
||||
* export const plugin = new PanelPlugin<ShapePanelOptions>(ShapePanel)
|
||||
* .setCustomFieldConfigEditor(builder => {
|
||||
* .setCustomFieldOptions(builder => {
|
||||
* builder
|
||||
* .addNumberInput({
|
||||
* id: 'shapeBorderWidth',
|
||||
@ -134,7 +134,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
||||
*
|
||||
* @public
|
||||
**/
|
||||
setCustomFieldConfigEditor(builder: (builder: FieldConfigEditorBuilder) => void) {
|
||||
setCustomFieldOptions(builder: (builder: FieldConfigEditorBuilder) => void) {
|
||||
// builder is applied lazily when custom field configs are accessed
|
||||
this.registerCustomFieldConfigs = builder;
|
||||
return this;
|
||||
@ -151,7 +151,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
||||
* interface ShapePanelOptions {}
|
||||
*
|
||||
* export const plugin = new PanelPlugin<ShapePanelOptions>(ShapePanel)
|
||||
* .setOptionsEditor(builder => {
|
||||
* .setPanelOptions(builder => {
|
||||
* builder
|
||||
* .addSelect({
|
||||
* id: 'shape',
|
||||
@ -170,7 +170,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
||||
*
|
||||
* @public
|
||||
**/
|
||||
setOptionsEditor(builder: (builder: PanelOptionsEditorBuilder) => void) {
|
||||
setPanelOptions(builder: (builder: PanelOptionsEditorBuilder) => void) {
|
||||
// builder is applied lazily when options UI is created
|
||||
this.registerOptionEditors = builder;
|
||||
return this;
|
||||
|
@ -5,44 +5,46 @@ import { NumberFieldConfigSettings, SelectFieldConfigSettings, StringFieldConfig
|
||||
/**
|
||||
* Option editor registry item
|
||||
*/
|
||||
interface OptionsEditorItem<TSettings, TEditorProps> extends RegistryItem {
|
||||
export interface OptionsEditorItem<TSettings, TEditorProps> extends RegistryItem {
|
||||
editor: ComponentType<TEditorProps>;
|
||||
settings?: TSettings;
|
||||
editor?: ComponentType<TEditorProps>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration of option editor registry item
|
||||
*/
|
||||
type OptionEditorConfig<TSettings, TEditorProps> = Pick<
|
||||
OptionsEditorItem<TSettings, TEditorProps>,
|
||||
'id' | 'name' | 'description' | 'editor' | 'settings'
|
||||
>;
|
||||
interface OptionEditorConfig<TSettings> {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
settings?: TSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes an API for option editors UI builder
|
||||
*/
|
||||
export interface OptionsUIRegistryBuilderAPI<TEditorProps, T extends OptionsEditorItem<any, TEditorProps>> {
|
||||
addNumberInput?<TSettings extends NumberFieldConfigSettings = NumberFieldConfigSettings>(
|
||||
config: OptionEditorConfig<TSettings, TEditorProps>
|
||||
config: OptionEditorConfig<TSettings>
|
||||
): this;
|
||||
|
||||
addTextInput?<TSettings extends StringFieldConfigSettings = StringFieldConfigSettings>(
|
||||
config: OptionEditorConfig<TSettings, TEditorProps>
|
||||
config: OptionEditorConfig<TSettings>
|
||||
): this;
|
||||
|
||||
addSelect?<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
||||
config: OptionEditorConfig<TSettings, TEditorProps>
|
||||
config: OptionEditorConfig<TSettings>
|
||||
): this;
|
||||
|
||||
addRadio?<TOption, TSettings extends SelectFieldConfigSettings<TOption> = SelectFieldConfigSettings<TOption>>(
|
||||
config: OptionEditorConfig<TSettings, TEditorProps>
|
||||
config: OptionEditorConfig<TSettings>
|
||||
): this;
|
||||
|
||||
addBooleanSwitch?<TSettings = any>(config: OptionEditorConfig<TSettings, TEditorProps>): this;
|
||||
addBooleanSwitch?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
||||
|
||||
addUnitPicker?<TSettings = any>(config: OptionEditorConfig<TSettings, TEditorProps>): this;
|
||||
addUnitPicker?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
||||
|
||||
addColorPicker?<TSettings = any>(config: OptionEditorConfig<TSettings, TEditorProps>): this;
|
||||
addColorPicker?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
||||
|
||||
/**
|
||||
* Enables custom editor definition
|
||||
|
@ -9,9 +9,10 @@ import {
|
||||
GrafanaTheme,
|
||||
TimeZone,
|
||||
} from '../types';
|
||||
import { Registry, RegistryItem } from '../utils';
|
||||
import { Registry } from '../utils';
|
||||
import { InterpolateFunction } from './panel';
|
||||
import { StandardEditorProps } from '../field';
|
||||
import { OptionsEditorItem } from './OptionsUIRegistryBuilder';
|
||||
|
||||
export interface DynamicConfigValue {
|
||||
prop: string;
|
||||
@ -53,24 +54,21 @@ export interface FieldOverrideEditorProps<TValue, TSettings> extends Omit<Standa
|
||||
context: FieldOverrideContext;
|
||||
}
|
||||
|
||||
export interface FieldConfigEditorConfig<TSettings = any, TValue = any>
|
||||
extends Omit<Pick<FieldPropertyEditorItem<TValue, TSettings>, 'id' | 'description' | 'name'>, 'settings'> {
|
||||
export interface FieldConfigEditorConfig<TSettings = any> {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
settings?: TSettings;
|
||||
shouldApply?: (field: Field) => boolean;
|
||||
}
|
||||
|
||||
export interface FieldPropertyEditorItem<TValue = any, TSettings = any> extends RegistryItem {
|
||||
// An editor the creates the well typed value
|
||||
editor: ComponentType<FieldConfigEditorProps<TValue, TSettings>>;
|
||||
|
||||
export interface FieldPropertyEditorItem<TValue = any, TSettings extends {} = any>
|
||||
extends OptionsEditorItem<TSettings, FieldConfigEditorProps<TValue, TSettings>> {
|
||||
// An editor that can be filled in with context info (template variables etc)
|
||||
override: ComponentType<FieldOverrideEditorProps<TValue, TSettings>>;
|
||||
|
||||
// Convert the override value to a well typed value
|
||||
process: (value: any, context: FieldOverrideContext, settings: TSettings) => TValue;
|
||||
|
||||
// Configuration options for the particular property
|
||||
settings: TSettings;
|
||||
process: (value: any, context: FieldOverrideContext, settings?: TSettings) => TValue;
|
||||
|
||||
// Checks if field should be processed
|
||||
shouldApply: (field: Field) => boolean;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { ComponentType } from 'react';
|
||||
import { DataQueryError, DataQueryRequest, DataQueryTimings } from './datasource';
|
||||
import { PluginMeta } from './plugin';
|
||||
import { ScopedVars } from './ScopedVars';
|
||||
@ -6,8 +5,9 @@ import { LoadingState } from './data';
|
||||
import { DataFrame } from './dataFrame';
|
||||
import { AbsoluteTimeRange, TimeRange, TimeZone } from './time';
|
||||
import { FieldConfigSource } from './fieldOverrides';
|
||||
import { Registry, RegistryItem } from '../utils';
|
||||
import { Registry } from '../utils';
|
||||
import { StandardEditorProps } from '../field';
|
||||
import { OptionsEditorItem } from './OptionsUIRegistryBuilder';
|
||||
|
||||
export type InterpolateFunction = (value: string, scopedVars?: ScopedVars, format?: string | Function) => string;
|
||||
|
||||
@ -115,14 +115,16 @@ export type PanelOptionEditorsRegistry = Registry<PanelOptionsEditorItem>;
|
||||
|
||||
export interface PanelOptionsEditorProps<TValue> extends StandardEditorProps<TValue> {}
|
||||
|
||||
export interface PanelOptionsEditorItem<TValue = any, TSettings = any> extends RegistryItem {
|
||||
editor: ComponentType<PanelOptionsEditorProps<TValue>>;
|
||||
export interface PanelOptionsEditorItem<TValue = any, TSettings = any>
|
||||
extends OptionsEditorItem<TSettings, PanelOptionsEditorProps<TValue>> {}
|
||||
|
||||
export interface PanelOptionsEditorConfig<TSettings = any> {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
settings?: TSettings;
|
||||
}
|
||||
|
||||
export interface PanelOptionsEditorConfig<TSettings = any, TValue = any>
|
||||
extends Pick<PanelOptionsEditorItem<TValue, TSettings>, 'id' | 'description' | 'name' | 'settings'> {}
|
||||
|
||||
export interface PanelMenuItem {
|
||||
type?: 'submenu' | 'divider';
|
||||
text?: string;
|
||||
|
@ -16,14 +16,14 @@ export const NumberValueEditor: React.FC<FieldConfigEditorProps<number, NumberFi
|
||||
return (
|
||||
<Forms.Input
|
||||
value={isNaN(value) ? '' : value}
|
||||
min={settings.min}
|
||||
max={settings.max}
|
||||
min={settings?.min}
|
||||
max={settings?.max}
|
||||
type="number"
|
||||
step={settings.step}
|
||||
placeholder={settings.placeholder}
|
||||
step={settings?.step}
|
||||
placeholder={settings?.placeholder}
|
||||
onChange={e => {
|
||||
onChange(
|
||||
settings.integer ? toIntegerOrUndefined(e.currentTarget.value) : toFloatOrUndefined(e.currentTarget.value)
|
||||
settings?.integer ? toIntegerOrUndefined(e.currentTarget.value) : toFloatOrUndefined(e.currentTarget.value)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
@ -7,5 +7,5 @@ export function SelectValueEditor<T>({
|
||||
onChange,
|
||||
item,
|
||||
}: FieldConfigEditorProps<T, SelectFieldConfigSettings<T>>) {
|
||||
return <Forms.Select<T> defaultValue={value} onChange={e => onChange(e.value)} options={item.settings.options} />;
|
||||
return <Forms.Select<T> defaultValue={value} onChange={e => onChange(e.value)} options={item.settings?.options} />;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ interface Props<V, D> {
|
||||
/**
|
||||
* Render a single value
|
||||
*/
|
||||
renderValue: (value: V, width: number, height: number, dims: D) => JSX.Element;
|
||||
renderValue: (props: VizRepeaterRenderValueProps<V, D>) => JSX.Element;
|
||||
height: number;
|
||||
width: number;
|
||||
source: any; // If this changes, new values will be requested
|
||||
@ -23,6 +23,14 @@ interface Props<V, D> {
|
||||
itemSpacing?: number;
|
||||
}
|
||||
|
||||
export interface VizRepeaterRenderValueProps<V, D = {}> {
|
||||
value: V;
|
||||
width: number;
|
||||
height: number;
|
||||
orientation: VizOrientation;
|
||||
alignmentFactors: D;
|
||||
}
|
||||
|
||||
interface DefaultProps {
|
||||
itemSpacing: number;
|
||||
}
|
||||
@ -99,13 +107,14 @@ export class VizRepeater<V, D = {}> extends PureComponent<Props<V, D>, State<V>>
|
||||
itemStyles.width = `${vizWidth}px`;
|
||||
itemStyles.height = `${vizHeight}px`;
|
||||
|
||||
const dims = getAlignmentFactors ? getAlignmentFactors(values, vizWidth, vizHeight) : ({} as D);
|
||||
const alignmentFactors = getAlignmentFactors ? getAlignmentFactors(values, vizWidth, vizHeight) : ({} as D);
|
||||
|
||||
return (
|
||||
<div style={repeaterStyle}>
|
||||
{values.map((value, index) => {
|
||||
return (
|
||||
<div key={index} style={getItemStylesForIndex(itemStyles, index, values.length)}>
|
||||
{renderValue(value, vizWidth, vizHeight, dims)}
|
||||
{renderValue({ value, width: vizWidth, height: vizHeight, alignmentFactors, orientation })}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
@ -78,7 +78,7 @@ export { GraphWithLegend } from './Graph/GraphWithLegend';
|
||||
export { GraphContextMenu } from './Graph/GraphContextMenu';
|
||||
export { BarGauge, BarGaugeDisplayMode } from './BarGauge/BarGauge';
|
||||
export { GraphTooltipOptions } from './Graph/GraphTooltip/types';
|
||||
export { VizRepeater } from './VizRepeater/VizRepeater';
|
||||
export { VizRepeater, VizRepeaterRenderValueProps } from './VizRepeater/VizRepeater';
|
||||
|
||||
export {
|
||||
LegendOptions,
|
||||
|
@ -315,6 +315,7 @@ export const PanelEditor = connect(mapStateToProps, mapDispatchToProps)(PanelEdi
|
||||
*/
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
const handleColor = theme.colors.blueLight;
|
||||
const paneSpaceing = theme.spacing.md;
|
||||
|
||||
const resizer = css`
|
||||
font-style: italic;
|
||||
@ -354,21 +355,21 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
`,
|
||||
panelWrapper: css`
|
||||
width: 100%;
|
||||
padding-left: ${theme.spacing.sm};
|
||||
padding-left: ${paneSpaceing};
|
||||
height: 100%;
|
||||
`,
|
||||
resizerV: cx(
|
||||
resizer,
|
||||
css`
|
||||
cursor: col-resize;
|
||||
width: 8px;
|
||||
width: ${paneSpaceing};
|
||||
border-right-width: 1px;
|
||||
`
|
||||
),
|
||||
resizerH: cx(
|
||||
resizer,
|
||||
css`
|
||||
height: 8px;
|
||||
height: ${paneSpaceing};
|
||||
cursor: row-resize;
|
||||
position: relative;
|
||||
top: 49px;
|
||||
|
@ -4,7 +4,7 @@ import React, { PureComponent } from 'react';
|
||||
// Services & Utils
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
import { BarGauge, VizRepeater, DataLinksContextMenu } from '@grafana/ui';
|
||||
import { BarGauge, VizRepeater, VizRepeaterRenderValueProps, DataLinksContextMenu } from '@grafana/ui';
|
||||
import { BarGaugeOptions } from './types';
|
||||
import {
|
||||
getFieldDisplayValues,
|
||||
@ -16,13 +16,9 @@ import {
|
||||
import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
|
||||
export class BarGaugePanel extends PureComponent<PanelProps<BarGaugeOptions>> {
|
||||
renderValue = (
|
||||
value: FieldDisplay,
|
||||
width: number,
|
||||
height: number,
|
||||
alignmentFactors: DisplayValueAlignmentFactors
|
||||
): JSX.Element => {
|
||||
renderValue = (valueProps: VizRepeaterRenderValueProps<FieldDisplay, DisplayValueAlignmentFactors>): JSX.Element => {
|
||||
const { options } = this.props;
|
||||
const { value, alignmentFactors, orientation, width, height } = valueProps;
|
||||
const { field, display, view, colIndex } = value;
|
||||
|
||||
return (
|
||||
@ -33,7 +29,7 @@ export class BarGaugePanel extends PureComponent<PanelProps<BarGaugeOptions>> {
|
||||
value={display}
|
||||
width={width}
|
||||
height={height}
|
||||
orientation={options.orientation}
|
||||
orientation={orientation}
|
||||
field={field}
|
||||
display={view?.getFieldDisplayProcessor(colIndex)}
|
||||
theme={config.theme}
|
||||
|
@ -95,6 +95,10 @@ export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGauge
|
||||
return (
|
||||
<NewPanelEditorContext.Consumer>
|
||||
{useNewEditor => {
|
||||
if (useNewEditor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<PanelOptionsGrid>
|
||||
@ -135,38 +139,28 @@ export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGauge
|
||||
)}
|
||||
</>
|
||||
</PanelOptionsGroup>
|
||||
<>
|
||||
{!useNewEditor && (
|
||||
<>
|
||||
<PanelOptionsGroup title="Field">
|
||||
<FieldPropertiesEditor
|
||||
showMinMax={true}
|
||||
showTitle={true}
|
||||
onChange={this.onDefaultsChange}
|
||||
value={defaults}
|
||||
/>
|
||||
</PanelOptionsGroup>
|
||||
|
||||
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</PanelOptionsGrid>
|
||||
|
||||
{!useNewEditor && (
|
||||
<LegacyValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />
|
||||
)}
|
||||
|
||||
{!useNewEditor && (
|
||||
<PanelOptionsGroup title="Data links">
|
||||
<DataLinksEditor
|
||||
value={defaults.links}
|
||||
onChange={this.onDataLinksChanged}
|
||||
suggestions={suggestions}
|
||||
maxLinks={10}
|
||||
<PanelOptionsGroup title="Field">
|
||||
<FieldPropertiesEditor
|
||||
showMinMax={true}
|
||||
showTitle={true}
|
||||
onChange={this.onDefaultsChange}
|
||||
value={defaults}
|
||||
/>
|
||||
</PanelOptionsGroup>
|
||||
)}
|
||||
|
||||
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
|
||||
</PanelOptionsGrid>
|
||||
|
||||
<LegacyValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={defaults.mappings} />
|
||||
|
||||
<PanelOptionsGroup title="Data links">
|
||||
<DataLinksEditor
|
||||
value={defaults.links}
|
||||
onChange={this.onDataLinksChanged}
|
||||
suggestions={suggestions}
|
||||
maxLinks={10}
|
||||
/>
|
||||
</PanelOptionsGroup>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
|
@ -1,14 +1,30 @@
|
||||
import { sharedSingleStatPanelChangedHandler } from '@grafana/ui';
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { BarGaugePanel } from './BarGaugePanel';
|
||||
import { BarGaugePanelEditor } from './BarGaugePanelEditor';
|
||||
import { BarGaugeOptions, defaults } from './types';
|
||||
import { standardFieldConfig } from '../stat/types';
|
||||
import { BarGaugePanelEditor } from './BarGaugePanelEditor';
|
||||
import { barGaugePanelMigrationHandler } from './BarGaugeMigrations';
|
||||
|
||||
export const plugin = new PanelPlugin<BarGaugeOptions>(BarGaugePanel)
|
||||
.setDefaults(defaults)
|
||||
.setFieldConfigDefaults(standardFieldConfig)
|
||||
.setEditor(BarGaugePanelEditor)
|
||||
.setFieldConfigDefaults(standardFieldConfig)
|
||||
.setPanelOptions(builder => {
|
||||
/* addStandardSingleValueOptions(builder); */
|
||||
|
||||
builder.addRadio({
|
||||
id: 'orientation',
|
||||
name: 'Orientation',
|
||||
description: 'Stacking direction for multiple bars',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
{ value: 'horizontal', label: 'Horizontal' },
|
||||
{ value: 'vertical', label: 'Vertical' },
|
||||
],
|
||||
},
|
||||
});
|
||||
})
|
||||
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
||||
.setMigrationHandler(barGaugePanelMigrationHandler);
|
||||
|
@ -5,17 +5,17 @@ import React, { PureComponent } from 'react';
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
// Components
|
||||
import { Gauge, DataLinksContextMenu } from '@grafana/ui';
|
||||
import { Gauge, DataLinksContextMenu, VizRepeater, VizRepeaterRenderValueProps } from '@grafana/ui';
|
||||
|
||||
// Types
|
||||
import { GaugeOptions } from './types';
|
||||
import { VizRepeater } from '@grafana/ui';
|
||||
import { FieldDisplay, getFieldDisplayValues, VizOrientation, PanelProps } from '@grafana/data';
|
||||
import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
|
||||
export class GaugePanel extends PureComponent<PanelProps<GaugeOptions>> {
|
||||
renderValue = (value: FieldDisplay, width: number, height: number): JSX.Element => {
|
||||
renderValue = (valueProps: VizRepeaterRenderValueProps<FieldDisplay>): JSX.Element => {
|
||||
const { options } = this.props;
|
||||
const { value, width, height } = valueProps;
|
||||
const { field, display } = value;
|
||||
|
||||
return (
|
||||
|
@ -6,7 +6,14 @@ import { config } from 'app/core/config';
|
||||
|
||||
// Types
|
||||
import { StatPanelOptions } from './types';
|
||||
import { VizRepeater, BigValue, DataLinksContextMenu, BigValueSparkline, BigValueGraphMode } from '@grafana/ui';
|
||||
import {
|
||||
VizRepeater,
|
||||
VizRepeaterRenderValueProps,
|
||||
BigValue,
|
||||
DataLinksContextMenu,
|
||||
BigValueSparkline,
|
||||
BigValueGraphMode,
|
||||
} from '@grafana/ui';
|
||||
|
||||
import {
|
||||
PanelProps,
|
||||
@ -21,13 +28,9 @@ import {
|
||||
import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
|
||||
export class StatPanel extends PureComponent<PanelProps<StatPanelOptions>> {
|
||||
renderValue = (
|
||||
value: FieldDisplay,
|
||||
width: number,
|
||||
height: number,
|
||||
alignmentFactors: DisplayValueAlignmentFactors
|
||||
): JSX.Element => {
|
||||
renderValue = (valueProps: VizRepeaterRenderValueProps<FieldDisplay, DisplayValueAlignmentFactors>): JSX.Element => {
|
||||
const { timeRange, options } = this.props;
|
||||
const { value, alignmentFactors, width, height } = valueProps;
|
||||
let sparkline: BigValueSparkline | undefined;
|
||||
|
||||
if (value.sparkline) {
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
FieldConfigSource,
|
||||
ThresholdsMode,
|
||||
} from '@grafana/data';
|
||||
import { PanelOptionsEditorBuilder } from '@grafana/data/src/utils/OptionsUIBuilders';
|
||||
|
||||
// Structure copied from angular
|
||||
export interface StatPanelOptions extends SingleStatBaseOptions {
|
||||
@ -49,6 +50,20 @@ export const standardFieldConfig: FieldConfigSource = {
|
||||
overrides: [],
|
||||
};
|
||||
|
||||
export function addStandardSingleValueOptions(builder: PanelOptionsEditorBuilder) {
|
||||
builder.addRadio({
|
||||
id: 'values',
|
||||
name: 'Show',
|
||||
description: 'Calculate a single value per colum or series or show each row',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: false, label: 'Calculate' },
|
||||
{ value: true, label: 'All values' },
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const defaults: StatPanelOptions = {
|
||||
graphMode: BigValueGraphMode.Area,
|
||||
colorMode: BigValueColorMode.Value,
|
||||
|
@ -8,20 +8,18 @@ import { Options } from './types';
|
||||
|
||||
interface Props extends PanelProps<Options> {}
|
||||
|
||||
const paddingBottom = 16;
|
||||
|
||||
export class TablePanel extends Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, height, width } = this.props;
|
||||
const { data, height, width, options } = this.props;
|
||||
|
||||
if (data.series.length < 1) {
|
||||
return <div>No Table Data...</div>;
|
||||
}
|
||||
|
||||
return <Table height={height - paddingBottom} width={width} data={data.series[0]} />;
|
||||
return <Table height={height} width={width} data={data.series[0]} noHeader={!options.showHeader} />;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { Options, defaults } from './types';
|
||||
|
||||
export const plugin = new PanelPlugin<Options>(TablePanel)
|
||||
.setDefaults(defaults)
|
||||
.setCustomFieldConfigEditor(builder => {
|
||||
.setCustomFieldOptions(builder => {
|
||||
builder
|
||||
.addNumberInput({
|
||||
id: 'width',
|
||||
@ -20,7 +20,6 @@ export const plugin = new PanelPlugin<Options>(TablePanel)
|
||||
id: 'displayMode',
|
||||
name: 'Cell display mode',
|
||||
description: 'Color value, background, show as gauge, etc',
|
||||
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
@ -31,7 +30,7 @@ export const plugin = new PanelPlugin<Options>(TablePanel)
|
||||
},
|
||||
});
|
||||
})
|
||||
.setOptionsEditor(builder => {
|
||||
.setPanelOptions(builder => {
|
||||
builder.addBooleanSwitch({
|
||||
id: 'showHeader',
|
||||
name: 'Show header',
|
||||
|
Reference in New Issue
Block a user