mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
NodeGraph: Fix invisible arrow tips in Editor (#86517)
NodeGraphPanel: Namespace marker IDs to fix invisible arrow tips in editor Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
This commit is contained in:
parent
1d1ebee36b
commit
f3fcfad2c8
@ -11,13 +11,14 @@ export const defaultEdgeColor = '#999';
|
||||
interface Props {
|
||||
edge: EdgeDatum;
|
||||
hovering: boolean;
|
||||
svgIdNamespace: string;
|
||||
onClick: (event: MouseEvent<SVGElement>, link: EdgeDatum) => void;
|
||||
onMouseEnter: (id: string) => void;
|
||||
onMouseLeave: (id: string) => void;
|
||||
}
|
||||
|
||||
export const Edge = memo(function Edge(props: Props) {
|
||||
const { edge, onClick, onMouseEnter, onMouseLeave, hovering } = props;
|
||||
const { edge, onClick, onMouseEnter, onMouseLeave, hovering, svgIdNamespace } = props;
|
||||
|
||||
// Not great typing but after we do layout these properties are full objects not just references
|
||||
const { source, target, sourceNodeRadius, targetNodeRadius } = edge as {
|
||||
@ -47,8 +48,8 @@ export const Edge = memo(function Edge(props: Props) {
|
||||
// in case both are provided
|
||||
const highlightedEdgeColor = edge.color || defaultHighlightedEdgeColor;
|
||||
|
||||
const markerId = `triangle-${edge.id}`;
|
||||
const coloredMarkerId = `triangle-colored-${edge.id}`;
|
||||
const markerId = `triangle-${svgIdNamespace}-${edge.id}`;
|
||||
const coloredMarkerId = `triangle-colored-${svgIdNamespace}-${edge.id}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -111,8 +111,9 @@ interface Props {
|
||||
dataFrames: DataFrame[];
|
||||
getLinks: (dataFrame: DataFrame, rowIndex: number) => LinkModel[];
|
||||
nodeLimit?: number;
|
||||
panelId?: string;
|
||||
}
|
||||
export function NodeGraph({ getLinks, dataFrames, nodeLimit }: Props) {
|
||||
export function NodeGraph({ getLinks, dataFrames, nodeLimit, panelId }: Props) {
|
||||
const nodeCountLimit = nodeLimit || defaultNodeCountLimit;
|
||||
const { edges: edgesDataFrames, nodes: nodesDataFrames } = useCategorizeFrames(dataFrames);
|
||||
|
||||
@ -122,6 +123,13 @@ export function NodeGraph({ getLinks, dataFrames, nodeLimit }: Props) {
|
||||
const firstNodesDataFrame = nodesDataFrames[0];
|
||||
const firstEdgesDataFrame = edgesDataFrames[0];
|
||||
|
||||
// Ensure we use unique IDs for the marker tip elements, since IDs are global
|
||||
// in the entire HTML document. This prevents hidden tips when an earlier
|
||||
// occurence is hidden (editor is open in front of an existing node graph
|
||||
// panel) or when the earlier tips have different properties (color, size, or
|
||||
// shape for example).
|
||||
const svgIdNamespace = panelId || 'nodegraphpanel';
|
||||
|
||||
// TODO we should be able to allow multiple dataframes for both edges and nodes, could be issue with node ids which in
|
||||
// that case should be unique or figure a way to link edges and nodes dataframes together.
|
||||
const processed = useMemo(
|
||||
@ -215,6 +223,7 @@ export function NodeGraph({ getLinks, dataFrames, nodeLimit }: Props) {
|
||||
onClick={onEdgeOpen}
|
||||
onMouseEnter={setEdgeHover}
|
||||
onMouseLeave={clearEdgeHover}
|
||||
svgIdNamespace={svgIdNamespace}
|
||||
/>
|
||||
)}
|
||||
<Nodes
|
||||
@ -332,6 +341,7 @@ interface EdgesProps {
|
||||
edges: EdgeDatum[];
|
||||
nodeHoveringId?: string;
|
||||
edgeHoveringId?: string;
|
||||
svgIdNamespace: string;
|
||||
onClick: (event: MouseEvent<SVGElement>, link: EdgeDatum) => void;
|
||||
onMouseEnter: (id: string) => void;
|
||||
onMouseLeave: (id: string) => void;
|
||||
@ -351,6 +361,7 @@ const Edges = memo(function Edges(props: EdgesProps) {
|
||||
onClick={props.onClick}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
svgIdNamespace={props.svgIdNamespace}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import memoizeOne from 'memoize-one';
|
||||
import React from 'react';
|
||||
import React, { useId } from 'react';
|
||||
|
||||
import { PanelProps } from '@grafana/data';
|
||||
|
||||
@ -11,6 +11,8 @@ import { getNodeGraphDataFrames } from './utils';
|
||||
|
||||
export const NodeGraphPanel = ({ width, height, data, options }: PanelProps<NodeGraphOptions>) => {
|
||||
const getLinks = useLinks(data.timeRange);
|
||||
const panelId = useId();
|
||||
|
||||
if (!data || !data.series.length) {
|
||||
return (
|
||||
<div className="panel-empty">
|
||||
@ -22,7 +24,11 @@ export const NodeGraphPanel = ({ width, height, data, options }: PanelProps<Node
|
||||
const memoizedGetNodeGraphDataFrames = memoizeOne(getNodeGraphDataFrames);
|
||||
return (
|
||||
<div style={{ width, height }}>
|
||||
<NodeGraph dataFrames={memoizedGetNodeGraphDataFrames(data.series, options)} getLinks={getLinks} />
|
||||
<NodeGraph
|
||||
dataFrames={memoizedGetNodeGraphDataFrames(data.series, options)}
|
||||
getLinks={getLinks}
|
||||
panelId={panelId}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user