일부 XML 파일을 읽고 해당 XML 파일의 정보를 기반으로 그래프 다이어그램을 만드는 프로그램을 만들고 있습니다.Java에서 Treelayout 그래프를 만드는 방법
그래프 다이어그램을 만드는 데 어려움이 있습니다. http://pic.dhe.ibm.com/infocenter/elixent/v3r5/topic/com.ibm.ilog.elixir.doc/Content/Visualization/Documentation/Flex/Diagram4Flex/_media/TreeLayoutExample_default.png
그래서, 내가 꼭지점의 이름 (현 항목의 다른 종류에 대해 서로 다른 색상을 가지고) 어떤 색깔의 사각형의 내부로, 그것은 treelayout을 갖고 싶어하고 나는 또한 갖고 싶어 : 내 그래프 보는 것을 원하는 두 꼭지점 사이의 가장자리에 쓰기. 그 중 꼭두각시를 프로젝트에서 만든 일부 개체로 만들기를 원합니다. 그래서 꼭지점을 클릭하여 꼭지점에 배치 된 개체의 인스턴스를 가져옵니다.
package mainPack;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JApplet;
import javax.swing.JFrame;
import org.jgraph.JGraph;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphConstants;
import org.jgrapht.ListenableGraph;
import org.jgrapht.ext.JGraphModelAdapter;
import org.jgrapht.graph.ListenableDirectedGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.ListenableDirectedWeightedGraph;
/**
* A demo applet that shows how to use JGraph to visualize JGraphT graphs.
*
* @author Barak Naveh
*
* @since Aug 3, 2003
*/
public class Test extends JApplet {
private static final Color DEFAULT_BG_COLOR = Color.decode("#FAFBFF");
private static final Dimension DEFAULT_SIZE = new Dimension(530, 320);
//
private JGraphModelAdapter m_jgAdapter;
/**
* @see java.applet.Applet#init().
*/
public void init() {
// create a JGraphT graph
ListenableGraph g = new ListenableDirectedGraph(DefaultEdge.class);
// create a visualization using JGraph, via an adapter
m_jgAdapter = new JGraphModelAdapter(g);
JGraph jgraph = new JGraph(m_jgAdapter);
adjustDisplaySettings(jgraph);
getContentPane().add(jgraph);
resize(DEFAULT_SIZE);
// add some sample data (graph manipulated via JGraphT)
g.addVertex("v1");
g.addVertex("v2");
g.addVertex("v3");
g.addVertex("v4");
g.addEdge("v1", "v2", "1");
g.addEdge("v2", "v3", "2");
g.addEdge("v3", "v1", "3");
g.addEdge("v4", "v3", "4");
// position vertices nicely within JGraph component
positionVertexAt("v1", 130, 40);
positionVertexAt("v2", 60, 200);
positionVertexAt("v3", 310, 230);
positionVertexAt("v4", 380, 70);
// that's all there is to it!...
}
private void adjustDisplaySettings(JGraph jg) {
jg.setPreferredSize(DEFAULT_SIZE);
Color c = DEFAULT_BG_COLOR;
String colorStr = null;
try {
colorStr = getParameter("bgcolor");
}
catch(Exception e) {}
if(colorStr != null) {
c = Color.decode(colorStr);
}
jg.setBackground(c);
}
private void positionVertexAt(Object vertex, int x, int y) {
DefaultGraphCell cell = m_jgAdapter.getVertexCell(vertex);
Map attr = cell.getAttributes();
// Rectangle b = new Rectangle((int)(Math.random()*1000),(int)(Math.random()*500),100,30);
Rectangle b = new Rectangle(20,50 ,100,30);
GraphConstants.setBounds(attr, b);
Map cellAttr = new HashMap();
cellAttr.put(cell, attr);
m_jgAdapter.edit(cellAttr, null, null, null);
}
}
: 나는 jgraph의 frameowork을 시도 처음에는
:
지금까지, 내 그래프를 쉽게 그려진 도면 알고리즘에 너무 많은 작업없이이 두 프레임 워크를 시도 이 프레임 워크는 그래프를 만들 때 잘 작동하며, Rectangle 내부에 정점 이름과 가장자리에 이름이 있으며 MouseListener를 사용하여 정점 안에있는 String을 클릭 할 수 있습니다.그러나 TreeLayout을 만들고 버텍스를 클릭 할 때 반환 될 수있는 개체로 버텍스를 추가하는 방법을 찾지 못했습니다. 이 예제에있는 제네릭 클래스를 사용하려고 시도했지만이를 실행하려고 시도했을 때만 예외가 발생했습니다. 인터넷에서 수색했지만이 그래프에서 treelayout을 적용 할 방법을 찾지 못했습니다.
그래프를 그리는 데 더 많은 옵션이있는 Java JUNG Framework를 사용해 보았습니다. 에 toString의 객체를 반환() 메소드가 표시됩니다 내가 만든 정점 이름에 일부 개체로 정점을 추가 할 수 있습니다이 프레임 워크를 사용
@SuppressWarnings("serial")
public class TreeLayoutDemo extends JApplet {
/**
* the graph
*/
Forest<String,Integer> graph;
Factory<DirectedGraph<String,Integer>> graphFactory =
new Factory<DirectedGraph<String,Integer>>() {
public DirectedGraph<String, Integer> create() {
return new DirectedSparseMultigraph<String,Integer>();
}
};
Factory<Tree<String,Integer>> treeFactory =
new Factory<Tree<String,Integer>>() {
public Tree<String, Integer> create() {
return new DelegateTree<String,Integer>(graphFactory);
}
};
Factory<Integer> edgeFactory = new Factory<Integer>() {
int i=0;
public Integer create() {
return i++;
}};
Factory<String> vertexFactory = new Factory<String>() {
int i=0;
public String create() {
return "V"+i++;
}};
/**
* the visual component and renderer for the graph
*/
VisualizationViewer<String,Integer> vv;
VisualizationServer.Paintable rings;
String root;
TreeLayout<String,Integer> treeLayout;
RadialTreeLayout<String,Integer> radialLayout;
public TreeLayoutDemo() {
// create a simple graph for the demo
graph = new DelegateForest<String,Integer>();
createTree();
treeLayout = new TreeLayout<String,Integer>(graph);
radialLayout = new RadialTreeLayout<String,Integer>(graph);
radialLayout.setSize(new Dimension(600,600));
vv = new VisualizationViewer<String,Integer>(treeLayout, new Dimension(600,600));
vv.setBackground(Color.white);
vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
// vv.getRenderContext().setVertexShapeTransformer(arg0);
// add a listener for ToolTips
vv.setVertexToolTipTransformer(new ToStringLabeller());
vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
rings = new Rings();
Container content = getContentPane();
final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
content.add(panel);
final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
vv.setGraphMouse(graphMouse);
JComboBox modeBox = graphMouse.getModeComboBox();
modeBox.addItemListener(graphMouse.getModeListener());
graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);
final ScalingControl scaler = new CrossoverScalingControl();
JButton plus = new JButton("+");
plus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
scaler.scale(vv, 1.1f, vv.getCenter());
}
});
JButton minus = new JButton("-");
minus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
scaler.scale(vv, 1/1.1f, vv.getCenter());
}
});
JToggleButton radial = new JToggleButton("Radial");
radial.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
LayoutTransition<String,Integer> lt =
new LayoutTransition<String,Integer>(vv, treeLayout, radialLayout);
Animator animator = new Animator(lt);
animator.start();
vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
vv.addPreRenderPaintable(rings);
} else {
LayoutTransition<String,Integer> lt =
new LayoutTransition<String,Integer>(vv, radialLayout, treeLayout);
Animator animator = new Animator(lt);
animator.start();
vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
vv.removePreRenderPaintable(rings);
}
vv.repaint();
}});
JPanel scaleGrid = new JPanel(new GridLayout(1,0));
scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
JPanel controls = new JPanel();
scaleGrid.add(plus);
scaleGrid.add(minus);
controls.add(radial);
controls.add(scaleGrid);
controls.add(modeBox);
content.add(controls, BorderLayout.SOUTH);
}
class Rings implements VisualizationServer.Paintable {
Collection<Double> depths;
public Rings() {
depths = getDepths();
}
private Collection<Double> getDepths() {
Set<Double> depths = new HashSet<Double>();
Map<String,PolarPoint> polarLocations = radialLayout.getPolarLocations();
for(String v : graph.getVertices()) {
PolarPoint pp = polarLocations.get(v);
depths.add(pp.getRadius());
}
return depths;
}
public void paint(Graphics g) {
g.setColor(Color.lightGray);
Graphics2D g2d = (Graphics2D)g;
Point2D center = radialLayout.getCenter();
Rectangle2D rectangle = new Rectangle2D.Double(); // (center.getX()-10, center.getY()-20, 20, 40);
Ellipse2D ellipse = new Ellipse2D.Double();
for(double d : depths) {
ellipse.setFrameFromDiagonal(center.getX()-d, center.getY()-d,
center.getX()+d, center.getY()+d);
rectangle.setFrameFromDiagonal(center.getX()-d, center.getY()-d,
center.getX()+d, center.getY()+d);
Shape shape = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).transform(rectangle);
g2d.draw(shape);
}
}
public boolean useTransform() {
return true;
}
}
/**
*
*/
private void createTree() {
graph.addVertex("V0");
graph.addEdge(edgeFactory.create(), "V0", "V1");
graph.addEdge(edgeFactory.create(), "V0", "V2");
graph.addEdge(edgeFactory.create(), "V1", "V4");
graph.addEdge(edgeFactory.create(), "V2", "V3");
graph.addEdge(edgeFactory.create(), "V2", "V5");
graph.addEdge(edgeFactory.create(), "V4", "V6");
graph.addEdge(edgeFactory.create(), "V4", "V7");
graph.addEdge(edgeFactory.create(), "V3", "V8");
graph.addEdge(edgeFactory.create(), "V6", "V9");
graph.addEdge(edgeFactory.create(), "V4", "V10");
graph.addVertex("A0");
graph.addEdge(edgeFactory.create(), "A0", "A1");
graph.addEdge(edgeFactory.create(), "A0", "A2");
graph.addEdge(edgeFactory.create(), "A0", "A3");
graph.addVertex("B0");
graph.addEdge(edgeFactory.create(), "B0", "B1");
graph.addEdge(edgeFactory.create(), "B0", "B2");
graph.addEdge(edgeFactory.create(), "B1", "B4");
graph.addEdge(edgeFactory.create(), "B2", "B3");
graph.addEdge(edgeFactory.create(), "B2", "B5");
graph.addEdge(edgeFactory.create(), "B4", "B6");
graph.addEdge(edgeFactory.create(), "B4", "B7");
graph.addEdge(edgeFactory.create(), "B3", "B8");
graph.addEdge(edgeFactory.create(), "B6", "B9");
}
/**
* a driver for this demo
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
Container content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content.add(new TreeLayoutDemo());
frame.pack();
frame.setVisible(true);
}
}
:이 예를 발견했다. 또한 TreeLayout 알고리즘이 너무 많아 구현했지만 꼭지점 모양을 변경할 수는 없습니다. 저는 JGraph 프레임 워크에 의해 그려지는 꼭지점처럼 보이기를 원합니다. 그러나 JUNG에서는 단지 일부 원형 만 얻었고 꼭지점 이름은 꼭지점 모양 밖에 있습니다. 버텍스의 모양을 바꾸는 예제를 발견했지만 글쓰기는 여전히 바깥입니다.
그래서이 두 프레임 워크에서 얻을 수있는 것 사이에 어떤 그래프를 그릴 수있는 방법에 대한 제안을 많이 드리고자합니다. 모양 안에 정점 이름을 지정하고 Treelayout을 사용하고 정점을 개체로 추가합니다. 버텍스를 클릭하면 돌아올 수 있습니다.
Marco13의 대답은 매우 유용했습니다. Rectangle에 Rectangle의 너비에 String.length * 10을 설정하여 String을 맞출 수있는 크기로 만들었습니다.
이 그래프를 만들려는 다른 누군가에게 유용 할 것 같습니다 :이 예제에서 가장 일반적인 클래스에 나타나는 것은 대신에 Object가 필요하고 String은 Vertex이고 Integer는 가장자리 유형입니다. . Transformer 함수 안에서 Vertex 나 Edge에 할당 된 Object를 얻습니다. 이처럼 특정 속성을 가진 객체에 대해 다른 모양, 색상 및 글꼴을 설정할 수있었습니다.
클릭 할 때 Edge 객체를 반환하는 MouseListener를 만드는 방법을 알아 냈습니다. 그러나 쉽게 할 수 있기를 바랍니다.