寻找一种使用JUNG Graph Visualization来增加vertexLabel大小的方法。顶点本身大于其中的文本标签,我想在不减小顶点本身大小的情况下平衡它们,从而获得更美观的视觉效果。下面是我一直在鬼混的一些代码:
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);
}
}
这是当前输出的Example Graph。我希望字体可以多填充一点,甚至可以操纵它们的属性(粗体,斜体等)。
此外,如果您知道如何增加边缘线的权重,我也将不胜感激。
感谢您的光临。任何反馈表示赞赏。很抱歉,这是一团糟,尚在进行中,远远没有完成(显然)。
答案 0 :(得分:1)
您可以设置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);
(在将顶点转换到所需位置之前将顶点居中放置)