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