Created
June 6, 2018 21:20
-
-
Save benjaminaaron/3bbe300838c93717a1cc88ecad99c23a to your computer and use it in GitHub Desktop.
convert find-output to GraphML to visualize directory structures in yEd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.PrintWriter; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import static java.nio.file.Files.newInputStream; | |
public class FilesTreeToGraphML { | |
public static void main(String[] args) { | |
(new FilesTreeToGraphML()).run(); | |
} | |
private void run() { | |
/* | |
Expects a textfile as input that contains the output of a tree or find command to list | |
directories and files. | |
This linux-command "find -type d > dev.txt" for instance collects all directories starting | |
from where it gets run. The output will look like this (remove the first line of just "."): | |
. | |
./dir1 | |
./dir1/dir2 | |
./dir1/dir3 | |
./dir1/dir3/dir4 | |
./dir5/dir6 | |
*/ | |
Path input = Paths.get("/Users/benja/Desktop/dev.txt"); | |
String filename = input.getFileName().toString(); | |
filename = filename.substring(0, filename.lastIndexOf('.')); | |
Path output = input.resolveSibling(filename + ".graphml"); | |
Node root = new Node(filename.toUpperCase()); | |
try (BufferedReader lines = new BufferedReader(new InputStreamReader(newInputStream(input)))) { | |
String line; | |
while ((line = lines.readLine()) != null) { | |
String[] nodeNames = line.substring(2).split("/"); | |
Node parent = root; | |
for (String nodeName : nodeNames) { | |
parent = parent.addChildIfAbsent(nodeName.replaceAll("&", "&")); | |
} | |
} | |
} catch (IOException ignored) {} | |
List<Node> nodes = new ArrayList<>(); | |
List<Edge> edges = new ArrayList<>(); | |
root.collectNodesAndBuildEdges(nodes, edges); | |
doExport(nodes, edges, output); | |
} | |
class Node { | |
String name; | |
Map<String, Node> children = new HashMap<>(); | |
Node(String name) { | |
this.name = name; | |
} | |
Node addChildIfAbsent(String nodeName) { | |
children.putIfAbsent(nodeName, new Node(nodeName)); | |
return children.get(nodeName); | |
} | |
void collectNodesAndBuildEdges(List<Node> nodes, List<Edge> edges) { | |
nodes.add(this); | |
children.values().forEach(child -> { | |
edges.add(new Edge(this, child)); | |
child.collectNodesAndBuildEdges(nodes, edges); | |
}); | |
} | |
} | |
class Edge { | |
Node from, to; | |
Edge(Node from, Node to) { | |
this.from = from; | |
this.to = to; | |
} | |
} | |
// GraphML Exporter | |
private static PrintWriter output; | |
private void doExport(List<FilesTreeToGraphML.Node> nodes, List<FilesTreeToGraphML.Edge> edges, Path path) { | |
try { | |
output = new PrintWriter(path.toFile()); | |
} catch (FileNotFoundException ignored) {} | |
output.println("<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:y=\"http://www.yworks.com/xml/graphml\" xmlns:yed=\"http://www.yworks.com/xml/yed/3\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd\">"); | |
output.println("\t<key attr.name=\"description\" attr.type=\"string\" for=\"node\" id=\"d5\"/>"); | |
output.println("\t<key for=\"node\" id=\"d6\" yfiles.type=\"nodegraphics\"/>"); | |
output.println("\t<key attr.name=\"description\" attr.type=\"string\" for=\"edge\" id=\"d9\"/>"); | |
output.println("\t<key for=\"edge\" id=\"d10\" yfiles.type=\"edgegraphics\"/>"); | |
output.println("<graph>"); | |
for (FilesTreeToGraphML.Node node : nodes) { | |
writeNode(node.hashCode(), node.name); | |
} | |
for (FilesTreeToGraphML.Edge edge : edges) { | |
writeEdge(edge.hashCode(), edge.from.hashCode(), edge.to.hashCode()); | |
} | |
output.println("</graph>"); | |
output.println("</graphml>"); | |
output.close(); | |
} | |
private void writeNode(int ID, String name) { | |
output.println("<node id=" + '"' + ID + '"' + ">" + | |
"<data key=\"d6\">" + | |
"<y:ShapeNode><y:Fill color=\"#FFCC00\" transparent=\"false\"/>" + | |
"<y:BorderStyle color=\"#FF0000\" type=\"line\" width=\"1.0\"/>" + | |
"<y:NodeLabel textColor=\"#000000\">" + name + "</y:NodeLabel>" + | |
"<y:Shape type=\"ellipse\"/></y:ShapeNode></data></node>"); | |
} | |
private void writeEdge(int ID, int sourceID, int targetID) { | |
output.println("<edge id=" + '"' + ID + '"' + " source=" + '"' + sourceID + '"' + " target=" + '"' + targetID + '"' + ">" + | |
"<data key=\"d9\"><![CDATA[Edge ID: " + ID + "]]></data>" + | |
"<data key=\"d10\"><y:BezierEdge>" + | |
"<y:LineStyle color=\"#000000\" type=\"line\" width=\"1.0\"/>" + | |
"<y:Arrows source=\"none\" target=\"standard\"/>" + | |
"</y:BezierEdge></data></edge>"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example result of a directory structure. The Circular Layout algorithm in yEd was applied: