aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java160
1 files changed, 160 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java
new file mode 100644
index 00000000..f7f6b5ed
--- /dev/null
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/DotGenerator.java
@@ -0,0 +1,160 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2019, Tamas Szabo, Istvan Rath and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.viatra.runtime.rete.itc.graphimpl;
10
11import tools.refinery.viatra.runtime.rete.itc.alg.misc.scc.SCC;
12import tools.refinery.viatra.runtime.rete.itc.alg.misc.scc.SCCResult;
13import tools.refinery.viatra.runtime.matchers.util.IMemoryView;
14
15import java.util.HashMap;
16import java.util.Map;
17import java.util.Set;
18import java.util.function.Function;
19
20/**
21 * This class contains utility methods to generate dot representations for {@link Graph} instances.
22 *
23 * @author Tamas Szabo
24 * @since 2.3
25 */
26public class DotGenerator {
27
28 private static final String[] colors = new String[] { "yellow", "blue", "red", "green", "gray", "cyan" };
29
30 private DotGenerator() {
31
32 }
33
34 /**
35 * Generates the dot representation for the given graph.
36 *
37 * @param graph
38 * the graph
39 * @param colorSCCs
40 * specifies if the strongly connected components with size greater than shall be colored
41 * @param nameFunction
42 * use this function to provide custom names to nodes, null if the default toString shall be used
43 * @param colorFunction
44 * use this function to provide custom color to nodes, null if the default white color shall be used
45 * @param edgeFunction
46 * use this function to provide custom edge labels, null if no edge label shall be printed
47 * @return the dot representation as a string
48 */
49 public static <V> String generateDot(final Graph<V> graph, final boolean colorSCCs,
50 final Function<V, String> nameFunction, final Function<V, String> colorFunction,
51 final Function<V, Function<V, String>> edgeFunction) {
52 final Map<V, String> colorMap = new HashMap<V, String>();
53
54 if (colorSCCs) {
55 final SCCResult<V> result = SCC.computeSCC(graph);
56 final Set<Set<V>> sccs = result.getSccs();
57
58 int i = 0;
59 for (final Set<V> scc : sccs) {
60 if (scc.size() > 1) {
61 for (final V node : scc) {
62 final String color = colorMap.get(node);
63 if (color == null) {
64 colorMap.put(node, colors[i % colors.length]);
65 } else {
66 colorMap.put(node, colorMap.get(node) + ":" + colors[i % colors.length]);
67 }
68 }
69 i++;
70 }
71 }
72
73 // if a node has no color yet, then make it white
74 for (final V node : graph.getAllNodes()) {
75 if (!colorMap.containsKey(node)) {
76 colorMap.put(node, "white");
77 }
78 }
79 } else {
80 for (final V node : graph.getAllNodes()) {
81 colorMap.put(node, "white");
82 }
83 }
84
85 if (colorFunction != null) {
86 for (final V node : graph.getAllNodes()) {
87 colorMap.put(node, colorFunction.apply(node));
88 }
89 }
90
91 final StringBuilder builder = new StringBuilder();
92 builder.append("digraph g {\n");
93
94 for (final V node : graph.getAllNodes()) {
95 final String nodePresentation = nameFunction == null ? node.toString() : nameFunction.apply(node);
96 builder.append("\"" + nodePresentation + "\"");
97 builder.append("[style=filled,fillcolor=" + colorMap.get(node) + "]");
98 builder.append(";\n");
99 }
100
101 for (final V source : graph.getAllNodes()) {
102 final IMemoryView<V> targets = graph.getTargetNodes(source);
103 if (!targets.isEmpty()) {
104 final String sourcePresentation = nameFunction == null ? source.toString() : nameFunction.apply(source);
105 for (final V target : targets.distinctValues()) {
106 String edgeLabel = null;
107 if (edgeFunction != null) {
108 final Function<V, String> v1 = edgeFunction.apply(source);
109 if (v1 != null) {
110 edgeLabel = v1.apply(target);
111 }
112 }
113
114 final String targetPresentation = nameFunction == null ? target.toString()
115 : nameFunction.apply(target);
116
117 builder.append("\"" + sourcePresentation + "\" -> \"" + targetPresentation + "\"");
118 if (edgeLabel != null) {
119 builder.append("[label=\"" + edgeLabel + "\"]");
120 }
121 builder.append(";\n");
122 }
123 }
124 }
125
126 builder.append("}");
127 return builder.toString();
128 }
129
130 /**
131 * Generates the dot representation for the given graph. No special pretty printing customization will be applied.
132 *
133 * @param graph
134 * the graph
135 * @return the dot representation as a string
136 */
137 public static <V> String generateDot(final Graph<V> graph) {
138 return generateDot(graph, false, null, null, null);
139 }
140
141 /**
142 * Returns a simple name shortener function that can be used in the graphviz visualization to help with readability.
143 * WARNING: if you shorten the name of the {@link Node}s too much, the visualization may become incorrect because
144 * grahpviz will treat different nodes as the same if their shortened names are the same.
145 *
146 * @param maxLength
147 * the maximum length of the text that is kept from the toString of the objects in the graph
148 * @return the shrunk toString value
149 */
150 public static <V> Function<V, String> getNameShortener(final int maxLength) {
151 return new Function<V, String>() {
152 @Override
153 public String apply(final V obj) {
154 final String value = obj.toString();
155 return value.substring(0, Math.min(value.length(), maxLength));
156 }
157 };
158 }
159
160}