|
| 1 | +package toylangs; |
| 2 | + |
| 3 | +import guru.nidi.graphviz.attribute.Label; |
| 4 | +import guru.nidi.graphviz.engine.Format; |
| 5 | +import guru.nidi.graphviz.engine.Graphviz; |
| 6 | +import guru.nidi.graphviz.model.Graph; |
| 7 | +import guru.nidi.graphviz.model.Node; |
| 8 | + |
| 9 | +import java.io.IOException; |
| 10 | +import java.nio.file.Path; |
| 11 | +import java.util.Arrays; |
| 12 | +import java.util.Collection; |
| 13 | +import java.util.Objects; |
| 14 | +import java.util.stream.Stream; |
| 15 | + |
| 16 | +import static guru.nidi.graphviz.model.Factory.graph; |
| 17 | +import static guru.nidi.graphviz.model.Factory.node; |
| 18 | + |
| 19 | +public class AbstractNodeVisualizer { |
| 20 | + |
| 21 | + private int nextNodeId = 0; |
| 22 | + |
| 23 | + private Node makeNode(String label) { |
| 24 | + return node(Integer.toString(nextNodeId++)).with(Label.of(label)); |
| 25 | + } |
| 26 | + |
| 27 | + private Node visit(Object object) { |
| 28 | + return switch (object) { |
| 29 | + case AbstractNode node -> visit(node); |
| 30 | + default -> makeNode(Objects.toString(object)); |
| 31 | + }; |
| 32 | + } |
| 33 | + |
| 34 | + private Node visit(AbstractNode node) { |
| 35 | + return makeNode(node.getNodeLabel()).link( |
| 36 | + node.getChildren().stream() |
| 37 | + .flatMap(AbstractNodeVisualizer::flattenChild) |
| 38 | + .filter(Objects::nonNull) |
| 39 | + .map(this::visit) |
| 40 | + .toList() |
| 41 | + ); |
| 42 | + } |
| 43 | + |
| 44 | + private static Stream<?> flattenChild(Object child) { |
| 45 | + if (child instanceof Collection<?> collection) |
| 46 | + return collection.stream(); |
| 47 | + else if (child != null && child.getClass().isArray()) |
| 48 | + return Arrays.stream((Object[]) child); |
| 49 | + else |
| 50 | + return Stream.of(child); |
| 51 | + } |
| 52 | + |
| 53 | + public static void renderPngFile(AbstractNode node, Path path) throws IOException { |
| 54 | + Node rootNode = new AbstractNodeVisualizer().visit(node); |
| 55 | + Graph graph = graph("tree").directed().with(rootNode).graphAttr().with("ordering", "out"); |
| 56 | + //System.out.println(Graphviz.fromGraph(graph).render(Format.DOT)); |
| 57 | + Graphviz.fromGraph(graph).scale(3).render(Format.PNG).toFile(path.toFile().getCanonicalFile()); |
| 58 | + } |
| 59 | +} |
0 commit comments