mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Canvas: Add tooltip for data links (#61648)
This commit is contained in:
@@ -11,6 +11,7 @@ import { DimensionContext } from 'app/features/dimensions/context';
|
||||
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
|
||||
import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor';
|
||||
|
||||
import { getDataLinks } from '../../../plugins/panel/canvas/utils';
|
||||
import { CanvasElementItem, CanvasElementProps, defaultBgColor, defaultTextColor } from '../element';
|
||||
import { ElementState } from '../runtime/element';
|
||||
import { Align, TextConfig, TextData, VAlign } from '../types';
|
||||
@@ -159,6 +160,8 @@ export const metricValueItem: CanvasElementItem<TextConfig, TextData> = {
|
||||
data.color = ctx.getColor(cfg.color).value();
|
||||
}
|
||||
|
||||
data.links = getDataLinks(ctx, cfg, data.text);
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DimensionContext } from 'app/features/dimensions/context';
|
||||
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
|
||||
import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor';
|
||||
|
||||
import { getDataLinks } from '../../../plugins/panel/canvas/utils';
|
||||
import { CanvasElementItem, CanvasElementProps, defaultThemeTextColor } from '../element';
|
||||
import { ElementState } from '../runtime/element';
|
||||
import { Align, TextConfig, TextData, VAlign } from '../types';
|
||||
@@ -158,6 +159,8 @@ export const textItem: CanvasElementItem<TextConfig, TextData> = {
|
||||
data.color = ctx.getColor(cfg.color).value();
|
||||
}
|
||||
|
||||
data.links = getDataLinks(ctx, cfg, data.text);
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
|
||||
@@ -446,6 +446,45 @@ export class ElementState implements LayerElement {
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseEnter = (event: React.MouseEvent, isSelected: boolean | undefined) => {
|
||||
const scene = this.getScene();
|
||||
if (!scene?.isEditingEnabled) {
|
||||
this.handleTooltip(event);
|
||||
} else if (!isSelected) {
|
||||
scene?.connections.handleMouseEnter(event);
|
||||
}
|
||||
};
|
||||
|
||||
handleTooltip = (event: React.MouseEvent) => {
|
||||
const scene = this.getScene();
|
||||
if (scene?.tooltipCallback) {
|
||||
const rect = this.div?.getBoundingClientRect();
|
||||
scene.tooltipCallback({
|
||||
anchorPoint: { x: rect?.right ?? event.pageX, y: rect?.top ?? event.pageY },
|
||||
element: this,
|
||||
isOpen: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseLeave = (event: React.MouseEvent) => {
|
||||
const scene = this.getScene();
|
||||
if (scene?.tooltipCallback && !scene?.tooltip?.isOpen) {
|
||||
scene.tooltipCallback(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
onElementClick = (event: React.MouseEvent) => {
|
||||
const scene = this.getScene();
|
||||
if (scene?.tooltipCallback && scene.tooltip?.anchorPoint) {
|
||||
scene.tooltipCallback({
|
||||
anchorPoint: { x: scene.tooltip.anchorPoint.x, y: scene.tooltip.anchorPoint.y },
|
||||
element: this,
|
||||
isOpen: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { item, div } = this;
|
||||
const scene = this.getScene();
|
||||
@@ -456,7 +495,9 @@ export class ElementState implements LayerElement {
|
||||
<div
|
||||
key={this.UID}
|
||||
ref={this.initElement}
|
||||
onMouseEnter={!isSelected ? scene?.connections.handleMouseEnter : undefined}
|
||||
onMouseEnter={(e: React.MouseEvent) => this.handleMouseEnter(e, isSelected)}
|
||||
onMouseLeave={!scene?.isEditingEnabled ? this.handleMouseLeave : undefined}
|
||||
onClick={!scene?.isEditingEnabled ? this.onElementClick : undefined}
|
||||
>
|
||||
<item.display
|
||||
key={`${this.UID}/${this.revId}`}
|
||||
|
||||
@@ -26,9 +26,10 @@ import {
|
||||
getTextDimensionFromData,
|
||||
} from 'app/features/dimensions/utils';
|
||||
import { CanvasContextMenu } from 'app/plugins/panel/canvas/CanvasContextMenu';
|
||||
import { CanvasTooltip } from 'app/plugins/panel/canvas/CanvasTooltip';
|
||||
import { CONNECTION_ANCHOR_DIV_ID } from 'app/plugins/panel/canvas/ConnectionAnchors';
|
||||
import { Connections } from 'app/plugins/panel/canvas/Connections';
|
||||
import { AnchorPoint, LayerActionID } from 'app/plugins/panel/canvas/types';
|
||||
import { AnchorPoint, CanvasTooltipPayload, LayerActionID } from 'app/plugins/panel/canvas/types';
|
||||
|
||||
import appEvents from '../../../core/app_events';
|
||||
import { CanvasPanel } from '../../../plugins/panel/canvas/CanvasPanel';
|
||||
@@ -74,6 +75,9 @@ export class Scene {
|
||||
inlineEditingCallback?: () => void;
|
||||
setBackgroundCallback?: (anchorPoint: AnchorPoint) => void;
|
||||
|
||||
tooltipCallback?: (tooltip: CanvasTooltipPayload | undefined) => void;
|
||||
tooltip?: CanvasTooltipPayload;
|
||||
|
||||
readonly editModeEnabled = new BehaviorSubject<boolean>(false);
|
||||
subscription: Subscription;
|
||||
|
||||
@@ -149,6 +153,7 @@ export class Scene {
|
||||
getScalar: (scalar: ScalarDimensionConfig) => getScalarDimensionFromData(this.data, scalar),
|
||||
getText: (text: TextDimensionConfig) => getTextDimensionFromData(this.data, text),
|
||||
getResource: (res: ResourceDimensionConfig) => getResourceDimensionFromData(this.data, res),
|
||||
getPanelData: () => this.data,
|
||||
};
|
||||
|
||||
updateData(data: PanelData) {
|
||||
@@ -600,6 +605,8 @@ export class Scene {
|
||||
|
||||
render() {
|
||||
const canShowContextMenu = this.isPanelEditing || (!this.isPanelEditing && this.isEditingEnabled);
|
||||
const canShowElementTooltip =
|
||||
!this.isEditingEnabled && this.tooltip?.element && this.tooltip.element.data.links?.length > 0;
|
||||
|
||||
return (
|
||||
<div key={this.revId} className={this.styles.wrap} style={this.style} ref={this.setRef}>
|
||||
@@ -610,6 +617,11 @@ export class Scene {
|
||||
<CanvasContextMenu scene={this} panel={this.panel} />
|
||||
</Portal>
|
||||
)}
|
||||
{canShowElementTooltip && (
|
||||
<Portal>
|
||||
<CanvasTooltip scene={this} />
|
||||
</Portal>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LinkModel } from '@grafana/data/src';
|
||||
import { ColorDimensionConfig, ResourceDimensionConfig, TextDimensionConfig } from 'app/features/dimensions/types';
|
||||
|
||||
export interface Placement {
|
||||
@@ -77,6 +78,7 @@ export interface TextData {
|
||||
size?: number; // 0 or missing will "auto size"
|
||||
align: Align;
|
||||
valign: VAlign;
|
||||
links?: LinkModel[];
|
||||
}
|
||||
|
||||
export interface TextConfig {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { PanelData } from '@grafana/data/src';
|
||||
|
||||
import {
|
||||
ColorDimensionConfig,
|
||||
DimensionSupplier,
|
||||
@@ -13,4 +15,5 @@ export interface DimensionContext {
|
||||
getScalar(scalar: ScalarDimensionConfig): DimensionSupplier<number>;
|
||||
getText(text: TextDimensionConfig): DimensionSupplier<string>;
|
||||
getResource(resource: ResourceDimensionConfig): DimensionSupplier<string>;
|
||||
getPanelData(): PanelData | undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user