Skip to content

Commit

Permalink
update dynamic edge
Browse files Browse the repository at this point in the history
  • Loading branch information
maximun85 committed Sep 11, 2024
1 parent a947a46 commit 8c68d41
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 67 deletions.
142 changes: 80 additions & 62 deletions src/modules/blockchains/Buy/getEdgeParams.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,100 @@
import { Position } from '@xyflow/react';
import { Position, MarkerType } from '@xyflow/react';

// returns the position (top,right,bottom or right) passed node compared to
function getParams(nodeA: any, nodeB: any) {
const centerA = getNodeCenter(nodeA);
const centerB = getNodeCenter(nodeB);
// this helper function returns the intersection point
// of the line between the center of the intersectionNode and the target node
function getNodeIntersection(intersectionNode: any, targetNode: any) {
// https://math.stackexchange.com/questions/1724792/an-algorithm-for-finding-the-intersection-point-between-a-center-of-vision-and-a
const { width: intersectionNodeWidth, height: intersectionNodeHeight } =
intersectionNode.measured;
const intersectionNodePosition = intersectionNode.internals.positionAbsolute;
const targetPosition = targetNode.internals.positionAbsolute;

const horizontalDiff = Math.abs(centerA.x - centerB.x);
const verticalDiff = Math.abs(centerA.y - centerB.y);
const w = intersectionNodeWidth / 2;
const h = intersectionNodeHeight / 2;

let position;
const x2 = intersectionNodePosition.x + w;
const y2 = intersectionNodePosition.y + h;
const x1 = targetPosition.x + targetNode.measured.width / 2;
const y1 = targetPosition.y + targetNode.measured.height / 2;

// when the horizontal difference between the nodes is bigger, we use Position.Left or Position.Right for the handle
if (horizontalDiff > verticalDiff) {
position = centerA.x > centerB.x ? Position.Left : Position.Right;
} else {
// here the vertical difference between the nodes is bigger, so we use Position.Top or Position.Bottom for the handle
position = centerA.y > centerB.y ? Position.Top : Position.Bottom;
}
const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h);
const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h);
const a = 1 / (Math.abs(xx1) + Math.abs(yy1));
const xx3 = a * xx1;
const yy3 = a * yy1;
const x = w * (xx3 + yy3) + x2;
const y = h * (-xx3 + yy3) + y2;

const [x, y] = getHandleCoordsByPosition(nodeA, position);
return [x, y, position];
return { x, y };
}

function getHandleCoordsByPosition(node: any, handlePosition: any) {
// all handles are from type source, that's why we use handleBounds.source here
const handle = node.internals.handleBounds.source.find(
(h: any) => h.position === handlePosition,
);
console.log('nodegetHandleCoordsByPosition', node);
let offsetX = handle.width / 2;
let offsetY = handle.height / 2;
// returns the position (top,right,bottom or right) passed node compared to the intersection point
function getEdgePosition(node: any, intersectionPoint: any) {
const n = { ...node.internals.positionAbsolute, ...node };
const nx = Math.round(n.x);
const ny = Math.round(n.y);
const px = Math.round(intersectionPoint.x);
const py = Math.round(intersectionPoint.y);

// this is a tiny detail to make the markerEnd of an edge visible.
// The handle position that gets calculated has the origin top-left, so depending which side we are using, we add a little offset
// when the handlePosition is Position.Right for example, we need to add an offset as big as the handle itself in order to get the correct position
switch (handlePosition) {
case Position.Left:
offsetX = 0;
console.log('Position Left');
break;
case Position.Right:
offsetX = handle.width;
console.log('Position Right');
break;
case Position.Top:
offsetY = 0;
console.log('Position Top');
break;
case Position.Bottom:
console.log('Position Bottom');
offsetY = handle.height;
break;
if (px <= nx + 1) {
return Position.Left;
}
if (px >= nx + n.measured.width - 1) {
return Position.Right;
}
if (py <= ny + 1) {
return Position.Top;
}
if (py >= n.y + n.measured.height - 1) {
return Position.Bottom;
}

const x = node.internals.positionAbsolute.x + handle.x + offsetX;
const y = node.internals.positionAbsolute.y + handle.y + offsetY;

return [x, y];
}

function getNodeCenter(node: any) {
return {
x: node.internals.positionAbsolute.x + node.measured.width / 2,
y: node.internals.positionAbsolute.y + node.measured.height / 2,
};
return Position.Top;
}

// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge
export function getEdgeParams(source: any, target: any) {
const [sx, sy, sourcePos] = getParams(source, target);
const [tx, ty, targetPos] = getParams(target, source);
const sourceIntersectionPoint = getNodeIntersection(source, target);
const targetIntersectionPoint = getNodeIntersection(target, source);

const sourcePos = getEdgePosition(source, sourceIntersectionPoint);
const targetPos = getEdgePosition(target, targetIntersectionPoint);

return {
sx,
sy,
tx,
ty,
sx: sourceIntersectionPoint.x,
sy: sourceIntersectionPoint.y,
tx: targetIntersectionPoint.x,
ty: targetIntersectionPoint.y,
sourcePos,
targetPos,
};
}

// export function createNodesAndEdges() {
// const nodes = [];
// const edges = [];
// const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
//
// nodes.push({ id: 'target', data: { label: 'Target' }, position: center });
//
// for (let i = 0; i < 8; i++) {
// const degrees = i * (360 / 8);
// const radians = degrees * (Math.PI / 180);
// const x = 250 * Math.cos(radians) + center.x;
// const y = 250 * Math.sin(radians) + center.y;
//
// nodes.push({ id: `${i}`, data: { label: 'Source' }, position: { x, y } });
//
// edges.push({
// id: `edge-${i}`,
// target: 'target',
// source: `${i}`,
// type: 'floating',
// markerEnd: {
// type: MarkerType.Arrow,
// },
// });
// }
//
// return { nodes, edges };
// }
15 changes: 10 additions & 5 deletions src/modules/blockchains/Buy/hooks/useLineIssueToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import useFlowStore from '@/modules/blockchains/Buy/stores/useFlowStore';
import { useParams } from 'next/navigation';
import { useAAModule } from '@/modules/blockchains/detail_v4/hook/useAAModule';
import { Edge, MarkerType } from '@xyflow/react';
import { useChainProvider } from '@/modules/blockchains/detail_v4/provider/ChainProvider.hook';
import handleStatusEdges from '@utils/helpers';

function useLineIssueToken(): void {
const { nodes, edges, setEdges } = useFlowStore()
const params = useParams();
const isUpdateFlow = React.useMemo(() => !!params.id, [params.id]);
const { aaInstalledData, } = useAAModule();

const { aaInstalledData } = useAAModule();
const { getAAStatus } = useChainProvider();
const { lineAAStatus } = useAAModule();
function addLineIssueToken() {
if(nodes.length === 0) return;
const newEdges: Edge[] = [];
Expand Down Expand Up @@ -43,8 +46,10 @@ function useLineIssueToken(): void {
target: node.id,
sourceHandle: `${issueTokenNode.id}-s-account_abstraction`,
targetHandle: `account_abstraction-t-${issueTokenNode.id}`,
label: '',
animated: false,
label: handleStatusEdges('', lineAAStatus, 'account_abstraction')
.icon,
animated: handleStatusEdges('', lineAAStatus, 'account_abstraction')
.animate,
type: 'customEdge',
selectable: false,
selected: false,
Expand All @@ -66,7 +71,7 @@ function useLineIssueToken(): void {

// Airdrop Node
// @ts-ignore
if(dataNode?.dapp?.id === 'airdrop' && tokenNameOfAirdrop?.options[0].key == tokenNameOfIssueToken?.value) {
if(dataNode?.dapp?.id === 'airdrop' && tokenNameOfAirdrop?.options[0].key == tokenNameOfIssueToken?.value && checkStatusNode(statusNode)) {
dataNode.sourceHandles.push(`airdrop-t-${issueTokenNode.id}`);
issueTokenNode.data.sourceHandles.push(`${issueTokenNode.id}-s-airdrop`)
const issueTokenToAirdrop: Edge = {
Expand Down

0 comments on commit 8c68d41

Please sign in to comment.