View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20  */
21  
22  
23  
24  package zeus.visualiser.statistics;
25  
26  import java.io.File;
27  import java.util.*;
28  import java.awt.*;
29  import java.awt.event.*;
30  import javax.swing.*;
31  
32  import zeus.util.*;
33  import zeus.concepts.*;
34  import zeus.gui.*;
35  import zeus.gui.help.*;
36  import zeus.actors.*;
37  import zeus.visualiser.VisualiserModel;
38  import zeus.visualiser.statistics.charts.*;
39  import zeus.visualiser.basic.*;
40  
41  
42  public class StatisticsTool extends VideoTool {
43    private static int count = 0;
44  
45    static final int NIL = 0;
46    static final int BAT = 1;
47    static final int TVT = 2;
48    static final int TVA = 4;
49    static final int IAT = 8;
50    static final int MPG = 16;
51    static final int NEG = 32;
52    static final int GCS = 64;
53    static final int AEM = 128;
54    static final int AMS = 256;
55    static final int CRR = 512;
56    static final int GLT = 1024;
57    static final int TAL = 2048;
58  
59    static final int PIE = 1;
60    static final int BAR = 2;
61    static final int LIN = 4;
62    static final int XYG = 8;
63    static final int TAB = 16;
64  
65    static String[] STATS_MENU_ITEMS = {
66        "Breakdown of agent types",
67        "Traffic volume by type",
68        "Traffic volume by agent",
69        "Inter agent traffic volume",
70        "Messages per goal",
71        "Inter agent negotiation graphs",
72  
73        "Goal completion status",
74        "Agent efficiency measure",
75        "Agent monetary statement",
76        "Plan/Resources ratio",
77        "Average goal lapse times",
78        "Task activity level"
79    };
80  
81  
82    protected StatisticsMenuBar menubar;
83    protected StatisticsToolBar statisticsToolBar;
84  
85    protected EditableMultipleSelectionDialog message_dialog = null;
86    protected DoubleSelectionDialog           neg_dialog = null;
87    protected NumberDialog                    as_dialog = null;
88  
89    protected JScrollPane scrollpane;
90    protected DrawCanvas canvas;
91  
92    private  int chart_type = PIE;
93    private  int statistics_type = NIL;
94  
95    protected TrafficVolume  offlineQueue;
96    protected TrafficVolume  onlineQueue;
97    protected TrafficVolume  msgQueue = null;
98    protected Grapher grapher = null;
99  
100   protected MultipleSelectionDialog ms_dialog = null;
101 
102 
103   public StatisticsTool(AgentContext context, VisualiserModel model) {
104     super(context, model);
105     this.setTitle(context.whoami() + " - Statistics Tool:" + (count++));
106     this.setBackground(Color.lightGray);
107     ImageIcon icon = new ImageIcon(SystemProps.getProperty("gif.dir") +
108        File.separator + "visualiser" +																	 File.separator + "stats-icon.gif");
109     setIconImage(icon.getImage());
110 
111     offlineQueue = new TrafficVolume(context.OntologyDb());
112     onlineQueue = new TrafficVolume(context.OntologyDb());
113 
114     getContentPane().setLayout(new BorderLayout());
115 
116     canvas = new DrawCanvas();
117     canvas.setBackground(new Color(245,230,145));
118 
119     scrollpane = new JScrollPane(canvas);
120     scrollpane.setPreferredSize(new Dimension(460,460));
121     scrollpane.setMaximumSize(new Dimension(1600, 1600));
122     canvas.setPreferredSize(new Dimension(1600,1600));
123 
124     // Create the statistics tool bar
125     statisticsToolBar = new StatisticsToolBar();
126 
127     // Create a panel for the tool bars
128     JPanel toolpane = new JPanel();
129     toolpane.setLayout(new GridLayout(1,2));
130     toolpane.add(statisticsToolBar);
131     toolpane.add(videoToolbar);
132 
133     getContentPane().add("North",toolpane);
134     getContentPane().add("Center",scrollpane);
135 
136     msgQueue = onlineQueue;
137     grapher = new Grapher();
138 
139     // Create the frame's menu bar
140     menubar = new StatisticsMenuBar();
141     setJMenuBar(menubar);
142 
143     this.pack();
144     this.setVisible(true);
145     
146     /* initialisation sequence */
147     setMode(ONLINE);
148   }
149 
150   public void Exit() {
151      if ( grapher != null )
152         grapher.terminate();
153      grapher = null;
154      super.Exit();
155   }
156 
157   public Dimension getViewportSize() {
158      return scrollpane.getViewport().getExtentSize();
159   }
160 
161   public void SaveGoalTraffic(boolean set) {
162      msgQueue.setUpdatingGoalTraffic(set);
163   }
164   public void ClearGoalTraffic() {
165      msgQueue.clearGoalTraffic();
166   }
167 
168   public void StreamMessages(boolean mode) {
169       if ( !hubOK() ) return;
170       if ( !stopPlayback() ) return;
171 
172       String[] agents = model.getAgents();
173       if ( message_dialog == null ) {
174          message_dialog = new EditableMultipleSelectionDialog(this,
175             "Select Agents", agents);
176          message_dialog.setLocationRelativeTo(this);
177       }
178       else {
179          Object[] chosen = message_dialog.getPriorSelection();
180          message_dialog.setListData(agents);
181          message_dialog.setSelection(chosen);
182       }
183 
184       Object[] data = message_dialog.getSelection();
185       model.addAgents(Misc.stringArray(message_dialog.getListData()));
186       subscribe(mode,model.keys[VisualiserModel.MESSAGE_KEY],
187          Misc.stringArray(data),"log_message");
188    }
189 
190 
191    protected void setMode(int mode) {
192      if ( mode == ONLINE ) {
193         menubar.update(ONLINE);
194         videoToolbar.setStatus(false);
195         offlineQueue.clear();
196         msgQueue = onlineQueue;
197      }
198      else {
199         menubar.update(PLAYBACK);
200         videoToolbar.setStatus(true);
201         offlineQueue.clear();
202         msgQueue = offlineQueue;
203      }
204    }
205 
206    protected void registerAgent(String name, String type) {
207       //onlineQueue.addAgent(name,type);
208    }
209 
210    protected void registerListOfPlaybackAgents(Vector List) {
211       //offlineQueue.addAgents(List);
212    }
213 
214    protected void  visualiseVideoData(int dir, Performative msg) {
215       if ( state.mode == PLAYBACK && filterMsg(msg) )
216          offlineQueue.update(msg);
217    }
218 
219    public void log_message(Performative msg) {
220 try {
221       Performative imsg = ZeusParser.performative(msg.getContent());
222       if ( filterMsg(imsg) )
223          onlineQueue.update(imsg);
224 
225       // save to persistent db
226       record_item(imsg);
227 } catch(Exception e) {
228 }
229    }
230 
231   public void AnimationSpeed() {
232     if ( !hubOK() ) return;
233     long speed = grapher.getSpeed();
234     if ( as_dialog == null ) {
235        as_dialog = new NumberDialog(this, "Set Animation Speed", "Enter speed:");
236        as_dialog.setLocationRelativeTo(this);
237     }
238     as_dialog.setValue(speed);
239     Long value = as_dialog.getValue();
240     if ( value != null )
241        grapher.setSpeed(value.longValue());
242   }
243 
244   protected boolean statisticIsOneOf(int st) {
245      if ( statistics_type != NIL && ((statistics_type & st) == 0) ) {
246         JOptionPane.showMessageDialog(this, "Invalid chart type for current statistic");
247         return false;
248      }
249      return true;
250   }
251   public void RedrawGraph() {
252      if ( grapher != null )
253         grapher.drawChart();
254   }
255   public void DrawPieGraph() {
256      if ( !statisticIsOneOf(BAT|TVT) ) return;
257      chart_type = PIE;
258      if ( grapher != null )
259         grapher.drawChart();
260   }
261   public void DrawBarGraph() {
262      if ( !statisticIsOneOf(BAT|TVT|TVA|MPG) ) return;
263      chart_type = BAR;
264      if ( grapher != null )
265         grapher.drawChart();
266   }
267   public void DrawLineGraph() {
268      if ( !statisticIsOneOf(BAT|TVT|TVA|MPG) ) return;
269      chart_type = LIN;
270      if ( grapher != null )
271         grapher.drawChart();
272   }
273   public void DrawXYGraph() {
274      if ( !statisticIsOneOf(NEG) ) return;
275      chart_type = XYG;
276      if ( grapher != null )
277         grapher.drawChart();
278   }
279   public void DrawTabularGraph() {
280      if ( !statisticIsOneOf(IAT) ) return;
281      chart_type = TAB;
282      if ( grapher != null )
283         grapher.drawChart();
284   }
285 
286   public void setStatisticsType(int type) {
287      if ( grapher == null ) return;
288 
289      Object[] user_choice;
290      Object[] prior_goals;
291      String[] current_goals;
292 
293      switch(type) {
294         case NIL: // None
295              break;
296         case BAT: // Breakdown of Agent Types
297              if ( (chart_type & (PIE|BAR|LIN)) == 0 )
298                 chart_type = PIE;
299              statistics_type = type;
300              grapher.drawChart();
301              break;
302         case TVT: // Traffic Volume by Type
303              if ( (chart_type & (PIE|BAR|LIN)) == 0 )
304                 chart_type = BAR;
305              statistics_type = type;
306              grapher.drawChart();
307              break;
308         case TVA: // Traffic Volume by Agent
309              if ( (chart_type & (BAR|LIN)) == 0 )
310                 chart_type = BAR;
311              statistics_type = type;
312              grapher.drawChart();
313              break;
314         case IAT: // Inter Agent Traffic Volume
315              if ( (chart_type & (TAB)) == 0 )
316                 chart_type = TAB;
317              statistics_type = type;
318              grapher.drawChart();
319              break;
320         case MPG: // Messages per Goal
321              current_goals = msgQueue.getCurrentGoals();
322              if ( current_goals.length == 0 ) {
323                 JOptionPane.showMessageDialog(this,"No goals currently available");
324                 menubar.setStatisticsType(statistics_type);
325                 return;
326              }
327 
328              if ( ms_dialog == null ) {
329                 ms_dialog = new MultipleSelectionDialog(this,"Select Required Goals");
330                 ms_dialog.setLocationRelativeTo(this);
331              }
332 
333              prior_goals = ms_dialog.getPriorSelection();
334              ms_dialog.setListData(current_goals);
335              ms_dialog.setSelection(prior_goals);
336              user_choice = ms_dialog.getSelection();
337 
338              if ( user_choice == null ) return;
339 
340              if ( (chart_type & (BAR|LIN)) == 0 )
341                 chart_type = BAR;
342              statistics_type = type;
343 
344              grapher.setUserGoals(Misc.stringArray(user_choice));
345              grapher.drawChart();
346              break;
347 
348 	case NEG: // Inter-agent negotiation graph
349              current_goals = msgQueue.getCurrentGoals();
350              if ( current_goals.length == 0 ) {
351                 JOptionPane.showMessageDialog(this,"No goals currently available");
352                 menubar.setStatisticsType(statistics_type);
353                 return;
354              }
355 
356              Hashtable input = msgQueue.getNegotiationGoals();
357              if ( neg_dialog == null ) {
358                 neg_dialog = new DoubleSelectionDialog(this,
359 	           "Goal & Negotiation Partners","Goal","Negotiation Partners");
360                 neg_dialog.setLocationRelativeTo(this);
361              }
362 
363              prior_goals = neg_dialog.getPriorSelection();
364              neg_dialog.setListData(input);
365              neg_dialog.setSelection(prior_goals[0],prior_goals[1]);
366              user_choice = neg_dialog.getSelection();
367 
368              if ( user_choice == null ) return;
369 
370              if ( (chart_type & XYG) == 0 )
371                 chart_type = XYG;
372              statistics_type = type;
373 
374              grapher.setUserGoals(Misc.stringArray(user_choice));
375              grapher.drawChart();
376              break;
377 
378 	case TAL: // Task Activity Level
379         case GCS: // Goal Completion Status
380         case AEM: // Agent Efficiency Measure
381         case AMS: // Agent Monetary Statement
382         case CRR: // Plan/Resources Ratio
383         case GLT: // Average Goal Lapse Times
384              statistics_type = type;
385              grapher.drawChart();
386              break;
387 
388         default:
389            break;
390      }
391   }
392 
393   public void Help()   {
394      Point pt = getLocation();
395      HelpWindow helpWin = new HelpWindow(this, pt, "visualiser", "Statistics Tool");
396      helpWin.setSize(new Dimension(getWidth(),440));
397      helpWin.setLocation(pt.x+24, pt.y+24);
398      helpWin.validate();
399    }
400 
401 class StatisticsMenuBar extends JMenuBar
402                                implements ActionListener,
403                                           ItemListener {
404 
405     protected static final int CHECKITEM = 0;
406     protected static final int PLAINITEM = 1;
407     protected static final int RADIOITEM = 2;
408 
409     protected JMenu     fileMenu, onLineMenu, replayMenu;
410     protected JMenu     optionsMenu, viewMenu, helpMenu;
411     protected JMenu     animationMenu;
412     protected JMenu     doMenu;
413     protected JMenuItem sessions, load, save, close, forward, rewind,
414                       fforward, frewind, stop, forward_step, rewind_step,
415                       forward_last, rewind_first, delete, purge;
416     protected JMenuItem connect, disconnect, exit;
417     protected JMenuItem cc, un_cc;
418     protected JMenuItem filter, animation_speed, player_speed, clear_goal;
419     protected JMenuItem redraw, line, bar, pie, xy, table;
420     protected JMenuItem help, about;
421     protected JCheckBoxMenuItem save_goal;
422     protected JRadioButtonMenuItem[] statsRadioBox;
423 
424     public StatisticsMenuBar()	{
425       super();
426       add(fileMenu());
427       add(onlineMenu());
428       add(playbackMenu());
429       add(optionsMenu());
430       add(doMenu());
431       add(viewMenu());
432       add(helpMenu());
433     }
434 
435     private JMenu fileMenu() {
436         JMenu menu = new JMenu("File");
437         menu.setMnemonic('F');
438         connect = createMenuItem(menu,PLAINITEM,"Connect to namservers", 'C');
439         disconnect=createMenuItem(menu,PLAINITEM,"Disconnect from nameservers",'D');
440         exit = createMenuItem(menu, PLAINITEM, "Quit", 'Q');
441         return menu;
442     }
443 
444     private JMenu onlineMenu() {
445         JMenu menu = new JMenu("Online");
446         menu.setMnemonic('O');
447         cc    = createMenuItem(menu, PLAINITEM, "Request messages...", 'R');
448         un_cc = createMenuItem(menu, PLAINITEM, "Unrequest messages...", 'U');
449         return menu;
450     }
451 
452     private JMenu playbackMenu() {
453         JMenu menu = new JMenu("Playback");
454         menu.setMnemonic('P');
455         sessions = createMenuItem(menu, PLAINITEM, "Request saved sessions", 0);
456         delete = createMenuItem(menu, PLAINITEM, "Delete session", 0);
457         purge = createMenuItem(menu, PLAINITEM, "Purge database", 0);
458         menu.addSeparator();
459         load = createMenuItem(menu, PLAINITEM, "Load session", 0);
460         save = createMenuItem(menu, PLAINITEM, "Save session", 0);
461         close = createMenuItem(menu, PLAINITEM, "Close session", 0);
462         menu.addSeparator();
463         forward = createMenuItem(menu, PLAINITEM, "Forward", 0);
464         rewind = createMenuItem(menu, PLAINITEM, "Rewind", 0);
465         fforward = createMenuItem(menu, PLAINITEM, "Fast forward", 0);
466         frewind = createMenuItem(menu, PLAINITEM, "Fast rewind", 0);
467         forward_step = createMenuItem(menu, PLAINITEM, "Step forward", 0);
468         rewind_step = createMenuItem(menu, PLAINITEM, "Step backward", 0);
469         forward_last = createMenuItem(menu, PLAINITEM, "Forward to end", 0);
470         rewind_first = createMenuItem(menu, PLAINITEM, "Rewind to beginning", 0);
471         stop = createMenuItem(menu, PLAINITEM, "Stop", 0);
472         return menu;
473     }
474 
475    private JMenu optionsMenu() {
476         JMenu menu = new JMenu("Options");
477         menu.setMnemonic('O');
478         filter       = createMenuItem(menu, PLAINITEM, "Filter messages...", 0);
479         player_speed = createMenuItem(menu, PLAINITEM, "Player speed...", 0);
480         animation_speed = createMenuItem(menu, PLAINITEM, "Animation speed...", 0);
481         save_goal  = (JCheckBoxMenuItem) createMenuItem(menu, CHECKITEM, "Save goal traffic data", 0);
482         clear_goal = createMenuItem(menu, PLAINITEM, "Clear goal traffic data", 0);
483 
484         save_goal.setState(StatisticsTool.this.msgQueue.isUpdatingGoalTraffic());
485         return menu;
486     }
487 
488     private JMenu doMenu() {
489         JMenu menu = new JMenu("Statistics");
490         ButtonGroup group = new ButtonGroup();
491         menu.setMnemonic('S');
492         statsRadioBox = new JRadioButtonMenuItem[STATS_MENU_ITEMS.length];
493         for(int i= 0; i < STATS_MENU_ITEMS.length; i++) {
494            statsRadioBox[i] = new JRadioButtonMenuItem(STATS_MENU_ITEMS[i]);
495            statsRadioBox[i].addActionListener(this);
496            if ( i >= 6 ) statsRadioBox[i].setEnabled(false);
497            menu.add(statsRadioBox[i]);
498            group.add(statsRadioBox[i]);
499        	}
500         return menu;
501     }
502 
503     private JMenu viewMenu() {
504         JMenu menu = new JMenu("View");
505         menu.setMnemonic('V');
506         redraw = createMenuItem(menu, PLAINITEM, "Redraw current", 'R');
507         pie    = createMenuItem(menu, PLAINITEM, "Pie chart", 'P');
508         line   = createMenuItem(menu, PLAINITEM, "Line graph",  0);
509         xy     = createMenuItem(menu, PLAINITEM, "XY graph", 'X');
510         table  = createMenuItem(menu, PLAINITEM, "Table", 'T');
511         bar    = createMenuItem(menu, PLAINITEM, "Bar chart", 'B');
512         return menu;
513     }
514 
515     private JMenu helpMenu() {
516         JMenu menu = new JMenu("Help");
517         menu.setMnemonic('H');
518         help  = createMenuItem(menu, PLAINITEM, "Using the statistics tool", 'U');
519         about = createMenuItem(menu, PLAINITEM, "About ZEUS...", 'A');
520         return menu;
521     }
522 
523     private JMenuItem createMenuItem(JMenu menu, int type, String text, int accelKey)	{
524         JMenuItem item;
525         switch(type) {
526             case CHECKITEM:
527                 item = new JCheckBoxMenuItem(text);
528                 ((JCheckBoxMenuItem) item).setState(false);
529                 item.addItemListener(this);
530                 break;
531             case RADIOITEM:
532                 item = new JRadioButtonMenuItem(text,false);
533                 item.addActionListener(this);
534             default:
535                 item = new JMenuItem(text);
536                 item.addActionListener(this);
537                 break;
538         }
539         if (accelKey > 0)
540            item.setMnemonic(accelKey);
541         menu.add(item);
542         return item;
543     }
544 
545 
546 
547     public void actionPerformed(ActionEvent event) {
548       Object src = event.getSource();
549 
550       if ( src == connect ) 		Connect(true);
551       if ( src == disconnect ) 		Connect(false);
552       else if ( src == exit )		Exit();
553 
554       else if ( src == cc)		StreamMessages(true);
555       else if ( src == un_cc )		StreamMessages(false);
556 
557       else if ( src == sessions)	Sessions();
558       else if ( src == delete)		Delete();
559       else if ( src == purge)		Purge();
560       else if ( src == load)		Load();
561       else if ( src == save )		Record();
562       else if ( src == close )		Close();
563       else if ( src == forward )	Forward();
564       else if ( src == rewind )		Rewind();
565       else if ( src == fforward )	FForward();
566       else if ( src == frewind )	FRewind();
567       else if ( src == stop )		Stop();
568       else if ( src == forward_step )	StepForward();
569       else if ( src == forward_last )	ForwardEnd();
570       else if ( src == rewind_step )	StepRewind();
571       else if ( src == rewind_first )	RewindBegin();
572 
573       else if ( src == clear_goal ) 	ClearGoalTraffic();
574 
575       else if ( src == filter )		Filter();
576       else if ( src == player_speed )	PlayerSpeed();
577       else if ( src == animation_speed) AnimationSpeed();
578 
579       else if ( src == redraw )	RedrawGraph();
580       else if ( src == xy )	DrawXYGraph();
581       else if ( src == table )	DrawTabularGraph();
582       else if ( src == line )	DrawLineGraph();
583       else if ( src == pie )	DrawPieGraph();
584       else if ( src == bar )  	DrawBarGraph();
585 
586       else if (src == help)	Help();
587       else if (src == about)	About();
588 
589       else
590       	for(int i = 0; i < STATS_MENU_ITEMS.length; i++ )
591 	   if ( statsRadioBox[i] == src )
592               StatisticsTool.this.setStatisticsType((int)(Math.pow(2,(double)i) +0.51));
593   }
594 
595    public void itemStateChanged(ItemEvent event) {
596       Object src = event.getSource();
597 
598       if ( src == save_goal ) {
599          boolean v = save_goal.getState();
600          SaveGoalTraffic(v);
601          return;
602       }
603    }
604 
605    public void setStatisticsType(int type) {
606       if ( type == 0 ) {
607          for(int j = 0; j < STATS_MENU_ITEMS.length; j++ )
608             statsRadioBox[j].setSelected(false);
609          return;
610       }
611       int n = (int)(Math.log((double)type)/Math.log(2) + 0.51);
612       statsRadioBox[n].setSelected(true);
613    }
614 
615    public void update(int mode) {
616       boolean b = mode == StatisticsTool.this.PLAYBACK;
617       cc.setEnabled(!b);
618 
619       forward.setEnabled(b);
620       rewind.setEnabled(b);
621       fforward.setEnabled(b);
622       frewind.setEnabled(b);
623       stop.setEnabled(b);
624       forward_step.setEnabled(b);
625       rewind_step.setEnabled(b);
626       forward_last.setEnabled(b);
627       rewind_first.setEnabled(b);
628    }
629 }
630 
631 
632 protected class StatisticsToolBar extends JToolBar implements ActionListener {
633   protected JButton  barBtn, pieBtn, lineBtn, xyBtn, tabularBtn;
634 
635   public StatisticsToolBar() {
636     setFloatable(false);
637 
638     String path = SystemProps.getProperty("gif.dir") + File.separator +
639                   "visualiser" + File.separator;
640     addSeparator();
641 
642     // Bar Button
643     barBtn = new JButton(new ImageIcon(path + "bar.gif"));
644     add(barBtn);
645     barBtn.setPreferredSize(new Dimension(24,24));
646     barBtn.setToolTipText("Show as Bar Chart");
647     barBtn.setMargin(new Insets(0,0,0,0));
648     addSeparator();
649 
650     // Pie Button
651     pieBtn = new JButton(new ImageIcon(path + "pie.gif"));
652     add(pieBtn);
653     pieBtn.setPreferredSize(new Dimension(24,24));
654     pieBtn.setToolTipText("Show as Pie Chart");
655     pieBtn.setMargin(new Insets(0,0,0,0));
656     addSeparator();
657 
658     // Line Button
659     lineBtn = new JButton(new ImageIcon(path + "line.gif"));
660     add(lineBtn);
661     lineBtn.setPreferredSize(new Dimension(24,24));
662     lineBtn.setToolTipText("Show as Line Chart");
663     lineBtn.setMargin(new Insets(0,0,0,0));
664     addSeparator();
665 
666     // XY Button
667     xyBtn = new JButton(new ImageIcon(path + "xy.gif"));
668     add(xyBtn);
669     xyBtn.setPreferredSize(new Dimension(24,24));
670     xyBtn.setToolTipText("Show as XY Chart");
671     xyBtn.setMargin(new Insets(0,0,0,0));
672     addSeparator();
673 
674     // Tabluar Button
675     tabularBtn = new JButton(new ImageIcon(path + "table.gif"));
676     add(tabularBtn);
677     tabularBtn.setPreferredSize(new Dimension(24,24));
678     tabularBtn.setToolTipText("Show as Tabular Chart");
679     tabularBtn.setMargin(new Insets(0,0,0,0));
680     addSeparator();
681 
682     setPreferredSize(new Dimension(300,32));
683 
684     barBtn.addActionListener(this);
685     pieBtn.addActionListener(this);
686     lineBtn.addActionListener(this);
687     xyBtn.addActionListener(this);
688     tabularBtn.addActionListener(this);
689   }
690 
691   public void actionPerformed(ActionEvent evt) {
692      Object src = evt.getSource();
693           if ( src == xyBtn      ) DrawXYGraph();
694      else if ( src == tabularBtn ) DrawTabularGraph();
695      else if ( src == barBtn     ) DrawBarGraph();
696      else if ( src == pieBtn     ) DrawPieGraph();
697      else if ( src == lineBtn    ) DrawLineGraph();
698   }
699 }
700 
701 class Grapher extends Thread {
702    protected long speed = 3000;
703    protected boolean running = true;
704    protected PieChart pie = new PieChart();
705    protected Histogram bar = new Histogram();
706    protected LineGraph line = new LineGraph();
707    protected XYGraph xy = new XYGraph();
708    protected TabularGraph tabular = new TabularGraph();
709    protected String[] user_goals;
710 
711    public String[] AGENT_TYPES = {
712       SystemProps.getProperty("agent.names.nameserver"),
713       SystemProps.getProperty("agent.names.facilitator"),
714       SystemProps.getProperty("agent.names.visualiser"),
715       SystemProps.getProperty("agent.names.dbProxy"),
716       SystemProps.getProperty("agent.names.agent")
717    };
718 
719    public Grapher()	 {
720       this.setPriority(Thread.NORM_PRIORITY-3);
721       this.start();
722    }
723 
724    public void setSpeed(long speed) {
725       this.speed = speed;
726    }
727 
728    public long getSpeed() {
729       return speed;
730    }
731 
732    public void run() {
733       long count = 0;
734       while( running ) {
735          synchronized(this) {
736             try {
737                while( !StatisticsTool.this.state.animating ||
738 	              chart_type == StatisticsTool.NIL ||
739                       statistics_type == StatisticsTool.NIL )
740                   wait(speed);
741                drawChart();
742                wait(speed);
743             }
744             catch(InterruptedException e) {
745             }
746          }
747       }
748    }
749 
750    public void terminate() {
751       running = false;
752    }
753 
754    public void wakeup() {
755       notifyAll();
756    }
757 
758    public void setUserGoals(String[] goals) {
759       user_goals = goals;
760    }
761    public String[] getUserGoals() {
762       return user_goals;
763    }
764 
765    public void drawChart() {
766       double[][] values = null;
767       double[][] x_values = null;
768       double[]   data = null;
769       double[]   x_data = null;
770       String[]   labels = null;
771       String[]   keys = null;
772       String     title = null;
773 
774       switch( statistics_type ) {
775          case StatisticsTool.NIL: // None
776             return;
777 
778          case StatisticsTool.BAT:
779             title = "Breakdown of Agent Types";
780             labels = AGENT_TYPES;
781             data = new double[AGENT_TYPES.length];
782             String[] s;
783             for(int i = 0; i < data.length; i++ ) {
784                s = StatisticsTool.this.model.getAgents(AGENT_TYPES[i]);
785                data[i] = (s == null) ? 0.0 : s.length;
786             }
787             break;
788 
789          case StatisticsTool.TVT:
790             title = "Traffic Volume: Distribution by Type";
791             labels = msgQueue.getDistributionByTypeLabels();
792             data = msgQueue.getDistributionByTypeData();
793             break;
794 
795          case StatisticsTool.TVA:
796             title = "Traffic Volume: Distribution by Agent";
797             labels = msgQueue.getDistributionByAgentLabels();
798             values = msgQueue.getDistributionByAgentData();
799             keys = msgQueue.getDistributionByAgentKeys();
800             if ( values == null ) return;
801             break;
802 
803          case StatisticsTool.IAT: // Inter-Agent Traffic Volume
804             title = "Inter-Agent Traffic Volume";
805             labels = msgQueue.getInterAgentTrafficLabels();
806             values = msgQueue.getInterAgentTrafficData();
807             if ( values == null ) return;
808             break;
809 
810          case StatisticsTool.MPG: // Messages per Goal
811             title = "Traffic Volume for Selected Goals: Distribution by Agent";
812             labels = msgQueue.getDistributionByGoalLabels(user_goals);
813             values = msgQueue.getDistributionByGoalData(user_goals);
814             keys = msgQueue.getDistributionByGoalKeys();
815             if ( values == null ) return;
816             break;
817 
818          case StatisticsTool.NEG: // Negotiation graphs
819             title = "Negotiation Graph for " + user_goals[1];
820             values = msgQueue.getDistributionByNegotiationDialogueData(user_goals);
821             x_values = msgQueue.getDistributionByNegotiationDialogueXData(user_goals);
822             keys = msgQueue.getDistributionByNegotiationDialogueKeys(user_goals);
823             if ( x_values == null ) return;
824             break;
825 
826          case StatisticsTool.TAL: // Task Activity Level
827          case StatisticsTool.GCS: // Goal Completion Status
828          case StatisticsTool.AEM: // Agent Efficiency Measure
829          case StatisticsTool.AMS: // Agent Monetary Statement
830          case StatisticsTool.CRR: // Plan/Resources Ratio
831          case StatisticsTool.GLT: // Average Goal Lapse Times
832             return;
833 
834          default:
835             return;
836       }
837 
838       Dimension d;
839       switch( chart_type ) {
840          case StatisticsTool.NIL:
841             return;
842 
843          case  StatisticsTool.PIE:
844             pie.setData(data,labels,title);
845             d = getViewportSize();
846             pie.setXY(d.width,d.height);
847 	    canvas.setDrawType(pie);
848             canvas.repaint();
849             return;
850 
851          case  StatisticsTool.BAR:
852             if ( keys != null )
853                bar.setData(values,labels,keys,title);
854             else
855                bar.setData(data,labels,title);
856             d = getViewportSize();
857             bar.setXY(d.width,d.height);
858             canvas.setDrawType(bar);
859             canvas.repaint();
860             return;
861 
862          case  StatisticsTool.LIN:
863             if ( keys != null )
864                line.setData(values,labels,keys,title);
865             else
866                line.setData(data,labels,title);
867             d = getViewportSize();
868             line.setXY(d.width,d.height);
869             canvas.setDrawType(line);
870             canvas.repaint();
871             return;
872 
873          case  StatisticsTool.TAB:
874             tabular.setData(values,labels,title);
875             d = getViewportSize();
876             tabular.setXY(d.width,d.height);
877             canvas.setDrawType(tabular);
878             canvas.repaint();
879             return;
880 
881          case  StatisticsTool.XYG:
882             if ( keys != null )
883                xy.setData(values,x_values,keys,title);
884             else
885                xy.setData(data,x_data,title);
886             d = getViewportSize();
887             xy.setXY(d.width,d.height);
888             canvas.setDrawType(xy);
889             canvas.repaint();
890             return;
891 
892          default:
893             return;
894       }
895    }
896 }
897 
898 }