Prefuse学习(二)从数据库中读取数据

prefuse是一个非常不错的开源可视化项目,尤其是用在social network/complex network上,个人感觉要比jung好。不过可惜的是,prefuse的user manual还在建设中,并且google resource也少得可怜。好在开源提供了源码,只好看源码了,呵呵。

prefuse user manual上提供了一个简单的例子,这个例子的数据来自一个符合GraphML标准的xml文件(socialnet.xml),大致内容如下:

xml 代码

<?xml version="1.0" encoding="UTF-8"?> <!-- 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">Jeff</data> <data key="gender">M</data> </node> <edge source="21" target="128"></edge> <edge source="21" target="129"></edge> </graph> </graphml>

大致就是这个样子,程序也比较简单。但是不可能在想要可视化某个社群网络的时候,数据都来自xml,其实大部分还是来自数据库的。prefuse支持从数据库直接获取数据。不过它的user manual上没讲。只好自己探索。

先建立一个在mysql上测试数据库。一个代表节点,一个代表边。

-- phpMyAdmin SQL Dump -- version 2.11.10 -- http://www.phpmyadmin.net -- -- 主机: localhost -- 生成日期: 2010 年 07 月 06 日 03:24 -- 服务器版本: 5.0.22 -- PHP 版本: 5.2.13 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- 数据库: `test` -- -- -------------------------------------------------------- -- -- 表的结构 `node` -- CREATE TABLE IF NOT EXISTS `node` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(45) NOT NULL, `gender` varchar(45) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ; -- -- 导出表中的数据 `node` -- INSERT INTO `node` (`id`, `name`, `gender`) VALUES (1, 'cuiran', 'boy'), (2, 'aojuan', 'girl'), (3, 'zhangsan', 'boy'), (4, 'lisi', 'girl'), (5, 'aomiao', 'girl'), (6, 'aoqian', 'girl'), (7, 'wangwu', 'boy');

-- -- 表的结构 `edge` -- CREATE TABLE IF NOT EXISTS `edge` ( `id` int(10) unsigned NOT NULL auto_increment, `sid` int(10) unsigned NOT NULL, `tid` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ; -- -- 导出表中的数据 `edge` -- INSERT INTO `edge` (`id`, `sid`, `tid`) VALUES (3, 2, 1), (4, 3, 1), (5, 4, 1), (6, 5, 2), (7, 6, 2), (8, 7, 1);

接下来随便在两个表中插入几条数据,需要注意的是edge表中,sid和tid一定要在node表中存在(即node表中有id与其对应),否则prefuse在读取时会抛出异常。

接下来是程序了:

java 代码
package com.cayden.prefuse; import javax.swing.JFrame; import prefuse.Constants; import prefuse.Display; import prefuse.Visualization; import prefuse.action.ActionList; import prefuse.action.RepaintAction; import prefuse.action.assignment.ColorAction; import prefuse.action.assignment.DataColorAction; import prefuse.action.layout.graph.ForceDirectedLayout; import prefuse.activity.Activity; import prefuse.controls.DragControl; import prefuse.controls.NeighborHighlightControl; import prefuse.controls.PanControl; import prefuse.controls.ZoomControl; import prefuse.data.Graph; import prefuse.data.Table; import prefuse.data.io.sql.ConnectionFactory; import prefuse.data.io.sql.DatabaseDataSource; import prefuse.render.DefaultRendererFactory; import prefuse.render.LabelRenderer; import prefuse.util.ColorLib; import prefuse.visual.VisualItem; public class TestMySql { public static final String driverName = "com.mysql.jdbc.Driver"; public static final String dbURL = "jdbc:mysql://localhost:3306/test"; public static final String userName = "root"; public static final String userPwd = "root"; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub DatabaseDataSource datasrc = null; try { //get database connection datasrc = ConnectionFactory.getDatabaseConnection( driverName, dbURL, userName, userPwd); //create a table of data Table nodes = datasrc.getData("select * from node"); Table edges = datasrc.getData("select * from edge"); Graph graph = new Graph(nodes, edges, false, "id", "sid", "tid"); Visualization vis = new Visualization(); vis.add("graph", graph); LabelRenderer r = new LabelRenderer("name"); r.setRoundedCorner(8, 8); vis.setRendererFactory(new DefaultRendererFactory(r)); int[] palette = new int[] { ColorLib.rgb(255,180,180), ColorLib.rgb(190,190,255) }; DataColorAction fill = new DataColorAction("graph.nodes", "gender", Constants.NOMINAL, VisualItem.FILLCOLOR, palette); ColorAction textColor = new ColorAction("graph.nodes", VisualItem.TEXTCOLOR, ColorLib.gray(0)); ColorAction edgesColor = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.gray(200)); ActionList color = new ActionList(); color.add(fill); color.add(textColor); color.add(edgesColor); ActionList layout = new ActionList(Activity.INFINITY); layout.add(new ForceDirectedLayout("graph")); layout.add(new RepaintAction()); vis.putAction("color", color); vis.putAction("layout", layout); Display d = new Display(vis); d.setSize(720, 500); d.addControlListener(new DragControl()); d.addControlListener(new PanControl()); d.addControlListener(new ZoomControl()); d.addControlListener(new NeighborHighlightControl()); JFrame frame = new JFrame("Prefuse"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(800, 600); frame.add(d); frame.setVisible(true); vis.run("color"); vis.run("layout"); } catch (Exception e) { e.printStackTrace(); } } }
运行后效果图:
Prefuse学习(二)从数据库中读取数据
需要源码及其demo的就在留言中写上自己的邮箱,我会在第一时间发送到您的邮箱.