mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-24 00:48:36 +00:00
modify the appeariance of self connecting edge lineage (#19714)
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
0d73ee7e36
commit
a76b9bdcec
@ -15,7 +15,7 @@ import Icon from '@ant-design/icons/lib/components/Icon';
|
|||||||
import { Button, Tag } from 'antd';
|
import { Button, Tag } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { Fragment, useCallback, useMemo } from 'react';
|
import React, { Fragment, useCallback, useMemo } from 'react';
|
||||||
import { EdgeProps, getBezierPath } from 'reactflow';
|
import { EdgeProps } from 'reactflow';
|
||||||
import { ReactComponent as IconEditCircle } from '../../../assets/svg/ic-edit-circle.svg';
|
import { ReactComponent as IconEditCircle } from '../../../assets/svg/ic-edit-circle.svg';
|
||||||
import { ReactComponent as FunctionIcon } from '../../../assets/svg/ic-function.svg';
|
import { ReactComponent as FunctionIcon } from '../../../assets/svg/ic-function.svg';
|
||||||
import { ReactComponent as IconTimesCircle } from '../../../assets/svg/ic-times-circle.svg';
|
import { ReactComponent as IconTimesCircle } from '../../../assets/svg/ic-times-circle.svg';
|
||||||
@ -27,7 +27,10 @@ import { EntityType } from '../../../enums/entity.enum';
|
|||||||
import { StatusType } from '../../../generated/entity/data/pipeline';
|
import { StatusType } from '../../../generated/entity/data/pipeline';
|
||||||
import { LineageLayer } from '../../../generated/settings/settings';
|
import { LineageLayer } from '../../../generated/settings/settings';
|
||||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
||||||
import { getColumnSourceTargetHandles } from '../../../utils/EntityLineageUtils';
|
import {
|
||||||
|
getColumnSourceTargetHandles,
|
||||||
|
getEdgePathData,
|
||||||
|
} from '../../../utils/EntityLineageUtils';
|
||||||
import { getEntityName } from '../../../utils/EntityUtils';
|
import { getEntityName } from '../../../utils/EntityUtils';
|
||||||
import EntityPopOverCard from '../../common/PopOverCard/EntityPopOverCard';
|
import EntityPopOverCard from '../../common/PopOverCard/EntityPopOverCard';
|
||||||
import { CustomEdgeData } from './EntityLineage.interface';
|
import { CustomEdgeData } from './EntityLineage.interface';
|
||||||
@ -69,6 +72,8 @@ export const CustomEdge = ({
|
|||||||
markerEnd,
|
markerEnd,
|
||||||
data,
|
data,
|
||||||
selected,
|
selected,
|
||||||
|
source,
|
||||||
|
target,
|
||||||
}: EdgeProps) => {
|
}: EdgeProps) => {
|
||||||
const {
|
const {
|
||||||
edge,
|
edge,
|
||||||
@ -96,6 +101,21 @@ export const CustomEdge = ({
|
|||||||
|
|
||||||
const { theme } = useApplicationStore();
|
const { theme } = useApplicationStore();
|
||||||
|
|
||||||
|
const {
|
||||||
|
edgePath,
|
||||||
|
edgeCenterX,
|
||||||
|
edgeCenterY,
|
||||||
|
invisibleEdgePath,
|
||||||
|
invisibleEdgePath1,
|
||||||
|
} = getEdgePathData(source, target, offset, {
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition,
|
||||||
|
});
|
||||||
|
|
||||||
const showDqTracing = useMemo(() => {
|
const showDqTracing = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
(activeLayer.includes(LineageLayer.DataObservability) &&
|
(activeLayer.includes(LineageLayer.DataObservability) &&
|
||||||
@ -122,31 +142,6 @@ export const CustomEdge = ({
|
|||||||
);
|
);
|
||||||
}, [isColumnLineage, tracedColumns, sourceHandle, targetHandle]);
|
}, [isColumnLineage, tracedColumns, sourceHandle, targetHandle]);
|
||||||
|
|
||||||
const [edgePath, edgeCenterX, edgeCenterY] = getBezierPath({
|
|
||||||
sourceX,
|
|
||||||
sourceY,
|
|
||||||
sourcePosition,
|
|
||||||
targetX,
|
|
||||||
targetY,
|
|
||||||
targetPosition,
|
|
||||||
});
|
|
||||||
const [invisibleEdgePath] = getBezierPath({
|
|
||||||
sourceX: sourceX + offset,
|
|
||||||
sourceY: sourceY + offset,
|
|
||||||
sourcePosition,
|
|
||||||
targetX: targetX + offset,
|
|
||||||
targetY: targetY + offset,
|
|
||||||
targetPosition,
|
|
||||||
});
|
|
||||||
const [invisibleEdgePath1] = getBezierPath({
|
|
||||||
sourceX: sourceX - offset,
|
|
||||||
sourceY: sourceY - offset,
|
|
||||||
sourcePosition,
|
|
||||||
targetX: targetX - offset,
|
|
||||||
targetY: targetY - offset,
|
|
||||||
targetPosition,
|
|
||||||
});
|
|
||||||
|
|
||||||
const updatedStyle = useMemo(() => {
|
const updatedStyle = useMemo(() => {
|
||||||
const isNodeTraced =
|
const isNodeTraced =
|
||||||
tracedNodes.includes(edge.fromEntity.id) &&
|
tracedNodes.includes(edge.fromEntity.id) &&
|
||||||
|
@ -30,6 +30,7 @@ import React, { MouseEvent as ReactMouseEvent } from 'react';
|
|||||||
import {
|
import {
|
||||||
Connection,
|
Connection,
|
||||||
Edge,
|
Edge,
|
||||||
|
getBezierPath,
|
||||||
getConnectedEdges,
|
getConnectedEdges,
|
||||||
getIncomers,
|
getIncomers,
|
||||||
getOutgoers,
|
getOutgoers,
|
||||||
@ -1451,3 +1452,112 @@ export const getColumnFunctionValue = (
|
|||||||
|
|
||||||
return column?.function;
|
return column?.function;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface EdgeAlignmentPathDataProps {
|
||||||
|
sourceX: number;
|
||||||
|
sourceY: number;
|
||||||
|
targetX: number;
|
||||||
|
targetY: number;
|
||||||
|
sourcePosition: Position;
|
||||||
|
targetPosition: Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isSelfConnectingEdge = (source: string, target: string) => {
|
||||||
|
return source === target;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSelfConnectingEdgePath = ({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
}: EdgeAlignmentPathDataProps) => {
|
||||||
|
const radiusX = (sourceX - targetX) * 0.6;
|
||||||
|
const radiusY = 50;
|
||||||
|
|
||||||
|
return `M ${sourceX - 5} ${sourceY} A ${radiusX} ${radiusY} 0 1 0 ${
|
||||||
|
targetX + 2
|
||||||
|
} ${targetY}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEdgePathAlignmentData = (
|
||||||
|
source: string,
|
||||||
|
target: string,
|
||||||
|
edgePathData: {
|
||||||
|
sourceX: number;
|
||||||
|
sourceY: number;
|
||||||
|
targetX: number;
|
||||||
|
targetY: number;
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
if (isSelfConnectingEdge(source, target)) {
|
||||||
|
// modify the edge path data as per the self connecting edges behavior
|
||||||
|
return {
|
||||||
|
sourceX: edgePathData.sourceX - 5,
|
||||||
|
sourceY: edgePathData.sourceY - 80,
|
||||||
|
targetX: edgePathData.targetX + 2,
|
||||||
|
targetY: edgePathData.targetY - 80,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return edgePathData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getEdgePath = (
|
||||||
|
edgePath: string,
|
||||||
|
source: string,
|
||||||
|
target: string,
|
||||||
|
alignmentPathData: EdgeAlignmentPathDataProps
|
||||||
|
) => {
|
||||||
|
return isSelfConnectingEdge(source, target)
|
||||||
|
? getSelfConnectingEdgePath(alignmentPathData)
|
||||||
|
: edgePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEdgePathData = (
|
||||||
|
source: string,
|
||||||
|
target: string,
|
||||||
|
offset: number,
|
||||||
|
edgePathData: EdgeAlignmentPathDataProps
|
||||||
|
) => {
|
||||||
|
const { sourceX, sourceY, targetX, targetY } = getEdgePathAlignmentData(
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
edgePathData
|
||||||
|
);
|
||||||
|
const { sourcePosition, targetPosition } = edgePathData;
|
||||||
|
|
||||||
|
const [edgePath, edgeCenterX, edgeCenterY] = getBezierPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
targetPosition,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [invisibleEdgePath] = getBezierPath({
|
||||||
|
sourceX: sourceX + offset,
|
||||||
|
sourceY: sourceY + offset,
|
||||||
|
sourcePosition,
|
||||||
|
targetX: targetX + offset,
|
||||||
|
targetY: targetY + offset,
|
||||||
|
targetPosition,
|
||||||
|
});
|
||||||
|
const [invisibleEdgePath1] = getBezierPath({
|
||||||
|
sourceX: sourceX - offset,
|
||||||
|
sourceY: sourceY - offset,
|
||||||
|
sourcePosition,
|
||||||
|
targetX: targetX - offset,
|
||||||
|
targetY: targetY - offset,
|
||||||
|
targetPosition,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
edgePath: getEdgePath(edgePath, source, target, edgePathData), // pass the initial data edgePathData, as edge modification will be done based on the initial data
|
||||||
|
edgeCenterX,
|
||||||
|
edgeCenterY,
|
||||||
|
invisibleEdgePath,
|
||||||
|
invisibleEdgePath1,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user