自己摸索了几天,搞了这么点注释,大家帮忙看看有神马不对的,请不吝赐教
package prefuse;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.GroupAction;
import prefuse.action.ItemAction;
import prefuse.action.RepaintAction;
import prefuse.action.animate.ColorAnimator;
import prefuse.action.animate.PolarLocationAnimator;
import prefuse.action.animate.QualityControlAnimator;
import prefuse.action.animate.VisibilityAnimator;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.assignment.FontAction;
import prefuse.action.layout.CollapsedSubtreeLayout;
import prefuse.action.layout.graph.RadialTreeLayout;
import prefuse.activity.SlowInSlowOutPacer;
import prefuse.controls.ControlAdapter;
import prefuse.controls.DragControl;
import prefuse.controls.FocusControl;
import prefuse.controls.HoverActionControl;
import prefuse.controls.PanControl;
import prefuse.controls.WheelZoomControl;
import prefuse.controls.ZoomControl;
import prefuse.controls.ZoomToFitControl;
import prefuse.controls.ZoomingPanControl;
import prefuse.data.Graph;
import prefuse.data.Node;
import prefuse.data.Table;
import prefuse.data.Tuple;
import prefuse.data.event.TupleSetListener;
import prefuse.data.io.GraphMLReader;
import prefuse.data.query.SearchQueryBinding;
import prefuse.data.search.PrefixSearchTupleSet;
import prefuse.data.search.SearchTupleSet;
import prefuse.data.tuple.DefaultTupleSet;
import prefuse.data.tuple.TupleSet;
import prefuse.render.AbstractShapeRenderer;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.EdgeRenderer;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.util.FontLib;
import prefuse.util.ui.JFastLabel;
import prefuse.util.ui.JSearchPanel;
import prefuse.util.ui.UILib;
import prefuse.visual.NodeItem;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.InGroupPredicate;
import prefuse.visual.sort.TreeDepthItemSorter;
/**
* Demonstration of a node-link tree viewer
* @author lee http://faithlee.iteye.com
* @version 1.0
*/
public class CopyOfTest extends Display {
public static final String DATA_FILE = "project.xml";
private static final String tree = "tree";
private static final String treeNodes = "tree.nodes";
private static final String treeEdges = "tree.edges";
private static final String linear = "linear";
private LabelRenderer m_nodeRenderer;
private EdgeRenderer m_edgeRenderer;
private String m_label = "label";
private String m_sex = "sex";
public CopyOfTest(Graph g, String label, String sex) {
super(new Visualization());
m_label = label;
m_sex = sex;
// -- set up visualization --
m_vis.add(tree, g);
m_vis.setInteractive(treeEdges, null, false);
// -- 设置渲染器 --
m_nodeRenderer = new LabelRenderer(m_label); // 使用label来创建带有标签的节点
m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL);
m_nodeRenderer.setHorizontalAlignment(Constants.CENTER);
m_nodeRenderer.setRoundedCorner(8, 8);// 标签为平滑的边缘
m_edgeRenderer = new EdgeRenderer();
DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer);// 决定图形怎么画的主要工具
rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer);
m_vis.setRendererFactory(rf);
// -- 设置节点颜色,字体大小、颜色 --
ItemAction edgeColor = new ColorAction(treeEdges,
VisualItem.STROKECOLOR, ColorLib.rgb(200, 200, 200));
FontAction fonts = new FontAction(treeNodes, FontLib.getFont("宋体&新宋体",
10));
fonts.add("ingroup('_focus_')", FontLib.getFont("宋体&新宋体", 11));
// 创建调色板,颜色对应配置文件中相应属性的字母顺序
int[] palette = new int[] { ColorLib.rgb(128, 128, 255),
ColorLib.rgb(255, 128, 192), ColorLib.rgb(255, 140, 85) };
// 文件不同类别的数据值,根据调色板使用不同颜色
DataColorAction fill = new DataColorAction("tree.nodes", "gender",
Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
// use black for node text
fill.add("_hover", ColorLib.gray(220, 230));
fill.add("ingroup('_search_')", ColorLib.rgb(255, 190, 190));
fill.add("ingroup('_focus_')", ColorLib.rgb(198, 229, 229));
ColorAction text = new ColorAction("tree.nodes", VisualItem.TEXTCOLOR,
ColorLib.gray(0));
text.add("_hover", ColorLib.rgb(255, 0, 0));
// use light grey for edges
ColorAction edges = new ColorAction("tree.nodes",
VisualItem.STROKECOLOR, ColorLib.gray(200));
// create an action list containing all color assignments
ActionList color = new ActionList();
color.add(fill);
color.add(text);
color.add(edges);
m_vis.putAction("color", color);
// recolor
ActionList recolor = new ActionList();
recolor.add(fill);
m_vis.putAction("recolor", recolor);
// repaint
ActionList repaint = new ActionList();
repaint.add(recolor);
repaint.add(new RepaintAction());
m_vis.putAction("repaint", repaint);
// animate paint change
ActionList animatePaint = new ActionList(400);
animatePaint.add(new ColorAnimator(treeNodes));
animatePaint.add(new RepaintAction());
m_vis.putAction("animatePaint", animatePaint);
// create the tree layout action
RadialTreeLayout treeLayout = new RadialTreeLayout(tree);
// treeLayout.setLayoutRoot() // 可以设置初始中心点
// treeLayout.setAngularBounds(-Math.PI/2, Math.PI);
m_vis.putAction("treeLayout", treeLayout);
CollapsedSubtreeLayout subLayout = new CollapsedSubtreeLayout(tree);
m_vis.putAction("subLayout", subLayout);
// create the filtering and layout
ActionList filter = new ActionList();
filter.add(new TreeRootAction(tree));
filter.add(fonts);
filter.add(treeLayout);
filter.add(subLayout);
filter.add(fill);
filter.add(edgeColor);
m_vis.putAction("filter", filter);
// animated transition 动画过渡
ActionList animate = new ActionList(1250);// 活动时间
animate.setPacingFunction(new SlowInSlowOutPacer());
animate.add(new QualityControlAnimator());
animate.add(new VisibilityAnimator(tree));
animate.add(new PolarLocationAnimator(treeNodes, linear));
animate.add(new ColorAnimator(treeNodes));
animate.add(new RepaintAction());
m_vis.putAction("animate", animate);
m_vis.alwaysRunAfter("filter", "animate");
// ------------------------------------------------
// initialize the display
setSize(700, 600);// 初始化jframe大小
setItemSorter(new TreeDepthItemSorter());
// 添加对一系列鼠标事件的监听
addControlListener(new WheelZoomControl());// 鼠标滚轮放大缩小效果
// addControlListener(new NeighborHighlightControl()); //相邻节点加亮监听
addControlListener(new DragControl());
addControlListener(new ZoomToFitControl());// 右键单击使画面最适合状态
// addControlListener(new ZoomControl());//右键移动改变图像大小
addControlListener(new PanControl());
addControlListener(new FocusControl(1, "filter"));// 设置鼠标点击次数改变节点中心
addControlListener(new HoverActionControl("repaint"));
// ------------------------------------------------
// filter graph and perform layout
m_vis.run("filter");
// maintain a set of items that should be interpolated linearly
// this isn't absolutely necessary, but makes the animations nicer
// the PolarLocationAnimator should read this set and act accordingly
m_vis.addFocusGroup(linear, new DefaultTupleSet());
m_vis.getGroup(Visualization.FOCUS_ITEMS).addTupleSetListener(
new TupleSetListener() {
public void tupleSetChanged(TupleSet t, Tuple[] add,
Tuple[] rem) {
TupleSet linearInterp = m_vis.getGroup(linear);
if (add.length < 1)
return;
linearInterp.clear();
for (Node n = (Node) add[0]; n != null; n = n
.getParent())
linearInterp.addTuple(n);
}
});
SearchTupleSet search = new PrefixSearchTupleSet();
m_vis.addFocusGroup(Visualization.SEARCH_ITEMS, search);
search.addTupleSetListener(new TupleSetListener() {
public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) {
m_vis.cancel("animatePaint");
m_vis.run("recolor");
m_vis.run("animatePaint");
}
});
}
// ------------------------------------------------------------------------
public static void main(String argv[]) {
String infile = DATA_FILE;
String label = "name";
String sex = "gender";
if (argv.length > 1) {
infile = argv[0];
label = argv[1];
sex = argv[2];
}
UILib.setPlatformLookAndFeel();// 适合当前系统平台。
JFrame frame = new JFrame("关系图");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setContentPane(demo(infile, label));
// JPanel jpanel = demo(infile,label);
frame.getContentPane().add(demo(infile, label, sex),
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null); // 当参数为null时窗体处于屏幕正中
}
public static JPanel demo() {
return demo(DATA_FILE, "name", "gender");
}
public static JPanel demo(String datafile, final String label,
final String sex) {
Graph g = null;
try {
g = new GraphMLReader().readGraph(datafile);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return demo(g, label, sex);
}
public static JPanel demo(Graph g, final String label, final String sex) {
// create a new radial tree view
final CopyOfTest gview = new CopyOfTest(g, label, sex);
Visualization vis = gview.getVisualization();
// create a search panel for the tree map
SearchQueryBinding sq = new SearchQueryBinding((Table) vis
.getGroup(treeNodes), label, (SearchTupleSet) vis
.getGroup(Visualization.SEARCH_ITEMS));
JSearchPanel search = sq.createSearchPanel();
search.setShowResultCount(true);
search.setBorder(BorderFactory.createEmptyBorder(5, 5, 4, 0));
search.setFont(FontLib.getFont("宋体&新宋体", Font.PLAIN, 12));
final JFastLabel title = new JFastLabel("");
title.setPreferredSize(new Dimension(25, 20));
title.setVerticalAlignment(SwingConstants.BOTTOM);
title.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
title.setFont(FontLib.getFont("宋体&新宋体", Font.PLAIN, 12));
gview.addControlListener(new ControlAdapter() {
public void itemEntered(VisualItem item, MouseEvent e) {
if (item.canGetString(label))
title.setText(item.getString(label));
}
public void itemExited(VisualItem item, MouseEvent e) {
title.setText(null);
}
});
Box box = new Box(BoxLayout.X_AXIS);
box.add(Box.createHorizontalStrut(10));
box.add(title);
box.add(Box.createHorizontalGlue());
box.add(search);
box.add(Box.createHorizontalStrut(3));
JPanel panel = new JPanel(new BorderLayout());
panel.add(gview, BorderLayout.CENTER);
panel.add(box, BorderLayout.SOUTH);
Color BACKGROUND = Color.WHITE;
Color FOREGROUND = Color.DARK_GRAY;
UILib.setColor(panel, BACKGROUND, FOREGROUND);
return panel;
}
// ------------------------------------------------------------------------
/**
* Switch the root of the tree by requesting a new spanning tree at the
* desired root
*/
public static class TreeRootAction extends GroupAction {
public TreeRootAction(String graphGroup) {
super(graphGroup);
}
public void run(double frac) {
TupleSet focus = m_vis.getGroup(Visualization.FOCUS_ITEMS);
if (focus == null || focus.getTupleCount() == 0)
return;
Graph g = (Graph) m_vis.getGroup(m_group);
Node f = null;
Iterator tuples = focus.tuples();
while (tuples.hasNext()
&& !g.containsTuple(f = (Node) tuples.next())) {
f = null;
}
if (f == null)
return;
g.getSpanningTree(f);
}
}
}
xml文件 涉及一些数据问题,不贴了,大概编写一下格式
<?xml version="1.0" encoding="GB2312"?>
<!-- An excerpt of an egocentric social network -->
<graphml xmlns="http://graphml.graphdrawing.org/xmlns">
<graph edgedefault="undirected">
<!-- data schema -->
<key id="name" for="node" attr.name="name" attr.type="string" />
<key id="gender" for="node" attr.name="gender" attr.type="string" />
<!-- nodes -->
<node id="1">
<data key="name">张三</data>
<data key="gender">H</data>
</node>
<node id="2">
<data key="name">王二</data>
<data key="gender">H</data>
</node>
//此处省略。。。
<node id="107">
<data key="name">D:资源部</data>
<data key="gender">D</data>
</node>
<node id="108">
<data key="name">D:发展部</data>
<data key="gender">D</data>
</node>
//此处省略N多。。
<node id="s1">
<data key="name">P:管理安全</data>
<data key="gender">P</data>
</node>
//此处省略
<edge source="1" target="s1"></edge>
<edge source="1" target="100"></edge>
<edge source="1" target="s2"></edge>
<edge source="1" target="s3"></edge>
<edge source="2" target="s1"></edge>
<edge source="2" target="101"></edge>
<edge source="2" target="s2"></edge>
<edge source="2" target="s3"></edge>
<edge source="2" target="s7"></edge>
<edge source="2" target="s8"></edge>
<edge source="2" target="s9"></edge>
<edge source="2" target="s13"></edge>
<edge source="3" target="102"></edge>
<edge source="3" target="s1"></edge>
<edge source="4" target="103"></edge>
<edge source="4" target="s1"></edge>
<edge source="5" target="s2"></edge>
<edge source="5" target="100"></edge>
<edge source="6" target="s2"></edge>
<edge source="6" target="101"></edge>
<edge source="7" target="s3"></edge>
<edge source="7" target="s7"></edge>
<edge source="7" target="104"></edge>
<edge source="8" target="105"></edge>
<edge source="8" target="s4"></edge>
<edge source="8" target="s15"></edge>
<edge source="8" target="s16"></edge>
<edge source="9" target="100"></edge>
<edge source="9" target="s5"></edge>
<edge source="10" target="104"></edge>
<edge source="10" target="s5"></edge>
<edge source="11" target="100"></edge>
<edge source="11" target="s6"></edge>
<edge source="12" target="106"></edge>
<edge source="12" target="s6"></edge>
<edge source="13" target="100"></edge>
<edge source="13" target="s7"></edge>
<edge source="14" target="s8"></edge>
<edge source="14" target="s9"></edge>
<edge source="14" target="s10"></edge>
<edge source="14" target="s11"></edge>
<edge source="14" target="s12"></edge>
<edge source="14" target="s13"></edge>
<edge source="14" target="100"></edge>
<edge source="15" target="108"></edge>
<edge source="15" target="s12"></edge>
<edge source="15" target="s14"></edge>
<edge source="16" target="s14"></edge>
<edge source="16" target="s15"></edge>
<edge source="16" target="s16"></edge>
<edge source="16" target="100"></edge>
<edge source="17" target="s11"></edge>
<edge source="17" target="107"></edge>
</graph>
</graphml>
至于完成后的图像 等我改过数据后再贴。。。。
转载请标出处,前段在网上搜不到相关资料,我自己摸索出来点东西贴上来吧,过了没两周,网上铺天盖地的全是那篇文章。。哎,这样太浪费那些急于找相关资料人的时间了。