mirror of
https://github.com/grafana/grafana.git
synced 2024-11-28 03:34:15 -06:00
Canvas: New circle/ellipse element (#74389)
* feat(canvas): add circle element
This commit is contained in:
parent
bd23d48660
commit
d6bddf3c68
185
public/app/features/canvas/elements/ellipse.tsx
Normal file
185
public/app/features/canvas/elements/ellipse.tsx
Normal file
@ -0,0 +1,185 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { stylesFactory } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { DimensionContext } from 'app/features/dimensions/context';
|
||||
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
|
||||
import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor';
|
||||
|
||||
import { CanvasElementItem, CanvasElementProps, defaultBgColor, defaultTextColor } from '../element';
|
||||
import { Align, VAlign, EllipseConfig, EllipseData } from '../types';
|
||||
|
||||
class EllipseDisplay extends PureComponent<CanvasElementProps<EllipseConfig, EllipseData>> {
|
||||
render() {
|
||||
const { data } = this.props;
|
||||
const styles = getStyles(config.theme2, data);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<span className={styles.span}>{data?.text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme2, data) => ({
|
||||
container: css`
|
||||
display: table;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: ${data?.backgroundColor};
|
||||
border: ${data?.width}px solid ${data?.borderColor};
|
||||
border-radius: 50%;
|
||||
`,
|
||||
span: css`
|
||||
display: table-cell;
|
||||
vertical-align: ${data?.valign};
|
||||
text-align: ${data?.align};
|
||||
font-size: ${data?.size}px;
|
||||
color: ${data?.color};
|
||||
`,
|
||||
}));
|
||||
|
||||
export const ellipseItem: CanvasElementItem<EllipseConfig, EllipseData> = {
|
||||
id: 'ellipse',
|
||||
name: 'Ellipse',
|
||||
description: 'Ellipse',
|
||||
|
||||
display: EllipseDisplay,
|
||||
|
||||
defaultSize: {
|
||||
width: 160,
|
||||
height: 160,
|
||||
},
|
||||
|
||||
getNewOptions: (options) => ({
|
||||
...options,
|
||||
config: {
|
||||
backgroundColor: {
|
||||
fixed: defaultBgColor,
|
||||
},
|
||||
borderColor: {
|
||||
fixed: 'transparent',
|
||||
},
|
||||
width: 1,
|
||||
align: Align.Center,
|
||||
valign: VAlign.Middle,
|
||||
color: {
|
||||
fixed: defaultTextColor,
|
||||
},
|
||||
},
|
||||
background: {
|
||||
color: {
|
||||
fixed: 'transparent',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
prepareData: (ctx: DimensionContext, cfg: EllipseConfig) => {
|
||||
const data: EllipseData = {
|
||||
width: cfg.width,
|
||||
text: cfg.text ? ctx.getText(cfg.text).value() : '',
|
||||
align: cfg.align ?? Align.Center,
|
||||
valign: cfg.valign ?? VAlign.Middle,
|
||||
size: cfg.size,
|
||||
};
|
||||
|
||||
if (cfg.backgroundColor) {
|
||||
data.backgroundColor = ctx.getColor(cfg.backgroundColor).value();
|
||||
}
|
||||
if (cfg.borderColor) {
|
||||
data.borderColor = ctx.getColor(cfg.borderColor).value();
|
||||
}
|
||||
if (cfg.color) {
|
||||
data.color = ctx.getColor(cfg.color).value();
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
// Heatmap overlay options
|
||||
registerOptionsUI: (builder) => {
|
||||
const category = ['Ellipse'];
|
||||
builder
|
||||
.addCustomEditor({
|
||||
category,
|
||||
id: 'textSelector',
|
||||
path: 'config.text',
|
||||
name: 'Text',
|
||||
editor: TextDimensionEditor,
|
||||
})
|
||||
.addCustomEditor({
|
||||
category,
|
||||
id: 'config.color',
|
||||
path: 'config.color',
|
||||
name: 'Text color',
|
||||
editor: ColorDimensionEditor,
|
||||
settings: {},
|
||||
defaultValue: {},
|
||||
})
|
||||
.addRadio({
|
||||
category,
|
||||
path: 'config.align',
|
||||
name: 'Align text',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: Align.Left, label: 'Left' },
|
||||
{ value: Align.Center, label: 'Center' },
|
||||
{ value: Align.Right, label: 'Right' },
|
||||
],
|
||||
},
|
||||
defaultValue: Align.Left,
|
||||
})
|
||||
.addCustomEditor({
|
||||
category,
|
||||
id: 'config.borderColor',
|
||||
path: 'config.borderColor',
|
||||
name: 'Ellipse border color',
|
||||
editor: ColorDimensionEditor,
|
||||
settings: {},
|
||||
defaultValue: {},
|
||||
})
|
||||
.addNumberInput({
|
||||
category,
|
||||
path: 'config.width',
|
||||
name: 'Ellipse border width',
|
||||
settings: {
|
||||
placeholder: 'Auto',
|
||||
},
|
||||
})
|
||||
.addCustomEditor({
|
||||
category,
|
||||
id: 'config.backgroundColor',
|
||||
path: 'config.backgroundColor',
|
||||
name: 'Ellipse background color',
|
||||
editor: ColorDimensionEditor,
|
||||
settings: {},
|
||||
defaultValue: {},
|
||||
})
|
||||
.addRadio({
|
||||
category,
|
||||
path: 'config.valign',
|
||||
name: 'Vertical align',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: VAlign.Top, label: 'Top' },
|
||||
{ value: VAlign.Middle, label: 'Middle' },
|
||||
{ value: VAlign.Bottom, label: 'Bottom' },
|
||||
],
|
||||
},
|
||||
defaultValue: VAlign.Middle,
|
||||
})
|
||||
.addNumberInput({
|
||||
category,
|
||||
path: 'config.size',
|
||||
name: 'Text size',
|
||||
settings: {
|
||||
placeholder: 'Auto',
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
@ -5,6 +5,7 @@ import { buttonItem } from './elements/button';
|
||||
import { droneFrontItem } from './elements/droneFront';
|
||||
import { droneSideItem } from './elements/droneSide';
|
||||
import { droneTopItem } from './elements/droneTop';
|
||||
import { ellipseItem } from './elements/ellipse';
|
||||
import { iconItem } from './elements/icon';
|
||||
import { metricValueItem } from './elements/metricValue';
|
||||
import { rectangleItem } from './elements/rectangle';
|
||||
@ -22,6 +23,7 @@ export const DEFAULT_CANVAS_ELEMENT_CONFIG: CanvasElementOptions = {
|
||||
export const defaultElementItems = [
|
||||
metricValueItem, // default for now
|
||||
textItem,
|
||||
ellipseItem,
|
||||
rectangleItem,
|
||||
iconItem,
|
||||
serverItem,
|
||||
|
@ -48,6 +48,18 @@ export interface TextConfig {
|
||||
valign: VAlign;
|
||||
}
|
||||
|
||||
export interface EllipseConfig extends TextConfig {
|
||||
backgroundColor?: ColorDimensionConfig;
|
||||
borderColor?: ColorDimensionConfig;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export interface EllipseData extends TextData {
|
||||
backgroundColor?: string;
|
||||
borderColor?: string;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export {
|
||||
Placement,
|
||||
Constraint,
|
||||
|
Loading…
Reference in New Issue
Block a user