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)" ]; }