source: trunk/greenstone3-extensions/vishnu/src/vishnu/testvis/sammon/ClusterPanel.java@ 8189

Last change on this file since 8189 was 8189, checked in by kjdon, 20 years ago

first version of Imperial College's Visualiser code

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 16.1 KB
Line 
1package vishnu.testvis.sammon;
2
3import javax.swing.*;
4import java.awt.*;
5import java.awt.event.*;
6import java.util.Vector;
7import java.util.Enumeration;
8import vishnu.testvis.visual.*;
9import vishnu.testvis.object.*;
10import java.awt.image.*;
11
12class ClusterPanel extends JPanel
13{
14 Image offScreen=null;
15 Dimension offScreenSize;
16 Graphics2D offGraphics;
17 private SammCluster currentCluster;
18 private final int RADIUS = 30;
19 private SammCluster drawnCluster;
20 private GraphicalPane parentSammon;
21
22 boolean firstTime = true;
23 Graphics2D big;
24 BufferedImage bi;
25 Rectangle area;
26 Dimension d = null;
27
28 int locationID = -1;
29 JPopupMenu[] popups;
30 JPopupMenu popup;
31 Vishnu _currentMain;
32 DataManager dm;
33
34 public ClusterPanel(Vishnu currentMain, GraphicalPane parent)
35 {
36 this.parentSammon = parent;
37 _currentMain=currentMain;
38 dm = _currentMain.dataManager;
39 popup = new JPopupMenu();
40 popup.setVisible(false);
41 add(popup);
42
43 setOpaque(true);
44 setPreferredSize(new Dimension(600,600));
45 setBorder(BorderFactory.createCompoundBorder(
46 BorderFactory.createEmptyBorder(20,20,20,20),
47 BorderFactory.createLoweredBevelBorder()));
48
49 addComponentListener(
50 new ComponentAdapter()
51 {
52 public void componentResized(ComponentEvent evt)
53 {
54 if( parentSammon.dataMan != null && parentSammon.dataMan.getDocCount()>0){
55 repaint();
56 }
57
58 }
59 }
60 );
61
62 addMouseMotionListener( new MouseMotionAdapter()
63 {
64 public void mouseMoved(MouseEvent mouseEvent)
65 {
66 int docsInSelectedClusters=0;
67
68 if( parentSammon.dataMan == null) return;
69 int oldLocationID = locationID;
70
71 Vector clusters = parentSammon.dataMan.getSammonClusters();
72 if (clusters == null) return;
73 locationID = -1;
74 for (int i = clusters.size()-1 ; i >= 0 ; i--)
75 {
76
77 SammCluster cluster = (SammCluster) clusters.elementAt(i);
78 int x = (int) (cluster.getX()*(offScreenSize.width-2*RADIUS)) + RADIUS;
79 int y = (int) (cluster.getY()*(offScreenSize.height-2*RADIUS)) +RADIUS;
80
81 if (inCircle(mouseEvent,x,y,cluster.getDisplayedRadius()))
82 {
83 locationID = i;
84 }
85 if(cluster.getSelected())
86 docsInSelectedClusters+=cluster.documentIDs.size();
87 }
88
89 if ((oldLocationID != locationID) && (oldLocationID != -1))
90 popup.setVisible(false);
91
92
93 if (locationID != -1)
94 {
95 if (locationID != oldLocationID)
96 {
97
98 popup.removeAll();
99
100 String[] allWords = parentSammon.dataMan.getWords();
101
102 currentCluster = (SammCluster) clusters.elementAt(locationID);
103 String str = currentCluster.getSize() + " documents";
104 JMenuItem menuItem = new JMenuItem(str);
105 popup.add(menuItem);
106
107 menuItem.addActionListener(new ActionListener()
108 {
109 public void actionPerformed(ActionEvent actionEvent)
110 {
111 drawnCluster = currentCluster;
112 updateHLinkPanel();
113 repaint();
114 //update
115 }
116 });
117
118 popup.add(new JPopupMenu.Separator());
119 menuItem = new JMenuItem("Drill down");
120
121 if(!currentCluster.getSelected())
122 docsInSelectedClusters+=currentCluster.documentIDs.size();
123
124 if(docsInSelectedClusters<7)menuItem.setEnabled(false);
125 else menuItem.setEnabled(true);
126
127 // for drilldown
128 menuItem.addActionListener(new ActionListener()
129 {
130 public void actionPerformed(ActionEvent ActionEvent)
131 {
132 Vector idVector;
133 SammCluster thisCluster = getCurrentCluster();
134
135 int theIndex = thisCluster.getWords()[0];
136 String drillWords = new String(parentSammon.dataMan.getWords()[theIndex]);
137 for( int i = 1; i < thisCluster.getWords().length; i++ )
138 {
139 theIndex = thisCluster.getWords()[i];
140 drillWords += " " + parentSammon.dataMan.getWords()[theIndex];
141 }
142
143 Vector clusterPl = parentSammon.dataMan.getSammonClusters();
144
145 Vector idVect = (Vector)thisCluster.getIDs().clone();
146
147 thisCluster.setSelected(true);
148 for (int i = clusterPl.size()-1; i >= 0; i--)
149 {
150
151 SammCluster cluster = (SammCluster) clusterPl.elementAt(i);
152 if (!cluster.equals(thisCluster) && cluster.getSelected())
153 idVect.addAll(cluster.getIDs());
154 }
155 if(idVect.size()>6)
156 {
157
158 parentSammon.drillDown(idVect);
159
160 currentCluster=null;
161 drawnCluster=null;
162 //update();
163 repaint();
164 }
165
166 }
167 });
168 popup.add(menuItem);
169 if(!currentCluster.getSelected())
170 menuItem = new JMenuItem("Select");
171 else
172 menuItem = new JMenuItem("Deselect");
173 menuItem.addActionListener(new ActionListener()
174 {
175 public void actionPerformed(ActionEvent ActionEvent)
176 {
177 SammCluster cluster = getCurrentCluster();
178 cluster.setSelected(!cluster.getSelected());
179 //update();
180 repaint();
181
182 }
183 });
184
185 popup.add(menuItem);
186 int[] words = currentCluster.getWords();
187 popup.add(new JPopupMenu.Separator());
188 for(int c=0;c<4;c++)
189 {
190 int index = words[c];
191 if (index>= 0)menuItem = new JMenuItem(allWords[index]);
192 popup.add(menuItem);
193 menuItem.setEnabled(false);
194 }
195
196 popup.validate();
197 popup.setVisible(true);
198
199 }
200 popup.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
201 mouseEvent.consume();
202 }
203
204 }
205 });
206
207 setVisible(true);
208 }
209
210
211 public SammCluster getCurrentCluster() {return currentCluster;}
212
213
214 public void paint(Graphics g)
215 {
216 update(g);
217 }
218
219
220 public boolean inCircle(MouseEvent mouseEvent, int x, int y, int radius)
221 {
222 int dx2 = (mouseEvent.getX()-x)*(mouseEvent.getX()-x);
223 int dy2 = (mouseEvent.getY()-y)*(mouseEvent.getY()-y);
224
225 return (dx2 + dy2 < radius*radius);
226 }
227
228
229 private void drawFlag(Graphics g,int x, int y)
230 {
231 g.drawLine(x,y,x,y-12);
232 int [] xs = new int[3];
233 int [] ys = new int[3];
234 xs[0]=x;xs[1]= x+10; xs[2]=x;
235 ys [0]=y-12; ys[1]=y-7;ys[2]=y-2;
236 g.fillPolygon(xs,ys,3);
237 }
238
239
240 public void update(Graphics g)
241 {
242 Graphics2D g2 = (Graphics2D)g;
243 Dimension d = getSize();
244 offScreenSize = d;
245
246 int w = d.width;
247 int h = d.height;
248
249 area = new Rectangle(d);
250 bi = (BufferedImage)createImage(w, h);
251 offGraphics = bi.createGraphics();
252 area.setLocation(w/2-50, h/2-25);
253 BasicStroke myStroke = new BasicStroke(2,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER);
254
255 offGraphics.setColor(Color.white);
256 /*offGraphics.clearRect(0, 0, area.width, area.height);
257 offGraphics.draw(area);
258 offGraphics.fill(area);*/
259 offGraphics.fillRect(0,0,d.width,d.height);
260
261 if( parentSammon.dataMan.getDocCount()<1) return;
262
263 Vector clusters = parentSammon.dataMan.getSammonClusters();
264 if (clusters.size()==0) return;
265 double minNumDocs = ((SammCluster) clusters.elementAt(0)).getSize();
266 double maxNumDocs = ((SammCluster) clusters.elementAt(clusters.size()-1)).getSize();
267 double deltaNumDocs = maxNumDocs - minNumDocs;
268
269 for (int i = clusters.size()-1; i >= 0; i--) {
270
271 SammCluster cluster = (SammCluster) clusters.elementAt(i);
272 int x = (int) (cluster.getX()*(offScreenSize.width-2*RADIUS)) + RADIUS;
273 int y = (int) (cluster.getY()*(offScreenSize.height-2*RADIUS)) + RADIUS;
274
275 // Value between 0 and 1 representing the cluster (0 is the smaller cluster and 1 is the bigger one
276 double clusterWeight = (cluster.getSize() - minNumDocs)/ deltaNumDocs;
277
278 offGraphics.setColor(new Color((float)0.7, (float)0.7, (float)1));
279
280 cluster.setDisplayedRadius(RADIUS-(int)(RADIUS*(1-clusterWeight)/2));
281 myStroke = new BasicStroke(3,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER);
282 offGraphics.setStroke(myStroke);
283 offGraphics.fillOval(x - cluster.getDisplayedRadius(),
284 y - cluster.getDisplayedRadius(),
285 2*cluster.getDisplayedRadius(),
286 2*cluster.getDisplayedRadius());
287
288 offGraphics.setColor(new Color((float)0,(float)0, (float)0.7));
289 offGraphics.drawOval(x - cluster.getDisplayedRadius(),
290 y - cluster.getDisplayedRadius(),
291 2*cluster.getDisplayedRadius(),
292 2*cluster.getDisplayedRadius());
293
294 if (cluster.getSelected())
295 drawFlag(offGraphics,x,y-cluster.getDisplayedRadius());
296
297 if (cluster.equals(this.drawnCluster))
298 {
299
300 offGraphics.setColor(new Color((float)0.3, (float)0.3, (float)1));
301 offGraphics.fillOval(x - cluster.getDisplayedRadius(),
302 y - cluster.getDisplayedRadius(),
303 2*cluster.getDisplayedRadius(),
304 2*cluster.getDisplayedRadius());
305
306 offGraphics.setColor(new Color((float)0, (float)0, (float)0.7));
307 offGraphics.drawOval(x - cluster.getDisplayedRadius(),
308 y - cluster.getDisplayedRadius(),
309 2*cluster.getDisplayedRadius(),
310 2*cluster.getDisplayedRadius());
311 }
312
313 }
314
315 int i = clusters.size();
316 Font normal = new Font("Courier",Font.PLAIN,16);
317 Font bold = new Font("Courier",Font.BOLD,16);
318 for (Enumeration enum = clusters.elements() ; enum.hasMoreElements();)
319 {
320
321 SammCluster cluster = (SammCluster) enum.nextElement();
322 int x = (int) (cluster.getX()*(offScreenSize.width-2*RADIUS)) + RADIUS;
323 int y = (int) (cluster.getY()*(offScreenSize.height-2*RADIUS)) + RADIUS;
324 offGraphics.setFont(bold);
325 offGraphics.setColor(new Color((float)0, (float)0,(float)0.4));
326
327 FontMetrics fm = offGraphics.getFontMetrics();
328 int theIndex = cluster.getWords()[0];
329
330 String theWord = parentSammon.dataMan.getWords()[theIndex];
331
332 int width = fm.stringWidth(theWord);
333 offGraphics.drawString(theWord,x-(width/2),y+5);
334 i--;
335 }
336
337 g2.drawImage(bi,0,0,this);
338 }
339
340
341 public void update()
342 {
343 /* Dimension d = getSize();
344 offScreenSize = d;
345 offScreen = createImage(d.width,d.height);
346 offGraphics = (Graphics2D)offScreen.getGraphics();
347
348 offGraphics.setColor(Color.white);
349 offGraphics.fillRect(0,0,d.width,d.height);
350
351 if( parentSammon.dataMan.getDocCount()<1) return;
352
353 Vector clusters = parentSammon.dataMan.getSammonClusters();
354
355 double minNumDocs = ((SammCluster) clusters.elementAt(0)).getSize();
356 double maxNumDocs = ((SammCluster) clusters.elementAt(clusters.size()-1)).getSize();
357 double deltaNumDocs = maxNumDocs - minNumDocs;
358
359 for (int i = clusters.size()-1; i >= 0; i--) {
360
361 SammCluster cluster = (SammCluster) clusters.elementAt(i);
362 int x = (int) (cluster.getX()*(offScreenSize.width-2*RADIUS)) + RADIUS;
363 int y = (int) (cluster.getY()*(offScreenSize.height-2*RADIUS)) + RADIUS;
364
365 // Value between 0 and 1 representing the cluster (0 is the smaller cluster and 1 is the bigger one
366 double clusterWeight = (cluster.getSize() - minNumDocs)/ deltaNumDocs;
367
368 //offGraphics.setColor(new Color((float) (1 - 0.7*clusterWeight),(float) 0, (float) 0));
369 offGraphics.setColor(new Color((float)0.7, (float)0.7, (float)1));
370
371 cluster.setDisplayedRadius(RADIUS-(int)(RADIUS*(1-clusterWeight)/2));
372 BasicStroke myStroke = new BasicStroke(3,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER);
373 offGraphics.setStroke(myStroke);
374 offGraphics.fillOval(x - cluster.getDisplayedRadius(),
375 y - cluster.getDisplayedRadius(),
376 2*cluster.getDisplayedRadius(),
377 2*cluster.getDisplayedRadius());
378
379 offGraphics.setColor(new Color((float)0,(float)0, (float)0.7));
380 offGraphics.drawOval(x - cluster.getDisplayedRadius(),
381 y - cluster.getDisplayedRadius(),
382 2*cluster.getDisplayedRadius(),
383 2*cluster.getDisplayedRadius());
384
385 if (cluster.getSelected())
386 drawFlag(offGraphics,x,y-cluster.getDisplayedRadius());
387
388 if (cluster.equals(this.drawnCluster))
389 {
390
391 offGraphics.setColor(new Color((float)0.3, (float)0.3, (float)1));
392 offGraphics.fillOval(x - cluster.getDisplayedRadius(),
393 y - cluster.getDisplayedRadius(),
394 2*cluster.getDisplayedRadius(),
395 2*cluster.getDisplayedRadius());
396
397 offGraphics.setColor(new Color((float)0, (float)0, (float)0.7));
398 offGraphics.drawOval(x - cluster.getDisplayedRadius(),
399 y - cluster.getDisplayedRadius(),
400 2*cluster.getDisplayedRadius(),
401 2*cluster.getDisplayedRadius());
402 }
403
404 }
405
406 int i = clusters.size();
407 Font normal = new Font("Courier",Font.PLAIN,16);
408 Font bold = new Font("Courier",Font.BOLD,16);
409 for (Enumeration enum = clusters.elements() ; enum.hasMoreElements();)
410 {
411
412 SammCluster cluster = (SammCluster) enum.nextElement();
413 int x = (int) (cluster.getX()*(offScreenSize.width-2*RADIUS)) + RADIUS;
414 int y = (int) (cluster.getY()*(offScreenSize.height-2*RADIUS)) + RADIUS;
415 offGraphics.setFont(bold);
416 offGraphics.setColor(new Color((float)0, (float)0,(float)0.4));
417
418 FontMetrics fm = offGraphics.getFontMetrics();
419 int theIndex = cluster.getWords()[0];
420
421 String theWord = parentSammon.dataMan.getWords()[theIndex];
422
423 int width = fm.stringWidth(theWord);
424 offGraphics.drawString(theWord,x-(width/2),y+5);
425 i--;
426 }*/
427 repaint();
428 }
429
430
431 private void updateHLinkPanel()
432 {
433 if( parentSammon.dataMan==null) return;
434
435 if (locationID != -1)
436 {
437
438 Vector clusters = parentSammon.dataMan.getSammonClusters();
439
440 SammCluster selectedCluster = (SammCluster) clusters.elementAt(locationID);
441 ClusterObj cObj = selectedCluster.getClusterObj();
442 String htmlDescription = cObj.formatDocs();
443
444 parentSammon.hLinkPanel.setText(htmlDescription);
445 parentSammon.keywordPanel.update(cObj);
446 }
447 }
448}
449
450
Note: See TracBrowser for help on using the repository browser.