mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Adds color and stroke-dasharray support for node graph edges Adds support for providing color, highlighted color, and visual display of node graph edges as dashed lines via stroke-dasharray. * Updates node graph documentation * Updates documentation Adds default for `highlightedColor` * Update docs/sources/panels-visualizations/visualizations/node-graph/index.md Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com> * Update packages/grafana-data/src/utils/nodeGraph.ts Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com> * Update docs/sources/panels-visualizations/visualizations/node-graph/index.md Co-authored-by: Isabel Matwawana <76437239+imatwawana@users.noreply.github.com> * Removes highlightedColor; deprecates highlighted Per [request](https://github.com/grafana/grafana/pull/83855#issuecomment-1999810826), deprecates `highlighted` in code and documentation, and removes `highlightedColor` as an additional property. `highlighted` will continue to be supported in its original state (makes the edge red), but is superseded if `color` is provided. * Update types.ts Missed a file in my last commit. Removes `highlightedColor` and deprecates `highlighted`. * Add test scenario in test data source --------- Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com> Co-authored-by: Isabel Matwawana <76437239+imatwawana@users.noreply.github.com> Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import React, { MouseEvent, memo } from 'react';
|
|
|
|
import { EdgeArrowMarker } from './EdgeArrowMarker';
|
|
import { computeNodeCircumferenceStrokeWidth, nodeR } from './Node';
|
|
import { EdgeDatum, NodeDatum } from './types';
|
|
import { shortenLine } from './utils';
|
|
|
|
export const defaultHighlightedEdgeColor = '#a00';
|
|
export const defaultEdgeColor = '#999';
|
|
|
|
interface Props {
|
|
edge: EdgeDatum;
|
|
hovering: boolean;
|
|
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;
|
|
|
|
// Not great typing but after we do layout these properties are full objects not just references
|
|
const { source, target, sourceNodeRadius, targetNodeRadius } = edge as {
|
|
source: NodeDatum;
|
|
target: NodeDatum;
|
|
sourceNodeRadius: number;
|
|
targetNodeRadius: number;
|
|
};
|
|
const arrowHeadHeight = 10 + edge.thickness * 2; // resized value, just to make the UI nicer
|
|
|
|
// As the nodes have some radius we want edges to end outside of the node circle.
|
|
const line = shortenLine(
|
|
{
|
|
x1: source.x!,
|
|
y1: source.y!,
|
|
x2: target.x!,
|
|
y2: target.y!,
|
|
},
|
|
sourceNodeRadius + computeNodeCircumferenceStrokeWidth(sourceNodeRadius) / 2 || nodeR,
|
|
targetNodeRadius + computeNodeCircumferenceStrokeWidth(targetNodeRadius) / 2 || nodeR,
|
|
arrowHeadHeight
|
|
);
|
|
|
|
const edgeColor = edge.color || defaultEdgeColor;
|
|
|
|
// @deprecated -- until 'highlighted' is removed we'll prioritize 'color'
|
|
// in case both are provided
|
|
const highlightedEdgeColor = edge.color || defaultHighlightedEdgeColor;
|
|
|
|
const markerId = `triangle-${edge.id}`;
|
|
const coloredMarkerId = `triangle-colored-${edge.id}`;
|
|
|
|
return (
|
|
<>
|
|
<EdgeArrowMarker id={markerId} fill={edgeColor} headHeight={arrowHeadHeight} />
|
|
<EdgeArrowMarker id={coloredMarkerId} fill={highlightedEdgeColor} headHeight={arrowHeadHeight} />
|
|
<g
|
|
onClick={(event) => onClick(event, edge)}
|
|
style={{ cursor: 'pointer' }}
|
|
aria-label={`Edge from: ${source.id} to: ${target.id}`}
|
|
>
|
|
<line
|
|
strokeWidth={(hovering ? 1 : 0) + (edge.highlighted ? 1 : 0) + edge.thickness}
|
|
stroke={edge.highlighted ? highlightedEdgeColor : edgeColor}
|
|
x1={line.x1}
|
|
y1={line.y1}
|
|
x2={line.x2}
|
|
y2={line.y2}
|
|
strokeDasharray={edge.strokeDasharray}
|
|
markerEnd={`url(#${edge.highlighted ? coloredMarkerId : markerId})`}
|
|
/>
|
|
<line
|
|
stroke={'transparent'}
|
|
x1={line.x1}
|
|
y1={line.y1}
|
|
x2={line.x2}
|
|
y2={line.y2}
|
|
strokeWidth={20}
|
|
onMouseEnter={() => {
|
|
onMouseEnter(edge.id);
|
|
}}
|
|
onMouseLeave={() => {
|
|
onMouseLeave(edge.id);
|
|
}}
|
|
/>
|
|
</g>
|
|
</>
|
|
);
|
|
});
|