Japanese Only

Step 5: 視覚属性の設定

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

ノードの色の設定

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

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

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

Sample5a.scala

  1: import swing._
  2: import java.util._
  3: import java.awt.{Color,Dimension,Paint}
  4: import java.awt.geom.Point2D

  5: import org.apache.commons.collections15.Transformer
  6: import edu.uci.ics.jung.algorithms.layout.{Layout,StaticLayout}
  7: import edu.uci.ics.jung.graph.{Graph,UndirectedSparseGraph}
  8: import edu.uci.ics.jung.visualization.BasicVisualizationServer

  9: object Sample5a extends SimpleSwingApplication {
 10:     def top = new MainFrame {
 11:         title = "Graph View: Blue Nodes"
 12:         val (graph, layout) = createGraph
 13:         val panel = new BasicVisualizationServer[MyNode,MyEdge](layout, new Dimension(300, 300))

 14:         val nodeFillColor = new Transformer[MyNode,Paint] {
 15:             override def transform(n: MyNode): Paint = Color.BLUE
 16:         }
 17:         panel.getRenderContext.setVertexFillPaintTransformer(nodeFillColor)

 18:         contents = Component.wrap(panel)
 19:     }

 20:     def createGraph: Tuple2[Graph[MyNode,MyEdge],Layout[MyNode,MyEdge]] = {
 21:         val graph: Graph[MyNode,MyEdge] = new UndirectedSparseGraph[MyNode,MyEdge]()
 22:         val n1 = new MyNode("n1")
 23:         val n2 = new MyNode("n2")
 24:         val n3 = new MyNode("n3")
 25:         graph.addVertex(n1)
 26:         graph.addVertex(n2)
 27:         graph.addVertex(n3)
 28:         graph.addEdge(new MyEdge("e1"), n1, n2)
 29:         graph.addEdge(new MyEdge("e2"), n2, n3)

 30:         val layout: Layout[MyNode,MyEdge] = new StaticLayout[MyNode,MyEdge](graph)
 31:         layout.setLocation(n1, new Point2D.Double(100, 100))
 32:         layout.setLocation(n2, new Point2D.Double(200, 100))
 33:         layout.setLocation(n3, new Point2D.Double(150, 200))

 34:         (graph, layout)
 35:     }
 36: }

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

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

Execution result of Sample5a.scala

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

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

Sample5a2.scala

 14:         val nodeFillColor = new Transformer[MyNode,Paint] {
 15:             override def transform(n: MyNode): Paint = {
 16:                 val id: Int = n.label.substring(1).toInt
 17:                 new Color(Color.HSBtoRGB(id / 3f, 0.7f, 1.0f))
 18:                 }
 19:         }

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

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

Execution result of Sample5a2.scala

ノードの輪郭線色の設定

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

Sample5a3.scala

 14:         val nodeDrawColor = new Transformer[MyNode,Paint] {
 15:             override def transform(n: MyNode): Paint = Color.GREEN
 16:         }
 17:         panel.getRenderContext.setVertexDrawPaintTransformer(nodeDrawColor)

Transformer[MyNode,Paint]型のオブジェクトの定義は塗り潰し色の指定と同様です。ここではtransform()メソッドは単にColor.GREENを返しています。こうして定義したnodeDrawColorをsetVertexDrawPaintTransformer()メソッドで指定します。

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

Execution result of Sample5a3.scala

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

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

Sample5a4.scala

 14:         panel.getRenderer.setVertexRenderer(
                 new GradientVertexRenderer[MyNode,MyEdge](
                     Color.YELLOW, Color.BLUE, false))

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

Execution result of Sample5a4.scala

ノードの形状の設定

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

Sample5b.scala

 14:         val nodeShapeTransformer = new Transformer[MyNode,Shape] {
 15:             override def transform(n: MyNode): Shape = new Rectangle(-15, -10, 30, 20)
 16:         };
 17:         panel.getRenderContext.setVertexShapeTransformer(nodeShapeTransformer)

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

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

Execution result of Sample5b.scala

エッジの色の設定

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

Sample5c.scala

 14:         val edgeColor = new Transformer[MyEdge,Paint] {
 15:             override def transform(e: MyEdge): Paint = Color.BLUE
 16:         }
 17:         panel.getRenderContext.setEdgeDrawPaintTransformer(edgeColor)

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

Execution result of Sample5c.scala

エッジの形状の設定

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

Sample5d.scala

 14:         panel.getRenderContext.setEdgeShapeTransformer(new EdgeShape.Line[MyNode,MyEdge])

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

Execution result of Sample5d.scala

その他の形状

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

エッジの太さの設定

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

Sample5e.scala

 14:         val edgeStroke: Stroke = new BasicStroke(10.0f)
 15:         val edgeStrokeTransformer = new Transformer[MyEdge,Stroke] {
 16:             override def transform(e: MyEdge): Stroke = edgeStroke
 17:         }
 18:         panel.getRenderContext.setEdgeStrokeTransformer(edgeStrokeTransformer)

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

Execution result of Sample5e.scala

エッジの線種の設定

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

Sample5e2.scala

 14:         val dash = Array(5f)
 15:         val edgeStroke: Stroke = 
                new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f)
 16:         val edgeStrokeTransformer = new Transformer[MyEdge,Stroke] {
 17:             override def transform(e: MyEdge): Stroke = edgeStroke
 18:         }
 19:         panel.getRenderContext.setEdgeStrokeTransformer(edgeStrokeTransformer)

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

Execution result of Sample5e2.scala

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

目次ページへ