22.01.2014 Views

Guião prefuse - Sweet

Guião prefuse - Sweet

Guião prefuse - Sweet

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Aula 6- Introdução ao <strong>prefuse</strong><br />

Resumo:<br />

Prefuse no eclipse: configuração do ambiente de desenvolvimento<br />

Primeiro exemplo com <strong>prefuse</strong><br />

ColorAction: atribuição de cores a itens visuais<br />

Mudar o layout<br />

Acrescentar campos numa tabela<br />

DataColorAction: atribuição de cores a itens visuais baseado num campo<br />

de dados.<br />

6.1 <strong>prefuse</strong> no eclipse<br />

Importe para o eclipse o projecto <strong>prefuse</strong>.zip no eclipse (botão direito na janela<br />

do Package Explorer seleccionar import->Existing Projects into<br />

Workspace->Select archive File e escolher o ficheiro <strong>prefuse</strong>.zip).<br />

É possível aceder a todo o projecto <strong>prefuse</strong> incluindo código fonte, dados, testes,<br />

etc… navegue no projecto e execute algumas demonstrações para ver as<br />

potencialidades do <strong>prefuse</strong> (ver na pasta demos alguns exemplos (GraphView, ).<br />

Note que as principais fontes de ajuda para a utilização do <strong>prefuse</strong> são:<br />

Demos fornecidas no package.<br />

Página web do <strong>prefuse</strong> (http://<strong>prefuse</strong>.org/) nomeadamente a documentação<br />

(http://<strong>prefuse</strong>.org/doc/) e a API da biblioteca (http://<strong>prefuse</strong>.org/doc/api/)<br />

Código fonte.<br />

Configuração do ambiente de desenvolvimento:<br />

A associação da biblioteca <strong>prefuse</strong> a um projecto pode ser feita Adicionando um<br />

link para o ficheiro do tipo jar (tecla da direita Build Path-> Configure Build<br />

Path-> libraries->Add external JARs)<br />

É possível gerar o ficheiro <strong>prefuse</strong>.jar a partir do projecto importado na secção<br />

6.1 usando a opção export->JAR File.<br />

6.2 Esqueleto em Java<br />

Crie um novo projecto no Eclipse com o nome aula_1 e adicione o ficheiro<br />

aula_1.java que contem o código necessário para abrir uma janela 2D de desenho em<br />

Java. Execute o programa e observe o resultado.<br />

Associe ao projecto a biblioteca <strong>prefuse</strong> como indicado no ponto anterior.<br />

2ºsemestre 2010-2011 1/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

6.3 Primeiro exemplo em <strong>prefuse</strong>: um grafo simples<br />

Modifique o código fornecido para permitir realizar a visualização de um grafo<br />

simples. Para tal, deve apagar a função paint e acrescentar no main o código que<br />

segue de acordo com os 6 passos seguintes:<br />

1. Definição dos dados a visualizar: Crie um grafo com 6 nós ligados entre<br />

eles de forma arbitrária a partir do código:<br />

Graph graph = new Graph();<br />

Node Node1 = graph.addNode();<br />

Node Node2 = graph.addNode();<br />

graph.addEdge(Node1, Node2);<br />

2. Criação do objecto de visualização: O grafo será referenciado através da<br />

string associada a visualização.<br />

Visualization vis = new Visualization();<br />

vis.add("graph", graph);<br />

3. Rendering: Define como os objectos irão ser desenhados através da<br />

definição de um renderer e de uma renderFactory. A renderFactory<br />

pode conter mais do que um render permitindo desenhar objectos diferentes<br />

de forma diferente. Neste exemplo usamos um renderer simples.<br />

ShapeRenderer r = new ShapeRenderer();<br />

// create a new DefaultRendererFactory<br />

// This Factory will use the ShapeRenderer for all nodes.<br />

vis.setRendererFactory(new DefaultRendererFactory(r));<br />

4. Definição das acções: indica quais as acções a realizar sobre os dados que<br />

estamos a visualizar, ou seja vai definir os vários mapeamentos entre os<br />

dados e as representações visuais dos mesmos. Neste exemplo vamos<br />

desenhar os nós como quadrados verdes. As acções devem ser colocadas<br />

num lista de acções que serão depois associadas a visualização:<br />

ColorAction fill = new ColorAction("graph.nodes",<br />

VisualItem.FILLCOLOR, ColorLib.rgb(0, 200, 0));<br />

ActionList color = new ActionList();<br />

color.add(fill);<br />

5. Layout: O layout define a posição dos vários nós que irão ser desenhados,<br />

neste exemplo vamos usar um layout aleatório:<br />

ActionList layout = new ActionList();<br />

// We add the layout to the layout ActionList, and tell it<br />

// to operate on the "graph".<br />

layout.add(new RandomLayout("graph"));<br />

2ºsemestre 2010-2011 2/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Vamos também indicar a visualização que sempre que houver alterações do<br />

layout, a visualização deve ser actualizada através da acção<br />

RepaintAction.<br />

layout.add(new RepaintAction());<br />

É ainda necessário adicionar as acções e os layouts a visualização.<br />

vis.putAction("color", color);<br />

vis.putAction("layout", layout);<br />

6. Display e interacção: Falta agora criar uma display e adicionar alguma<br />

interacção através do controlListener.<br />

Display d = new Display(vis);<br />

// Set the size of the display.<br />

d.setSize(720, 500);<br />

// We use the addControlListener method to set up<br />

interaction.<br />

// The DragControl is a built in class for manually moving<br />

// nodes with the mouse.<br />

d.addControlListener(new DragControl());<br />

// Pan with left-click drag on background<br />

d.addControlListener(new PanControl());<br />

// Zoom with right-click drag<br />

d.addControlListener(new ZoomControl());<br />

7. Lançar a visualização: Aqui é criado o JFrame para a visualização e<br />

adicionado o display, não esquecer de lançar a visualização.<br />

JFrame frame = new JFrame("<strong>prefuse</strong> example");<br />

// Ensure application exits when window is closed<br />

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

// The Display object (d) is a subclass of JComponent,<br />

// wich can be added to JFrames with the add method.<br />

frame.add(d);<br />

// Prepares the window.<br />

frame.pack();<br />

// Shows the window.<br />

frame.setVisible(true);<br />

//Sem esquecer de lançar as listas de acções que criamos:<br />

vis.run("color");<br />

vis.run("layout");<br />

2ºsemestre 2010-2011 3/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Não se esqueça de adicionar os vários import necessários a medida que adiciona o<br />

código no programa, por exemplo neste caso:<br />

import <strong>prefuse</strong>.Display;<br />

import <strong>prefuse</strong>.Visualization;<br />

import <strong>prefuse</strong>.action.ActionList;<br />

import <strong>prefuse</strong>.action.RepaintAction;<br />

import <strong>prefuse</strong>.action.assignment.ColorAction;<br />

import <strong>prefuse</strong>.action.layout.RandomLayout;<br />

import <strong>prefuse</strong>.controls.DragControl;<br />

import <strong>prefuse</strong>.controls.PanControl;<br />

import <strong>prefuse</strong>.controls.ZoomControl;<br />

import <strong>prefuse</strong>.data.Graph;<br />

import <strong>prefuse</strong>.data.Node;<br />

import <strong>prefuse</strong>.render.DefaultRendererFactory;<br />

import <strong>prefuse</strong>.render.ShapeRenderer;<br />

import <strong>prefuse</strong>.util.ColorLib;<br />

import <strong>prefuse</strong>.util.GraphLib;<br />

import <strong>prefuse</strong>.visual.VisualItem;<br />

Corra o programa assim executado e observe o resultado. Comente algumas partes<br />

do código e observe o que ocorre.<br />

Acrescente nós para obter um grafo final com pelos menos 5 nós.<br />

6.4 Introdução de outras acções<br />

Repare que ainda não se consegue ver as ligações entre os nós. Crie mais algumas<br />

ligações arbitrarias entres os nós e acrescente uma acção que permita visualizar as<br />

ligações que existem no grafo (utilize a palavra chave edges e associe a cor ao<br />

VisualItem.STROKECOLOR).<br />

Pode ainda experimentar adicionar mais acções a visualização (por exemplo<br />

ColorAction, ShapeAction, SizeAction, StrokeAction (opcional)). Note<br />

que o strokeAction implica a utilização da classe java.awt.BasicStroke;<br />

6.5 Mudar o Layout<br />

Modifique agora o layout do grafo. Experimente por exemplo um layout baseado<br />

em forças de acordo (ForceDirectedLayout). Observe e interaja com o resultado.<br />

Neste caso não se esquece de especificar que a ActionList tem uma duração do tipo<br />

Activity.INFINITY para garantir que o display seja actualizado e que a animação<br />

nunca pare.<br />

ActionList layout = new ActionList(Activity.INFINITY);<br />

Pode ainda experimentar outros layout (por exemplo,<br />

NodeLinkTreeLayout, etc…)<br />

CircleLayout,<br />

6.6 Adição de mais informação e alterações na forma do objecto<br />

Modifique o grafo para conter informação adicional para cada nó (neste caso, o<br />

nome, idade, sexo e trabalho).<br />

Para tal adapte o código seguinte para criar de uma forma aleatório 20 nós<br />

diferentes usando a função rand.nextInt(valor) (rand do tipo random) e<br />

2ºsemestre 2010-2011 4/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

considerando 4 classes de trabalhos diferentes (por exemplo: professor, estudante,<br />

electricista e canalizador).<br />

graph.addColumn("id", Integer.class);<br />

graph.addColumn("idade", int.class);<br />

graph.addColumn("sexo", String.class);<br />

graph.addColumn("profissao", String.class);<br />

Random rand = new Random();<br />

Node n = graph.addNode();<br />

n.set("id",1);<br />

n.set("idade",rand.nextInt(45)+20);<br />

n.set("sexo", "M");<br />

n.set("profissao", "Canalizador");<br />

Crie também ligações entre nós de uma forma aleatória (por exemplo):<br />

for(int i = 0; i < 20; i++)<br />

{<br />

int primeiro = rand.nextInt(20);<br />

int segundo = rand.nextInt(20);<br />

graph.addEdge(primeiro, segundo);<br />

}<br />

6.7 DataColorAction<br />

Adicione uma acção do tipo DataColorAction para permitir visualizar com<br />

vermelho as mulheres e a azul os homens adaptando o código que segue:<br />

int[] palette = {ColorLib.rgb(200, 0, 0), ColorLib.rgb(0,0, 200)};<br />

DataColorAction fill = new DataColorAction("graph.nodes", "sexo",<br />

Constants.NOMINAL, VisualItem.FILLCOLOR, palette);<br />

Usando as classes DataColorAction e DataSizeAction modifique a visualização<br />

de acordo com outros campos de dados.<br />

2ºsemestre 2010-2011 5/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Aula 7- Introdução ao <strong>prefuse</strong><br />

Resumo:<br />

Modificar a representação<br />

abstractShapeRenderer.<br />

dos nós, utilização de um<br />

Visualização de informação textual (labels).<br />

Interacção com o rato através de controlListener e controlAdapter.<br />

7.1 Modificar o objecto a visualizar<br />

Crie um novo Projecto e utilizando o código aula_2.java fornecido que é uma<br />

possível solução da última aula (em alternativa pode utilizar o código da última aula).<br />

Modifique o código outros objectos visuais para representar cada nó. Para tal, é<br />

necessário criar uma nova classe baseada na classe AbstractShapeRenderer de<br />

forma a poder modificar a representação de cada nó de acordo com os dados.<br />

Acrescente a classe que segue num ficheiro (Finalrenderer.java) e faça as<br />

alterações necessário para utilizar esta função para desenhar os objectos em vez do<br />

ShapeRenderer usado na última aula.<br />

import java.awt.Shape;<br />

import java.awt.geom.Ellipse2D;<br />

import <strong>prefuse</strong>.render.AbstractShapeRenderer;<br />

import <strong>prefuse</strong>.visual.VisualItem;<br />

public class FinalRenderer extends AbstractShapeRenderer{<br />

protected Ellipse2D m_ell = new Ellipse2D.Double();<br />

// Método que retorna o objecto a visualizar<br />

protected Shape getRawShape(VisualItem item)<br />

{<br />

m_ell.setFrame(item.getX(),item.getY(),(Integer)<br />

item.get("idade")/3, (Integer) item.get("idade")/3);<br />

return m_ell;<br />

}<br />

}<br />

Modifique a classe para que os homens sejam representados com rectângulos e as<br />

mulheres com elipses.<br />

2ºsemestre 2010-2011 6/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

7.2 Utilização de um LabelRenderer<br />

Existe um renderer predefinido para visualizar informação textual junto aos<br />

nomes.<br />

Crie um LabelRenderer associado ao id e utilize esse renderer no lugar do<br />

finalRenderer criado na alínea anterior para visualizar junto a cada nó o id<br />

associada ao mesmo.<br />

Modifique o programa para obter uma visualização parecida com aquela<br />

apresentada na Figura 7-1. Note que é necessário criar uma nova acção associada a<br />

propriedade VisualItem.TEXTCOLOR. faça as modificações para visualizar a profissão<br />

em vez do id.<br />

Figura 7-1: Exemplo de utilização do LabelRenderer<br />

7.3 Utilização de um decorator<br />

A utlização de um LabelRenderer permite facilmente criar uma visualização<br />

baseado numa string. Contudo no exemplo anterior substituímos o shapeRenderer<br />

pelo labelRenderer logo, não era possível modificar a representação gráfica de cada<br />

nó.<br />

Vamos agora modificar o código para permitir utilizar um renderer diferente em<br />

função do objecto visual a representar (nó ou etiqueta). Para tal vamos utilizar as<br />

etiquestas (decorators).<br />

Altere o programa para voltar a visualização do ponto 7.1 (utilizando o<br />

Finalrenderer) e sem informação textual junto do nó.<br />

Modifique o código associado ao renderer pelo código seguinte. Este código<br />

coloca dois renderer na renderFactory um para os nós, e um para as etiquetas que<br />

estão associado ao nome label e que irão visualizar o id do nó.<br />

FinalRenderer r = new FinalRenderer();<br />

LabelRenderer l = new LabelRenderer("id");<br />

DefaultRendererFactory drf = new DefaultRendererFactory(r);<br />

drf.add(new InGroupPredicate("labels"),l);<br />

final Schema DECORATOR_SCHEMA = PrefuseLib.getVisualItemSchema();<br />

DECORATOR_SCHEMA.setDefault(VisualItem.INTERACTIVE, false);<br />

2ºsemestre 2010-2011 7/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

DECORATOR_SCHEMA.setDefault(VisualItem.TEXTCOLOR,ColorLib.rgb(200,<br />

200,0));<br />

DECORATOR_SCHEMA.setDefault(VisualItem.FONT,FontLib.getFont("Times<br />

New Roman",18));<br />

vis.addDecorators("labels", "graph.nodes", DECORATOR_SCHEMA);<br />

vis.setRendererFactory(drf);<br />

É preciso ainda criar um layout para indicar onde os decorators (etiquetas)<br />

devem ser colocadas. Para tal, crie um ficheiro DecoratorLayout.java com o código<br />

seguinte:<br />

import java.awt.geom.Rectangle2D;<br />

import java.util.Iterator;<br />

import <strong>prefuse</strong>.action.layout.Layout;<br />

import <strong>prefuse</strong>.visual.DecoratorItem;<br />

import <strong>prefuse</strong>.visual.VisualItem;<br />

public class DecoratorLayout extends Layout<br />

{<br />

public DecoratorLayout(String group) {<br />

super(group);<br />

}<br />

public void run(double frac)<br />

{<br />

Iterator iter = m_vis.items(m_group);<br />

while ( iter.hasNext() ) {<br />

DecoratorItem decorator = (DecoratorItem)iter.next();<br />

VisualItem decoratedItem = decorator.getDecoratedItem();<br />

Rectangle2D bounds = decoratedItem.getBounds();<br />

// Get the center point for the object,<br />

// and then set that point as the decorator's location.<br />

}<br />

}<br />

double x = bounds.getCenterX();<br />

double y = bounds.getCenterY();<br />

setX(decorator, null, x);<br />

setY(decorator, null, y);<br />

}<br />

Não se esqueça de adicionar esse layout a visualização.<br />

Modifique o código para que as etiquetas não apareçam sobre os nós, mas sim ao<br />

lado. Tente obter uma visualização final parecida com a Figura 7-2 (note a utilização<br />

de um DataColorAction para mapear a cor em função do sexo e a presença de um<br />

contorno nos nós).<br />

2ºsemestre 2010-2011 8/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Figura 7-2: Visualização final com decorators<br />

7.4 Interacção com o rato<br />

Vamos agora permitir adicionar mais alguma interactividade a visualização.<br />

Vamos começar por criar um tooltip para permitir indicar alguma informação<br />

quando o rato estiver localizado sobre um nó. Adicione o código seguinte e observe o<br />

que sucede:<br />

d.addControlListener(new ToolTipControl("profissao"));<br />

Outra forma mais avançada de criar interacção é criar um controlAdapter que irá<br />

capturar os eventos do rato. Crie um novo ficheiro MyControlListener com o código<br />

seguinte e tente adicionar esse controlo a visualização. Observe.<br />

import java.awt.event.MouseEvent;<br />

import javax.swing.JPopupMenu;<br />

import <strong>prefuse</strong>.visual.NodeItem;<br />

import <strong>prefuse</strong>.controls.ControlAdapter;<br />

import <strong>prefuse</strong>.controls.Control;<br />

import <strong>prefuse</strong>.visual.VisualItem;<br />

public class MyControlListener extends ControlAdapter implements<br />

Control {<br />

public void itemClicked(VisualItem item, MouseEvent e)<br />

{<br />

if(item instanceof NodeItem)<br />

{<br />

String prof = ((String) item.get("profissao"));<br />

int idade = (Integer) item.get("idade");<br />

JPopupMenu jpub = new JPopupMenu();<br />

2ºsemestre 2010-2011 9/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

jpub.add("profissao: " + prof);<br />

jpub.add("idade: " + idade);<br />

jpub.show(e.getComponent(),(int) item.getX(), (int)<br />

item.getY());<br />

}<br />

}<br />

}<br />

Adicione na classe MyControlListener o código necessário para capturar os<br />

eventos de seleccionar e libertar um item (itemPressed e itemRelease)<br />

modificando a cor do item entre esses dois eventos para amarelo.<br />

Considere os 20 nomes no ficheiro nomes.txt. Modifique a visualização para<br />

permitir visualizar não só o ID mas também o nome das pessoas (por exemplo 1 –<br />

João Rocha) na visualização final. Modifique ainda os parâmetros que achar<br />

necessários para tornar a visualização mais ao seu gosto.<br />

2ºsemestre 2010-2011 10/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Aula 8- Visualização de tabelas com <strong>prefuse</strong><br />

Resumo:<br />

<br />

<br />

<br />

<br />

<br />

Análise da tabela de dados com EXCEL - gráficos dinâmicos<br />

Leitura de um ficheiro CSV<br />

Visualização de uma tabela (área de desenho, eixos)<br />

Exemplos de acções e Interacções<br />

Filtragem dos dados a visualizar<br />

8.1 Análise da tabela com EXCEL - gráficos dinâmicos<br />

Abra, no EXCEL, o ficheiro Musicas.xls que contém uma listagem com<br />

informação de uma colecção de CD’s. Analise a informação disponibilizada e crie<br />

uma tabela dinâmica com o campo “Tipo de Música” nas colunas, o campo Editora<br />

nas linhas e o Preço na área de Dados.<br />

Efectue agora um gráfico dinâmico apresentando o valor total dos CD’s em função<br />

das editoras. O gráfico obtido (semelhante a Figura 8-1) deverá possibilitar também a<br />

apresentação da informação numa base anual.<br />

Figura 8-1: Exemplo de Gráfico dinâmico obtido com o EXCEL.<br />

2ºsemestre 2010-2011 11/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

8.2 Leitura de uma tabela para o <strong>prefuse</strong><br />

Guarde o ficheiro Musica.xls no formato csv. Verifique que o Excel usa o ponto e<br />

vírgula “;” como separador.<br />

Utilize o código fornecido (aula_3.java) para ler o ficheiro assim criado<br />

utilizando um DelimitedTextTableReader. Utilize as funções de escrita do JAVA<br />

(println) e as funções de acesso a tabela (getString) para verificar se os valores<br />

estão a ser lidos correctamente através da escrita na console. Verifique<br />

nomeadamente se o preço está a ser lido correctamente (ex:<br />

System.out.println("Preço: " + t.getDouble(i, 4)) ).<br />

Caso observe um problema tente arranjar forma de resolver o mesmo.<br />

8.3 Visualização da tabela<br />

Acrescente o código seguinte para permitir visualizar os preços dos CD’s em<br />

função do tipo de música. Note que a informação a mapear em cada eixo é definida<br />

através dos axislayout.<br />

Visualization vis = new Visualization();<br />

vis.addTable("tabela",t);<br />

ShapeRenderer r = new ShapeRenderer();<br />

vis.setRendererFactory(new DefaultRendererFactory(r));<br />

AxisLayout xaxis = new AxisLayout("tabela","Editora",<br />

Constants.X_AXIS,VisiblePredicate.TRUE);<br />

AxisLayout yaxis = new AxisLayout("tabela","Preço",<br />

Constants.Y_AXIS,VisiblePredicate.TRUE);<br />

ColorAction color = new ColorAction("tabela",<br />

VisualItem.STROKECOLOR, ColorLib.rgb(150,150,255));<br />

ActionList draw = new ActionList();<br />

draw.add(color);<br />

draw.add(xaxis);<br />

draw.add(yaxis);<br />

draw.add(new RepaintAction());<br />

vis.putAction("draw", draw);<br />

Display d = new Display(vis);<br />

d.setSize(720, 500);<br />

d.setAlignmentX(1000);<br />

d.addControlListener(new ZoomToFitControl());<br />

d.addControlListener(new PanControl());<br />

d.addControlListener(new WheelZoomControl());<br />

// create a new window to hold the visualization<br />

JFrame frame = new JFrame("<strong>prefuse</strong> example");<br />

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

frame.add(d);<br />

frame.pack();<br />

// layout components in window<br />

frame.setVisible(true); // show the window<br />

vis.run("draw"); // start up the animated layout<br />

2ºsemestre 2010-2011 12/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Modifique a visualização para mapear outra informação (o preço em função das<br />

editoras por exemplo). Acrescente também mais algumas acções (por exemplo<br />

modificar a cor de acordo com o CD ser duplo ou não).<br />

8.4 Área de desenho<br />

Acrescente o código seguinte no princípio da classe principal:<br />

private static Visualization m_vis ;<br />

private static Display m_d;<br />

private static Rectangle2D m_dataB = new<br />

Rectangle2D.Double();<br />

public static void displayLayout() {<br />

Insets i = m_d.getInsets();<br />

int w = m_d.getWidth();<br />

int h = m_d.getHeight();<br />

int iw = i.left+i.right;<br />

int ih = i.top+i.bottom;<br />

int aw = 85;<br />

int ah = 15;<br />

m_dataB.setRect(i.left, i.top, w-iw-aw, h-ih-ah);<br />

}<br />

m_vis.run("draw");<br />

Esta função vai permitir definir a partir da dimensão do display o tamanho da<br />

área onde desenhar o gráfico. Note que as variáveis de Visualization e de Display<br />

passam a ser membros da classe main para ser possível aceder as mesmas no método<br />

displayLayout (modifique o código com isso em atenção).<br />

A variável m_dataB contêm informação sobre a área de visualização do gráfico<br />

pelo que tem que ser associada aos AxisLayout da seguinte forma:<br />

xaxis.setLayoutBounds(m_dataB);<br />

yaxis.setLayoutBounds(m_dataB);<br />

Finalmente a função displayLayout() tem que ser executada no fim do<br />

programa para actualizar as dimensões da janela. Execute o código obtido.<br />

Modifique o programa para que a área do gráfico seja mais pequena deixando uma<br />

área de 20 pixéis livres de cada lado da janela.<br />

Redimensione a janela de desenho. O que observa? Este problema pode ser<br />

resolvido com um ComponentListener para garantir que a função seja invocada<br />

sempre que se muda o tamanho da janela da forma seguinte:<br />

m_d.addComponentListener(new ComponentAdapter() {<br />

public void componentResized(ComponentEvent e) {<br />

displayLayout();<br />

}<br />

});<br />

2ºsemestre 2010-2011 13/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

8.5 Visualização dos eixos<br />

Vamos agora visualizar os eixos do gráfico utilizando a classe AxisLabelLayout.<br />

Comece por criar dois eixos com o código seguinte. Note que os eixos vão usar os<br />

dados associados aos mesmos.<br />

AxisLabelLayout xlabels = new AxisLabelLayout("xlab",<br />

xaxis, m_xlabB);<br />

AxisLabelLayout ylabels = new AxisLabelLayout("ylab",<br />

yaxis, m_ylabB);<br />

m_xlabB e m_ylabB são dois membros (semelhantes a m_dataB) que definem a<br />

área de desenho dos eixos e que podem ser definidos na função displayLayout da<br />

forma seguinte:<br />

m_xlabB.setRect(i.left, h-ah-i.bottom, w-iw-aw, ah-10);<br />

m_ylabB.setRect(i.left, i.top, w-iw, h-ih-ah);<br />

Não se esqueça de adicionar os AxisLabelLayout a uma lista de acções.<br />

Finalmente é preciso indicar ao RenderFactory os renderers a usar para<br />

desenhar os eixos (semelhante ao que fizemos na última aula para as etiquetas e os<br />

nós), isso pode ser feito com o código seguinte:<br />

m_vis.setRendererFactory(new RendererFactory() {<br />

AbstractShapeRenderer sr = new ShapeRenderer();<br />

Renderer arY = new AxisRenderer(Constants.RIGHT,<br />

Constants.TOP);<br />

Renderer arX = new AxisRenderer(Constants.CENTER,<br />

Constants.FAR_BOTTOM);<br />

public Renderer getRenderer(VisualItem item) {<br />

if (item.isInGroup("xlab") )<br />

return arX;<br />

else if (item.isInGroup("ylab") )<br />

return arY;<br />

else<br />

return sr;<br />

}<br />

});<br />

Pode ainda modificar a formatação dos preços utilizando o código seguinte para o<br />

yLabel.<br />

NumberFormat nf = NumberFormat.getCurrencyInstance();<br />

nf.setMaximumFractionDigits(2);<br />

ylabels.setNumberFormat(nf);<br />

Tente também modificar a posição dos eixos (para cima e para a esquerda).<br />

2ºsemestre 2010-2011 14/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Figura 8-2: Visualização possível com eixos<br />

8.6 Acções e interacções adicionais<br />

Modifique a visualização para permitir veicular mais informação através de acções<br />

que modifiquem, por exemplo, a forma, a cor, etc. de acordo com a informação<br />

fornecida (Editora, álbum). Seria por exemplo interessante representar o tipo de<br />

música.<br />

Adicione também um tooltip para indicar o nome do álbum (note que o Tooltip<br />

é um ControlListener).<br />

8.7 Filtragem pelo ano<br />

Para permitir uma filtragem dos dados pelos anos, é necessário criar uma pesquisa<br />

do tipo lista (para retornar os anos que existem nos dados). Para tal comece por<br />

acrescentar ao código a linha seguinte que cria uma pesquisa do tipo lista no campo<br />

anos dos dados:<br />

ListQueryBinding yearsQ = new ListQueryBinding(vt, "Ano");<br />

Onde o objecto vt do tipo VisualTable e é retornada na criação da visualização:<br />

VisualTable vt = m_vis.addTable("tabela",t);<br />

É agora possível criar uma listbox na frame usando o código seguinte:<br />

Box ListBox = new Box(BoxLayout.X_AXIS);<br />

ListBox.add(yearsQ.createComboBox());<br />

ListBox.add(Box.createHorizontalGlue());<br />

frame.add(ListBox, BorderLayout.SOUTH);<br />

Execute o código e observe o que acontece.<br />

2ºsemestre 2010-2011 15/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Falta agora actualizar a visualização sempre que ocorrer uma modificação no filtro<br />

de pesquisa. Para tal adicione o código seguinte:<br />

e:<br />

ActionList update = new ActionList();<br />

update.add(new<br />

VisibilityFilter("tabela",yearsQ.getPredicate()));<br />

update.add(color);<br />

update.add(xaxis);<br />

update.add(yaxis);<br />

update.add(ylabels);<br />

update.add(xlabels);<br />

update.add(new RepaintAction());<br />

m_vis.putAction("update", update);<br />

UpdateListener lstnr = new UpdateListener() {<br />

public void update(Object src) {<br />

m_vis.run("update");<br />

}<br />

};<br />

yearsQ.getPredicate().addExpressionListener(lstnr);<br />

Observe outras opções de filtragem no exemplo Congress.java e adicione, por<br />

exemplo, uma opção de pesquisa pelo artista.<br />

Em alternativa, retire do site do Instituto Nacional de Estatística – INE<br />

(www.ine.pt) uma tabela que lhe pareça interessante e utilizando o que aprendeu nesta<br />

aula, crie uma visualização para esses dados.<br />

2ºsemestre 2010-2011 16/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Aula 9- Visualização de Árvores (Trees)<br />

Resumo:<br />

<br />

<br />

<br />

<br />

<br />

<br />

Leitura e visualização de uma árvore<br />

Criação de uma árvore.<br />

Mudança de Layouts<br />

Vista geral - Overview<br />

Graus de interesse.<br />

Exemplo: visualização de árvore de directórios.<br />

9.1 Leitura e visualização de uma árvore<br />

Utilize o código fornecido (aula_4.java) que permite ler o ficheiro treemlexemplo.xml<br />

utilizando a classe TreeMLReader. Note que esta classe permite abrir<br />

um ficheiro xml contendo uma arvore de acordo com a dtd definida no ficheiro<br />

treeml.dtd. Observe os ficheiros fornecidos para perceber a estrutura do ficheiro e<br />

ter uma ideia da árvore a visualizar.<br />

Note que para poder indicar a localização da DTD, tem que indicar no ficheiro<br />

XML o caminho completo com a localização do mesmo, ou em alternativa importar<br />

os dois ficheiros para o sistema de directórios do eclipse.<br />

Execute o código fornecido para visualizar a informação contida na árvore. Se<br />

desejar, modifique algumas acções da visualização (por exemplo as cores, ou o<br />

tamanho da fonte através de um objecto do tipo FontAction com a fonte por omissão<br />

(SetDefaultFont): FontLib.getFont("Tahoma",16)).<br />

9.2 Utilização de outros layouts<br />

Modifique o layout original e teste alternativas (É possível ver os layout<br />

disponíveis na classe <strong>prefuse</strong>.action.layout.graph.TreeLayout. Utilize e<br />

modifique por exemplo os layouts: NodeLinkTreeLayout, BalloonTreeLayout,<br />

RadialTreeLayout). Veja qual o layout que lhe parece mais adequado para um<br />

ficheiro com muitos nós (por exemplo chi-ontology.xml).<br />

2ºsemestre 2010-2011 17/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

9.3 Criação da uma árvore<br />

Crie uma árvore que indique a estrutura de ensino DETI de acordo com a Figura. A<br />

visualização final deve utilizar a abreviatura como etiqueta, a cor para indicar a área<br />

(Ensino ou Investigação), o tamanho para reflectir o nº de pessoas/nº clausus e um<br />

tooltip para indicar o nome completo.<br />

Para criar esta árvore pode em alternativa:<br />

Modificar o código fornecido utilizando as funções de criação de grafos<br />

(ver a aula 6.6) - Note que uma árvore é sempre um grafo – e a função<br />

addchild para adicionar filhos aos vários nós.<br />

Criar um novo ficheiro xml com a informação organizada de acordo com a<br />

dtd fornecida.<br />

Utilize a informação seguinte para criar a árvore (considere um valor de 50 para o<br />

tamanho dos ramos):<br />

DETI<br />

Teaching<br />

Undergraduate:<br />

MIECT –Engenharia de Computadores e Telemática (65)<br />

MIEET – Engenharia Electrónica e Telecomunicações (105)<br />

MSI – Tecnologias e Sistemas de Informação (30)<br />

Masters<br />

MIECT – Mestrado Integrado em Engenharia de Computadores e Telemática (65)<br />

MIEET – Mestrado Integrado em Engenharia Electrónica e Telecomunicações (105)<br />

MSI – Mestrado em Sistemas de Informação (30)<br />

Research<br />

IEETA - Institute of Electronics and Telematics Engineering of Aveiro<br />

ESCCL - Embedded Systems, Computing and Control Laboratory (10)<br />

ISTL - Information Systems and Telematics Laboratory (17)<br />

SPL - Signal Processing Laboratory (27)<br />

ATIBT - Transverse Activity on Innovative Biomedical Technologies (16)<br />

ATRI - Transverse Activity on Intelligent Robotics (17)<br />

IT – Telecomunication Institute<br />

EOC – Electronic and Optoelectronic Components (3)<br />

ICS - Integrated Circuits and Systems (4)<br />

NMC - Networks and Multimedia Communications (18)<br />

OC - Optical Communications (11)<br />

RMOM - Radio Microwaves and Millimeter Waves (26)<br />

Figura 9-1: Exemplo de árvore<br />

2ºsemestre 2010-2011 18/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

9.4 Vista geral - Overview<br />

Acrescente agora uma vista geral da visualização criando um novo Display de<br />

acordo com o código que segue:<br />

Display overview = new Display(vis);<br />

overview.setBorder(BorderFactory.createLineBorder(Color.BLA<br />

CK, 1));<br />

overview.setSize(100,100);<br />

overview.zoom(new Point2D.Float(0,0),0.2);<br />

overview.addControlListener(new PanControl());<br />

overview.addControlListener(new ZoomControl());<br />

d.add(overview);<br />

9.5 Grau de interesse e animação<br />

Modifique o código para permitir vários graus de interesse na visualização.<br />

Comece por voltar a um layout do tipo NodeLinkTreeLayout e de seguida adicione<br />

no principio da lista de acções um FisheyeTreeFilter semelhante ao código que<br />

segue:<br />

filter.add(new FisheyeTreeFilter("tree", 1));<br />

Execute o código assim obtido alterando o último parâmetro do<br />

FisheyeTreeFilter variando entre 1 e 3. Observe.<br />

É preciso agora adicionar alguma interactividade para permitir mudar o grau de<br />

interesse ao clicar nos nós. Para tal vamos adicionar um controlo listener que vai<br />

correr o filtre sempre que se clicar num dado nó:<br />

d.addControlListener(new FocusControl(1, "filter"));<br />

Teste o código novamente tentando clicar nos vários nós e observar o<br />

comportamento da visualização. Modifique o valor de 1 para 0, o que observa?<br />

Finalmente vamos permitir uma animação na passagem entre graus de interesse.<br />

Vamos criar uma nova acção para realizar esta animação:<br />

ActionList animate = new ActionList(1000);<br />

animate.setPacingFunction(new SlowInSlowOutPacer());<br />

animate.add(new QualityControlAnimator());<br />

animate.add(new VisibilityAnimator("tree"));<br />

animate.add(new LocationAnimator("tree.nodes"));<br />

animate.add(new ColorAnimator("tree.nodes"));<br />

animate.add(new RepaintAction());<br />

vis.putAction("animate", animate);<br />

vis.alwaysRunAfter("filter", "animate");<br />

Repare que na primeira animação a localização dos nós não é correcta. Pois a<br />

mesma só é calculada quando é necessário. Pode se resolver esse problema<br />

adicionando um layout que força o cálculo de todo o layout antes da visualização.<br />

2ºsemestre 2010-2011 19/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

CollapsedSubtreeLayout subLayout = new<br />

CollapsedSubtreeLayout("tree",<br />

Constants.ORIENT_LEFT_RIGHT);<br />

Este novo layout deve ser adicionada a acção de layout. Os dois Layout<br />

também devem ser adicionados a actionList Filter para garantir que sempre que é<br />

actualizada a visualização, os layouts também são actualizados.<br />

9.6 Exemplo: visualização de uma arvore de directórios<br />

Utilize o programa xml-dir-listing (http://code.google.com/p/xml-dir-listing/)<br />

para criar um ficheiro xml com a organização de uma parte do seu disco. Em<br />

alternativa pode utilizar o ficheiro Aulas_list.xml que mapeia uma parte de uma<br />

árvore de directórios criado com o xml-dir-listing.<br />

O ficheiro assim criado não obedece ao formato padrão para árvores usado pelo<br />

<strong>prefuse</strong>. Contudo é fornecido uma classe (DirectoryMLReader) baseada na classe<br />

(TreeMLReader) que permite ler os ficheiros criados pelo xml-dir-listing.<br />

Tente visualizar o resultado do xml-dir-listing com o código anterior.<br />

Acrescente acções para tornar mais intuitiva a visualização, nomeadamente modificar<br />

os nós (cores, formas, …). Pode por exemplo utilizar o método que segue para<br />

permitir modificar as propriedades do nó que está seleccionado (note que a variável de<br />

visualização tem que ser um membro da classe para usar este código):<br />

public static class NodeColorAction extends ColorAction {<br />

public NodeColorAction(String group) {<br />

super(group, VisualItem.FILLCOLOR);<br />

}<br />

public int getColor(VisualItem item) {<br />

if ( m_vis.isInGroup(item, Visualization.FOCUS_ITEMS) )<br />

return ColorLib.rgb(198,229,229);<br />

else if ( item instanceof NodeItem ) {<br />

NodeItem nitem = (NodeItem)item;<br />

return ColorLib.color(Color.YELLOW);<br />

}<br />

return 0;<br />

}<br />

Modifique a classe NodeColorAction para que ficheiros apareçam em amarelo e<br />

directórios em azul (pode verificar o nº de filhos de um nó).<br />

Se não o fez, utilize o xml-dir-listing para criar a árvore correspondendo a<br />

parte de a sua árvore de directórios, para tal pode utilizar o comando seguinte na linha<br />

de comandos para criar a árvore do directório fornecido no ficheiro list.xml com<br />

profundidade 2. Note que este ficheiro será também usado na próxima aula.<br />

>>xml-dir-listing –d 2 –o “list.xml” “c:\Meu Directório”<br />

2ºsemestre 2010-2011 20/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Aula 10- Visualização de mapas de arvores (TreeMaps)<br />

Resumo:<br />

<br />

<br />

<br />

<br />

<br />

Leitura e visualização de uma árvore de directórios<br />

Visualização de um treemap<br />

Acções adicionais<br />

Interacção<br />

Pesquisa e filtragens<br />

10.1 Leitura e visualização de uma árvore<br />

Utilize o programa xml-dir-listing (http://code.google.com/p/xml-dir-listing/)<br />

para criar um ficheiro xml com a organização de uma parte do seu disco (se fez a<br />

alínea 9.6 da última aula pode aproveitar o ficheiro gerado). Utilize a classe fornecida<br />

(DirectoryMLReader) baseada na classe (TreeMLReader) que permite ler os ficheiros<br />

criados pelo xml-dir-listing.<br />

Ao longo da aula para testar as visualizações pode alternar entre o ficheiro gerado<br />

anteriormente ou o ficheiro chi-ontology.xml fornecido na última aula.<br />

Comece por utilizar o programa fornecido na aula anterior (aula5_1.java) ou, em<br />

alternativa, o programa da aula anterior para visualizar os dados numa árvore.<br />

10.2 Visualização de um TreeMap<br />

Modifique a visualização para permitir ver a árvore de directórios como um<br />

treemap.<br />

Comece por retirar todo o código associado a animação e visualize toda a árvore de<br />

directórios (para tal remova também o FisheyeTreeFilter), repare na dificuldade<br />

em visualizar toda a informação desse modo.<br />

Modifique agora o layout para o tipo SquarifiedTreeMapLayout, este layout<br />

utiliza um algoritmo para calcular os tamanhos das caixas do treemap que vão ser<br />

utilizados na visualização.<br />

Teste o código assim obtido. Repare como o SquarifiedTreeMapLayout apesar<br />

de calculado ainda não é aplicado. Para tal, é preciso criar uma classe do tipo<br />

AbstractShapeRenderer a colocar no RenderFactory para indicar qual a forma a<br />

utilizar na visualização da árvore.<br />

2ºsemestre 2010-2011 21/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

public static class NodeRenderer extends<br />

AbstractShapeRenderer {<br />

private Rectangle2D m_bounds = new Rectangle2D.Double();<br />

public NodeRenderer() {<br />

m_manageBounds = false;<br />

}<br />

protected Shape getRawShape(VisualItem item) {<br />

m_bounds.setRect(item.getBounds());<br />

return m_bounds;<br />

}<br />

} // end of inner class NodeRenderer<br />

Repare que esta classe indica que devem ser desenhados rectângulos (devolvidos<br />

pela método (getRawShape) mas deixa o cálculo das fronteiras ao layout<br />

(m_manageBounds = false). Acrescente este código ao programa e adicione um<br />

objecto do tipo NodeRenderer ao RenderFactory. Observe o resultado e modifique o<br />

código retirando todas as acções que deixam de ser necessárias (por exemplo a<br />

visualização das ligações).<br />

10.3 Acções adicionais<br />

Modifique a visualização para que a o preenchimento dos vários nós sem filhos do<br />

TreeMap esteja associado a sua profundidade na árvore. Para tal, pode adaptar a<br />

classe NodeColorAction (ver última aula) que extenda a classe ColorAction e onde<br />

o método GetColor retorne uma cor diferente em função do profundidade do item a<br />

visualizar. Para verificar a profundidade do nó, utilize o método getDepth do<br />

NodeItem. Crie uma classe BorderColorAction para modificar as cores dos limites<br />

da caixa de uma forma semelhante ao ColorAction. Nste caso, utilize um ColorMap<br />

para definir um mapa de cores através de uma lista de cores e dos índices máximos e<br />

mínimos. Note que pode criar o mapa de cores com o método<br />

ColorLib.getInterpolatedPalette.<br />

10.4 Etiquetas<br />

Acrescente um decorator para permitir a visualização de uma etiqueta (ver 7.3).<br />

O mesmo deve ser associado a uma condição do tipo treedepth para associar a<br />

etiqueta a nós de uma dada profundidade, por exemplo:<br />

Predicate labelP =<br />

(Predicate)ExpressionParser.parse("treedepth()=1");<br />

vis.addDecorators("labels", "tree.nodes", labelP,<br />

LABEL_SCHEMA);<br />

Para o tipo de fonte, pode utilizar o código seguinte:<br />

final Schema LABEL_SCHEMA =<br />

PrefuseLib.getVisualItemSchema();<br />

LABEL_SCHEMA.setDefault(VisualItem.INTERACTIVE, false);<br />

LABEL_SCHEMA.setDefault(VisualItem.TEXTCOLOR,<br />

ColorLib.gray(200));<br />

LABEL_SCHEMA.setDefault(VisualItem.FONT,<br />

FontLib.getFont("Tahoma",16));<br />

2ºsemestre 2010-2011 22/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

Crie também uma classe labelLayout (veja o exemplo TreeMap) para poder<br />

permitir visualizar em branco o nome dos directórios de mais alto nível (depth=1) e<br />

adicione um objecto dessa classe ao layout.<br />

public static class LabelLayout extends Layout {<br />

public LabelLayout(String group) {<br />

super(group);<br />

}<br />

public void run(double frac) {<br />

Iterator iter = m_vis.items(m_group);<br />

while ( iter.hasNext() ) {<br />

DecoratorItem item =<br />

(DecoratorItem)iter.next();<br />

VisualItem node = item.getDecoratedItem();<br />

Rectangle2D bounds = node.getBounds();<br />

setX(item, null, bounds.getCenterX());<br />

setY(item, null, bounds.getCenterY());<br />

}<br />

}<br />

} // end of inner class LabelLayout<br />

Modifique a condição do predicate para visualizar só directórios (pode<br />

acrescentar a condição "childcount()>0").<br />

Por fim, acrescente o código necessário para permitir acrescentar uma caixa branca<br />

relativa aos nós cujo nome estamos a visualizar para tal modificando adequadamente<br />

a classe BorderColorAction.<br />

Tente modificar a profundidade dos nós para os quais visualiza a etiqueta (varie<br />

por exemplo a profundidade entre 0 e 3). O código comporta-se como esperado?<br />

Acrescente o código seguinte que garante que nós pais estão acima dos nós filhos e<br />

observe o resultado:<br />

d.setItemSorter(new TreeDepthItemSorter());<br />

10.5 Interacção<br />

Comece por desactivar a interacção para todos os nós que tenham filhos, pode usar<br />

o código:<br />

Predicate<br />

No=<br />

(Predicate)ExpressionParser.parse("childcount()>0");<br />

vis.setInteractive(“tree.nodes”, No, false);<br />

Altere a classe que modifica a cor para permitir que o contorno do nó abaixo do<br />

rato tenha uma cor diferente (utilize a classe nitem.isHover() para verificar essa<br />

condição).<br />

É preciso ainda adicionar uns controllistener para garantir a actualização<br />

adequada da visualização. Pode ser feito com o código seguinte onde myBorder<br />

corresponde ao objecto do tipo BorderColorAction que controla as cores do<br />

contorno, note que este objecto tem de ser definido como final:<br />

d.addControlListener(new ControlAdapter() {<br />

public void itemEntered(VisualItem item,<br />

MouseEvent e) {<br />

item.setStrokeColor(myBorder.getColor(item));<br />

item.getVisualization().repaint();<br />

}<br />

public void itemExited(VisualItem item,<br />

MouseEvent e) {<br />

2ºsemestre 2010-2011 23/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

item.setStrokeColor(item.getEndStrokeColor());<br />

item.getVisualization().repaint();<br />

}<br />

});<br />

Acrescente agora uma caixa de texto por baixo da visualização que indique o nome<br />

do item. Pode usar o código que segue.<br />

final JFastLabel title = new JFastLabel("<br />

");<br />

title.setPreferredSize(new Dimension(350, 20));<br />

title.setVerticalAlignment(SwingConstants.BOTTOM);<br />

title.setBorder(BorderFactory.createEmptyBorder(3,0,0,0));<br />

title.setFont(FontLib.getFont("Tahoma", Font.PLAIN,<br />

16));<br />

Box box = UILib.getBox(new Component[]{title}, true, 10, 3,<br />

0);<br />

Adicione ainda a box a frame principal com o código:<br />

frame.add(box,BorderLayout.SOUTH);<br />

Acrescente ainda nos métodos itemEntered e itemExited o código necessário<br />

para actualizar o título de acordo com o nome do item seleccionado usando o código<br />

seguinte nas posições adequadas. Note que o title tem que ser do tipo final para<br />

permitir a sua utilização nestes métodos.<br />

title.setText(item.getString("name"));<br />

title.setText(null);<br />

10.6 Filtragem<br />

Para a pesquisa, pode utilizar o código seguinte semelhante ao utilizado em 8.7.<br />

searchQ = new SearchQueryBinding(vt.getNodeTable(),"name");<br />

vis.addFocusGroup(Visualization.SEARCH_ITEMS,<br />

searchQ.getSearchSet());<br />

searchQ.getPredicate().addExpressionListener(new<br />

UpdateListener() {<br />

public void update(Object src) {<br />

vis.run("filter");<br />

vis.run("layout");<br />

}<br />

});<br />

Note que a variável vt é do tipo VisualTree devolvido pelo código e que para<br />

permitir a utilização da variável vis no membro update, a mesma deve passar a<br />

final.<br />

final Visualization vis = new Visualization();<br />

VisualTree vt = vis.addTree("tree", t);<br />

Acrescente um searchPanel para permitir fazer uma pesquisa nos dados<br />

JSearchPanel search = searchQ.createSearchPanel();<br />

search.setShowResultCount(true);<br />

2ºsemestre 2010-2011 24/25 Paulo Dias


Visualização de Informação – Introdução ao <strong>prefuse</strong><br />

search.setBorder(BorderFactory.createEmptyBorder(5,5,4,0));<br />

search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11));<br />

Este SearchPanel pode ser colocado logo a seguir ao title modificando a linha<br />

onde é criado a caixa de visualização:<br />

Box box = UILib.getBox(new Component[]{title,search}, true,<br />

10, 3,0);<br />

Modifique agora a classe NodeColorAction para realçar os resultados da pesquisa<br />

usando o código seguinte.<br />

if ( vis.isInGroup(item, Visualization.SEARCH_ITEMS) )<br />

return ColorLib.rgb(191,99,130);<br />

Opcional:<br />

Utilize o método setColor da classe UILib para modificar as cores da caixa de<br />

texto (box). Modifique a cor do texto apresentado em função de uma propriedade dos<br />

dados que está a utilizar (pode utilizar código do tipo item.getString("atributo")<br />

para aceder aos dados de um item seleccionado)<br />

Faça os ajustes necessários para que os contornos do nível para o qual está a ser<br />

visualizado uma etiqueta tenham uma espessura diferente dos outros.<br />

2ºsemestre 2010-2011 25/25 Paulo Dias

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!