Reputation: 21
Looking for a way to increase the size of the vertexLabel using JUNG Graph Visualization. The vertex's themselves are larger than the text label within them and I would like to balance them for a more aesthetically pleasing visual without having to decrease the size of the vertex itself. Below is some code I've been fooling around with:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.DefaultVertexLabelRenderer;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
public class GraphViewer extends JFrame {
private static final long serialVersionUID = 1L;
public GraphViewer(CustomObject user) {
final Graph<CustomObject, String> graph = new DirectedSparseMultigraph<>();
graph.addVertex(user);
for (CustomObject friend: user.getFriends()) {
graph.addVertex(friend);
graph.addEdge(user.toString() + "-" + friend.toString(), user, friend);
}
Layout<CustomObject, String> layout = new ISOMLayout<>(graph);
layout.setSize(new Dimension(1000, 800));
BasicVisualizationServer<CustomObject,String> vv = new BasicVisualizationServer<>(layout);
vv.setPreferredSize(new Dimension(1100,900));
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<CustomObject>());
vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
final Color vertexLabelColor = Color.WHITE;
DefaultVertexLabelRenderer vertexLabelRenderer = new DefaultVertexLabelRenderer(vertexLabelColor) {
@Override
public <V> Component getVertexLabelRendererComponent(
JComponent vv, Object value, Font font,
boolean isSelected, V vertex)
{
super.getVertexLabelRendererComponent(vv, value, font, isSelected, vertex);
setForeground(vertexLabelColor);
return this;
}
};
Transformer<CustomObject,Paint> vertexColor = new Transformer<CustomObject,Paint>() {
public Color transform(CustomObject u) {
// First user colored red
// Any user other than first colored blue
if(u.getUsername().equals(user.getUsername()))
return Color.RED;
return Color.BLUE;
}
};
Transformer<CustomObject,Shape> vertexSize = new Transformer<CustomObject,Shape>(){
public Shape transform(CustomObject u) {
Graphics graphics = getGraphics();
FontMetrics metrics = graphics.getFontMetrics();
// Ellipse size is calculated by multiplying the username by a value
int radius = (int) (metrics.stringWidth(u.toString()) * 4.5);
return new Ellipse2D.Double(-15, -15, radius, radius);
}
};
vv.getRenderContext().setVertexLabelRenderer(vertexLabelRenderer);
vv.getRenderContext().setVertexFillPaintTransformer(vertexColor);
vv.getRenderContext().setVertexShapeTransformer(vertexSize);
setTitle(user.toString() + "'s Graph");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
getContentPane().add(vv);
pack();
setVisible(true);
}
}
Here is an Example Graph of the current output. I would like the font to fill the vertex's a bit more or even be able to manipulate the properties of them (Bold, Italic, etc..)
Also, If you know how to increase the weight of the edge lines I would appreciate any info on that as well.
Thanks for looking. Any feedback is appreciated. Sorry its a mess, its a work in progress and far from finished (obviously).
Upvotes: 1
Views: 351
Reputation:
You can set the VertexFontTransformer (for example):
vv.getRenderContext().setVertexFontTransformer(new Transformer<CustomObject, Font>(){
@Override
public Font transform(CustomObject customObject) {
return new Font("Helvetica", Font.BOLD, 30);
}
});
You may want to experiment with your vertexShapeTransformer since you are using the size of the label (affected by the font size) to determine the size of the vertices.
To increase the weight of the edge lines, do something like this:
vv.getRenderContext().setEdgeStrokeTransformer(new Transformer<String,Stroke>(){
@Override
public Stroke transform(String s) {
return new BasicStroke(5);
}
});
vv.getRenderContext().setEdgeArrowStrokeTransformer(new Transformer<String,Stroke>(){
@Override
public Stroke transform(String s) {
return new BasicStroke(5);
}
});
And finally, to place your vertices in better position relative to the edges, you may want to do this:
return new Ellipse2D.Double(-radius/2, -radius/2, radius, radius);
instead of this:
return new Ellipse2D.Double(-15, -15, radius, radius);
(centering the vertices at the origin before they are transformed to their desired position)
Upvotes: 2