论坛首页 Java企业应用论坛

Use prefuse with database

浏览 4322 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-04  

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

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

xml 代码
  1. <!---->xml version="1.0" encoding="UTF-8"?>  
  2. <!---->  
  3. <graphml xmlns="http://graphml.graphdrawing.org/xmlns">  
  4.   <graph edgedefault="undirected">  
  5.     
  6.     <!---->  
  7.     <key id="name" for="node" attr.name="name" attr.type="string"/>  
  8.     <key id="gender" for="node" attr.name="gender" attr.type="string"/>  
  9.      
  10.     <!---->     
  11.     <node id="1">  
  12.      <data key="name">Jeffdata>  
  13.      <data key="gender">Mdata>  
  14.      node>  
  15.     <node id="2">  
  16.      <data key="name">Eddata>  
  17.      <data key="gender">Mdata>  
  18.     node>  
  19.     ...........................   
  20.     <edge source="1" target="2">edge>  
  21.     <edge source="1" target="3">edge>  
  22.     ............................   
  23.   graph>  
  24. graphml>  

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

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

sql 代码
  1. DROP TABLE IF EXISTS `test`.`node`;   
  2. CREATE TABLE  `test`.`node` (   
  3.   `id` int(10) unsigned NOT NULL auto_increment,   
  4.   `namevarchar(45) NOT NULL,   
  5.   `gender` varchar(45) NOT NULL,   
  6.   PRIMARY KEY  (`id`)   
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;   
  8.   
  9. DROP TABLE IF EXISTS `test`.`edge`;   
  10. CREATE TABLE  `test`.`edge` (   
  11.   `id` int(10) unsigned NOT NULL auto_increment,   
  12.   `sid` int(10) unsigned NOT NULL,   
  13.   `tid` int(10) unsigned NOT NULL,   
  14.   PRIMARY KEY  (`id`)   
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

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

接下来是程序了:

java 代码
  1. public class TestMysql {   
  2.     public static final String driverName   = "com.mysql.jdbc.Driver";   
  3.     public static final String dbURL        = "jdbc:mysql://localhost:3306/test";   
  4.     public static final String userName     = "root";   
  5.     public static final String userPwd      = "123456";   
  6.        
  7.     public static void main(String[] args) {   
  8.         DatabaseDataSource datasrc = null;   
  9.            
  10.         try {   
  11.             //get database connection   
  12.             datasrc = ConnectionFactory.getDatabaseConnection(   
  13.                     driverName, dbURL, userName, userPwd);   
  14.                
  15.             //create a table of data   
  16.             Table nodes = datasrc.getData("select * from node");   
  17.             Table edges = datasrc.getData("select * from edge");   
  18.                
  19.             Graph graph = new Graph(nodes, edges, false"id""sid""tid");   
  20.                
  21.             Visualization vis = new Visualization();   
  22.             vis.add("graph", graph);   
  23.                
  24.             LabelRenderer r = new LabelRenderer("name");   
  25.             r.setRoundedCorner(88);   
  26.             vis.setRendererFactory(new DefaultRendererFactory(r));   
  27.                
  28.             int[] palette = new int[] {   
  29.                     ColorLib.rgb(255,180,180), ColorLib.rgb(190,190,255)   
  30.             };   
  31.                
  32.             DataColorAction fill = new DataColorAction("graph.nodes""gender",   
  33.                     Constants.NOMINAL, VisualItem.FILLCOLOR, palette);   
  34.             ColorAction textColor = new ColorAction("graph.nodes",   
  35.                     VisualItem.TEXTCOLOR, ColorLib.gray(0));   
  36.             ColorAction edgesColor = new ColorAction("graph.edges",   
  37.                     VisualItem.STROKECOLOR, ColorLib.gray(200));   
  38.                
  39.             ActionList color = new ActionList();   
  40.             color.add(fill);   
  41.             color.add(textColor);   
  42.             color.add(edgesColor);   
  43.                
  44.             ActionList layout = new ActionList(Activity.INFINITY);   
  45.             layout.add(new ForceDirectedLayout("graph"));   
  46.             layout.add(new RepaintAction());   
  47.                
  48.             vis.putAction("color", color);   
  49.             vis.putAction("layout", layout);   
  50.                
  51.             Display d = new Display(vis);   
  52.             d.setSize(720500);   
  53.             d.addControlListener(new DragControl());   
  54.             d.addControlListener(new PanControl());   
  55.             d.addControlListener(new ZoomControl());   
  56.             d.addControlListener(new NeighborHighlightControl());   
  57.                
  58.             JFrame frame = new JFrame("haha");   
  59.             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
  60.             frame.setSize(800600);   
  61.             frame.add(d);   
  62.             frame.setVisible(true);   
  63.                
  64.             vis.run("color");   
  65.             vis.run("layout");   
  66.         } catch (Exception e) {   
  67.             e.printStackTrace();   
  68.         }   
  69.     }  

第19行:生成一个graph对象,这是可视化的关键。graph对象可以有多种生成方式,光是从数据库生成(也可以说是从table生成,应为prefuse从数据库中取出的都封装成Table)就有好几个方式。不过推荐本例的生成方式,提供的信息越多越可以更精确的描述自己。参数意义分别是:节点的Table,边的Table,是否是有向(true有,false无),节点的主键,边中代表源的列名(与edge表中对应),边中代表目标的列名(与edge表中对应)。

其他的就没得说了,和user manual上差不多。个人认为prefuse的另外一个优点是final类比较少,也就是说可扩展性比较强。例如53-56行添加的动作(在prefuse.controls包),我们就可以随意生成自己的Control。

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics