<?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();
}
}
}
运行后效果图:
针对下面很多评论提到了是否支持中文
因为上面采用的是MySQL可能在 显示的时候中文会乱码,
需要在连接的url上加上字符集 utf-8
我后来在SQL2005上测试 中文也可以显示。
附图片: