🍳 Cookbook
+Practical recipes for common graph analysis tasks using the GraphVisual API.
+ +Contents
+-
+
- 1. Generate a Synthetic Graph +
- 2. Find the Most Influential Nodes +
- 3. Detect Communities +
- 4. Find Shortest Paths +
- 5. Export to GraphML / GEXF +
- 6. Test Network Resilience +
- 7. Detect Anomalous Nodes +
- 8. Compare Two Graph Snapshots +
- 9. Run PageRank +
- 10. Full Analysis Pipeline +
+
+
+
+ 1. Generate a Synthetic Graph
+ +Create test graphs with known properties. Useful for benchmarking analyzers or building demo visualizations without needing real data.
+
+import gvisual.GraphGenerator;
+import gvisual.GraphGenerator.GeneratedGraph;
+
+GraphGenerator gen = new GraphGenerator();
+
+// Scale-free network (BarabΓ‘si-Albert): 200 nodes, 3 edges per step
+GeneratedGraph sf = gen.scaleFreeBa(200, 3);
+System.out.println("Nodes: " + sf.graph.getVertexCount());
+System.out.println("Edges: " + sf.graph.getEdgeCount());
+
+// Small-world network (Watts-Strogatz): 100 nodes, k=4, rewire p=0.1
+GeneratedGraph sw = gen.smallWorldWs(100, 4, 0.1);
+
+// Complete graph: every node connected to every other
+GeneratedGraph complete = gen.complete(20);
+// Expected edges: n*(n-1)/2 = 190
+System.out.println("Complete graph edges: " + complete.graph.getEdgeCount());
+
+// Grid: 10 rows x 10 columns
+GeneratedGraph grid = gen.grid(10, 10);
+
+ Nodes: 200
+Edges: 591
+Complete graph edges: 190
+
+ Tip: Scale-free graphs exhibit power-law degree distributions and are good models for social networks. Small-world graphs have high clustering with short average paths.
+
+
+
+
+ 2. Find the Most Influential Nodes
+ +Identify key nodes using degree, betweenness, and closeness centrality. Useful for finding hubs, bridges, and well-connected individuals in a network.
+
+import gvisual.NodeCentralityAnalyzer;
+import gvisual.NodeCentralityAnalyzer.CentralityResult;
+import java.util.List;
+
+NodeCentralityAnalyzer nca = new NodeCentralityAnalyzer(graph);
+nca.compute();
+
+// Get top 10 nodes by combined centrality
+List<CentralityResult> top10 = nca.getRanking(10);
+
+System.out.println("=== Top Influential Nodes ===");
+for (CentralityResult r : top10) {
+ System.out.printf("%-20s degree=%.3f betweenness=%.3f closeness=%.3f%n",
+ r.getNode(), r.getDegreeCentrality(),
+ r.getBetweennessCentrality(), r.getClosenessCentrality());
+}
+
+// Get centrality for a specific node
+double betweenness = nca.getBetweennessCentrality("Alice");
+System.out.println("Alice betweenness: " + betweenness);
+
+ When to use which metric:
+ • Degree — who has the most direct connections
+ • Betweenness — who bridges different groups (gatekeepers)
+ • Closeness — who can reach everyone fastest +
+ + • Degree — who has the most direct connections
+ • Betweenness — who bridges different groups (gatekeepers)
+ • Closeness — who can reach everyone fastest +
+
+
+
+ 3. Detect Communities
+ +Find clusters of tightly connected nodes. Use the basic detector for connected components or Louvain for modularity-optimized communities.
+
+import gvisual.CommunityDetector;
+import gvisual.LouvainCommunityDetector;
+
+// Basic: connected components
+CommunityDetector cd = new CommunityDetector(graph);
+List<Set<String>> components = cd.detect();
+System.out.println("Connected components: " + components.size());
+for (int i = 0; i < components.size(); i++) {
+ System.out.printf(" Community %d: %d members%n", i + 1, components.get(i).size());
+}
+
+// Advanced: Louvain modularity optimization
+LouvainCommunityDetector louvain = new LouvainCommunityDetector(graph);
+LouvainCommunityDetector.LouvainResult result = louvain.detect();
+System.out.printf("Louvain found %d communities (modularity: %.4f)%n",
+ result.getCommunityCount(), result.getModularity());
+
+// Get community assignment for each node
+Map<String, Integer> assignments = result.getNodeCommunities();
+System.out.println("Alice is in community: " + assignments.get("Alice"));
+
+ Tip: Modularity > 0.3 generally indicates meaningful community structure. Values > 0.7 suggest very strong clustering.
+
+
+
+
+ 4. Find Shortest Paths
+ +Compute hop-optimal and weight-optimal paths between any two nodes.
+
+import gvisual.ShortestPathFinder;
+import gvisual.ShortestPathFinder.PathResult;
+
+ShortestPathFinder spf = new ShortestPathFinder(graph);
+
+// Unweighted shortest path (BFS)
+PathResult path = spf.findShortestPath("Alice", "Eve");
+if (path != null) {
+ System.out.println("Path: " + path.getVertices());
+ System.out.println("Hops: " + path.getHopCount());
+ System.out.println("Edges: " + path.getEdges());
+} else {
+ System.out.println("No path exists between Alice and Eve");
+}
+
+// All shortest paths from a source
+Map<String, PathResult> allPaths = spf.findAllShortestPaths("Alice");
+for (Map.Entry<String, PathResult> entry : allPaths.entrySet()) {
+ System.out.printf(" Alice -> %s: %d hops%n",
+ entry.getKey(), entry.getValue().getHopCount());
+}
+
+
+
+
+ 5. Export to GraphML / GEXF / DOT
+ +Export your graph for use in Gephi, Cytoscape, Graphviz, or other tools.
+
+import gvisual.GraphMLExporter;
+import gvisual.GexfExporter;
+import gvisual.DotExporter;
+
+// GraphML (standard XML format, works with Gephi, yEd, Cytoscape)
+GraphMLExporter gml = new GraphMLExporter(graph);
+gml.export("network.graphml");
+
+// GEXF (Gephi's native format, supports dynamics/time)
+GexfExporter gexf = new GexfExporter(graph);
+gexf.export("network.gexf");
+
+// DOT (Graphviz format, great for quick visualizations)
+DotExporter dot = new DotExporter(graph);
+dot.export("network.dot");
+// Then render: dot -Tpng network.dot -o network.png
+
+// JSON export for web-based visualization (D3.js, Sigma.js)
+JsonGraphExporter json = new JsonGraphExporter(graph);
+json.export("network.json");
+
+ Format guide:
+ • GraphML — most portable, XML-based, widely supported
+ • GEXF — best for Gephi with temporal data
+ • DOT — simplest, render directly with Graphviz
+ • JSON — best for web dashboards +
+ + • GraphML — most portable, XML-based, widely supported
+ • GEXF — best for Gephi with temporal data
+ • DOT — simplest, render directly with Graphviz
+ • JSON — best for web dashboards +
+
+
+
+ 6. Test Network Resilience
+ +Find how robust a network is against node/edge removal. Identify critical failure points.
+
+import gvisual.GraphResilienceAnalyzer;
+import gvisual.ArticulationPointAnalyzer;
+
+// Find articulation points (nodes whose removal disconnects the graph)
+ArticulationPointAnalyzer apa = new ArticulationPointAnalyzer(graph);
+Set<String> cutPoints = apa.findArticulationPoints();
+System.out.println("Critical nodes (removal disconnects graph): " + cutPoints);
+
+// Full resilience analysis
+GraphResilienceAnalyzer gra = new GraphResilienceAnalyzer(graph);
+GraphResilienceAnalyzer.ResilienceReport report = gra.analyze();
+
+System.out.printf("Node connectivity: %d%n", report.getNodeConnectivity());
+System.out.printf("Edge connectivity: %d%n", report.getEdgeConnectivity());
+System.out.printf("Avg path length after removing top hub: %.2f%n",
+ report.getPathLengthAfterHubRemoval());
+
+// Simulate targeted attack (remove highest-degree nodes one by one)
+List<Double> fragmentation = gra.simulateTargetedAttack(10);
+for (int i = 0; i < fragmentation.size(); i++) {
+ System.out.printf(" After removing %d hubs: %.1f%% still connected%n",
+ i + 1, fragmentation.get(i) * 100);
+}
+
+
+
+
+ 7. Detect Anomalous Nodes
+ +Find nodes with unusual connection patterns—potential outliers, bots, or interesting actors in social networks.
+
+import gvisual.GraphAnomalyDetector;
+
+GraphAnomalyDetector gad = new GraphAnomalyDetector(graph);
+List<GraphAnomalyDetector.Anomaly> anomalies = gad.detect();
+
+System.out.println("=== Detected Anomalies ===");
+for (GraphAnomalyDetector.Anomaly a : anomalies) {
+ System.out.printf("Node: %-15s Type: %-20s Score: %.3f%n",
+ a.getNode(), a.getType(), a.getScore());
+ System.out.println(" Reason: " + a.getReason());
+}
+
+// Common anomaly types:
+// - DEGREE_OUTLIER: unusually many or few connections
+// - BRIDGE_NODE: connects otherwise separate communities
+// - ISOLATED_CLUSTER: small group connected only to each other
+
+
+
+
+ 8. Compare Two Graph Snapshots
+ +Track how a network evolves over time by comparing snapshots. Find new/removed nodes and edges, and compute structural similarity.
+
+import gvisual.GraphDiffAnalyzer;
+import gvisual.GraphSimilarityAnalyzer;
+
+// Diff: what changed between two graph snapshots?
+GraphDiffAnalyzer diff = new GraphDiffAnalyzer(graphBefore, graphAfter);
+GraphDiffAnalyzer.DiffResult dr = diff.analyze();
+
+System.out.println("Nodes added: " + dr.getAddedVertices());
+System.out.println("Nodes removed: " + dr.getRemovedVertices());
+System.out.println("Edges added: " + dr.getAddedEdges().size());
+System.out.println("Edges removed: " + dr.getRemovedEdges().size());
+
+// Similarity: how structurally similar are two graphs?
+GraphSimilarityAnalyzer gsa = new GraphSimilarityAnalyzer(graphA, graphB);
+GraphSimilarityAnalyzer.SimilarityResult sim = gsa.analyze();
+
+System.out.printf("Jaccard similarity (nodes): %.3f%n", sim.getNodeJaccard());
+System.out.printf("Jaccard similarity (edges): %.3f%n", sim.getEdgeJaccard());
+System.out.printf("Degree distribution correlation: %.3f%n",
+ sim.getDegreeCorrelation());
+
+
+
+
+ 9. Run PageRank
+ +Compute PageRank scores to find globally important nodes. Unlike degree centrality, PageRank considers the importance of a node's neighbors.
+
+import gvisual.PageRankAnalyzer;
+
+PageRankAnalyzer pra = new PageRankAnalyzer(graph);
+// damping=0.85, maxIterations=100, convergence=1e-6
+pra.compute(0.85, 100, 1e-6);
+
+// Get ranked results
+List<PageRankAnalyzer.PageRankResult> ranked = pra.getRanking();
+System.out.println("=== PageRank Top 10 ===");
+for (int i = 0; i < Math.min(10, ranked.size()); i++) {
+ PageRankAnalyzer.PageRankResult r = ranked.get(i);
+ System.out.printf("%2d. %-20s PR=%.6f%n", i + 1, r.getNode(), r.getScore());
+}
+
+// Check convergence
+System.out.printf("Converged in %d iterations%n", pra.getIterationsUsed());
+
+ PageRank vs Betweenness: PageRank finds nodes connected to other important nodes (prestige). Betweenness finds nodes that control information flow (brokers). Use both for a complete picture.
+
+
+
+
+10. Full Analysis Pipeline
+ +Combine multiple analyzers to build a comprehensive network report. This pattern shows how the analyzers compose together.
+
+import gvisual.*;
+
+// 1. Generate or load a graph
+GraphGenerator gen = new GraphGenerator();
+Graph<String, edge> graph = gen.scaleFreeBa(500, 3).graph;
+
+// 2. Basic stats
+GraphStats stats = new GraphStats(graph);
+System.out.printf("Nodes: %d Edges: %d Density: %.4f%n",
+ stats.getVertexCount(), stats.getEdgeCount(), stats.getDensity());
+
+// 3. Community structure
+LouvainCommunityDetector louvain = new LouvainCommunityDetector(graph);
+var communities = louvain.detect();
+System.out.printf("Communities: %d Modularity: %.3f%n",
+ communities.getCommunityCount(), communities.getModularity());
+
+// 4. Key players
+NodeCentralityAnalyzer nca = new NodeCentralityAnalyzer(graph);
+nca.compute();
+System.out.println("Top 5 central nodes:");
+for (var r : nca.getRanking(5)) {
+ System.out.printf(" %s (degree=%.3f, betweenness=%.3f)%n",
+ r.getNode(), r.getDegreeCentrality(), r.getBetweennessCentrality());
+}
+
+// 5. Resilience
+ArticulationPointAnalyzer apa = new ArticulationPointAnalyzer(graph);
+Set<String> cutPoints = apa.findArticulationPoints();
+System.out.println("Articulation points: " + cutPoints.size());
+
+// 6. Small-world properties
+SmallWorldAnalyzer swa = new SmallWorldAnalyzer(graph);
+SmallWorldAnalyzer.SmallWorldResult sw = swa.analyze();
+System.out.printf("Clustering coefficient: %.3f%n", sw.getClusteringCoefficient());
+System.out.printf("Avg path length: %.2f%n", sw.getAveragePathLength());
+System.out.println("Is small-world: " + sw.isSmallWorld());
+
+// 7. Export the full report
+NetworkReportGenerator nrg = new NetworkReportGenerator(graph);
+nrg.generateReport("analysis-report.html");
+
+// 8. Export for Gephi
+GraphMLExporter gml = new GraphMLExporter(graph);
+gml.export("network.graphml");
+
+ Performance: For graphs with 10K+ nodes, run centrality analysis in a separate thread using
+ AnalysisTask. The Barnes-Hut optimization in ForceDirectedLayout kicks in automatically above 100 nodes.