Japanese Only

Step 5: 視覚属性の設定

  1. ノードの色の設定
  2. ノードの形状の設定
  3. エッジの色の設定
  4. エッジの形状の設定
  5. エッジの太さの設定
  6. エッジの線種の設定
目次ページへ

ノードの色の設定

ノードの視覚属性の設定は文字列の表示と同じような方法で行います。BasicVisualizationServer<MyNode,MyEdge>オブジェクトのpanelに対して、各ノードと視覚属性を対応付ける写像を設定します。写像はTransformerオブジェクトのtransform()メソッドによって定義します。

ノードの塗り色の設定 (1) 単色の設定

ノードから塗り色への写像はTransformer<MyNode,Paint>オブジェクトで定義し、その写像をsetVertexFillPaintTransformer()メソッドで設定します。

Sample5a.java

  1: import java.awt.Color;
  2: import java.awt.Dimension;
  3: import java.awt.Paint;
  4: import java.awt.geom.Point2D;
  5: import javax.swing.JFrame;

  6: import org.apache.commons.collections15.Transformer;

  7: import edu.uci.ics.jung.algorithms.layout.Layout;
  8: import edu.uci.ics.jung.algorithms.layout.StaticLayout;
  9: import edu.uci.ics.jung.graph.Graph;
 10: import edu.uci.ics.jung.graph.UndirectedSparseGraph;
 11: import edu.uci.ics.jung.visualization.BasicVisualizationServer;

 12: public class Sample5a {

 13:     public static void main(String[] args) {
 14:         Graph<MyNode,MyEdge> graph = new UndirectedSparseGraph<MyNode,MyEdge>();
 15:         MyNode n1 = new MyNode("n1");
 16:         MyNode n2 = new MyNode("n2");
 17:         MyNode n3 = new MyNode("n3");
 18:         graph.addEdge(new MyEdge("e1"), n1, n2);
 19:         graph.addEdge(new MyEdge("e2"), n2, n3);

 20:         Layout<MyNode,MyEdge> layout = new StaticLayout<MyNode,MyEdge>(graph);
 21:         layout.setLocation(n1, new Point2D.Double(100, 100));
 22:         layout.setLocation(n2, new Point2D.Double(200, 100));
 23:         layout.setLocation(n3, new Point2D.Double(150, 200));

 24:         BasicVisualizationServer<MyNode,MyEdge> panel = 
                 new BasicVisualizationServer<MyNode,MyEdge>(layout, new Dimension(300, 300));

 25:         Transformer<MyNode,Paint> nodeFillColor = new Transformer<MyNode,Paint>() {
 26:             @Override
 27:             public Paint transform(MyNode n) {
 28:                 return Color.BLUE;
 29:             }
 30:         };
 31:         panel.getRenderContext().setVertexFillPaintTransformer(nodeFillColor);

 32:         JFrame frame = new JFrame("Graph View: Blue Nodes");
 33:         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 34:         frame.getContentPane().add(panel);
 35:         frame.pack();
 36:         frame.setVisible(true);
 37:     }

 38: }

ノードから色への写像は、25行目から30行目で、Transformer<MyNode,Paint>オブジェクトのtransform()メソッドによって定義しています。ここでは28行目で、Color.BLUE(青色)を指定しています。定義した写像nodeFillColorを、31行目で、BasicVisualizationServer<MyNode,MyEdge>オブジェクトのpanelに対して、setVertexFillPaintTransformer()メソッドで設定しています。

上のプログラムを実行するとするとノードが下のように描かれます。

Execution result of Sample5a.java

ノードの塗り色の設定 (2) ノード毎の色の設定

Transformer<MyNode,Paint>オブジェクトのtransform()メソッドはMyNodeを引数として取るので、ノード毎に色を変えることもできます。

Sample5a2.java

 25:         Transformer<MyNode,Paint> nodeFillColor = new Transformer<MyNode,Paint>() {
 26:             @Override
 27:             public Paint transform(MyNode n) {
 28:                 int id = Integer.parseInt(n.label.substring(1));
 29:                 return new Color(Color.HSBtoRGB(id / 3f, 0.7f, 1.0f));
 30:             }
 31:         };

28行目でノードに指定された文字列から整数(「n1」の場合には1)を取り出しています。29行目では、取り出した整数を(ここではノード数が3なので)3で割ってHue(色相)のパラメータとし、色空間HSBからRGBに変更して、ノードnの色としています。28行目と29行目は、若干面倒なことをしていますが、その方法自体は重要ではありません(分らなければ無理して理解する必要はありません)。重要なことはノードnに対して適当なColorオブジェクトを返すようにtransform()メソッドを適切に定義することです。

上のように改造したプログラムを実行するとするとノードが下のように描かれます。

Execution result of Sample5a2.java

ノードの輪郭線色の設定

ノード内部を塗り潰す色だけでなく、輪郭線の色を指定することもできます。輪郭線の色はsetVertexDrawPaintTransformer()メソッドで設定します。次の例では境界線を緑にしています。

Sample5a3.java

 25:         Transformer<MyNode,Paint> nodeDrawColor = new Transformer<MyNode,Paint>() {
 26:             @Override
 27:             public Paint transform(MyNode n) {
 28:                 return Color.GREEN;
 29:             }
 30:         };
 31:         panel.getRenderContext().setVertexDrawPaintTransformer(nodeDrawColor);

Transformer<MyNode,Paint>クラスの定義は塗り潰し色の指定と同様です。ここではtransform()メソッドは単にColor.GREENを返しています。こうして定義したnodeDrawColorをsetVertexDrawPaintTransformer()メソッドで指定します。

上のように改造したプログラムを実行するとすると下のようにノードが描かれます。画面では分り難いかも知れませんが、ノードの輪郭線が緑になっています。

Execution result of Sample5a3.java

ノードの塗り色の設定 (3) グラデーションの設定

少し違う方法を使うと、ノードの塗り色にグラデーションを指定することもできます。

Sample5a4.java

 24:         panel.getRenderer().setVertexRenderer(
                 new GradientVertexRenderer<MyNode,MyEdge>(
                     Color.YELLOW, Color.BLUE, false));

上のように設定すると下のようなノードが描かれます。

Execution result of Sample5a4.java

ノードの形状の設定

形状の設定も色と同様の方法で行います。ノードから形状への写像はTransformer<MyNode,Shape>オブジェクトで定義し、その写像をsetVertexShapeTransformer()メソッドで設定します。

Sample5b.java

 25:         Transformer<MyNode,Shape> nodeShapeTransformer = new Transformer<MyNode,Shape>() {
 26:             @Override
 27:             public Shape transform(MyNode n) {
 28:                 return new Rectangle(-15, -10, 30, 20);
 29:             }
 30:         }; 
 31:         panel.getRenderContext().setVertexShapeTransformer(nodeShapeTransformer);

ノードの形状の定義は、25行目から30行目で、Transformer<MyNode,Shape>オブジェクトのtransform()メソッドによって定義しています。エッジは原点をつなぐように描かれるので、原点が中心になるようにノードの座標を指定すると良いでしょう。ここでは、(-15, -10)を左上の点とする横30、縦20の長方形(Rectangle)を指定しています。31行目でノードの形状の定義nodeShapeTransformerを指定しています。

上のプログラムを実行するとすると下のようなウィンドウが現われます。

Execution result of Sample5b.java

エッジの色の設定

エッジの色の設定もノードと同様の方法で行います。エッジから色への写像はTransformer<MyEdge,Color>オブジェクトで定義し、その写像をsetEdgeDrawPaintTransformer()メソッドで設定します。

Sample5c.java

 25:         Transformer<MyEdge, Paint> edgeColor = new Transformer<MyEdge, Paint>() {
 26:             @Override
 27:             public Paint transform(MyEdge e) {
 28:                 return Color.BLUE;
 29:             }
 30:         };
 31:         panel.getRenderContext().setEdgeDrawPaintTransformer(edgeColor);

上のように設定すると下のようにエッジが描かれます。

Execution result of Sample5c.java

エッジの形状の設定

エッジの形状の設定はsetEdgeShapeTransformer()メソッドで行います。たとえば、エッジを直線分(Line)で表すには下のようにします。

Sample5d.java

 23:         panel.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<MyNode,MyEdge>());

上のように設定すると下のようにエッジが描かれます。

Execution result of Sample5d.java

その他の形状

直線分以外にも、以下のような形状が用意されています。

エッジの太さの設定

エッジの太さの設定は、エッジに対してStrokeオブジェクトを指定することで行います。エッジからStrokeへの写像はTransformer<MyEdge,Stroke>オブジェクトで定義し、その写像をsetEdgeStrokeTransformer()メソッドで設定します。

Sample5e.java

 25:         final Stroke edgeStroke = new BasicStroke(10.0f);        
 26:         Transformer<MyEdge, Stroke> edgeStrokeTransformer = new Transformer<MyEdge, Stroke>() {
 27:             @Override
 28:             public Stroke transform(MyEdge e) {
 29:                 return edgeStroke;
 30:             }
 31:         };        
 32:         panel.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);

上のように設定すると下のようにエッジが描かれます。

Execution result of Sample5e.java

エッジの線種の設定

エッジに対応するStrokeを変更することで、太さだけでなく線種も設定できます。

Sample5e2.java

 25:         float dash[] = {5f};
 26:         final Stroke edgeStroke = 
                 new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);        
 27:         Transformer<MyEdge, Stroke> edgeStrokeTransformer = new Transformer<MyEdge, Stroke>() {
 28:             @Override
 29:             public Stroke transform(MyEdge e) {
 30:                 return edgeStroke;
 31:             }
 32:         };        
 33:         panel.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);

上のように設定すると下のようにエッジが描かれます。

Execution result of Sample5e2.java

配列dash[]の値によって破線のパターンを変更できます。たとえばdash[] = {10f, 3f, 3f, 3f};とすると一点鎖線を描くことができます。その他、下のようなパターンも試してみて下さい。

目次ページへ