Graph NG: annotations display (#27972)

* Annotations support POC

* Fix markers memoization

* dev dashboard update

* Update public/app/plugins/panel/graph3/plugins/AnnotationsPlugin.tsx
This commit is contained in:
Dominik Prokop
2020-10-06 11:39:06 +02:00
committed by GitHub
parent a2816ee64a
commit aa6c98f7ff
12 changed files with 609 additions and 83 deletions

View File

@@ -1,12 +1,12 @@
import React, { useState, useLayoutEffect, useRef } from 'react';
import React, { useState, useLayoutEffect, useRef, HTMLAttributes } from 'react';
import { stylesFactory } from '../../themes/stylesFactory';
import { selectThemeVariant } from '../../themes/selectThemeVariant';
import { css } from 'emotion';
import { css, cx } from 'emotion';
import { useTheme } from '../../themes/ThemeContext';
import useWindowSize from 'react-use/lib/useWindowSize';
import { GrafanaTheme } from '@grafana/data';
interface TooltipContainerProps {
interface TooltipContainerProps extends HTMLAttributes<HTMLDivElement> {
position: { x: number; y: number };
offset: { x: number; y: number };
children?: JSX.Element;
@@ -27,7 +27,13 @@ const getTooltipContainerStyles = stylesFactory((theme: GrafanaTheme) => {
};
});
export const TooltipContainer: React.FC<TooltipContainerProps> = ({ position, offset, children }) => {
export const TooltipContainer: React.FC<TooltipContainerProps> = ({
position,
offset,
children,
className,
...otherProps
}) => {
const theme = useTheme();
const tooltipRef = useRef<HTMLDivElement>(null);
const { width, height } = useWindowSize();
@@ -70,7 +76,8 @@ export const TooltipContainer: React.FC<TooltipContainerProps> = ({ position, of
top: 0,
transform: `translate3d(${placement.x}px, ${placement.y}px, 0)`,
}}
className={styles.wrapper}
{...otherProps}
className={cx(styles.wrapper, className)}
>
{children}
</div>

View File

@@ -25,7 +25,13 @@ export const Tag = forwardRef<HTMLElement, Props>(({ name, onClick, className, c
};
return (
<span key={name} ref={ref} onClick={onTagClick} className={cx(styles.wrapper, className)} {...rest}>
<span
key={name}
ref={ref}
onClick={onTagClick}
className={cx(styles.wrapper, className, onClick && styles.hover)}
{...rest}
>
{name}
</span>
);
@@ -50,8 +56,9 @@ const getTagStyles = (theme: GrafanaTheme, name: string, colorIndex?: number) =>
text-shadow: none;
padding: 3px 6px;
border-radius: ${theme.border.radius.md};
:hover {
`,
hover: css`
&:hover {
opacity: 0.85;
cursor: pointer;
}

View File

@@ -75,6 +75,7 @@ export * from './uPlot/geometries';
export { usePlotConfigContext } from './uPlot/context';
export { Canvas } from './uPlot/Canvas';
export * from './uPlot/plugins';
export { usePlotContext, usePlotData, usePlotPluginContext } from './uPlot/context';
export { Gauge } from './Gauge/Gauge';
export { Graph } from './Graph/Graph';
@@ -129,6 +130,7 @@ export { FadeTransition } from './transitions/FadeTransition';
export { SlideOutTransition } from './transitions/SlideOutTransition';
export { Segment, SegmentAsync, SegmentInput, SegmentSelect } from './Segment/';
export { default as Chart } from './Chart';
export { TooltipContainer } from './Chart/TooltipContainer';
export { Drawer } from './Drawer/Drawer';
export { Slider } from './Slider/Slider';

View File

@@ -82,7 +82,7 @@ export const UPlotChart: React.FC<PlotProps> = props => {
// Memoize plot context
const plotCtx = useMemo(() => {
return buildPlotContext(registerPlugin, addSeries, addAxis, addScale, canvasRef, props.data, plotInstance);
}, [registerPlugin, canvasRef, props.data, plotInstance, addSeries, addAxis, addScale]);
}, [registerPlugin, addSeries, addAxis, addScale, canvasRef, props.data, plotInstance]);
return (
<PlotContext.Provider value={plotCtx}>

View File

@@ -36,11 +36,11 @@ export const usePlotPlugins = () => {
(plugin: PlotPlugin) => {
pluginLog(plugin.id, false, 'register');
if (plugins.hasOwnProperty(plugin.id)) {
throw new Error(`${plugin.id} that is already registered`);
}
setPlugins(plugs => {
if (plugs.hasOwnProperty(plugin.id)) {
throw new Error(`${plugin.id} that is already registered`);
}
return {
...plugs,
[plugin.id]: plugin,
@@ -58,7 +58,7 @@ export const usePlotPlugins = () => {
});
};
},
[setPlugins, plugins]
[setPlugins]
);
// When uPlot mounts let's check if there are any plugins pending registration
@@ -74,7 +74,7 @@ export const usePlotPlugins = () => {
return {
arePluginsReady,
plugins,
plugins: plugins || {},
registerPlugin,
};
};

View File

@@ -10,7 +10,7 @@ interface ContextMenuPluginProps {
}
export const ContextMenuPlugin: React.FC<ContextMenuPluginProps> = ({ onClose }) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [isOpen, setIsOpen] = useState(false);
const onClick = useCallback(() => {
setIsOpen(!isOpen);

View File

@@ -32,7 +32,7 @@ export const LegendPlugin: React.FC<LegendPluginProps> = ({ placement, displayMo
label: getFieldDisplayName(field, data),
isVisible: true,
//flot vs uPlot differences
yAxis: (field.config.custom as GraphCustomFieldConfig).axis?.side === 1 ? 3 : 1,
yAxis: (field.config.custom as GraphCustomFieldConfig)?.axis?.side === 1 ? 3 : 1,
});
seriesIdx++;
}

View File

@@ -99,6 +99,9 @@ export const shouldReinitialisePlot = (prevConfig?: uPlot.Options, config?: uPlo
}
if (!prevConfig && config) {
if (config.width === 0 || config.height === 0) {
return false;
}
return true;
}