Skip to content
This repository was archived by the owner on Apr 7, 2024. It is now read-only.

Commit 7244d8b

Browse files
authored
Add better self-loops error, fix multiple edges in trees strategy (#83)
1 parent a83c78c commit 7244d8b

File tree

6 files changed

+39
-30
lines changed

6 files changed

+39
-30
lines changed

src/components/graphs/GraphComponent.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Group, Rect, Vector } from '@shopify/react-native-skia';
1+
import { Group, Vector } from '@shopify/react-native-skia';
22
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3-
import { useAnimatedReaction, useDerivedValue } from 'react-native-reanimated';
3+
import { useAnimatedReaction } from 'react-native-reanimated';
44

55
import {
66
ARROW_COMPONENT_SETTINGS,
@@ -388,22 +388,8 @@ export default function GraphComponent<
388388
[verticesData]
389389
);
390390

391-
const containerWidth = useDerivedValue(
392-
() => boundingRect.right.value - boundingRect.left.value
393-
);
394-
const containerHeight = useDerivedValue(
395-
() => boundingRect.bottom.value - boundingRect.top.value
396-
);
397-
398391
return (
399392
<Group>
400-
<Rect
401-
x={boundingRect.left}
402-
y={boundingRect.top}
403-
width={containerWidth}
404-
height={containerHeight}
405-
color='#222'
406-
/>
407393
{renderEdges()}
408394
{renderVertices()}
409395
</Group>

src/examples/Development.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ let idx = 0;
9494
let mode = 0;
9595

9696
export default function App() {
97-
const graph = DirectedGraph.fromData([{ key: 'A', data: 'A' }]);
97+
const graph = DirectedGraph.fromData({ vertices: [{ key: 'A', data: 'A' }] });
9898

9999
// TODO - remove this useEffect after testing
100100
useEffect(() => {

src/models/graphs/DirectedGraph.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ export default class DirectedGraph<V, E> extends Graph<
1212
DirectedEdgeData<E>
1313
> {
1414
// eslint-disable-next-line no-shadow
15-
static fromData<V, E>(
16-
vertices: Array<VertexData<V>>,
17-
edges?: Array<DirectedEdgeData<E>>
18-
): DirectedGraph<V, E> {
15+
static fromData<V, E>(data: {
16+
vertices: Array<VertexData<V>>;
17+
edges?: Array<DirectedEdgeData<E>>;
18+
}): DirectedGraph<V, E> {
1919
const instance = new DirectedGraph<V, E>();
20-
instance.insertBatch({ vertices, edges });
20+
instance.insertBatch(data);
2121
return instance;
2222
}
2323

@@ -43,6 +43,7 @@ export default class DirectedGraph<V, E> extends Graph<
4343
targetKey: string,
4444
notifyObservers?: boolean
4545
): DirectedEdge<E, V> {
46+
this.checkSelfLoop(sourceKey, targetKey);
4647
const source = this.getVertex(sourceKey);
4748
const target = this.getVertex(targetKey);
4849

src/models/graphs/Graph.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,13 @@ export default abstract class Graph<
256256
observer.graphChanged();
257257
});
258258
}
259+
260+
// TODO - remove this method after adding self-loop edges support
261+
protected checkSelfLoop(vertex1key: string, vertex2key: string): void {
262+
if (vertex1key === vertex2key) {
263+
throw new Error(
264+
`Self-loop edges are not yet supported. Vertex key: ${vertex1key}`
265+
);
266+
}
267+
}
259268
}

src/models/graphs/UndirectedGraph.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ export default class UndirectedGraph<V, E> extends Graph<
1212
UndirectedEdgeData<E>
1313
> {
1414
// eslint-disable-next-line no-shadow
15-
static fromData<V, E>(
16-
vertices: Array<VertexData<V>>,
17-
edges?: Array<UndirectedEdgeData<E>>
18-
): UndirectedGraph<V, E> {
15+
static fromData<V, E>(data: {
16+
vertices: Array<VertexData<V>>;
17+
edges?: Array<UndirectedEdgeData<E>>;
18+
}): UndirectedGraph<V, E> {
1919
const instance = new UndirectedGraph<V, E>();
20-
instance.insertBatch({ vertices, edges });
20+
instance.insertBatch(data);
2121
return instance;
2222
}
2323

@@ -43,6 +43,7 @@ export default class UndirectedGraph<V, E> extends Graph<
4343
vertex2key: string,
4444
notifyObservers = true
4545
): UndirectedEdge<E, V> {
46+
this.checkSelfLoop(vertex1key, vertex2key);
4647
const vertex1 = this.getVertex(vertex1key);
4748
const vertex2 = this.getVertex(vertex2key);
4849

src/utils/placement/strategies/trees.placement.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,23 @@ const arrangeVertices = <V, E>(
6969
const arrangeVerticesRecur = <V, E>(
7070
arrangedVertices: Record<string, { row: number; col: number }>,
7171
vertex: Vertex<V, E>,
72+
visitedVertices: Set<string> = new Set(),
7273
currentColumn = 0,
7374
currentDepth = 0
7475
): number => {
75-
const unusedVertexNeighbors = vertex.neighbors.filter(
76-
neighbor => !arrangedVertices[neighbor.key]
77-
);
76+
visitedVertices.add(vertex.key);
77+
const unusedVertexNeighbors: Array<Vertex<V, E>> = [];
78+
const alreadyCheckedNeighbors = new Set<string>();
79+
80+
vertex.neighbors.forEach(neighbor => {
81+
if (
82+
!alreadyCheckedNeighbors.has(neighbor.key) &&
83+
!visitedVertices.has(neighbor.key)
84+
) {
85+
alreadyCheckedNeighbors.add(neighbor.key);
86+
unusedVertexNeighbors.push(neighbor);
87+
}
88+
});
7889

7990
if (unusedVertexNeighbors.length === 0) {
8091
return 1;
@@ -86,6 +97,7 @@ const arrangeVerticesRecur = <V, E>(
8697
const childSubtreeWidth = arrangeVerticesRecur(
8798
arrangedVertices,
8899
neighbor,
100+
visitedVertices,
89101
currentColumn + subtreeWidth,
90102
currentDepth + 1
91103
);

0 commit comments

Comments
 (0)