Увеличить / Установить метку вершины в визуализации графика JUNG - PullRequest
0 голосов
/ 25 ноября 2018

Ищите способ увеличить размер vertexLabel с помощью визуализации JUNG Graph .Сами вершины больше, чем текстовая метка внутри них, и я хотел бы уравновесить их для более эстетичного изображения без необходимости уменьшать размер самой вершины.Ниже приведен код, с которым я дурачился:

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);
    }

}

Вот пример Примерного графика текущего выхода.Я бы хотел, чтобы шрифт немного больше заполнял вершины или даже мог манипулировать их свойствами (полужирный, курсив и т. Д.)

Также, если вы знаете, как увеличить вес Буду признателен за любую информацию по этому вопросу.

Спасибо за внимание.Любые отзывы приветствуются.Извините, это беспорядок, это незавершенная работа, и она далеко не закончена (очевидно).

1 Ответ

0 голосов
/ 25 ноября 2018

Вы можете установить VertexFontTransformer (например):

    vv.getRenderContext().setVertexFontTransformer(new Transformer<CustomObject, Font>(){
        @Override
        public Font transform(CustomObject customObject) {
            return new Font("Helvetica", Font.BOLD, 30);

        }
    });

Вы можете поэкспериментировать с вашим vertexShapeTransformer, поскольку вы используете размер метки (зависит от размера шрифта), чтобы определить размервершин.

Чтобы увеличить вес линий ребер, сделайте что-то вроде этого:

    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);
        }
    });

И, наконец, чтобы расположить ваши вершины в лучшем положении относительно ребер, вы можетехочу сделать это:

return new Ellipse2D.Double(-radius/2, -radius/2, radius, radius);

вместо этого:

return new Ellipse2D.Double(-15, -15, radius, radius);

(центрирование вершин в начале координат, прежде чем они будут преобразованы в желаемое положение)

...