root/mpich2/tags/release/MPICH2_1_0_6/src/mpe2/src/slog2sdk/src/viewer/timelines/CanvasTimeline.java

Revision 100, 24.2 kB (checked in by balaji, 1 year ago)

Added all components in the right places.

Line 
1 /*
2  *  (C) 2001 by Argonne National Laboratory
3  *      See COPYRIGHT in top-level directory.
4  */
5
6 /*
7  *  @author  Anthony Chan
8  */
9
10 package viewer.timelines;
11
12 import java.util.Date;
13 import java.util.Map;
14 import java.util.Iterator;
15 import java.awt.*;
16 import java.awt.event.*;
17 import javax.swing.*;
18 import javax.swing.event.*;
19
20 import base.drawable.TimeBoundingBox;
21 import base.drawable.Drawable;
22 import base.drawable.Shadow;
23 import base.drawable.NestingStacks;
24 import base.drawable.DrawnBoxSet;
25 import base.drawable.Method;
26 import base.statistics.BufForTimeAveBoxes;
27 import logformat.slog2.LineIDMap;
28 import logformat.slog2.input.TreeNode;
29 import logformat.slog2.input.TreeTrunk;
30 import viewer.common.Dialogs;
31 import viewer.common.Routines;
32 import viewer.common.Parameters;
33 import viewer.common.CustomCursor;
34 import viewer.zoomable.Debug;
35 import viewer.zoomable.Profile;
36 import viewer.zoomable.ModelTime;
37 import viewer.zoomable.YaxisMaps;
38 import viewer.zoomable.YaxisTree;
39 import viewer.zoomable.CoordPixelImage;
40 import viewer.zoomable.ScrollableObject;
41 import viewer.zoomable.SearchableView;
42 import viewer.zoomable.SummarizableView;
43 import viewer.zoomable.InfoDialog;
44 import viewer.zoomable.SearchPanel;
45 import viewer.zoomable.InitializableDialog;
46 import viewer.histogram.StatlineDialog;
47
48 public class CanvasTimeline extends ScrollableObject
49                             implements SearchableView, SummarizableView
50 {
51     private static final Drawable.Order INCRE_STARTTIME_ORDER
52                                         = Drawable.INCRE_STARTTIME_ORDER;
53     private static final Drawable.Order DECRE_STARTTIME_ORDER
54                                         = Drawable.DECRE_STARTTIME_ORDER;
55     private static final int            MIN_VISIBLE_ROW_COUNT = 2;
56     private static       GradientPaint  BackgroundPaint       = null;
57
58     private TreeTrunk          treetrunk;
59     private YaxisMaps          y_maps;
60     private YaxisTree          tree_view;
61     private BoundedRangeModel  y_model;
62     private Method[]           methods;
63     private String[]           y_colnames;
64
65     private Frame              root_frame;
66     private TimeBoundingBox    timeframe4imgs;   // TimeFrame for images[]
67
68     private ChangeListener     change_listener;
69     private ChangeEvent        change_event;
70
71     private int                num_rows;
72     private int                row_height;
73     private NestingStacks      nesting_stacks;
74     private Map                map_line2row;
75     private DrawnBoxSet        drawn_boxes;
76
77     private boolean            isConnectedComposite;
78     private SearchTreeTrunk    tree_search;
79
80     private Date               zero_time, init_time, final_time;
81
82
83     public CanvasTimeline( ModelTime           time_model,
84                            TreeTrunk           treebody,
85                            BoundedRangeModel   yaxis_model,
86                            YaxisMaps           yaxis_maps,
87                            String[]            yaxis_colnames,
88                            Method[]            dobj_methods )
89     {
90         super( time_model );
91
92         TreeNode   treeroot;
93         short      depth_max, depth_init;
94
95         treetrunk       = treebody;
96         y_maps          = yaxis_maps;
97         tree_view       = y_maps.getTreeView();
98         y_model         = yaxis_model;
99         y_colnames      = yaxis_colnames;
100         methods         = dobj_methods;
101         treeroot        = treetrunk.getTreeRoot();
102         depth_max       = treeroot.getTreeNodeID().depth;
103         nesting_stacks  = new NestingStacks( tree_view );
104         map_line2row    = null;
105         drawn_boxes     = new DrawnBoxSet( tree_view );
106         // timeframe4imgs to be initialized later in initializeAllOffImages()
107         timeframe4imgs  = null;
108
109         depth_init      = (short) ( depth_max
110                                   - Parameters.INIT_SLOG2_LEVEL_READ + 1 );
111         if ( depth_init < 0 )
112             depth_init = 0;
113         treetrunk.growInTreeWindow( treeroot, depth_init,
114                                     new TimeBoundingBox( treeroot ) );
115         treetrunk.setNumOfViewsPerUpdate( ScrollableObject.NumViewsTotal );
116
117         isConnectedComposite = false;
118         if ( methods != null && methods.length > 0 )
119             isConnectedComposite = methods[ 0 ].isConnectCompositeState();
120
121         tree_search     = new SearchTreeTrunk( treetrunk, tree_view,
122                                                isConnectedComposite );
123
124         root_frame      = null;
125         change_event    = null;
126         change_listener = null;
127
128         // if ( BackgroundPaint == null )
129         //     BackgroundPaint = new GradientPaint( 0, 0, Color.black,
130         //                                          5, 5, Color.gray, true );
131     }
132
133     public void addChangeListener( ChangeListener listener )
134     {
135         change_event    = new ChangeEvent( this );
136         change_listener = listener;
137     }
138
139     public Dimension getMinimumSize()
140     {
141         // int  min_view_height = MIN_VISIBLE_ROW_COUNT
142         //                      * Parameters.Y_AXIS_ROW_HEIGHT;
143         int  min_view_height = 0;
144         //  the width below is arbitary
145         if ( Debug.isActive() )
146             Debug.println( "CanvasTimeline: min_size = "
147                          + "(0," + min_view_height + ")" );
148         return new Dimension( 0, min_view_height );
149     }
150
151     public Dimension getMaximumSize()
152     {
153         if ( Debug.isActive() )
154             Debug.println( "CanvasTimeline: max_size = "
155                          + "(" + Short.MAX_VALUE
156                          + "," + Short.MAX_VALUE + ")" );
157         return new Dimension( Short.MAX_VALUE, Short.MAX_VALUE );
158     }
159
160     public int getJComponentHeight()
161     {
162         int rows_size = tree_view.getRowCount() * tree_view.getRowHeight();
163         int view_size = y_model.getMaximum() - y_model.getMinimum() + 1;
164         if ( view_size > rows_size )
165             return view_size;
166         else
167             return rows_size;
168     }
169
170     private void fireChangeEvent()
171     {
172         if ( change_event != null )
173             change_listener.stateChanged( change_event );
174     }
175
176     protected void initializeAllOffImages( final TimeBoundingBox imgs_times )
177     {
178         boolean isScrolling;
179
180         if ( Profile.isActive() )
181             zero_time = new Date();
182
183         if ( root_frame == null )
184             root_frame  = (Frame) SwingUtilities.windowForComponent( this );
185         if ( timeframe4imgs == null )
186             timeframe4imgs = new TimeBoundingBox( imgs_times );
187
188         // Read the SLOG-2 TreeNodes within TimeFrame into memory
189         /*
190            The cursor needs to be set from the top container, so even when
191            the mouse is at other components, e.g. ScrollbarTime,
192            the cursor can still turn HourGlass.
193         */
194         Routines.setComponentAndChildrenCursors( root_frame,
195                                                  CustomCursor.Wait );
196         num_rows    = tree_view.getRowCount();
197         row_height  = tree_view.getRowHeight();
198         isScrolling = ( treetrunk.updateTimeWindow( timeframe4imgs, imgs_times )
199                       == TreeTrunk.TIMEBOX_SCROLLING );
200         nesting_stacks.initialize( isScrolling );
201
202         if ( Profile.isActive() )
203             init_time = new Date();
204
205         map_line2row = y_maps.getMapOfLineIDToRowID();
206         if ( map_line2row == null ) {
207             if ( ! y_maps.update() )
208                 Dialogs.error( root_frame,
209                                "Error in updating YaxisMaps!" );
210             map_line2row = y_maps.getMapOfLineIDToRowID();
211         }
212         // System.out.println( "map_line2row = " + map_line2row );
213         drawn_boxes.initialize();
214     }
215
216     protected void finalizeAllOffImages( final TimeBoundingBox imgs_times )
217     {
218         drawn_boxes.finish();
219         map_line2row = null;
220         nesting_stacks.finish();
221         // Update the timeframe of all images
222         timeframe4imgs.setEarliestTime( imgs_times.getEarliestTime() );
223         timeframe4imgs.setLatestTime( imgs_times.getLatestTime() );
224         this.fireChangeEvent();  // to update TreeTrunkPanel.
225         Routines.setComponentAndChildrenCursors( root_frame,
226                                                  CustomCursor.Normal );
227
228         if ( Profile.isActive() )
229             final_time = new Date();
230         if ( Profile.isActive() )
231             Profile.println( "CanvasTimeline.finalizeAllOffImages(): "
232                            + "init. time = "
233                            + (init_time.getTime() - zero_time.getTime())
234                            + " msec.,   total time = "
235                            + (final_time.getTime() - zero_time.getTime())
236                            + " msec." );
237     }
238
239     protected void drawOneOffImage(       Image            offImage,
240                                     final TimeBoundingBox  timebounds )
241     {
242         if ( Debug.isActive() )
243             Debug.println( "CanvasTimeline: drawOneOffImage()'s offImage = "
244                          + offImage );
245         if ( offImage != null ) {
246             // int offImage_width = visible_size.width * NumViewsPerImage;
247             int        offImage_width  = offImage.getWidth( this );
248             int        offImage_height = offImage.getHeight( this );
249             Graphics2D offGraphics     = (Graphics2D) offImage.getGraphics();
250
251             // Set RenderingHint to have MAX speed.
252             offGraphics.setRenderingHint( RenderingHints.KEY_RENDERING,
253                                           RenderingHints.VALUE_RENDER_SPEED );
254
255             // offGraphics.getClipBounds() returns null
256             // offGraphics.setClip( 0, 0, getWidth()/NumImages, getHeight() );
257             // Do the ruler labels in a small font that's black.
258             // offGraphics.setPaint( BackgroundPaint );
259             offGraphics.setPaint(
260                         (Color) Parameters.BACKGROUND_COLOR.toValue() );
261             offGraphics.fillRect( 0, 0, offImage_width, offImage_height );
262
263             int    irow;
264             int    i_Y;
265
266             CoordPixelImage coord_xform;  // local Coordinate Transform
267             coord_xform = new CoordPixelImage( this, row_height, timebounds );
268
269             // Set AntiAliasing OFF for all the horizontal and vertical lines
270             offGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
271                                           RenderingHints.VALUE_ANTIALIAS_OFF );
272
273             // Draw the center TimeLines.
274             offGraphics.setColor( Color.cyan );
275             for ( irow = 0 ; irow < num_rows ; irow++ ) {
276                 //  Select only non-expanded row
277                 if ( ! tree_view.isExpanded( irow ) ) {
278                     i_Y = coord_xform.convertRowToPixel( (float) irow );
279                     offGraphics.drawLine( 0, i_Y, offImage_width-1, i_Y );
280                 }
281             }
282
283             // Draw the image separator when in Debug or Profile mode
284             if ( Debug.isActive() || Profile.isActive() ) {
285                 offGraphics.setColor( Color.gray );
286                 offGraphics.drawLine( 0, 0, 0, this.getHeight() );
287             }
288
289             nesting_stacks.reset();
290             drawn_boxes.reset();
291
292
293             Iterator sobjs;
294             Shadow   sobj;
295             Iterator dobjs;
296             Drawable dobj;
297
298             // set NestingFactor/RowID of Nestable Real Drawables and Shadows
299             dobjs = treetrunk.iteratorOfAllDrawables( timebounds,
300                                                       INCRE_STARTTIME_ORDER,
301                                                       isConnectedComposite,
302                                                       true );
303             while ( dobjs.hasNext() ) {
304                 dobj = (Drawable) dobjs.next();
305                 if ( dobj.getCategory().isVisible() ) {
306                     dobj.setStateRowAndNesting( coord_xform, map_line2row,
307                                                 nesting_stacks );
308                 }
309             }
310
311             int N_nestable = 0, N_nestless = 0;
312             int N_nestable_drawn = 0, N_nestless_drawn = 0;
313            
314             // Draw Nestable Real Drawables
315             dobjs = treetrunk.iteratorOfRealDrawables( timebounds,
316                                                        INCRE_STARTTIME_ORDER,
317                                                        isConnectedComposite,
318                                                        true );
319             while ( dobjs.hasNext() ) {
320                 dobj = (Drawable) dobjs.next();
321                 if ( dobj.getCategory().isVisible() ) {
322                     N_nestable_drawn +=
323                     dobj.drawOnCanvas( offGraphics, coord_xform,
324                                        map_line2row, drawn_boxes );
325                     N_nestable += dobj.getNumOfPrimitives();
326                 }
327             }
328
329             // Draw Nestable Shadows
330             sobjs = treetrunk.iteratorOfLowestFloorShadows( timebounds,
331                                                           INCRE_STARTTIME_ORDER,
332                                                           true );
333             while ( sobjs.hasNext() ) {
334                 sobj = (Shadow) sobjs.next();
335                 if ( sobj.getCategory().isVisible() ) {
336                     N_nestable_drawn +=
337                     sobj.drawOnCanvas( offGraphics, coord_xform,
338                                        map_line2row, drawn_boxes );
339                     N_nestable += sobj.getNumOfPrimitives();
340                 }
341             }
342
343             // Set AntiAliasing from Parameters for all slanted lines
344             offGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
345                                     Parameters.ARROW_ANTIALIASING.toValue() );
346
347             // Draw Nestless Shadows
348             /*
349             sobjs = treetrunk.iteratorOfLowestFloorShadows( timebounds,
350                                                           INCRE_STARTTIME_ORDER,
351                                                           false );
352             while ( sobjs.hasNext() ) {
353                 sobj = (Shadow) sobjs.next();
354                 if ( sobj.getCategory().isVisible() ) {
355                     N_nestless_drawn +=
356                     sobj.drawOnCanvas( offGraphics, coord_xform,
357                                        map_line2row, drawn_boxes );
358                     N_nestless += sobj.getNumOfPrimitives();
359                 }
360             }
361             */
362
363             // Draw all Nestless Real Drawables and Shadows
364             dobjs = treetrunk.iteratorOfAllDrawables( timebounds,
365                                                       INCRE_STARTTIME_ORDER,
366                                                       isConnectedComposite,
367                                                       false );
368             while ( dobjs.hasNext() ) {
369                 dobj = (Drawable) dobjs.next();
370                 if ( dobj.getCategory().isVisible() ) {
371                     N_nestless_drawn +=
372                     dobj.drawOnCanvas( offGraphics, coord_xform,
373                                        map_line2row, drawn_boxes );
374                     N_nestless += dobj.getNumOfPrimitives();
375                 }
376             }
377
378             if ( Profile.isActive() )
379                 Profile.println( "CanvasTimeline.drawOneOffImage(): "
380                                + "R_NestAble = "
381                                + N_nestable_drawn + "/" + N_nestable + ",  "
382                                + "R_NestLess = "
383                                + N_nestless_drawn + "/" + N_nestless );
384
385             // System.out.println( treetrunk.toStubString() );
386             offGraphics.dispose();
387         }
388     }   // endof drawOneOffImage()
389
390     public InfoDialog getPropertyAt( final Point            local_click,
391                                      final TimeBoundingBox  vport_timeframe )
392     {
393
394         /* System.out.println( "\nshowPropertyAt() " + local_click ); */
395         CoordPixelImage coord_xform;  // Local Coordinate Transform
396         coord_xform = new CoordPixelImage( this, row_height,
397                                            super.getTimeBoundsOfImages() );
398         double clicked_time = coord_xform.convertPixelToTime( local_click.x );
399
400         // Determine the timeframe of the current view by vport_timeframe
401         // System.out.println( "CurrView's timeframe = " + vport_timeframe );
402
403         Map map_line2treeleaf = y_maps.getMapOfLineIDToTreeLeaf();
404
405         Map map_line2row = y_maps.getMapOfLineIDToRowID();
406         if ( map_line2row == null ) {
407             if ( ! y_maps.update() )
408                 Dialogs.error( root_frame, "Error in updating YaxisMaps!" );
409             map_line2row = y_maps.getMapOfLineIDToRowID();
410         }
411
412         Iterator sobjs;
413         Shadow   sobj;
414         Iterator dobjs;
415         Drawable dobj;
416         Drawable clicked_dobj;
417
418         // Search Nestless Drawables in reverse drawing order
419         dobjs = treetrunk.iteratorOfAllDrawables( vport_timeframe,
420                                                   DECRE_STARTTIME_ORDER,
421                                                   isConnectedComposite,
422                                                   false );
423         while ( dobjs.hasNext() ) {
424             dobj = (Drawable) dobjs.next();
425             if ( dobj.getCategory().isVisible() ) {
426                 clicked_dobj = dobj.getDrawableAt( coord_xform,
427                                                    map_line2row,
428                                                    local_click );
429                 if (    clicked_dobj != null
430                      && clicked_dobj.getCategory().isVisible() ) {
431                     return  new InfoDialogForDrawable( root_frame,
432                                                        clicked_time,
433                                                        map_line2treeleaf,
434                                                        y_colnames,
435                                                        clicked_dobj );
436                 }
437             }
438         }
439
440         // Search Nestless Shadows in reverse drawing order
441         /*
442         sobjs = treetrunk.iteratorOfLowestFloorShadows( vport_timeframe,
443                                                         DECRE_STARTTIME_ORDER,
444                                                         false );
445         while ( sobjs.hasNext() ) {
446             sobj = (Shadow) sobjs.next();
447             if ( sobj.getCategory().isVisible() ) {
448                 clicked_dobj = sobj.getDrawableAt( coord_xform,
449                                                    map_line2row,
450                                                    local_click );
451                 if (    clicked_dobj != null
452                      && clicked_dobj.getCategory().isVisible() ) {
453                     return  new InfoDialogForDrawable( root_frame,
454                                                        clicked_time,
455                                                        map_line2treeleaf,
456                                                        y_colnames,
457                                                        clicked_dobj );
458                 }
459             }
460         }
461         */
462        
463         // Search Nestable Shadows in reverse drawing order
464         sobjs = treetrunk.iteratorOfLowestFloorShadows( vport_timeframe,
465                                                         DECRE_STARTTIME_ORDER,
466                                                         true );
467         while ( sobjs.hasNext() ) {
468             sobj = (Shadow) sobjs.next();
469             if ( sobj.getCategory().isVisible() ) {
470                 clicked_dobj = sobj.getDrawableAt( coord_xform,
471                                                    map_line2row,
472                                                    local_click );
473                 if (    clicked_dobj != null
474                      && clicked_dobj.getCategory().isVisible() ) {
475                     return  new InfoDialogForDrawable( root_frame,
476                                                        clicked_time,
477                                                        map_line2treeleaf,
478                                                        y_colnames,
479                                                        clicked_dobj );
480                 }
481             }
482         }
483
484         // Search Nestable Drawables in reverse drawing order
485         dobjs = treetrunk.iteratorOfRealDrawables( vport_timeframe,
486                                                    DECRE_STARTTIME_ORDER,
487                                                    isConnectedComposite,
488                                                    true );
489         while ( dobjs.hasNext() ) {
490             dobj = (Drawable) dobjs.next();
491             if ( dobj.getCategory().isVisible() ) {
492                 clicked_dobj = dobj.getDrawableAt( coord_xform,
493                                                    map_line2row,
494                                                    local_click );
495                 if (    clicked_dobj != null
496                      && clicked_dobj.getCategory().isVisible() ) {
497                     return  new InfoDialogForDrawable( root_frame,
498                                                        clicked_time,
499                                                        map_line2treeleaf,
500                                                        y_colnames,
501                                                        clicked_dobj );
502                 }
503             }
504         }
505
506         return super.getTimePropertyAt( local_click );
507     }   // endof  getPropertyAt()
508
509
510
511     public Rectangle localRectangleForDrawable( final Drawable dobj )
512     {
513         CoordPixelImage       coord_xform;
514         Rectangle             local_rect;
515         int                   rowID;
516         float                 nesting_ftr;
517         float                 rStart, rFinal;
518         int                   xloc, yloc, width, height;
519         // local_rect is created with CanvasTimeline's pixel coordinate system
520         coord_xform = new CoordPixelImage( this, row_height,
521                                            super.getTimeBoundsOfImages() );
522         xloc   = coord_xform.convertTimeToPixel( dobj.getEarliestTime() );
523         width  = coord_xform.convertTimeToPixel( dobj.getLatestTime() )
524                - xloc;
525
526         /* assume RowID and NestingFactor have been calculated */
527         rowID       = dobj.getRowID();
528         nesting_ftr = dobj.getNestingFactor();
529         rStart      = (float) rowID - nesting_ftr / 2.0f;
530         rFinal      = rStart + nesting_ftr;
531
532         yloc   = coord_xform.convertRowToPixel( rStart );
533         height = coord_xform.convertRowToPixel( rFinal ) - yloc;
534         local_rect = new Rectangle( xloc, yloc, width, height );
535         return local_rect;
536     }
537
538     private InfoPanelForDrawable createInfoPanelForDrawable( Drawable dobj )
539     {
540         InfoPanelForDrawable  info_popup;
541
542         Map map_line2treeleaf = y_maps.getMapOfLineIDToTreeLeaf();
543         info_popup = new InfoPanelForDrawable( map_line2treeleaf,
544                                                y_colnames, dobj );
545         return info_popup;
546     }
547
548     // NEW search starting from the specified time
549     public SearchPanel searchPreviousComponent( double searching_time )
550     {
551         Drawable  dobj = tree_search.previousDrawable( searching_time );
552         if ( dobj != null )
553             return this.createInfoPanelForDrawable( dobj );
554         else
555             return null;
556     }
557
558     // CONTINUING search
559     public SearchPanel searchPreviousComponent()
560     {
561         Drawable  dobj = tree_search.previousDrawable();
562         if ( dobj != null )
563             return this.createInfoPanelForDrawable( dobj );
564         else
565             return null;
566     }
567
568     // NEW search starting from the specified time
569     public SearchPanel searchNextComponent( double searching_time )
570     {
571         Drawable  dobj = tree_search.nextDrawable( searching_time );
572         if ( dobj != null )
573             return this.createInfoPanelForDrawable( dobj );
574         else
575             return null;
576     }
577
578     // CONTINUING search
579     public SearchPanel searchNextComponent()
580     {
581         Drawable  dobj = tree_search.nextDrawable();
582         if ( dobj != null )
583             return this.createInfoPanelForDrawable( dobj );
584         else
585             return null;
586     }
587
588     // Interface for SummarizableView
589     public InitializableDialog createSummary( final Dialog          dialog,
590                                               final TimeBoundingBox timebox )
591     {
592         BufForTimeAveBoxes  buf4statboxes;
593
594         buf4statboxes  = tree_search.createBufForTimeAveBoxes( timebox );
595         // System.out.println( "Statistics = " + buf4statboxes );
596         return new StatlineDialog( dialog, timebox,
597                                    y_maps.getLineIDMap(), buf4statboxes );
598     }
599 }
Note: See TracBrowser for help on using the browser.