私はしばらくの間JUNG2に取り組んでおり、一連のオブジェクトの非常に複雑な階層を視覚化しようとしています。残念ながら、この階層は、次の意味で実際にはツリーのようではありません。
- 一部のノードには複数の親があります。さらに、これらの親は木の異なる枝にいる可能性があります。
- 一部のノードには重複がある可能性があります(これは許可する必要があります。無視することはできません)
現在、私はSparseGraph
;を使用しています。すべてのノードをグラフに配置し、有向とのサブ/スーパー関係を描画し、ノード間の無向エッジとして複製します。次に、MinimumSpanningTreeDemoソースコードに従って、MinimumSpanningTreeForest2
オブジェクトを作成し、をに送信しForest
ますTreeLayout
。簡単に言えば、レイアウトはわかりますが、幅は約15000ピクセルです。私はこれらのグラフをインタラクティブな方法ではなく静止画像として使用しているため、これをレポートで使用することは不可能です。
並んでいるノードが多すぎると、ノードラベルにかなりのスペースが必要になることに気づいたので、代わりにラベルを回転させて垂直にすることができると考えました。これは惨めに失敗しました。拡張するカスタムクラスを使用してラベルを回転させることができますがDefaultVertexLabelRenderer
、rotationを設定するとMath.PI/2
、ラベルが表示されなくなります。だからここに私の質問があります:
- レイアウトを強制的にスリム化することは可能ですか?JUNG2を使えば可能だと言われている樹状図のようなものを作りたいと思います。これは本当に可能ですか?その場合どうやって?
- ノードラベルを垂直にレンダリングできるはずだという私の考えに誤りはありますか?クラスのアンカーポイントを変えようとしました
VertexLabelAsShapeRenderer
が、それでも喜びはありませんでした。問題と言えば;Renderer
sRendererContext
と実際にレンダリングされたオブジェクトの間の接続は本当にあいまいです。クラスはたくさんあり、実際にレンダリングに使用されているクラスを見つけるのに苦労しています。たとえばBasicVertexLabelRenderer
、デフォルトではまったく使用されていないようです。したがって、ラベルの全体的な配置は神秘的です...
JUNGの開発者がライブラリに何時間ものハードワークを費やしていることは知っています。苦い、または不幸に聞こえるのは嫌ですが、このチュートリアルと、デモの作成方法やレンダリングの仕組みを理解することには、長いギャップがあると思います。
とにかく; グラフが作成されるコードの一部は次のとおりです。
public void visualizeGraph(File saveFolder){
MinimumSpanningForest2<PHGNode, PHGEdge> prim = new MinimumSpanningForest2<PHGNode, PHGEdge>(
g, new DelegateForest<PHGNode, PHGEdge>(), DelegateTree.<PHGNode, PHGEdge>getFactory(),
new ConstantTransformer(1.0));
Forest<PHGNode, PHGEdge> tree = prim.getForest();
Layout<PHGNode, PHGEdge> layout = new TreeLayout<PHGNode, PHGEdge>(tree);
// custom visualization viewer that allows writing to disk
final WritingVisualizationViewer<PHGNode, PHGEdge> vv = new WritingVisualizationViewer<PHGNode, PHGEdge>(layout,layout.getSize());
// this class extends VertexLabelAsShapeRenderer and supplies means of fiddling with label coordinates
VerticalVertexLabelAsShapeRenderer<PHGNode,PHGEdge> vlasr =
new VerticalVertexLabelAsShapeRenderer<PHGNode,PHGEdge>(vv.getRenderContext());
vv.getRenderContext().setVertexLabelTransformer(
new ChainedTransformer<PHGNode,String>(new Transformer[]{
new ToStringLabeller<PHGEdge>(),new Transformer<String,String>() {
public String transform(String input) { return input; }}}));
// Change the background of node labels so that they appear transparent
Transformer<PHGNode,Paint> vertexPaint = new Transformer<PHGNode,Paint>() {
public Paint transform(PHGNode n) { return vv.getBackground(); }
};
// extends DefaultVertexLabelRendeder to provide rotation of labels
VerticalVertexLabelRenderer vvlr = new VerticalVertexLabelRenderer();
vv.getRenderContext().setVertexLabelRenderer(vvlr);
vv.getRenderContext().setVertexFontTransformer(new VertexFontTransformer<PathwayHierarchyGraph.PHGNode>());
vv.getRenderContext().setVertexShapeTransformer(vlasr);
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.BentLine<PHGNode, PHGEdge>());
vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
//printGraphStats(tree);
vv.writeToDisk(saveFolder,"hierarchyTree.png");
}