Skip to content

Instantly share code, notes, and snippets.

@benjaminaaron
Created June 6, 2018 21:20
Show Gist options
  • Save benjaminaaron/3bbe300838c93717a1cc88ecad99c23a to your computer and use it in GitHub Desktop.
Save benjaminaaron/3bbe300838c93717a1cc88ecad99c23a to your computer and use it in GitHub Desktop.
convert find-output to GraphML to visualize directory structures in yEd
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>");
}
}
@benjaminaaron
Copy link
Author

Example result of a directory structure. The Circular Layout algorithm in yEd was applied:

screen shot 2018-06-06 at 23 22 31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment