View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors
3    * All rights reserved.
4    *
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    *
8    * Created on Aug 23, 2005
9    */
10  package edu.uci.ics.jung.visualization.renderers;
11  
12  import java.awt.Component;
13  import java.awt.Dimension;
14  import java.awt.Shape;
15  import java.awt.geom.AffineTransform;
16  import java.awt.geom.Ellipse2D;
17  import java.awt.geom.Point2D;
18  
19  import edu.uci.ics.jung.algorithms.layout.Layout;
20  import edu.uci.ics.jung.graph.Graph;
21  import edu.uci.ics.jung.graph.util.Context;
22  import edu.uci.ics.jung.graph.util.Pair;
23  import edu.uci.ics.jung.visualization.Layer;
24  import edu.uci.ics.jung.visualization.RenderContext;
25  import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;
26  
27  public class BasicEdgeLabelRenderer<V,E> implements Renderer.EdgeLabel<V,E> {
28  	
29  	public Component prepareRenderer(RenderContext<V,E> rc, EdgeLabelRenderer graphLabelRenderer, Object value, 
30  			boolean isSelected, E edge) {
31  		return rc.getEdgeLabelRenderer().<E>getEdgeLabelRendererComponent(rc.getScreenDevice(), value, 
32  				rc.getEdgeFontTransformer().apply(edge), isSelected, edge);
33  	}
34      
35      public void labelEdge(RenderContext<V,E> rc, Layout<V,E> layout, E e, String label) {
36      	if(label == null || label.length() == 0) return;
37      	
38      	Graph<V,E> graph = layout.getGraph();
39          // don't draw edge if either incident vertex is not drawn
40          Pair<V> endpoints = graph.getEndpoints(e);
41          V v1 = endpoints.getFirst();
42          V v2 = endpoints.getSecond();
43          if (!rc.getEdgeIncludePredicate().apply(Context.<Graph<V,E>,E>getInstance(graph,e)))
44              return;
45  
46          if (!rc.getVertexIncludePredicate().apply(Context.<Graph<V,E>,V>getInstance(graph,v1)) || 
47              !rc.getVertexIncludePredicate().apply(Context.<Graph<V,E>,V>getInstance(graph,v2)))
48              return;
49  
50          Point2D p1 = layout.apply(v1);
51          Point2D p2 = layout.apply(v2);
52          p1 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p1);
53          p2 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p2);
54          float x1 = (float) p1.getX();
55          float y1 = (float) p1.getY();
56          float x2 = (float) p2.getX();
57          float y2 = (float) p2.getY();
58  
59          GraphicsDecorator g = rc.getGraphicsContext();
60          float distX = x2 - x1;
61          float distY = y2 - y1;
62          double totalLength = Math.sqrt(distX * distX + distY * distY);
63  
64          double closeness = rc.getEdgeLabelClosenessTransformer().apply(Context.<Graph<V,E>,E>getInstance(graph, e)).doubleValue();
65  
66          int posX = (int) (x1 + (closeness) * distX);
67          int posY = (int) (y1 + (closeness) * distY);
68  
69          int xDisplacement = (int) (rc.getLabelOffset() * (distY / totalLength));
70          int yDisplacement = (int) (rc.getLabelOffset() * (-distX / totalLength));
71          
72          Component component = prepareRenderer(rc, rc.getEdgeLabelRenderer(), label, 
73                  rc.getPickedEdgeState().isPicked(e), e);
74          
75          Dimension d = component.getPreferredSize();
76  
77          Shape edgeShape = rc.getEdgeShapeTransformer().apply(e);
78          
79          double parallelOffset = 1;
80  
81          parallelOffset += rc.getParallelEdgeIndexFunction().getIndex(graph, e);
82  
83          parallelOffset *= d.height;
84          if(edgeShape instanceof Ellipse2D) {
85              parallelOffset += edgeShape.getBounds().getHeight();
86              parallelOffset = -parallelOffset;
87          }
88          
89          
90          AffineTransform old = g.getTransform();
91          AffineTransform xform = new AffineTransform(old);
92          xform.translate(posX+xDisplacement, posY+yDisplacement);
93          double dx = x2 - x1;
94          double dy = y2 - y1;
95          if(rc.getEdgeLabelRenderer().isRotateEdgeLabels()) {
96              double theta = Math.atan2(dy, dx);
97              if(dx < 0) {
98                  theta += Math.PI;
99              }
100             xform.rotate(theta);
101         }
102         if(dx < 0) {
103             parallelOffset = -parallelOffset;
104         }
105         
106         xform.translate(-d.width/2, -(d.height/2-parallelOffset));
107         g.setTransform(xform);
108         g.draw(component, rc.getRendererPane(), 0, 0, d.width, d.height, true);
109 
110         g.setTransform(old);
111     }
112 
113 }