JGraphTのDOTExporterクラスのメモ。
DOTExporterは、JGraphTでGraphvizのdotファイルの内容を生成するクラス。
import org.jgrapht.nio.dot.DOTExporter;
使用する場合は依存ライブラリーにjgrapht-ioを入れる必要がある。
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DirectedAcyclicGraph; import org.jgrapht.nio.dot.DOTExporter;
public class DagExample {
static void example() throws IOException {
var dag = new DirectedAcyclicGraph<String, DefaultEdge>(DefaultEdge.class);
for (int i = 0; i < 5; i++) {
dag.addVertex(Character.toString('a' + i));
}
dag.addEdge("a", "e");
dag.addEdge("b", "e");
dag.addEdge("d", "c");
dag.addEdge("e", "c");
var path = Path.of(System.getProperty("java.io.tmpdir"), "jgrapht.example.dot");
try (var writer = Files.newBufferedWriter(path)) {
var exporter = new DOTExporter<String, DefaultEdge>();
exporter.exportGraph(dag, writer);
}
}
DOTExporterの型引数は、Graphの型引数と同じものを指定する。
↓生成されたファイルの内容
strict digraph G {
1;
2;
3;
4;
5;
1 -> 5;
2 -> 5;
4 -> 3;
5 -> 3;
}
グラフID(デフォルトは「G」)はsetGraphIdProviderメソッドで設定する。
グラフの属性(rankdir等)はsetGraphAttributeProviderメソッドで設定する。
デフォルトでは、頂点(vertex)には数値が割り振られ、それが使われる。setVertexIdProviderメソッドで変更可能。
頂点(vertex)の名前(ラベル)や枠の形状(shape)はsetVertexAttributeProviderメソッドで設定する。
辺(edge)の名前(ラベル)はsetEdgeAttributeProviderメソッドで設定する。
↓それぞれを設定したときの出力例
strict digraph exampleDot {
rankdir=TB;
a [ shape="rectangle" label="a" ];
b [ shape="rectangle" label="b" ];
c [ shape="rectangle" label="c" ];
d [ shape="rectangle" label="d" ];
e [ shape="rectangle" label="e" ];
a -> e [ label="(a : e)" ];
b -> e [ label="(b : e)" ];
d -> c [ label="(d : c)" ];
e -> c [ label="(e : c)" ];
}
グラフIDはsetGraphIdProviderメソッドで設定する。
デフォルトのグラフIDは「G」。
strict digraph G {
〜
exporter.setGraphIdProvider(() -> "exampleDot");
↓生成された内容
strict digraph exampleDot {
〜
グラフ全体の属性はsetGraphAttributeProviderメソッドで設定する。
→GraphvizのGraph Attributes
import java.util.LinkedHashMap; import org.jgrapht.nio.Attribute; import org.jgrapht.nio.DefaultAttribute;
exporter.setGraphAttributeProvider(() -> {
var attribute = new LinkedHashMap<String, Attribute>();
attribute.put("rankdir", DefaultAttribute.createAttribute("TB"));
return attribute;
});
↓生成された内容
strict digraph G {
rankdir=TB;
〜
頂点(vertex)のIDはsetVertexIdProviderメソッドあるいはDOTExporterのコンストラクターで設定する。
デフォルトはIntegerIdProviderが使われる。
これは頂点(vertex)に自動的に番号を振るもの。
exporter.setVertexIdProvider(vertex -> vertex.toString());
setVertexIdProviderの引数の型はFunction<V, String>(すなわちV→String)。
↓生成された内容(例)
strict digraph G {
a;
b;
c;
d;
e;
a -> e;
b -> e;
d -> c;
e -> c;
}
頂点(vertex)の属性はsetVertexAttributeProviderメソッドで設定する。
頂点(vertex)の名前(ラベル)や枠の形状(shape)等が指定できる。
→GraphvizのNode Attributes
import java.util.LinkedHashMap; import org.jgrapht.nio.Attribute; import org.jgrapht.nio.DefaultAttribute;
exporter.setVertexAttributeProvider(vertex -> {
var attribute = new LinkedHashMap<String, Attribute>();
attribute.put("shape", DefaultAttribute.createAttribute("rectangle"));
attribute.put("label", DefaultAttribute.createAttribute(vertex.toString()));
return attribute;
});
↓生成された内容(例)
strict digraph G {
1 [ shape="rectangle" label="a" ];
2 [ shape="rectangle" label="b" ];
3 [ shape="rectangle" label="c" ];
4 [ shape="rectangle" label="d" ];
5 [ shape="rectangle" label="e" ];
〜
なお、Graphvizでは、「node」という名前に属性を付けると全てのノード(頂点)にその属性が適用されるようだが、
JGraphT 1.5.1にはnodeの属性を出力する機能は無いようだ。
辺(edge)の属性はsetEdgeAttributeProviderメソッドで設定する。
→GraphvizのEdge Attributes
import java.util.LinkedHashMap; import org.jgrapht.nio.Attribute; import org.jgrapht.nio.DefaultAttribute;
exporter.setEdgeAttributeProvider(edge -> {
var attribute = new LinkedHashMap<String, Attribute>();
attribute.put("label", DefaultAttribute.createAttribute(edge.toString()));
return attribute;
});
↓生成された内容(例)
〜 1 -> 5 [ label="(a : e)" ]; 2 -> 5 [ label="(b : e)" ]; 4 -> 3 [ label="(d : c)" ]; 5 -> 3 [ label="(e : c)" ]; }