这个双12,别人都在抢红包、逛淘宝、上京东,我选择再续我的“漫谈可视化”系列(好了,不装了,其实是郎中羞涩。。。)

  上篇《漫谈可视化Prefuse(三)---Prefuse API数据结构阅读有感》主要介绍了可视化工具Prefuse API中主要解读的是prefuse.data包中的主要接口,并利用《漫谈可视化Prefuse(一)---从SQL Server数据库读取数据》中例子,将参数配置模块剥离出来,实现界面传值,绘制图形。

  本篇决定不再贴API,实在没啥意思,还占篇幅(但是不容置疑的是API确实很重要,想了解API点这里)。那今天我们主要讲讲Prefuse比较常用的包以及如何使用这些包做出自己想要的展示效果:

  Demo1.解决图形元素形状单一化问题——DataShapeAction的使用

  

  Prefuse对于节点的形状默认是使用Constants.SHAPE_RECTANGLE,这里使用DataShapeAction类完成一个图形中根据性别不同展示不同的节点形状,具体代码如下:

  1. public class Demo1 {
  2.  
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7.  
  8. Graph graph = null;
  9. try {
  10. graph = new GraphMLReader().readGraph("socialnet.xml");
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. System.out.println("Error loading");
  14. System.exit(1);
  15. }
  16.  
  17. Visualization vis = new Visualization();
  18. vis.add("graph", graph);
  19. vis.setRendererFactory(new DefaultRendererFactory());
  20.  
  21. int[] palette = new int[]{ColorLib.rgb(255, 180, 180),ColorLib.rgb(190, 190, 255)};
  22. DataColorAction fill = new DataColorAction("graph.nodes" , "gender" , Constants.NOMINAL, VisualItem.FILLCOLOR,palette);
  23. ColorAction text = new ColorAction("graph.nodes", VisualItem.TEXTCOLOR, ColorLib.gray(0));
  24. ColorAction edges = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.gray(200));
  25.  
  26. int[] shapes = new int[]{ Constants.SHAPE_RECTANGLE, Constants.SHAPE_DIAMOND};
  27. DataShapeAction shape = new DataShapeAction("graph.nodes", "gender", shapes);
  28.  
  29. ActionList color = new ActionList();
  30. color.add(fill);
  31. color.add(text);
  32. color.add(edges);
  33. color.add(shape);
  34.  
  35. ActionList layout = new ActionList(Activity.INFINITY);
  36. layout.add(new ForceDirectedLayout("graph"));
  37. layout.add(new RepaintAction());
  38.  
  39. vis.putAction("color", color);
  40. vis.putAction("layout", layout);
  41.  
  42. Display display = new Display(vis);
  43. display.setSize(750, 700);
  44. display.pan(250, 250);
  45. display.addControlListener(new DragControl());
  46. display.addControlListener(new PanControl());
  47. display.addControlListener(new ZoomControl());
  48. display.addControlListener(new WheelZoomControl());
  49. display.addControlListener(new FocusControl(1));
  50. display.addControlListener(new ZoomToFitControl());
  51.  
  52. JFrame jf = new JFrame();
  53. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  54. jf.add(display);
  55. jf.pack();
  56. jf.setVisible(true);
  57.  
  58. vis.run("color");
  59. vis.run("layout");
  60.  
  61. }
  62.  
  63. }

  

  DataShapeAction中的第一个参数为指定数据范围,这里指定针对“graph.nodes”点集;第二个参数为属性域,这里针对性别不同赋予不同的形状;第三个参数是形状数组,这里定义了Constants.SHAPE_RECTANGLE, Constants.SHAPE_DIAMOND,除此之外还有Constants.SHAPE_CROSS、Constants.SHAPE_ELLIPSE、Constants.SHAPE_STAR等。同理prefuse.action.assignment包下的DataColorAction用法与DataShapeAction类似。图形展示效果如下:

  Demo2:打破输入输出流的垄断亲自绘制图形——Graph的使用

  之前几篇介绍的例子主要依赖于prefuse.io中的读入写出操作类进行数据的导入,这里我们决定甩开膀子,自己丰衣足食,打造自己的图形,这里主要使用Graph类的添加节点以及添加边的方法,构建一个互连的三个三角形的形状。具体代码如下:

  1. public class Demo2{
  2.  
  3. public static void main(String[] argv) {
  4. Visualization vis = new Visualization();
  5. Graph g = new Graph();
  6. for(int i = 0; i<3; i++){
  7. Node n1 = g.addNode();
  8. Node n2 = g.addNode();
  9. Node n3 = g.addNode();
  10. g.addEdge(n1, n2);
  11. g.addEdge(n2, n3);
  12. g.addEdge(n3, n1);
  13. }
  14. g.addEdge(0, 3);
  15. g.addEdge(3, 6);
  16. g.addEdge(6, 0);
  17.  
  18. vis.add("graph", g);
  19. ShapeRenderer renderer = new ShapeRenderer(10);
  20. vis.setRendererFactory(new DefaultRendererFactory(renderer));
  21.  
  22. ColorAction nodeFill = new ColorAction("graph.nodes", VisualItem.FILLCOLOR, ColorLib.rgb(10, 150, 220));
  23. ColorAction edgesStroke = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.rgb(100, 80, 180));
  24. ColorAction nodeHighlight = new ColorAction("graph.nodes", VisualItem.HIGHLIGHT, ColorLib.rgb(10, 150, 220));
  25.  
  26. ActionList color = new ActionList();
  27. color.add(nodeFill);
  28. color.add(edgesStroke);
  29.  
  30. ActionList layout = new ActionList(Activity.INFINITY);
  31. layout.add(color);
  32. layout.add(new ForceDirectedLayout("graph"));
  33. layout.add(new RepaintAction());
  34.  
  35. Display display = new Display(vis);
  36. display.setSize(400, 500);
  37. display.pan(250, 250);
  38. display.addControlListener(new DragControl());
  39. display.addControlListener(new PanControl());
  40. display.addControlListener(new ZoomControl());
  41. display.addControlListener(new WheelZoomControl());
  42. display.addControlListener(new FocusControl(1));
  43. display.addControlListener(new ZoomToFitControl());
  44.  
  45. vis.putAction("color", color);
  46. vis.putAction("layout", layout);
  47.  
  48. JFrame frame = new JFrame();
  49. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  50. frame.pack();
  51. frame.setSize(600, 700);
  52. frame.add(display);
  53. frame.setVisible(true);
  54.  
  55. vis.run("color");
  56. vis.run("layout");
  57. }
  58.  
  59. }

  从代码可以看出,对于创建节点、添加边,Graph处理的游刃有余,只有你想不到的图形,没有创建不了的Graph。当然只是简单创建了node和edge只是有了骨架,还需要血肉的填充,所以可以看到有很多的Action纷纷来助阵,最终的众志成城之作如下:

  Demo3:谁说点点之间只能“直肠子”——EdgeRenderer的使用

  看不惯点与点之间的“直肠子”?可以,Prefuse了解你,知道你喜新厌旧,这不使用EdgeRenderer就可以实现曲线连接,具体代码与Demo1相近,只是多了一下几行代码:

  1. DefaultRendererFactory rf = new DefaultRendererFactory(label);
  2. EdgeRenderer edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_CURVE);
  3. rf.add(new InGroupPredicate("graph.edges"), edgeRenderer);

  这里采用EdgeRenderer边渲染器,将边渲染为曲线,并统一应用到组“graph.edges”中的元素上,除了Constants.EDGE_TYPE_CURVE,还有Constants.EDGE_ARROW_FORWARD、Constants.EDGE_ARROW_NONE等。话不多说,看效果:

Demo4:Prefuse没节操?不知道筛选?No!——Predicate的使用

Prefuse自带过滤器,可以完成十分强大的过滤操作,视个别情况个别对待。拿Demo2中的图形来说,处在中间的节点可以不收节点控制(无法拖拽,不能交互),人家兄弟姐妹多,就拿那些势力若的边缘小弟拖过来拽过去^_^。具体代码如下:

  1. public class Demo4{
  2.  
  3. public static void main(String[] argv) {
  4. Visualization vis = new Visualization();
  5. Graph g = new Graph();
  6. for(int i = 0; i<3; i++){
  7. Node n1 = g.addNode();
  8. Node n2 = g.addNode();
  9. Node n3 = g.addNode();
  10. g.addEdge(n1, n2);
  11. g.addEdge(n2, n3);
  12. g.addEdge(n3, n1);
  13. }
  14. g.addEdge(0, 3);
  15. g.addEdge(3, 6);
  16. g.addEdge(6, 0);
  17. vis.add("graph", g);
  18.  
  19. ShapeRenderer renderer = new ShapeRenderer(10);
  20. EdgeRenderer edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_CURVE);
  21. DefaultRendererFactory drf = new DefaultRendererFactory();
  22. drf.add(new InGroupPredicate("graph.edges"), edgeRenderer);
  23. vis.setRendererFactory(drf);
  24.  
  25. ColorAction nodeFill = new ColorAction("graph.nodes", VisualItem.FILLCOLOR, ColorLib.rgb(10, 150, 220));
  26. ColorAction edgesStroke = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.rgb(100, 80, 180));
  27. ColorAction nodeHighlight = new ColorAction("graph.nodes", VisualItem.HIGHLIGHT, ColorLib.rgb(10, 150, 220));
  28.  
  29. ShapeAction shape = new ShapeAction("graph.nodes",Constants.SHAPE_CROSS); //设置节点形状
  30.  
  31. ActionList color = new ActionList();
  32. color.add(nodeFill);
  33. color.add(edgesStroke);
  34. color.add(shape);
  35.  
  36. ActionList layout = new ActionList(Activity.INFINITY);
  37. layout.add(color);
  38. layout.add(new ForceDirectedLayout("graph"));
  39. layout.add(new RepaintAction());
  40.  
  41. Point p = new Point(100,200);
  42. p.move(300, 400);
  43.  
  44. Predicate pCount =(Predicate)ExpressionParser.parse("degree()>2");
  45.  
  46. Display display = new Display(vis);
  47. display.setSize(400, 500);
  48. display.pan(250, 250);
  49. display.animatePanAbs(230, 220, 2000);
  50. display.addControlListener(new DragControl());
  51. display.addControlListener(new PanControl());
  52. display.addControlListener(new ZoomControl());
  53. display.addControlListener(new WheelZoomControl());
  54. display.addControlListener(new FocusControl(1));
  55. display.addControlListener(new ZoomToFitControl());
  56.  
  57. vis.removeGroup("graph");
  58. VisualGraph vg = vis.addGraph("graph", g);
  59. Iterator nodes = vg.nodes();
  60. display.addControlListener(new ControlAdapter() {
  61. public void itemEntered(VisualItem item, MouseEvent e) {
  62. System.out.println("伦家已经是:" + item.getGroup()+"的人了");
  63. }
  64. public void itemExited(VisualItem item, MouseEvent e) {
  65. System.out.println("哦,那杰哥再找找-_-");
  66. }
  67. });//为组件添加监控并作相应的响应
  68.  
  69. vis.setInteractive("graph.nodes", pCount, false);
  70.  
  71. vis.putAction("color", color);
  72. vis.putAction("layout", layout);
  73.  
  74. JFrame frame = new JFrame();
  75. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  76. frame.pack();
  77. frame.setSize(600, 700);
  78. frame.add(display);
  79. frame.setVisible(true);
  80.  
  81. vis.run("color");
  82. vis.run("layout");
  83. }
  84.  
  85. }

  这里Predicate pCount =(Predicate)ExpressionParser.parse("degree()>2")表示过滤出节点度数大于2的,该过滤条件在vis.setInteractive("graph.nodes", pCount, false)中执行,即在组“graph.nodes”元素中节点度数大于2的不能交互(即鼠标拖拽无效)。

  另外从代码中可以看出当鼠标经过和离开VisualItem(点或边)时会执行相应的操作,下图展现了部分结果:

  Demo5:个性化定制,我有我个性——VisualItem的领悟

  要知道,在数据中心Visualizaiton里,每一个node或是edge都可以看成一个VisualItem,每个VisualItem都可以有属于自己的造型、尺寸,这里我们还是用Demo2中的图形继续玩,直到玩坏为止。具体代码如下:

  1. public class Demo5{
  2. public static Visualization vis = new Visualization();
  3.  
  4. public static void main(String[] argv) {
  5.  
  6. Graph g = new Graph();
  7. for(int i = 0; i<3; i++){
  8. Node n1 = g.addNode();
  9. Node n2 = g.addNode();
  10. Node n3 = g.addNode();
  11. g.addEdge(n1, n2);
  12. g.addEdge(n2, n3);
  13. g.addEdge(n3, n1);
  14. }
  15. g.addEdge(0, 3);
  16. g.addEdge(3, 6);
  17. g.addEdge(6, 0);
  18.  
  19. vis.add("graph", g);
  20. ShapeRenderer renderer = new ShapeRenderer(10);
  21. vis.setRendererFactory(new DefaultRendererFactory(renderer));
  22.  
  23. vis.removeGroup("graph");
  24. VisualGraph vg = vis.addGraph("graph", g);
  25. VisualItem nodeI = (VisualItem)vg.getEdge(7).getSourceNode();
  26. nodeI.setShape(Constants.SHAPE_STAR);
  27. nodeI.setSize(4);
  28. nodeI.setFixed(true);
  29. VisualItem edgeI = (VisualItem)vg.getEdge(5);
  30. edgeI.setSize(8);
  31.  
  32. ColorAction nodeFill = new ColorAction("graph.nodes", VisualItem.FILLCOLOR, ColorLib.rgb(10, 150, 220));
  33. ColorAction edgesStroke = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.rgb(100, 80, 180));
  34. ColorAction nodeHighlight = new ColorAction("graph.nodes", VisualItem.HIGHLIGHT, ColorLib.rgb(10, 150, 220));
  35.  
  36. ActionList color = new ActionList();
  37. color.add(nodeFill);
  38. color.add(edgesStroke);
  39.  
  40. ActionList layout = new ActionList(3000);
  41. layout.add(color);
  42. layout.add(new ForceDirectedLayout("graph"));
  43. layout.add(new RepaintAction());
  44.  
  45. Display display = new Display(vis);
  46. display.setSize(400, 500);
  47. display.pan(250, 250);
  48. display.addControlListener(new DragControl());
  49. display.addControlListener(new PanControl());
  50. display.addControlListener(new ZoomControl());
  51. display.addControlListener(new WheelZoomControl());
  52. display.addControlListener(new FocusControl(1));
  53. display.addControlListener(new ZoomToFitControl());
  54. display.addControlListener(new ControlAdapter(){
  55. public void itemEntered(VisualItem item, MouseEvent e) {
  56.  
  57. System.out.println("伦家已经是:" + item.getGroup()+"的人了");
  58. vis.run("color");
  59. vis.run("layout");//重绘三秒
  60. }
  61. });
  62.  
  63. vis.putAction("color", color);
  64. vis.putAction("layout", layout);
  65.  
  66. JFrame frame = new JFrame();
  67. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  68. frame.pack();
  69. frame.setSize(600, 700);
  70. frame.add(display);
  71. frame.setVisible(true);
  72.  
  73. vis.run("color");
  74. vis.run("layout");
  75. }
  76.  
  77. }

  可以看出代码中nodeI.setShape(Constants.SHAPE_STAR);nodeI.setSize(4);nodeI.setFixed(true);是将节点的形状设为星形,大小放大为4并固定此节点;edgeI.setSize(8);将边的粗细设为8。这里还具有一个功能,就是代码跑起来显示图形运行三秒,当鼠标经过某点或边是,整个图形在运行三秒,为展示这种效果,首次使用ps做gif,想想也是醉了。。。

  Prefuse就先玩到这吧,真材实料送上5个Demo,虽然抢不到红包,抢点Demo补补脑也不错哦,走到这里,似乎我已经拉近了与Prefuse的距离,下一步就是力求亲密接触,碰撞出可视化狂拽炫酷的展示效果。觉得有用,记得点赞哦。

本文链接:漫谈可视化Prefuse(四)---被玩坏的Prefuse APIhttp://www.cnblogs.com/bigdataZJ/p/VisualizationSoloShow4.html

友情赞助

如果你觉得博主的文章对你那么一点小帮助,恰巧你又有想打赏博主的小冲动,那么事不宜迟,赶紧扫一扫,小额地赞助下,攒个奶粉钱,也是让博主有动力继续努力,写出更好的文章^^。

    1. 支付宝                          2. 微信

                      

漫谈可视化Prefuse(四)---被玩坏的Prefuse API的更多相关文章

  1. 漫谈可视化Prefuse(五)---一款属于我自己的可视化工具

    伴随着前期的基础积累,翻过API,读过一些Demo,总觉得自己已经摸透了Prefuse,小打小闹似乎已经无法满足内心膨胀的自己.还记得儿时看的<武状元苏乞儿>中降龙十八掌最后一张居然是空白 ...

  2. 漫谈可视化Prefuse(五)

    伴随着前期的基础积累,翻过API,读过一些Demo,总觉得自己已经摸透了Prefuse,小打小闹似乎已经无法满足内心膨胀的自己.还记得儿时看的<武状元苏乞儿>中降龙十八掌最后一张居然是空白 ...

  3. 漫谈可视化Prefuse(二)---一分钟学会Prefuse

    前篇<漫谈可视化Prefuse(一)---从SQL Server数据库读取数据>主要介绍了prefuse如何连接数据库sql server并读取数据进行可视化展现. 回头想想还是应该好好捋 ...

  4. 漫谈可视化Prefuse(六)---改动源码定制边粗细

    可视化一路走来,体会很多:博客一路写来,收获颇丰:代码一路码来,思路越来越清晰.终究还是明白了一句古话:纸上得来终觉浅,绝知此事要躬行. 跌跌撞撞整合了个可视化小tool,零零碎碎结交了众多的志同道合 ...

  5. 漫谈可视化Prefuse(三)---Prefuse API数据结构阅读有感

    前篇回顾:上篇<漫谈可视化Prefuse(二)---一分钟学会Prefuse>主要通过一个Prefuse的具体实例了解了构建一个Prefuse application的具体步骤.一个Pre ...

  6. 漫谈可视化Prefuse(六)

    可视化一路走来,体会很多:博客一路写来,收获颇丰:代码一路码来,思路越来越清晰.终究还是明白了一句古话:纸上得来终觉浅,绝知此事要躬行. 跌跌撞撞整合了个可视化小tool,零零碎碎结交了众多的志同道合 ...

  7. JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性

    一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替,但它两者 ...

  8. 【读后感】读《漫谈“大学生的四个learn”》之后有感

    在看完<许纪霖教授在上海财经大学演讲——漫谈“大学生的四个Learn”>(下问简称<四l>)之后突然有点话想说.其实我对这篇文章有感的,所以想写这篇文章来说说看,我对四个lea ...

  9. [转]被玩坏的innerHTML、innerText、textContent和value属性

    一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它,一般情况下我们可以使用textContent来代替,但它两者是否就能完全等同呢?在坑爹的表单元素(如input ...

随机推荐

  1. Java学习笔记:控制反转

    控制反转(Ioc)模式(又称DI:Dependency Injection)就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在 ...

  2. Linux之脚本安装软件

      查看启动程序   ps aux    准备工作 1.保证yum源正常使用 2.关闭SELinux和防火墙   下载脚本文件包 解压缩 运行 ./centors.sh

  3. 字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略

    因为手头需要使用一个第三方类库,网络上又找不到它的可用的版本,于是只好自己动手.这个类库使用了Dotfuscator 加密,用.NET Reflector加载程序集, 看到的字符串是乱码,如下面的代码 ...

  4. 【腾讯Bugly干货分享】iOS10 SiriKit QQ适配详解

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ece0331288fb4d31137da6 1. 概述 苹果在iOS10开放 ...

  5. 常用的HTML5、CSS3新特性能力检测写法

    伴随着今年10月底HTML5标准版的发布,未来使用H5的场景会越来越多,这是令web开发者欢欣鼓舞的事情.然而有一个现实我们不得不看清,那就是IE系列浏览器还占有一大部分市场份额,以IE8.9为主,w ...

  6. swfupload 例子

    upload.html <!DOCTYPE html> <html lang="en"> <head> <script type='tex ...

  7. Enterprise Architect的共享Respository设置,postgresql数据库

    Enterprise Architect有一个很实用的共享,在设计UML图的时候,可以连接到一个数据库服务器,将所有的画图数据共享在上面,所有连到这个server的人,都可以看到 别人的图,图中的元素 ...

  8. Java-继承,多态练习0922-06

    编写一个Shape类,具有属性:周长和面积: 定义其子类三角形和矩形,分别具有求周长的方法. 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a.b,使用对象a.b来 ...

  9. 我心中的核心组件(可插拔的AOP)~分布式文件上传组件~基于FastDFS

    回到目录 一些概念 在大叔框架里总觉得缺点什么,在最近的项目开发中,终于知道缺什么了,分布式文件存储组件,就是缺它,呵呵,对于分布式文件存储来说,业界比较公认的是FastDFS组件,它自己本身就是集群 ...

  10. ThinkPHP框架里隐藏index.php

    本文所写的配置在ThinkPHP3.2.2上测试过.按理也兼容其它版本. 首先修改配置文件: 'URL_CASE_INSENSITIVE' => true, // 默认false 表示URL区分 ...