diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ChunksGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ChunksGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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.s60tools.swmtanalyser.ui.graphs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.ChunksData; +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * This class contains all needed logic to paint data related to Global and Non-Heap chunks. + * + */ +public class ChunksGraph extends GenericGraph { + + private HashMap> chunksData = new HashMap>(); + private HashMap> nonHeapChunksData = new HashMap>(); + + private HashMap pointsData = new HashMap(); + + private double visY; + private double multiplier; + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics) + */ + public void paint(Graphics graphics) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START"); + + ArrayList chunksList = this.getUserSelectedItems(); + + if(chunksList == null) + return; + + // Storing original settings before graphs are painted with case-specific settings + int origLineWidth = graphics.getLineWidth(); + Color origColor = graphics.getForegroundColor(); + int origLineStyle = graphics.getLineStyle(); + + // Setting graph drawing specific settings + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + graphics.setLineStyle(SWT.LINE_SOLID); + + int [] listX = this.calculateTimeIntervals(); + this.lastSampleTime = listX[listX.length-1]; + + int k=0; + + for(String chnk: chunksList) + { + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + valuesToBePlotted = getGlobalChnkSizeData(chnk); + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + valuesToBePlotted = getNonHeapChnkSizeData(chnk); + + int [] points = new int[valuesToBePlotted.length *2]; + + double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + boolean handleDeleted = false; + + List> ListOfSolidLinePoints = new ArrayList>(); + ArrayList solidLinePoints = new ArrayList(); + + for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++) + { + if (valuesToBePlotted[i] <= 0){ + // Not showing zero values to a user, not meaningful data + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "continued because value <= 0"); + continue; + } + + int x_point = (int)(listX[i]/getScale()); + int y_point =(int) (visY - valuesToBePlotted[i] /multiplier); + + points[j] = x_point; + points[++j] = y_point; + + if(!handleDeleted){ + if(y_point > 0){ + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + boolean handleStatus = getHandleStatus(i+1, chnk); + + if(handleStatus && !handleDeleted){ + handleDeleted = true; + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + solidLinePoints = new ArrayList(); + } + + if(handleDeleted && getChunkStatus(i+1, chnk)== CycleData.New ) + { + handleDeleted = false; + if(y_point > 0){ + // Graphing only positive values + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + points[i] = x_point; + points[i+1] = y_point; + } + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + graphics.setForegroundColor(this.getColors().get(k)); + graphics.setLineWidth(2); + + for(int i=0; i < ListOfSolidLinePoints.size(); i++) + { + int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i)); + + if(solidPts != null) + { + if(ListOfSolidLinePoints.size() > 1) + { + int instance_id = i+1; + graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15); + } + graphics.setLineStyle(SWT.LINE_SOLID); + graphics.drawPolyline(solidPts); + + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, solidPts); + } + } + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + + pointsData.put(chnk, line); + + k++; + } + + // Restoring original settings before paint call + graphics.setLineStyle(origLineStyle); + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END"); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC) + */ + public void paintYAxis(GC gc) { + + visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY; + + double yIncrement = visY / 10; + int previousBottom = 0; + + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + + String legend = ""; + + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + Point extent = gc.stringExtent(legend); + + gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1); + + if (y >= previousBottom) + { + gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + + final Image image = this.getVerticalLabel("Bytes"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -(int)visY/3, 1); + + transform.dispose(); + gc.dispose(); + + } + + private void fetchEntireDataForSelectedChunks() + { + ArrayList selectedChunks = this.getUserSelectedItems(); + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + for(String chunk:selectedChunks) + { + ArrayList chnkData = utils.getGLOBDataFromAllCycles(chunk, this.getCyclesData()); + chunksData.put(chunk, chnkData); + } + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + for(String chunk:selectedChunks) + { + ArrayList chnkData = utils.getChunkDataFromAllCycles(chunk, this.getCyclesData()); + nonHeapChunksData.put(chunk, chnkData); + } + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData() + */ + public void prepareData() { + fetchEntireDataForSelectedChunks(); + + for(String chnk:getUserSelectedItems()) + { + int [] valuesToBePlotted = null; + + switch(this.getEvent()) + { + case GLOBAL_DATA_SIZE: + valuesToBePlotted = getGlobalChnkSizeData(chnk); + break; + case NON_HEAP_CHUNK_SIZE: + valuesToBePlotted = getNonHeapChnkSizeData(chnk); + break; + } + + if(valuesToBePlotted == null) + continue; + + int maxValue = calculateMaxValue(valuesToBePlotted); + + if(maxValue > maxBytes) + maxBytes = maxValue; + } + + } + + private boolean getHandleStatus(int cycleNo, String chunkName) + { + boolean status = false; + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList glod_data = chunksData.get(chunkName); + + status = glod_data.get(cycleNo -1).isKernelHandleDeleted(); + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList chunks_data = nonHeapChunksData.get(chunkName); + + status = chunks_data.get(cycleNo -1).isKernelHandleDeleted(); + } + + return status; + } + + private int getChunkStatus(int cycleNo, String chunkName) + { + int status = 0; + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList glod_data = chunksData.get(chunkName); + + status = glod_data.get(cycleNo -1).getAttrib(); + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList chunks_data = nonHeapChunksData.get(chunkName); + + status = chunks_data.get(cycleNo -1).getAttrib(); + } + + return status; + } + private int [] getGlobalChnkSizeData(String chnkName) + { + ArrayList data = chunksData.get(chnkName); + + int [] values = new int[data.size()]; + + for(int i=0; i data = nonHeapChunksData.get(chnkName); + + int [] values = new int[data.size()]; + + for(int i=0; i (int)visY) + return null; + + String text = ""; + + double xValue = x + timeOffset; + int scaledX = (int)(xValue * getScale()); + + double valY = visY - y; + double bytes = valY * multiplier; + + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + text += scaledX + " s, " + scaledY; + for(String chnk: getUserSelectedItems()) + { + Polyline line = pointsData.get(chnk); + + if(line != null && line.containsPoint(x, y)) + text += "\n" + chnk; + } + + return text; + } + + /** + * Get {@link GlobalDataChunks} for given chunk name + * @param chnkName + * @return List of chunks with given name + */ + public ArrayList getGlobalChunkData(String chnkName) + { + return chunksData.get(chnkName); + } + + /** + * Get {@link ChunksData} for given chunk name + * @param chnkName + * @return List of data with given name + */ + public ArrayList getNonHeapChunkData(String chnkName) + { + return nonHeapChunksData.get(chnkName); + } + +}