string userName
string userName

Reputation: 21

Increase/Set vertex label in JUNG graph visualization

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

Answers (1)

user9295106
user9295106

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

Related Questions