欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[翻译]Prefuse用户手册

程序员文章站 2022-06-14 23:28:57
...

Prefuse用户手册

这个用户手册是为了帮助新用户熟悉prefuse的开发工具包,同时,也提供了相关的java API doc。第一章包含一个实例程序,展示了prefuse开发工具包可以提供的各方面功能。剩下的章节针对prefuse的各个特性,逐章作详细介绍。

您可以通过阅读手册的第一章的内容,并尝试运行其中的示例程序来了解prefuse的全貌。然后,根据需要阅读剩下的章节。

目录

  1. 介绍 - 介绍prefuse开发工具包的结构,并通过简单示例展示效果
    1.1. 概览
    1.2. 开发工具包的结构
    1.3. 构建项目
    1.4. 示例程序
  2. 2.数据
    2.1. 表 - 表数据结构
    2.2. 图和树 - 图、树数据结构
    2.3. 表达式 -
    2.4. 数据输入/输出 - 读、写格式化的文件
    2.5. 数据库连接 - 从关系数据库读取数据
  3. 可视化 -
    3.1. 可视化数据
    3.2. Action动作
    3.3. Renderer渲染器
    3.4. Display显示器
  4. 交互 -
    4.1. 控制器
    4.2. 动态查询 -
  5. 5.其他
    5.1. 颜色
    5.2. 字体
    5.3. 线条
    5.4. 日志

1. 简介

1.1 概览

Prefuse是一个用Java语言开发的、可扩展的数据可视化框架,主要用来构建可交互的数据可视化应用。prefuse可以被用来开发单独的应用程序、内嵌式的可视化组件和java applets。Prefuse简化了对数据的操作和数据到可视化组件的映射。

prefuse提供的特性:

  • 表、图、树等数据结构支持模糊的数据属性,支持数据索引,支持选择查询
  • 组件化的布局器、颜色、大小、图形等,支持分区,支持注解
  • 为通用的交互控制和操作提供一套库
  • 通过一个通用的活动调度机制来支持动画
  • 视图转换支持平移和缩放,包括几何和语义缩放
  • 动态查询数据的交互式过滤
  • 使用搜索引擎集成文本搜索
  • 动态布局和动画的物理力仿真引擎
  • 多个视图的灵活性,包括“概述+细节”和“小倍数”显示
  • 一种类似于sql的表达式语言,用于编写查询来预融合数据结构和创建派生的数据字段
  • 支持向SQL数据库发出查询,并将查询结果映射到预fuse的数据结构中
  • 用于创建自定义处理、交互和呈现组件的简单、开发人员友好的api

本手册的其余部分假定用户对Java编程语言有基本的了解,包括设置和构建Java项目。使用Swing或类似的用户界面工具包的知识,有助于理解prefuse的一些概念,以及将prefuse可视化工具集成到更大的应用程序中。使用数据库系统的经验也很有帮助(特别是如果使用内置的prefuse表达式语言进行数据操作),但不是必需的。

本章的其余部分提供了prefuse工具包的介绍,描述了软件体系结构,并对示例应用程序进行了分解,以演示所使用的体系结构。这里假设您已经能够下载并编译工具包,现在已经准备好开始学习如何使用它了。

1.2 prefuse工具包的结构

Prefuse是基于“信息可视化参考模型”而设计的,这个模型将数据可视化分解几个步骤,从获取数据和建模,到数据的可视化编码,再到数据可视化展示。这个过程如图所示:
[翻译]Prefuse用户手册

源数据被映射到支持可视化的表数据结构中;然后使用这些Table表数据来构造数据的可视化抽象,构建可视化模型中的属性,如:位置、颜色和几何形状等;然后使用可视化的抽象来创建可视化的交互视图,用户交互可能会影响到框架的任何级别的变化。

  • 第一步是确定源数据,源数据可以是一张数据表,一张社交网络图,一个文件目录结构,或者其他的数据集。
  • 然后,使用源数据来构造Table表数据,table是源数据的内部表示。从源数据到表数据的过程可能只涉及从格式化的文件或数据库中读取数据,但可能涉及到任何数量的数据转换。
  • 第二步,生成的表数据会被映射成一个可视化的抽象,这个数据模型包括空间布局、颜色、大小和形状等视觉特征。可视化抽象负责包含所有需要的信息,以获取数据的可视化表示。
  • 第三步,可视化抽象中的数据的实际呈现是通过一个视图转换过程完成的,在这个过程中,呈现组件将可视化抽象的内容提取到任意数量的交互视图中。这些视图可以为数据提供不同的透视图,例如支持在特定区域内进行平移和缩放操作,或者使用“小倍数”显示数组来显示波动数据变量的不同快照。
  • 用户与可视化的交互(最常见的是通过鼠标和键盘输入)可以反馈到这个过程中,在可视化模型流程的任何阶段造成更改或更新,例如:拖动一个项目,缩放一个视图,或者打开一个不同的数据文件。

上面描述的参考模型与用于实现用户界面的流行的MVC(模型-视图-控制器)设计模式非常相似。此模式将用户界面组件(例如,滑动条或组合框)分解为:
* 一个保存数据值的模型model
* 一个或多个视图view显示该模型的内容
* 用于处理用户输入的控制器,适当地更新模型和视图以响应交互式操作

下图演示了prefuse工具包的不同包和类如何实现信息可视化引用模型,为可视化流程的每个阶段提供支持。

[翻译]Prefuse用户手册

  • prefuse.data包:为表示数据提供表、图和树等数据结构,提供参考模型的数据表。Tuple类表示Table的行,Node和Edge类表示图和树结构的成员,Graph和Tree类是使用Table实例来实现的,用于存储节点和边数据。这些数据结构是内存有效的,并且,如在手册中稍后讨论的那样,也可以支持查询特定的数据范围或值。
  • 作为一个高级特性,prefuse还提供了一种集成的表达式语言。这种语言可以用来编写查询来预融合数据结构,并将派生的数据列作为现有数据字段的函数(从而提供一种简单的数据转换形式)。表达式语言是使用prefuse.data的类实现的。
  • prefuse.data.io包:提供了从格式化的文件中读取和写入表、图和树数据的类。对于表,CSV(逗号分隔值)和分隔文本(制表符分隔符、管道分隔符等)都支持。对于网络,支持基于xml的GraphML和TreeML文件格式。
  • prefuse.data.io.sql包:提供用于向sql数据库发出查询的工具,然后在prefuse表中返回结果。从数据库返回的适当结构化的表也可以用作图或树中的节点和边表。
  • Visualization类:通过将数据添加到prefuse的Visualization类,可以创建数据集的可视化抽象。这创建了一个特殊的数据结构,其中包括原始数据,但也引入了新的可视化特定的数据字段,比如x、y坐标和颜色、大小和字体值。对于任何支持元组、节点或添加到可视化的边,都会创建相应的VisualItem实例。VisualItems提供了对可视化属性和底层数据值的访问。NodeItem和edge类是VisualItem实例,它还提供了对支持图结构的访问。
  • prefuse.action包:具体的可视化映射由action模块提供,这些是独立的处理模块,用于设置项目可见性、计算布局、分配颜色值,以及在可视化的VisualItem实例上的任意数量的其他处理任务。
  • prefuse.action包及其子包:提供了一个丰富的组件库,用于布局、可视化编码、失真(例如,鱼眼视图)和动画。自定义可视化通常涉及创建新的Action子类来提供特定于应用程序的处理任务。
  • VisualItem实例的实际外观是由渲染器模块决定的。渲染器负责绘制项目和计算项目边界(一个项目在屏幕上占用了多少空间)。Prefuse提供了用于绘制各种形状、标签和图像的呈现程序。而且,呈现器接口非常简单(只有三种方法),从而简化了创建自定义呈现程序的过程。一个给定的VisualItem的渲染器是由一个渲染器工厂决定的,当一个VisualItem被绘制到屏幕上时,它被要求提供相应的渲染器。
  • 交互视图是由显示组件提供的,它作为一个摄像机在一个可视化的内容上。该显示将在当前视图中绘制所有项目,并可根据需要进行缩放、放大和旋转。单个可视化可以与多个显示实例相关联,支持不同的多视图配置,包括概述+细节视图和小的倍数显示。显示实例是一流的用户界面组件,可以添加到Java应用程序和applet中。
  • 每个显示还支持任意数量的交互控件,它们在显示和单独的VisualItems上处理鼠标或键盘操作。prefuse。控件包提供了预先构建的控件,用于选择焦点项目、拖拽项目、缩放和旋转显示视图。此外,通过子类化控件来创建定制控件是很容易的。
  • 最后,交互还可以通过在prefuse.data中提供的动态查询绑定来实现。查询包裹这些类在表数据的列和该列的表达式谓词(或查询)之间创建绑定。这些绑定可以自动生成适当的用户界面组件(例如,滑动条、单选按钮、复选框、文本搜索框等),以便直接操作查询的设置。正如在后面的示例应用程序中所看到的,这可以用于交互式地筛选感兴趣的数据项。

备注:

信息可视化参考模型(The information visualization reference model):在Ed Chi的博士论文工作中开发了信息可视化参考模型。Chi表示,该框架成功地模拟了大量的可视化应用程序,该模型与VTK等现有图形工具包中使用的数据流模型功能相当。

1.3 构建项目

构架基于prefuse的可视化应用的步骤如下:
1. 将数据加载到prefuse的数据结构中,或者从文件中读取数据,从数据库加载数据,或者通过自定义数据源。
2.创建一个可视化图,将已加载的数据映射到一个可视化的抽象。表、图形和/或树被添加到可视化中,并为后面的引用提供了一个惟一的数据组名称。
3.创建一个RendererFactory并将其注册为可视化。工厂负责将呈现程序分配给VisualItems。
4.构建一系列处理可视化抽象的数据处理操作。这些操作可能涉及到任何事情,但是常见的示例包括设置可视项目的位置、颜色、大小和形状,或者在不同的配置之间对这些属性进行动画。这些操作实例可以被分组到action list中,以执行各种处理任务。将直接调用的操作被添加到可视化中,并给出一个惟一的名称,以便可以引用它们。
5.初始化一个或多个交互显示,用于查看和操作可视项。通过向显示添加控件来指定交互行为。可以使用动态查询绑定添加对数据项的搜索和过滤。

1.4 示例程序

在本节中,我们将解析一个prefuse应用程序的示例:一个简单的社交网络可视化。我们的视觉化将会提供一个动态的、由动画控制的社交网络,其中的节点会根据性别来显示,并显示出他们所代表的人的名字。下面给出的所有代码都假定在应用程序类的主方法中。本例的完整代码如example.java所示:
[翻译]Prefuse用户手册
1.加载数据model
第一步是将图形数据加载到prefuse图实例中。首先看一下这个文件的内容:socialnet.xml。注意,节点有两个数据属性:一个名称字段和一个性别字段。下面的代码展示了如何加载graphml格式的socialnet.xml文件,使用GraphMLReader类添加prefuse图形数据结构。

Graph graph = null;
try {
    graph = new GraphMLReader().readGraph("/socialnet.xml");
} catch ( DataIOException e ) {
    e.printStackTrace();
    System.err.println("Error loading graph. Exiting...");
    System.exit(1);
}

2.创建Visualization
现在,我们需要创建图形的可视化抽象。为了做到这一点,我们首先创建一个新的 Visualization实例并将图形数据添加到它。我们用“graph”来命名要加载的图数据。这个数据组名称稍后将用于引用可视数据。当将Graph或Tree实例添加到visualization时,另外两个子组会自动注册:一个用于节点(带有”.node“后缀)和一个用于边(带有“.edge”后缀)。我们将在后面的示例中看到这些子组。

// add the graph to the visualization as the data group "graph"
// nodes and edges are accessible as "graph.nodes" and "graph.edges"
Visualization vis = new Visualization();
vis.add("graph", graph);

3.设置渲染器
下一步是设置渲染器,用来绘制现在包含在Visualiaztion中的VisualItems。默认情况下,可视化包含一个DefaultRendererFactory的实例,该工厂对象使用EdgeRenderer(默认情况下,它会直接画出直线的边)来处理所有的EdgeItems,以及使用ShapeRenderer(它将items作为基本形状,如正方形和三角形)来处理其他所有items。因为我们希望在节点上看到文本标签,所以我们创建了一个新的 LabelRenderer,并告诉它使用标签的“name”数据字段的值。我们还告诉渲染器使用圆形的边缘来进行标签的形状,让它看起来更流畅。然后,我们创建一个新的DefaultRendererFactory,作为所有非EdgeItems的默认渲染器(所有的EdgeItems都将使用前面提到的默认的EdgeRenderer)。DefaultRendererFactory有很多我们目前还没有使用的功能——我们还可以设置默认的edge渲染器,并添加任何管理渲染器分配的附加规则(请参阅API文档以获得更多信息)。

// draw the "name" label for NodeItems
LabelRenderer r = new LabelRenderer("name");
r.setRoundedCorner(8, 8); // round the corners

// create a new default renderer factory
// return our name label renderer as the default for all non-EdgeItems
// includes straight line edges for EdgeItems by default
vis.setRendererFactory(new DefaultRendererFactory(r));

4.定义操作Action
接着,写可视化相关的代码。这些都是通过创建在可视化中处理VisualItems的Action模块来提供的。我们从创建一组色彩动作开始。每个VisualItem在默认情况下支持三个颜色值: stroke描边、fill填充和textColor文本颜色。stroke描边的颜色是线条和轮廓的颜色,fill填充色代表了item的内部颜色,而textColor文字颜色是任何文本字符串或标签的颜色。所有颜色的默认值都是纯透明的,因此默认情况下没有绘制任何颜色。在prefuse中,每个颜色值被编码为一个整数,表示RGBA(红-绿-蓝alpha)值,每个值从0到255。Alpha表示透明度,0是完全透明的,255是完全不透明的。ColorLib类提供了许多用于创建颜色值的有用方法。
为了根据社交网络中的人的性别来分配颜色,我们首先创建一个自定义的调色板color palette。这只是一个被允许的颜色值的数组。在本例中,我们创建了一个为女性粉色的数组,为男性创建了淡蓝色的数组。然后,我们创建一个DataColorAction 来分配颜色。DataColorAction 的构造函数参数包括:
* 要处理的数据组的名称(在本例中是graph.node);
* 用于基础编码的数据字段的名称(在本例中是gender)
* 数据字段的类型:NOMINAL() 、ORDINAL ()、NUMERICAL (数字)
* 设置的颜色字段,通常是描边、填充或文本颜色
* 一个可选的调色板(如果没有提供调色板,就会创建一个默认的调色板)。
关于ORDINAL 的一个注意事项:DataColorAction将按其自然排序顺序,按字母顺序排列顺序和顺序数据的值,这是按字母顺序排列的。这就是为什么粉色的颜色首先出现在调色板palette上,因为女性的“F”先于“男性”的排序顺序。
最后,我们创建一个ActionList实例,它将所有颜色分配操作都分组到一个可执行单元中。

// create our nominal color palette
// pink for females, baby blue for males
int[] palette = new int[] {
    ColorLib.rgb(255,180,180), ColorLib.rgb(190,190,255)
};
// map nominal data values to colors using our provided palette
DataColorAction fill = new DataColorAction("graph.nodes", "gender",
    Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
// use black for node text
ColorAction text = new ColorAction("graph.nodes",
    VisualItem.TEXTCOLOR, ColorLib.gray(0));
// use light grey for edges
ColorAction edges = new ColorAction("graph.edges",
    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);

接下来,我们创建一个单独的ActionList,它提供了一个动画布局。所有的操作实例都可以被参数化来运行一次(默认),或者在给定的时间内重复运行。通过提供参数无限作为持续时间值,我们告诉ActionList将无限期地运行,从而导致布局的连续更新。然后,我们添加一个ForceDirectedLayout来分配图形元素的空间位置。我们还添加了一个重新绘制的动作,以表示在重新计算布局之后,任何显示都应该重新绘制。

// create an action list with an animated layout
// the INFINITY parameter tells the action list to run indefinitely
ActionList layout = new ActionList(Activity.INFINITY);
layout.add(new ForceDirectedLayout("graph"));
layout.add(new RepaintAction());

现在我们将两个actionlist添加到可视化中。这导致在可视化中正确地注册了这些操作,这样它们就可以在以后调用时访问可视化。每个注册的操作也都有一个惟一的名称供参考。

// add the actions to the visualization
vis.putAction("color", color);
vis.putAction("layout", layout);

5.设置Display
接着,我们需要为可视化数据创建一个Display。在这里,我们创建了一个新的Display实例,用于从可视化中拉出所有的VisualItems(您还可以选择一个谓词来控制显示将考虑的项目)。我们还设置了所需的大小,以像素为单位显示。然后,我们向显示器添加三个交互控件:
* 用鼠标拖拽来拖动VisualItems的拖动控件
* 在显示背景下移动显示区域的一种控制面板
* 放大显示的缩放控件,用垂直的右键单击鼠标拖动
我们使用控件的默认设置。用来触发控件和其他设置的鼠标按钮可以通过使用其他构造函数来更改。

// create a new Display that pull from our Visualization
Display display = new Display(vis);
display.setSize(720, 500); // set display size
display.addControlListener(new DragControl()); // drag items around
display.addControlListener(new PanControl());  // pan with background left-drag
display.addControlListener(new ZoomControl()); // zoom with vertical right-drag

6.加载 visualization
最后要做的就是将显示添加到一个新的应用程序窗口中,并设置正在运行的东西。我们创建一个新的JFrame实例(Java Swing用户界面工具包中的*窗口类),设置它的标题,并确保当窗口关闭时应用程序退出。然后我们添加我们的显示,“打包”窗口(确保组件——在本例中是我们的显示——被正确地放置),并使窗口可见。最后,我们运行颜色分配操作列表,确保每个项目都有正确的颜色,然后设置持续运行的布局列表。

// create a new window to hold the visualization
JFrame frame = new JFrame("prefuse example");
// ensure application exits when window is closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(display);
frame.pack();           // layout components in window
frame.setVisible(true); // show the window

vis.run("color");  // assign the colors
vis.run("layout"); // start up the animated layout

备注:

您可以将这个示例完整地粘贴到文件Example.java中。在运行示例之后,尝试替换其中的一些组件。例如,您可以通过删除Activity.INFINITY数来更改布局ActionList,然后尝试使用工具包中包含的任何其他图形布局。
此外,在prefuse工具包分发版的演示文件夹中还有许多其他的示例应用程序。如果您对上面的示例感到满意,那么您就可以开始探索其他的演示了。