Skip to content

Commit

Permalink
Merge pull request #7 from topology-foundation/feat/vertex-positions
Browse files Browse the repository at this point in the history
feat: vertex positions
  • Loading branch information
d-roak authored Nov 16, 2024
2 parents 3d4a847 + dcbee6e commit c4efab9
Show file tree
Hide file tree
Showing 7 changed files with 7,198 additions and 1,436 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow starter (Vite + TS)</title>
<title>Hashgraph visualisation</title>
</head>
<body>
<div id="root"></div>
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
"preview": "vite preview"
},
"dependencies": {
"@topology-foundation/node": "^0.3.1",
"@topology-foundation/object": "^0.3.1",
"@xyflow/react": "^12.3.5",
"@dagrejs/dagre": "^1.1.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand All @@ -26,4 +29,4 @@
"typescript": "^5.3.3",
"vite": "^5.0.12"
}
}
}
8,414 changes: 7,005 additions & 1,409 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

85 changes: 70 additions & 15 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useEffect } from "react";

import {
ReactFlow,
Background,
Expand All @@ -9,34 +10,79 @@ import {
useEdgesState,
type OnConnect,
Edge,
MarkerType,
Panel,
} from "@xyflow/react";
import dagre from "@dagrejs/dagre";

import "@xyflow/react/dist/style.css";

import { AppNode } from "./nodes/types";
import { initialNodes, nodeTypes } from "./nodes";
import { initialEdges, edgeTypes } from "./edges";
import { rawData } from "./data-mock";
import { testData } from "./data-mock";
import { VertexNode } from "./nodes/types";

const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));

const nodeWidth = 200;
const nodeHeight = 100;

const getLayoutedElements = (nodes: AppNode[], edges: Edge[]) => {
dagreGraph.setGraph({ rankdir: "LR" });

nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});

edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});

dagre.layout(dagreGraph);

const newNodes = nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
const newNode = {
...node,
/* We are shifting the dagre node position (anchor=center center) to the top left
so it matches the React Flow node anchor point (top left). */
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2,
},
};

return newNode;
});

return { nodes: newNodes, edges };
};

const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(initialNodes, initialEdges);

export default function App() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const [nodes, setNodes, onNodesChange] = useNodesState(layoutedNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges);
const onConnect: OnConnect = useCallback(
(connection) => setEdges((edges) => addEdge(connection, edges)),
[setEdges],
);

const onLayout = useCallback(() => {
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);
setNodes(layoutedNodes);
setEdges(layoutedEdges);
}, [nodes, edges]);

useEffect(() => {
const ns: VertexNode[] = [];
const es: Edge[] = [];
// @jan do ur magic to calculate the position of the nodes
let count_y = 0;
for (const v of rawData) {
count_y += 200;
ns.push({
const nodes: VertexNode[] = [];
const edges: Edge[] = [];
for (const v of testData) {
nodes.push({
id: v.hash,
type: "vertex",
position: { x: 0, y: count_y },
position: { x: 0, y: 0 },
data: {
hash: v.hash,
nodeId: v.nodeId,
Expand All @@ -46,22 +92,28 @@ export default function App() {
});

for (const dep of v.deps) {
es.push({
edges.push({
id: `${dep}->${v.hash}`,
source: dep,
target: v.hash,
animated: true,
markerEnd: {
type: MarkerType.Arrow,
width: 25,
height: 25,
}
});
}
}
// get layouted elements
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);

setNodes(ns);
setEdges(es);
setNodes(layoutedNodes);
setEdges(layoutedEdges);
}, [setNodes, setEdges]);

return (
<>
<input id="search" type="text" placeholder="DRP ID" onChange={() => {}} />
<ReactFlow
nodes={nodes}
nodeTypes={nodeTypes}
Expand All @@ -72,6 +124,9 @@ export default function App() {
onConnect={onConnect}
fitView
>
<Panel position="top-right">
<button onClick={onLayout}>Reset layout</button>
</Panel>
<Background />
<MiniMap />
<Controls />
Expand Down
66 changes: 56 additions & 10 deletions src/data-mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { Vertex } from "./nodes/types";

export const rawData: Vertex[] = [
/*
__ V6:ADD(3)
/
___ V2:ADD(1) <-- V3:RM(2) <-- V7:RM(1) <-- V8:RM(3)
/ ______________/
V1:ADD(1)/ /
\ /
\ ___ V4:RM(2) <-- V5:ADD(2) <-- V9:RM(1)
*/

export const testData: Vertex[] = [
{
hash: "hash-1",
nodeId: "node-1",
Expand All @@ -15,7 +25,7 @@ export const rawData: Vertex[] = [
nodeId: "node-2",
operation: {
type: "add",
value: "2",
value: "1",
},
deps: ["hash-1"],
},
Expand All @@ -24,26 +34,62 @@ export const rawData: Vertex[] = [
nodeId: "node-3",
operation: {
type: "rm",
value: "3",
value: "2",
},
deps: ["hash-1"],
deps: ["hash-2"],
},
{
hash: "hash-4",
nodeId: "node-4",
operation: {
type: "add",
value: "4",
type: "rm",
value: "2",
},
deps: ["hash-2"],
deps: ["hash-1"],
},
{
hash: "hash-5",
nodeId: "node-5",
operation: {
type: "add",
value: "5",
value: "2",
},
deps: ["hash-4"],
},
{
hash: "hash-6",
nodeId: "node-6",
operation: {
type: "add",
value: "3",
},
deps: ["hash-3"],
},
{
hash: "hash-7",
nodeId: "node-7",
operation: {
type: "rm",
value: "1",
},
deps: ["hash-3"],
},
{
hash: "hash-8",
nodeId: "node-8",
operation: {
type: "rm",
value: "3",
},
deps: ["hash-5", "hash-7"],
},
{
hash: "hash-9",
nodeId: "node-9",
operation: {
type: "rm",
value: "1",
},
deps: ["hash-3", "hash-4"],
deps: ["hash-5"],
},
];
];
20 changes: 20 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,23 @@ body,
height: 40px;
width: 300px;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
cursor: pointer;
transition: border-color 0.25s;
}

button:hover {
border-color: #646cff;
}

button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
42 changes: 42 additions & 0 deletions src/objects/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Color CRO
* 3 Operations:
* - Color Red
* - Color Green
* - Color Blue
*/
import {
ActionType,
type CRO,
type Operation,
type ResolveConflictsType,
SemanticsType,
type Vertex,
} from "@topology-foundation/object";

export class ColorCRO implements CRO {

operations: string[] = ["paint"];
semanticsType: SemanticsType = SemanticsType.pair;
colors: string[];

constructor() {
this.colors = [];
}

paint(color: string): void {
this._paint(color);
}

private _paint(color: string): void {
this.operations.push(color);
}

resolveConflicts(_: Vertex[]): ResolveConflictsType {
return { action: ActionType.Nop };
}

mergeCallback(_: Operation[]): void {
// To complete
}
}

0 comments on commit c4efab9

Please sign in to comment.