sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTraceGraph.java
changeset 5 844b047e260d
child 12 ae255c9aa552
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.MouseEvent;
+import org.eclipse.draw2d.MouseMotionListener;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.util.ColorPalette;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+
+/**
+ * The performance counter graph class, responsible for drawing the several graphs
+ * based on performance counters as well as managing the legend views to some extend
+ */
+public class PecCommonTraceGraph extends GenericTraceGraph implements 
+		MouseMotionListener, PIEventListener,  ITitleBarMenu  {
+
+	private static int X_LEGEND_HEIGHT = 20;
+
+	/** for tooltip: margin for search area for finding a domain object */
+	private static final int MARGIN_IN_PIXELS = 5;
+	
+	/** the graph index; there is one graph per editor page (with identical content)*/
+	//private int graphIndex;
+	protected PecCommonTrace trace;
+	private String graphTitle;
+	private String helpContextId;
+
+	/** number of series to draw; each in a separate graph section */
+	private int typeAmount = 0;
+	protected List<Integer> drawSeries;
+	
+	private int[][] origYCoords;
+	private int[][] points;
+
+	private int[] exact_mins;
+	private int[] exact_maxs;
+
+	private int[] mins;
+	private int[] maxs;
+	
+	private double currentlyCalcFinalScale = -1;
+	private int currentlyCalcFinalHeight = -1;
+
+	protected FigureCanvas leftFigureCanvas;
+
+	/** marks graph as dirty so it gets re-drawn */
+	protected boolean dirty;
+
+	private PecCommonLegend legend;
+	
+	/** GUI manager has knowledge off all IpcTraceGraphs; can broadcast some of the events */
+	private PecCommonGuiManager guiManager;
+	
+	/**
+	 * Constructor
+	 * @param graphIndex the index of the graph (corresponds to the page in the editor)
+	 * @param pecTrace the trace class
+	 * @param uid the uid to identify the current editor
+	 * @param guiManager IpcGuiManager which manages all graphs
+	 * @param title The title of the graph
+	 * @param helpContextIdMainPage 
+	 */
+	public PecCommonTraceGraph(int graphIndex, PecCommonTrace pecTrace, int uid, PecCommonGuiManager guiManager, String title, String helpContextIdMainPage) {
+		super(pecTrace);
+
+//		this.graphIndex = graphIndex;
+		this.trace = pecTrace;
+		this.guiManager = guiManager;
+		this.graphTitle = title;
+		this.helpContextId = helpContextIdMainPage;
+		
+		typeAmount = pecTrace.getValueTypes().length;
+
+		int sampleCount = pecTrace.getSampleAmount();
+		origYCoords = new int[typeAmount][sampleCount];
+		points = new int[typeAmount][sampleCount*2];
+		exact_mins = new int[typeAmount];
+		exact_maxs = new int[typeAmount];
+		mins = new int[typeAmount];
+		maxs = new int[typeAmount];
+		
+		drawSeries = new ArrayList<Integer>();
+		//by default, draw all graphs on screen
+		showAll();
+		
+		this.initialiseData();
+		
+		ProfileVisualiser pV = NpiInstanceRepository.getInstance().getProfilePage(uid, graphIndex);
+		legend = createLegend(pV.getBottomComposite());
+	}
+	
+	/**
+	 * Creates the legend
+	 * @param bottomComposite The composite to create the legend in
+	 */
+	protected PecCommonLegend createLegend(Composite bottomComposite) {		
+		return new PecCommonLegend(this, bottomComposite, getTitle(), trace);
+	}
+
+	/**
+	 * Fill mins, maxs, and origYCoords arrays
+	 */
+	private void initialiseData() {
+		Vector<GenericSample> sv = trace.samples;
+
+		Arrays.fill(exact_mins, Integer.MAX_VALUE);
+		Arrays.fill(exact_maxs, Integer.MIN_VALUE);
+
+		for (int x = 0; x < sv.size(); x++) {
+			PecCommonSample s = (PecCommonSample) sv.get(x);
+
+			for (int i = 0; i < typeAmount; i++) {
+				int value = s.values[i];
+
+				if (value < exact_mins[i]){
+					exact_mins[i] = value;					
+				} 
+				if (value > exact_maxs[i]){
+					exact_maxs[i] = value;					
+				}
+
+				origYCoords[i][x] = value;
+			}
+		}
+		
+		//let the graph draw in area [0, prettyMaxValue]
+		for (int i = 0; i < typeAmount; i++) {
+			mins[i] = 0;
+			maxs[i] = prettyMaxValue(exact_maxs[i]);
+		}
+	}
+	
+	private void showAll(){
+		drawSeries.clear();
+		for (int i = 0; i < typeAmount; i++) {
+			drawSeries.add(i);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#repaint()
+	 */
+	@Override
+	public void repaint() {
+		this.parentComponent.repaintComponent();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paint(org.eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics)
+	 */
+	@Override
+	public void paint(org.eclipse.draw2d.Panel panel,
+			org.eclipse.draw2d.Graphics graphics) {
+		this.setSize(this.getSize().width, getVisualSize().height);
+		this.drawDottedLineBackground(graphics, X_LEGEND_HEIGHT);
+		
+		drawGraphs(panel, graphics);
+		drawLabelsInGraph(panel, graphics);
+
+		this.drawSelectionSection(graphics, X_LEGEND_HEIGHT);
+	}
+
+	private void drawLabelsInGraph(Panel panel, Graphics graphics) {
+
+		float sectionHeight = getSectionHeight();
+		
+		if (sectionHeight > 60f){ //only draw the label if the section has a decent height
+			
+			int edgeX = ((Viewport) panel.getParent()).getViewLocation().x;
+
+			for (int i = 0; i < drawSeries.size(); i++) {
+				int seriesIdx = drawSeries.get(i);
+				int y = (int) sectionHeight * i;
+
+				graphics.setForegroundColor(ColorConstants.black);
+				graphics.drawString(trace.getValueTypes()[seriesIdx],
+						edgeX + 10, y + 6);
+				if (sectionHeight > 80f){
+					graphics.drawString(String.format(Messages.PecCommonTraceGraph_0,
+							this.exact_mins[seriesIdx], this.exact_maxs[seriesIdx]),
+							edgeX + 10, y + 18);					
+				}
+			}
+		}
+	}
+
+	private void drawGraphs(Panel panel, Graphics graphics) {
+		int visY = this.getVisualSize().height;
+		double scale = getScale();
+
+		if (dirty || this.currentlyCalcFinalHeight != visY
+				|| this.currentlyCalcFinalScale != scale) {
+
+			Vector<GenericSample> sv = trace.samples;
+			float sectionHeight = getSectionHeight();
+			
+			for (int sampleIdx = 0; sampleIdx < sv.size(); sampleIdx++) {
+				// calculate x-coordinate per sample
+				int xCoord = (int) (sampleIdx / scale);
+
+				for (int seriesIdx : drawSeries) {
+					points[seriesIdx][sampleIdx * 2] = xCoord;
+					points[seriesIdx][sampleIdx * 2 + 1] = convertValueToYCoordinate(origYCoords[seriesIdx][sampleIdx], mins[seriesIdx], maxs[seriesIdx], drawSeries.indexOf(seriesIdx), sectionHeight);
+				}
+			}
+			
+			dirty = false;
+			this.currentlyCalcFinalHeight = visY;
+			this.currentlyCalcFinalScale = scale;
+		}
+
+		graphics.setForegroundColor(ColorConstants.blue);
+
+		for (int seriesIdx : drawSeries) {
+			graphics.drawPolyline(points[seriesIdx]);
+		}
+	}
+	
+	/**
+	 * Converts a y coordinate into the actual value.
+	 * @param yCoordinate the y coordinate to convert
+	 * @param minValue the lowest value in the series
+	 * @param maxValue the highest value in the series
+	 * @param section the number of the section (for 3 sections this would be 0, 1, or 2)
+	 * @param sectionHeight the height of the section in pixels. All sections are of equal height
+	 * @return the converted value
+	 */
+	static int convertYCoordinateToValue(int yCoordinate, int minValue, int maxValue, int section, float sectionHeight){
+		float offset = sectionHeight * section;
+		
+		float location = sectionHeight - (yCoordinate - offset) ;
+		return (int)(location * (maxValue - minValue) / sectionHeight ) + minValue;
+	} 
+	
+	/**
+	 * Converts a value into a y coordinate; the opposite of convertYCoordinateToValue()
+	 * @param value the value to convert
+	 * @param minValue the lowest value in the series
+	 * @param maxValue the highest value in the series
+	 * @param section the number of the section (for 3 sections this would be 0, 1, or 2)
+	 * @param sectionHeight the height of the section in points. All sections are of equal height
+	 * @return the converted value
+	 */
+	static int convertValueToYCoordinate(int value, int minValue, int maxValue, int section, float sectionHeight){
+		float offset = sectionHeight * section;
+		
+		float location = (value - minValue) * sectionHeight / (maxValue - minValue); //lowest shown value is min (not 0)
+		return(int) ((sectionHeight - location) + offset);
+	}
+	
+	/**
+	 * Returns the height of a section in pixels. All sections are of equal height.
+	 * @return
+	 */
+	private float getSectionHeight(){
+		int visualHeight = getVisualSize().height - X_LEGEND_HEIGHT;
+		return drawSeries.size() == 0 ? visualHeight :  visualHeight / drawSeries.size();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paintLeftLegend
+	 * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC)
+	 */
+	@Override
+	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
+		GC localGC = gc;
+
+		if (gc == null)
+			gc = new GC(PIPageEditor.currentPageEditor().getSite().getShell());
+
+		Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas
+				.getClientArea();
+
+		int visY = rect.height;
+
+		float visYfloat = visY - X_LEGEND_HEIGHT;
+
+		if (visYfloat < 0f)
+			visYfloat = 0f;
+
+		gc.setForeground(ColorPalette.getColor(new RGB(100, 100, 100)));
+		gc.setBackground(ColorPalette.getColor(new RGB(255, 255, 255)));
+		
+		int legendsToDraw = drawSeries.size();
+		float legendHeight = visYfloat / legendsToDraw;
+		double yIncrement = legendHeight / 10;
+		int previousBottom = 0;
+		
+		for (int section = 0; section < legendsToDraw; section++) {
+			int seriesIdx = drawSeries.get(section);
+			int maxValue = maxs[seriesIdx];
+
+			float valuePerPixel = maxValue / legendHeight;
+
+			for (int k = 10; k >= 0; k--) {
+				// location for the value indicator is k * 1/10 the height of
+				// the
+				// height of the section
+				int y = (int) (legendHeight * (section+1) - (yIncrement * k));
+				int value = (int) ((((legendHeight * valuePerPixel) / 10.0) * k));
+
+				// construct the text for each scale
+				//use grouping for small numbers, then without grouping to fit the text
+				String sValue = String.format(value < 1000000 ? Messages.PecCommonTraceGraph_1 : Messages.PecCommonTraceGraph_2, value);
+
+				Point extent = gc.stringExtent(sValue);
+
+				gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3,  y + 1,
+						IGenericTraceGraph.Y_LEGEND_WIDTH, y + 1);
+
+				if (y >= previousBottom) {
+					gc.drawString(sValue, IGenericTraceGraph.Y_LEGEND_WIDTH
+							- extent.x - 4, y);
+					previousBottom = y + extent.y;
+				}
+			}
+		}
+
+		if (localGC == null) {
+			gc.dispose();
+			figureCanvas.redraw();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return this.graphTitle;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseDragged(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseEntered(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseExited(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseHover(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseMoved(MouseEvent me) {
+		//setting the tooltip
+		float sectionHeight = getSectionHeight();
+		int section = (int) (me.y / sectionHeight);
+		if (section < 0 || section >= drawSeries.size()){
+			this.setToolTipText(null);
+			return;
+		}
+		int seriesIdx = drawSeries.get(section);
+		
+		PecCommonSample sample = getSampleUnderMouse(me);
+
+		if (sample != null){
+			setToolTipText(String.format(Messages.PecCommonTraceGraph_3, trace.getValueTypes()[seriesIdx], sample.sampleSynchTime /1000f, sample.values[seriesIdx]));			
+		} else {
+			String tooltip = null;
+
+			//display default values
+			
+			if (section < drawSeries.size()) {
+				double time = me.x * this.getScale();
+				if (time >= 0 && time <= trace.getLastSampleTime()){
+					int value = convertYCoordinateToValue(me.y, mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+					tooltip = String.format(Messages.PecCommonTraceGraph_4, time / 1000f, value);
+				}
+			}
+			
+			this.setToolTipText(tooltip);			
+		}
+	}
+
+	/**
+	 * Returns the sample for the given mouse location, or null
+	 * @param me mouse event for the mouse location
+	 * @return the sample if found, or null
+	 */
+	private PecCommonSample getSampleUnderMouse(MouseEvent me) {
+		PecCommonSample ret = null;
+		
+		if (drawSeries.size() == 0){
+			return ret; //no graphs are being drawn so no samples can be found
+		}
+
+		int mex = me.x;
+		int mey = me.y;
+		float sectionHeight = getSectionHeight();
+		int section = (int) (mey / sectionHeight);
+		
+		if (section >= 0 && section < drawSeries.size()) {
+			int seriesIdx = drawSeries.get(section);
+			double idealTime = mex * this.getScale();
+			if (idealTime < 0 || idealTime > trace.getLastSampleTime()){
+				return null; 
+			}
+			int idealValue = convertYCoordinateToValue(mey, mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+
+			//calculate the boundary of the area in which to look for a sample
+			double leftBoudaryTime =  ((mex - MARGIN_IN_PIXELS) * getScale());
+			if (leftBoudaryTime < 0){
+				leftBoudaryTime = 0;
+			}
+			double rightBoundaryTime = ((mex + MARGIN_IN_PIXELS) * getScale());
+			if (rightBoundaryTime < 0){
+				return null; 
+			} else if (rightBoundaryTime > trace.getLastSampleTime()){
+				rightBoundaryTime = trace.getLastSampleTime();
+			}
+			 
+			int topBoundaryValue = convertYCoordinateToValue(Math.max((int)(section * sectionHeight), mey - MARGIN_IN_PIXELS), mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+			int bottomBoundaryValue = convertYCoordinateToValue(Math.min((int)((section +1) * sectionHeight), mey + MARGIN_IN_PIXELS), mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+			
+			int leftSample = (int)(leftBoudaryTime / trace.getSamplingInterval());
+			int rightSample = (int)(rightBoundaryTime+.5 / trace.getSamplingInterval());
+			
+			for (int i = leftSample; i <= rightSample; i++) {
+				PecCommonSample sample = (PecCommonSample)trace.getSample(i);
+				if (sample.values[seriesIdx] < topBoundaryValue && sample.values[seriesIdx] > bottomBoundaryValue){
+					//System.out.println("Cur: "+ sample.values[seriesIdx]+" Range: "+topBoundaryValue+", "+bottomBoundaryValue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					//check whether we have found a closer match to mid-point
+					if (ret == null 
+							|| (Math.abs(sample.sampleSynchTime - idealTime) < Math.abs(ret.sampleSynchTime - idealTime))
+							|| (ret.sampleSynchTime == sample.sampleSynchTime 
+									&& Math.abs(sample.values[seriesIdx] - idealValue) < Math.abs(ret.values[seriesIdx]	- idealValue))){
+						ret = sample;
+					}
+				}
+			} 
+		}
+		
+		return ret;
+	}
+
+	/**
+	 * Converts the passed X-coordiate into a time value (in milliseconds) using
+	 * the scale provided. Makes sure the return value is non-negative.
+	 * 
+	 * @param x
+	 *            the x coordinate to use
+	 * @param scale
+	 *            the scale to use
+	 * @return time in milliseconds
+	 */
+	protected static double getTimeForXCoordinate(int x, double scale) {
+		double time = x * scale;
+		// mouse event may return out of range X, that may
+		// crash when we use it to index data array
+		time = time >= 0 ? time : 0;
+		return time;
+	}
+	
+	/**
+	 * Make the input value a pretty value to display, such as 423,345 => 500,000
+	 * @param value the value to convert
+	 * @return the prettier value
+	 */
+	static int prettyMaxValue(final int value) {
+		double prettyVal = value;
+		int len = 0;
+
+		while (prettyVal >= 10) {
+			prettyVal/= 10;
+			len++;
+		}
+		
+		prettyVal = Math.ceil(prettyVal);
+		
+		if (prettyVal <= 1){
+			prettyVal = 1;
+		} else if (prettyVal <= 2){
+			prettyVal = 2;
+		} else if (prettyVal <= 3){
+			prettyVal = 3;
+		} else if (prettyVal <= 5){
+			prettyVal = 5;
+		} else {
+			prettyVal = 10;
+		}
+		
+		return (int)(prettyVal * Math.pow(10, len));
+	}
+
+	/**
+	 * Callback for PIEvent.SELECTION_AREA_CHANGED
+	 * @param newStart new selection start
+	 * @param newEnd new selection end
+	 */
+	void selectionAreaChanged(double newStart, double newEnd) {
+		this.setSelectionStart(newStart);
+		this.setSelectionEnd(newEnd);
+		
+		trace.selectionAreaChanged(newStart, newEnd);
+		legend.refreshLegend();
+		
+		this.repaint();				
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived(com.nokia.carbide.cpp.internal.pi.visual.PIEvent)
+	 */
+	public void piEventReceived(PIEvent be) {
+		switch (be.getType()) {
+		
+		case PIEvent.SELECTION_AREA_CHANGED:
+			double[] values = (double[]) be.getValueObject();
+			//broadcast to all IPC graphs
+			guiManager.selectionAreaChanged(values[0], values[1]);				
+			break;
+
+		case PIEvent.SCROLLED:
+			Event event = ((Event) be.getValueObject());
+			//this broadcasts to all graphs on this PICompositePanel
+			this.parentComponent.setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
+			this.repaint();
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean)
+	 */
+	@Override
+	public void graphMaximized(boolean value) {
+		legend.setLegendMaximised(value);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphVisibilityChanged(boolean)
+	 */
+	@Override
+	public void graphVisibilityChanged(boolean value) {
+		legend.setLegendVisible(value);
+	}
+
+	@Override
+	public void action(String action) {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/**
+	 * Adds or removes a series to be drawn
+	 * @param seriesId series id of the series to add or remove
+	 * @param add true if series is to be added, false for remove
+	 */
+	public void addOrRemoveSeries(int seriesId, boolean add){
+		if (add){
+			if (!drawSeries.contains(seriesId)){
+				drawSeries.add(seriesId);
+				Collections.sort(drawSeries);
+			}
+		} else {
+			drawSeries.remove(Integer.valueOf(seriesId));
+		}
+		
+		//repaint graphs
+		redrawGraphArea();
+	}
+	
+	private void redrawGraphArea() {
+		dirty = true;
+		setGraphImageChanged(true);
+		repaint();		
+	}
+
+	/**
+	 * Removes all series from display
+	 */
+	public void removeAllSeries(){
+		drawSeries.clear();
+		redrawGraphArea();
+		
+	}
+
+	/**
+	 * Shows all series in graph area
+	 */
+	public void showAllSeries(){
+		showAll();
+		redrawGraphArea();
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#addTitleBarMenuItems()
+	 */
+	public Action[] addTitleBarMenuItems() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return this.helpContextId;
+	}
+
+}