我要在层次结构中显示类似树级别的图形,因此我使用Jung中包含的TreeLayout,但我不知道是否可以使用此布局在两者之间添加多个边缘节点。如果不可能,你怎么建议我这样做?
谢谢!
public class Visualizacion extends JApplet {
/**
* the graph
*/
Graph<String,String> graph;
Forest<String,String> tree;
Funciones f=new Funciones();
/**
* the visual component and renderer for the graph
*/
VisualizationViewer<String,String> vv;
String root;
Layout<String,String> layout;
Layout<String,String> layout2; ;
public Visualizacion(org.graphstream.graph.Graph grafito) {
graph= new DirectedSparseMultigraph<String, String>();
createTree(grafito);
MinimumSpanningForest2<String,String> prim =
new MinimumSpanningForest2<String,String>(graph,
new DelegateForest<String,String>(), DelegateTree.<String,String>getFactory(),
new ConstantTransformer(1.0));
tree = prim.getForest();
layout = new TreeLayout<String,String>(tree,100,100);
layout2 = new StaticLayout<String,String>(graph, layout);
Transformer<String,Paint>vertexPaint= new Transformer<String,Paint>(){
public Paint transform(String i){
Node node=grafito.getNode(i);
if(node.hasAttribute("ExcedeCaudal")){
return Color.RED;}
else{
return Color.lightGray;}
}
};
vv = new VisualizationViewer<String,String>(layout2, new Dimension(800,600));
vv.addGraphMouseListener(new TestGraphMouseListener<String>());
vv.setBackground(Color.white);
vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
vv.getRenderContext().setVertexShapeTransformer(new ClusterVertexShapeFunction());
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
// add a listener for ToolTips
vv.setVertexToolTipTransformer(new ToStringLabeller());
vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
vv.getRenderContext().setEdgeLabelTransformer(new EdgeLabelTransformer<String>());
Container content = getContentPane();
final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
content.add(panel);
final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
vv.setGraphMouse(graphMouse);
//ver cual nodo se selecciona
final PickedState<String> pickedState=vv.getPickedVertexState();
pickedState.addItemListener(new ItemListener(){
@Override
public void itemStateChanged(ItemEvent e){
Object subject=e.getItem();
if(subject instanceof String){
String vertice=(String)subject;
if(pickedState.isPicked(vertice)){
System.out.println("Vertice "+vertice+" está seleccionado");
}
else{
System.out.println("Vertice "+vertice+"no está seleccionado");
}
}
}
});
}private void createTree(org.graphstream.graph.Graph grafito) {
for(Node node:grafito){
graph.addVertex(node.getId());
}
int count=0;
for (Edge edge: grafito.getEachEdge()){
String padre=edge.getNode0().getId();
String hijo=edge.getNode1().getId();
String caudal=(edge.getAttribute("Caudal"));
graph.addEdge(caudal+"-"+count, padre,hijo,EdgeType.DIRECTED);
System.out.println("intento agregar "+edge.getAttribute("Caudal")+" cuyo padre es "+padre+" e hijo "+hijo);
count++;
}}private class EdgeLabelTransformer<V>implements Transformer<V,String>{
public String transform(V v){
return v.toString().split("-")[0];
}
}
class ClusterVertexShapeFunction<V> extends EllipseVertexShapeTransformer<V> {
ClusterVertexShapeFunction() {
setSizeTransformer(new ClusterVertexSizeFunction<V>(20));
}
@SuppressWarnings("unchecked")
@Override
public Shape transform(V v) {
if(v instanceof Graph) {
int size = ((Graph)v).getVertexCount();
if (size < 8) {
int sides = Math.max(size, 3);
return factory.getRegularPolygon(v, sides);
}
else {
return factory.getRegularStar(v, size);
}
}
return super.transform(v);
}
}
class ClusterVertexSizeFunction<V> implements Transformer<V,Integer> {
int size;
public ClusterVertexSizeFunction(Integer size) {
this.size = size;
}
public Integer transform(V v) {
if(v instanceof Graph) {
return 30;
}
return size;
}
}
static class TestGraphMouseListener<V> implements GraphMouseListener<V> {
public void graphClicked(V v, MouseEvent me) {
if(me.getClickCount()==2){
System.err.println("Vertex "+v+" fui doble click");
}
System.err.println("Vertex "+v+" was clicked at ("+me.getX()+","+me.getY()+")");
}
public void graphPressed(V v, MouseEvent me) {
System.err.println("Vertex "+v+" was pressed at ("+me.getX()+","+me.getY()+")");
}
public void graphReleased(V v, MouseEvent me) {
System.err.println("Vertex "+v+" was released at ("+me.getX()+","+me.getY()+")");
}
}
public void execute(org.graphstream.graph.Graph grafito){
JFrame frame = new JFrame();
Container content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
content.add(new Visualizacion(grafito));
frame.pack();
frame.setVisible(true);}}
答案 0 :(得分:0)
JUNG Layout
实例确定顶点位置,而不是边缘位置;边缘渲染是根据您使用的边缘形状和连接边数自动确定的。
JUNG Tree
对象只能有一条边连接任何一对顶点(否则它不是树)。
因此,如果您想要Graph
顶点使用TreeLayout
进行布局,但不能直接表示为Tree
,那么您可以这样做:
(1)构造一个Tree
,它编码你想要的结构关系(来自原始Graph
),但没有你想要的平行边。您可以直接自己完成此操作(通过构建一个删除存在的并行边缘的副本,或者如果可行则不添加它们),或者使用MinimumWeightSpanningTree
算法从中提取Tree
您原来的Graph
。
(2)为此TreeLayout
生成Tree
。
(3)创建StaticLayout
,复制TreeLayout
使用的位置。
(4)将此StaticLayout
用作原始Graph
的布局算法。
您可以在JUNG MinimumSpanningTreeDemo.java
中看到此过程,该示例代码是JUNG源代码分发的一部分。如果您只想查看代码,请点击此处:http://jung.sourceforge.net/site/jung-samples/xref/edu/uci/ics/jung/samples/MinimumSpanningTreeDemo.html