sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SwmtGraph.java
changeset 7 8e12a575a9b5
equal deleted inserted replaced
6:f65f740e69f9 7:8e12a575a9b5
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 package com.nokia.s60tools.swmtanalyser.ui.graphs;
       
    18 
       
    19 import java.util.ArrayList;
       
    20 
       
    21 import org.eclipse.draw2d.ColorConstants;
       
    22 import org.eclipse.draw2d.FigureCanvas;
       
    23 import org.eclipse.draw2d.FlowLayout;
       
    24 import org.eclipse.draw2d.Graphics;
       
    25 import org.eclipse.draw2d.Panel;
       
    26 import org.eclipse.jface.action.Action;
       
    27 import org.eclipse.jface.action.IAction;
       
    28 import org.eclipse.jface.action.IMenuListener;
       
    29 import org.eclipse.jface.action.IMenuManager;
       
    30 import org.eclipse.jface.action.MenuManager;
       
    31 import org.eclipse.jface.action.Separator;
       
    32 import org.eclipse.swt.SWT;
       
    33 import org.eclipse.swt.events.ControlAdapter;
       
    34 import org.eclipse.swt.events.ControlEvent;
       
    35 import org.eclipse.swt.events.MouseEvent;
       
    36 import org.eclipse.swt.events.MouseMoveListener;
       
    37 import org.eclipse.swt.events.PaintEvent;
       
    38 import org.eclipse.swt.events.PaintListener;
       
    39 import org.eclipse.swt.events.SelectionEvent;
       
    40 import org.eclipse.swt.events.SelectionListener;
       
    41 import org.eclipse.swt.graphics.Color;
       
    42 import org.eclipse.swt.graphics.Drawable;
       
    43 import org.eclipse.swt.graphics.Image;
       
    44 import org.eclipse.swt.graphics.RGB;
       
    45 import org.eclipse.swt.layout.FormAttachment;
       
    46 import org.eclipse.swt.layout.FormData;
       
    47 import org.eclipse.swt.layout.FormLayout;
       
    48 import org.eclipse.swt.widgets.Composite;
       
    49 import org.eclipse.swt.widgets.Control;
       
    50 import org.eclipse.swt.widgets.Display;
       
    51 import org.eclipse.swt.widgets.Menu;
       
    52 import org.eclipse.swt.widgets.ScrollBar;
       
    53 
       
    54 import com.nokia.s60tools.swmtanalyser.data.ChunksData;
       
    55 import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
       
    56 import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
       
    57 import com.nokia.s60tools.swmtanalyser.data.KernelElements;
       
    58 import com.nokia.s60tools.swmtanalyser.data.ParsedData;
       
    59 import com.nokia.s60tools.swmtanalyser.data.SystemData;
       
    60 import com.nokia.s60tools.swmtanalyser.data.ThreadData;
       
    61 import com.nokia.s60tools.ui.IImageProvider;
       
    62 import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction;
       
    63 import com.nokia.s60tools.util.debug.DbgUtility;
       
    64 /**
       
    65  * Graph to be shown in Graphs tab.
       
    66  *
       
    67  */
       
    68 public class SwmtGraph extends ZoomableGraph implements MouseMoveListener, IImageProvider {
       
    69 
       
    70 	private FigureCanvas figureCanvas;
       
    71 	private FigureCanvas yAxis;
       
    72 	private ParsedData logData;
       
    73 	private Composite parentComposite;
       
    74 	
       
    75 	private boolean scaleNeedsUpdation = true;
       
    76 	private GenericGraph graph;
       
    77 	/**
       
    78 	 * Constructor
       
    79 	 * @param parent
       
    80 	 */
       
    81 	public SwmtGraph(Composite parent)
       
    82 	{
       
    83 		this.parentComposite = parent;
       
    84 	}
       
    85 	
       
    86 	/**
       
    87 	 * Set parsed data
       
    88 	 * @param parsedData
       
    89 	 */
       
    90 	public void setInputCyclesData(ParsedData parsedData)
       
    91 	{
       
    92 		this.logData = parsedData;
       
    93 	}
       
    94 	
       
    95 	/**
       
    96 	 * Draw graph area
       
    97 	 */
       
    98 	public void constructGraphArea()
       
    99 	{
       
   100 		if(this.logData == null || this.logData.getLogData() == null || parentComposite == null)
       
   101 			return;
       
   102 		
       
   103 		Control [] children = parentComposite.getChildren();
       
   104 		
       
   105 		if(children != null)
       
   106 		{
       
   107 			for(Control child:children)
       
   108 				child.dispose();
       
   109 		}
       
   110 		
       
   111 		Composite parent = new Composite(parentComposite, SWT.NONE);
       
   112 		parent.setLayout(new FormLayout());
       
   113 			
       
   114 		yAxis = new FigureCanvas(parent);
       
   115 		figureCanvas = new FigureCanvas(parent);
       
   116 		//figureCanvas.setSize(500, 450);
       
   117 		
       
   118 		FormData formData = new FormData();
       
   119 		formData.top = new FormAttachment(0);
       
   120 		formData.bottom = new FormAttachment(100);
       
   121 		formData.left   = new FormAttachment(0);
       
   122 		formData.width  = 60;
       
   123 		yAxis.setLayoutData(formData);
       
   124 		
       
   125 		formData = new FormData();
       
   126 		formData.top = new FormAttachment(0);
       
   127 		formData.bottom = new FormAttachment(100);
       
   128 		formData.left   = new FormAttachment(yAxis, 0, SWT.RIGHT);
       
   129 		formData.right  = new FormAttachment(100);
       
   130 		figureCanvas.setLayoutData(formData);
       
   131 		
       
   132 		yAxis.setBackground(ColorConstants.white);
       
   133 		yAxis.addPaintListener(new PaintListener()
       
   134 		{
       
   135 
       
   136 			public void paintControl(PaintEvent event) {
       
   137 				
       
   138 				if(graph != null)
       
   139 					graph.paintYAxis(event.gc);
       
   140 				else
       
   141 					event.gc.dispose();
       
   142 							
       
   143 			}		
       
   144 		});
       
   145 		
       
   146 		yAxis.addControlListener(new ControlAdapter(){
       
   147 			public void controlResized(ControlEvent e) {
       
   148 			}
       
   149 		});
       
   150 		
       
   151 		figureCanvas.setBackground(new Color(Display.getDefault(), new RGB(255,255,255)));
       
   152 		
       
   153 		Panel panel = new Panel()
       
   154 		{
       
   155 			public void paint(Graphics graphics)
       
   156 			{
       
   157 				DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint START");
       
   158 				
       
   159 				if(graph != null){
       
   160 					graph.drawBackGroundLines(figureCanvas, graphics);
       
   161 					graph.paint(graphics);
       
   162 				}
       
   163 				else{
       
   164 					erase();
       
   165 				}
       
   166 				DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint END");				
       
   167 			}
       
   168 					
       
   169 					
       
   170 		};
       
   171 		
       
   172 		panel.setLayoutManager(new FlowLayout());
       
   173 				
       
   174 		figureCanvas.setContents(panel);
       
   175 								
       
   176 		figureCanvas.addMouseMoveListener(this);
       
   177 		hookContextMenu();
       
   178 				
       
   179 		final ScrollBar horizontalBar = figureCanvas.getHorizontalBar();
       
   180 		
       
   181 		horizontalBar.addSelectionListener(new SelectionListener()
       
   182 		{
       
   183 
       
   184 			public void widgetDefaultSelected(SelectionEvent arg0) {
       
   185 			
       
   186 			}
       
   187 
       
   188 			public void widgetSelected(SelectionEvent event) {
       
   189 				
       
   190 				if(graph != null){
       
   191 					graph.setScrolledXOrigin((figureCanvas.getViewport().getViewLocation().x));
       
   192 				}
       
   193 		
       
   194 				figureCanvas.redraw();
       
   195 			}
       
   196 			
       
   197 		});
       
   198 		
       
   199 		figureCanvas.addControlListener(new ControlAdapter()
       
   200 		{
       
   201 			public void controlResized(ControlEvent e) {
       
   202 				horizontalBar.setPageIncrement(figureCanvas.getBounds().width);
       
   203 				
       
   204 				if(graph != null)
       
   205 					graph.setVisualSize(figureCanvas.getClientArea().height);
       
   206 				if(scaleNeedsUpdation)
       
   207 				{
       
   208 					zoomGraph();
       
   209 					scaleNeedsUpdation = false;
       
   210 				}
       
   211 				
       
   212 				yAxis.redraw();
       
   213 				figureCanvas.redraw();
       
   214 				
       
   215 			}
       
   216 		});
       
   217 		parentComposite.layout();
       
   218 		
       
   219 	}	
       
   220 	
       
   221 	/**
       
   222 	 * Add Pop-Up Menus on Graph area.
       
   223 	 *
       
   224 	 */
       
   225 	private void hookContextMenu() {
       
   226 		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
       
   227 		menuMgr.setRemoveAllWhenShown(true);
       
   228 		menuMgr.addMenuListener(new IMenuListener() {
       
   229 			public void menuAboutToShow(IMenuManager manager) {
       
   230 				fillContextMenu(manager);
       
   231 			}
       
   232         });
       
   233 	    Menu menu = menuMgr.createContextMenu(figureCanvas);
       
   234 	    figureCanvas.setMenu(menu);
       
   235 	}
       
   236 	
       
   237 	protected void fillContextMenu(IMenuManager manager) {
       
   238 		
       
   239 		zoomIn = new Action()
       
   240 		{
       
   241 			public void run()
       
   242 			{
       
   243 				zoomIn();
       
   244 			}
       
   245 			{
       
   246 				this.setText(ZOOM_IN_CONTEXT_MENU_TITLE);
       
   247 			}
       
   248 		};
       
   249 		
       
   250 		zoomOut = new Action()
       
   251 		{
       
   252 			public void run()
       
   253 			{
       
   254 				zoomOut();
       
   255 			}
       
   256 			{
       
   257 				this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE);
       
   258 			}
       
   259 		};
       
   260 		IAction showEntireGraph = new Action()
       
   261 		{
       
   262 			public void run()
       
   263 			{
       
   264 				zoomGraph();
       
   265 			}
       
   266 			{
       
   267 				this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
       
   268 			}
       
   269 		};
       
   270 		
       
   271 		IAction saveGraph = new Action()
       
   272 		{
       
   273 			public void run()
       
   274 			{
       
   275 				GraphsUtils.saveGraph(parentComposite);
       
   276 			}
       
   277 			{
       
   278 				this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
       
   279 			}
       
   280 		};
       
   281 				
       
   282 		copy = new CopyImageToClipboardAction(this);		
       
   283 		
       
   284 		manager.add(zoomIn);
       
   285 		manager.add(new Separator());
       
   286 		manager.add(zoomOut);
       
   287 		manager.add(new Separator());
       
   288 		manager.add(showEntireGraph);
       
   289 		manager.add(saveGraph);
       
   290 		manager.add(copy);
       
   291 		
       
   292 		// Finally updating action states
       
   293 		updateViewActionEnabledStates();
       
   294 	}
       
   295 	
       
   296 	/**
       
   297 	 * This method acts as an interface for redrawig graphs
       
   298 	 * @param graph 
       
   299 	 */
       
   300 	public void redraw(GenericGraph graph)
       
   301 	{
       
   302 		this.graph = graph;
       
   303 		
       
   304 		try{
       
   305 
       
   306 		graph.setVisualSize(figureCanvas.getClientArea().height);
       
   307 		graph.prepareData();
       
   308 		int [] timeSamples = graph.calculateTimeIntervals();
       
   309 		graph.lastSampleTime = timeSamples[timeSamples.length -1];
       
   310 		
       
   311 		//Zooms Graph to fit last sample value
       
   312 		zoomGraph();
       
   313 		yAxis.redraw();
       
   314 		figureCanvas.redraw();
       
   315 		}catch(Exception e){
       
   316 			e.printStackTrace();
       
   317 		}
       
   318 	}
       
   319 
       
   320 	/* (non-Javadoc)
       
   321 	 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
       
   322 	 */
       
   323 	public void mouseMove(MouseEvent event) {
       
   324 			
       
   325 		if(this.graph != null)
       
   326 		{
       
   327 			this.figureCanvas.setToolTipText(this.graph.getToolTipText(event.x, event.y));
       
   328 			this.figureCanvas.redraw();
       
   329 		}
       
   330 	}
       
   331 	
       
   332 	/**
       
   333 	 * Clear graph
       
   334 	 */
       
   335 	public void clearGraph()
       
   336 	{
       
   337 		this.graph = null;
       
   338 		try{
       
   339 			yAxis.redraw();
       
   340 			figureCanvas.redraw();
       
   341 		
       
   342 		}catch(NullPointerException e){
       
   343 			
       
   344 		}
       
   345 	}
       
   346 	
       
   347 	/**
       
   348 	 * This method stores data corresponding to given item, so that it can be 
       
   349 	 * used in Graphed items view.
       
   350 	 * @param itemName 
       
   351 	 * @param allEventsGraph
       
   352 	 */
       
   353 	public void storeClearedEventValues(String itemName, GraphForAllEvents allEventsGraph)
       
   354 	{
       
   355 		if(this.graph != null)
       
   356 		{
       
   357 			if(graph instanceof ThreadsGraph){
       
   358 				ArrayList<ThreadData> values = ((ThreadsGraph)(graph)).getDataForThread(itemName);
       
   359 			
       
   360 				allEventsGraph.setHeapSizeForThread(itemName, values);
       
   361 				
       
   362 			}
       
   363 			else if(graph instanceof ChunksGraph)
       
   364 			{
       
   365 				if(graph.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
       
   366 				{
       
   367 					ArrayList<GlobalDataChunks> values = ((ChunksGraph)(graph)).getGlobalChunkData(itemName);
       
   368 					
       
   369 					allEventsGraph.setGlobalChunkSizeForChunk(itemName, values);
       
   370 				}
       
   371 				else if(graph.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
       
   372 				{
       
   373 					ArrayList<ChunksData> values = ((ChunksGraph)(graph)).getNonHeapChunkData(itemName);
       
   374 					
       
   375 					allEventsGraph.setNonHeapChunkSizeForChunk(itemName, values);
       
   376 				}
       
   377 					
       
   378 			}
       
   379 			else if(graph instanceof DisksGraph)
       
   380 			{
       
   381 				if(graph.getEvent().equals(GenericGraph.EventTypes.DISK_USED_SIZE) || 
       
   382 						graph.getEvent().equals(GenericGraph.EventTypes.DISK_TOTAL_SIZE))
       
   383 				{
       
   384 					ArrayList<DiskOverview> values = ((DisksGraph)(graph)).getDiskData(itemName);
       
   385 					
       
   386 					allEventsGraph.setDiskData(itemName, values);
       
   387 				}
       
   388 				
       
   389 				else if(graph.getEvent().equals(GenericGraph.EventTypes.RAM_USED)||
       
   390 						graph.getEvent().equals(GenericGraph.EventTypes.RAM_TOTAL))
       
   391 				{
       
   392 					ArrayList<SystemData> sysData = ((DisksGraph)(graph)).getSystemData();
       
   393 					
       
   394 					allEventsGraph.setSystemData(sysData);
       
   395 				}
       
   396 			}
       
   397 			else if(graph instanceof SystemDataGraph)
       
   398 			{
       
   399 				ArrayList<KernelElements> kernelData = ((SystemDataGraph)(graph)).getKernelData();
       
   400 				
       
   401 				allEventsGraph.setKernelData(kernelData);
       
   402 			}
       
   403 		}
       
   404 	}
       
   405 
       
   406 	/**
       
   407 	 * Sets enabled/disabled states for actions commands
       
   408 	 * on this view, based on the current application state.
       
   409 	 * This method should be called whenever an operation is
       
   410 	 * started or stopped that might have effect on action 
       
   411 	 * button states.
       
   412 	 */
       
   413 	private void updateViewActionEnabledStates() {
       
   414 		//Zoom In
       
   415 		setEnableState(zoomIn, !(this.graph != null && graph.getScale() == GraphsUtils.nextScale(graph.getScale(), false)));
       
   416 		
       
   417 		//Zoom Out
       
   418 		if(this.graph != null)
       
   419 		{
       
   420 			boolean zoomOutEnableCondition1 = !(graph.getScale() == GraphsUtils.nextScale(graph.getScale(), true));
       
   421 			int width = figureCanvas.getClientArea().width;
       
   422 			boolean zoomOutEnableCondition2 = !(graph.lastSampleTime / graph.getScale() <= width);
       
   423 			setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2);
       
   424 		}
       
   425 		else{
       
   426 			setEnableState(zoomOut, false);			
       
   427 		}
       
   428 		
       
   429 	}
       
   430 	
       
   431 	/* (non-Javadoc)
       
   432 	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn()
       
   433 	 */
       
   434 	protected void zoomIn()
       
   435 	{
       
   436 		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom In");
       
   437 		//Preconditions checked already in updateViewActionEnabledStates
       
   438 		graph.setScale(GraphsUtils.nextScale(graph.getScale(), false));
       
   439 		setNewSize();
       
   440 	}
       
   441 	
       
   442 	/* (non-Javadoc)
       
   443 	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut()
       
   444 	 */
       
   445 	protected void zoomOut()
       
   446 	{
       
   447 		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom Out");
       
   448 		//Preconditions checked already in updateViewActionEnabledStates
       
   449 		graph.setScale(GraphsUtils.nextScale(graph.getScale(), true));
       
   450 		setNewSize();
       
   451 	}
       
   452 	
       
   453 	/**
       
   454 	 * This method first zooms in graph to the maximum possible scale
       
   455 	 * and zooms out so that it fits in the canvas area.
       
   456 	 *
       
   457 	 */
       
   458 	public void zoomGraph()
       
   459 	{		
       
   460 		int width = figureCanvas.getClientArea().width;
       
   461 		
       
   462 		if(width <=0 || this.graph == null)
       
   463 			return;
       
   464 		
       
   465 		double new_scale = graph.getScale();
       
   466 		
       
   467 		double prevNew  = new_scale;
       
   468 		
       
   469 		//first zoom in until it is too big to fit
       
   470 		while (graph.lastSampleTime / new_scale <= width){
       
   471 			new_scale = GraphsUtils.nextScale(new_scale, false);
       
   472 			
       
   473 			if(prevNew == new_scale)
       
   474 				break;
       
   475 			
       
   476 			prevNew = new_scale;
       
   477 			
       
   478 		}
       
   479 		// now zoom out until it just fits
       
   480 		while (graph.lastSampleTime / new_scale > width){
       
   481 			new_scale = GraphsUtils.nextScale(new_scale, true);
       
   482 			
       
   483 			if(prevNew == new_scale)
       
   484 				break;
       
   485 			
       
   486 			prevNew = new_scale;
       
   487 		}
       
   488 		
       
   489 		if (new_scale == graph.getScale())
       
   490 			return;
       
   491 	
       
   492 		graph.setScale(new_scale);
       
   493 		setNewSize();
       
   494 	}
       
   495 	
       
   496 	/**
       
   497 	 * This method sets the size of the panel, when scale is changed.  
       
   498 	 * When graph extends beyond visible area, horizontal scroll bar appears automatically.
       
   499 	 *
       
   500 	 */
       
   501 	private void setNewSize()
       
   502 	{
       
   503 		if(graph == null)
       
   504 			return;
       
   505 		
       
   506 		graph.setScrolledXOrigin(0);
       
   507 		double scale = graph.getScale();
       
   508 		int lastSample = graph.lastSampleTime;
       
   509 		
       
   510 		int prefSize = (int)(lastSample/scale);
       
   511 	
       
   512 		Panel panel = (Panel)(figureCanvas.getContents());
       
   513 		panel.setPreferredSize(prefSize + 100, 0);
       
   514 	
       
   515 		if (prefSize >= figureCanvas.getClientArea().width) {
       
   516 			graph.setScrolledXOrigin(figureCanvas.getViewport().getViewLocation().x);
       
   517 	    	panel.setSize(prefSize + 100, 0);
       
   518 	    }
       
   519 	
       
   520 	}
       
   521 	
       
   522 	/* (non-Javadoc)
       
   523 	 * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage()
       
   524 	 */
       
   525 	public Image getImage() {
       
   526 		return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height);
       
   527 	}
       
   528 	
       
   529 	/* (non-Javadoc)
       
   530 	 * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable()
       
   531 	 */
       
   532 	public Drawable getDrawable() {
       
   533 		return parentComposite;
       
   534 	}
       
   535 
       
   536 
       
   537 }