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:
Ashish Gupta 2025-02-10 13:41:41 +05:30 committed by GitHub
parent 0d73ee7e36
commit a76b9bdcec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 132 additions and 27 deletions

View File

@ -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) &&

View File

@ -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,
};
};