@graphty/layout
Version:
graph layout algorithms based on networkx
71 lines (58 loc) • 2.14 kB
text/typescript
/**
* Left-Right Planarity Test implementation
*/
import { Node, Edge, Embedding } from '../../types';
import { createTriangulationEmbedding } from './embedding';
/**
* Left-Right Planarity Test for general graphs
*
* @param nodes - List of nodes
* @param edges - List of edges
* @returns Object containing isPlanar flag and embedding
*/
export function lrPlanarityTest(
nodes: Node[],
edges: Edge[],
seed: number | null = null
): { isPlanar: boolean; embedding: Embedding | null } {
// Create adjacency list for the graph
const adjList: Record<Node, Node[]> = {};
for (const node of nodes) {
adjList[node] = [];
}
for (const [u, v] of edges) {
adjList[u].push(v);
adjList[v].push(u);
}
// Step 1: Perform DFS to get an st-numbering (ordering of nodes)
const visited = new Set<Node>();
const ordering: Node[] = [];
function dfs(node: Node): void {
visited.add(node);
ordering.push(node);
for (const neighbor of adjList[node]) {
if (!visited.has(neighbor)) {
dfs(neighbor);
}
}
}
// Start DFS from first node
dfs(nodes[0]);
// If the graph is disconnected, it's still planar but we need to handle each component
if (ordering.length < nodes.length) {
// Create a simple triangulation embedding for disconnected graphs
return { isPlanar: true, embedding: createTriangulationEmbedding(nodes, edges, seed) };
}
// Step 2: For a general implementation, we'll use a simplified approach
// since this would normally require implementing the entire LR algorithm
// For this implementation, since we can't fully implement Boyer-Myrvold,
// we'll create a reasonable planar embedding for most planar graphs
// We assume the graph is planar if it's sparse enough (|E| <= 3|V| - 6)
// This is a necessary but not sufficient condition for planar graphs
if (edges.length > 3 * nodes.length - 6) {
return { isPlanar: false, embedding: null };
}
// Create a planar embedding using a triangulation approach
const embedding = createTriangulationEmbedding(nodes, edges, seed);
return { isPlanar: true, embedding };
}