From 050df4a5f8a0a3b2ae1ad6be57e79494544bc8ac Mon Sep 17 00:00:00 2001 From: William Bourque Date: Fri, 9 Apr 2010 19:54:37 +0000 Subject: [PATCH] Final modifications to HistogramView before integration in TimeframeView (bugid=308695) --- .../ui/views/histogram/HistogramCanvas.java | 3 +- .../HistogramCanvasFocusListener.java | 5 +- .../HistogramCanvasPaintListener.java | 178 +++++-- .../ui/views/histogram/HistogramConstant.java | 3 +- .../ui/views/histogram/HistogramContent.java | 495 ++++++++++++++---- .../ui/views/histogram/HistogramElement.java | 9 +- .../ui/views/histogram/HistogramRequest.java | 15 +- .../histogram/HistogramSelectedWindow.java | 125 ++++- 8 files changed, 643 insertions(+), 190 deletions(-) diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java index 6d2780794e..b51e4e05d3 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java @@ -94,8 +94,7 @@ public class HistogramCanvas extends Canvas // paintlistener need to know about the new content... // This is nowhere near elegant, change me. paintListener.setHistogramContent(histogramContent); - paintListener.setColumnWidth(widthPerBar); - paintListener.setColumnHeight(barsHeight); + paintListener.setBarWidth(widthPerBar); // New selected window, not visible by default createNewSelectedWindow(windowSize); diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java index 7da5c78a4c..4f0566f1b3 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java @@ -22,7 +22,6 @@ import org.eclipse.swt.events.FocusListener; */ public class HistogramCanvasFocusListener implements FocusListener { - @SuppressWarnings("unused") private HistogramCanvas parentCanvas = null; /** @@ -37,12 +36,12 @@ public class HistogramCanvasFocusListener implements FocusListener { /** * Function that is called when the canvas get focus.

* - * Doesn't do anything yet... + * Redraw the screen to make sure everything is sane. * * @param event The focus event generated. */ public void focusGained(FocusEvent event) { - System.out.println("focusGained"); + parentCanvas.redrawAsynchronously(); } /** diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java index f215c8158a..39a7cc6057 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java @@ -15,122 +15,186 @@ import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Rectangle; -public class HistogramCanvasPaintListener implements PaintListener { +/** + * HistogramCanvasPaintListener + *

+ * Implementation of a PaintListener for the need of the HistogramCanvas + *

+ */ +public class HistogramCanvasPaintListener implements PaintListener +{ private HistogramContent histogramContent = null; private HistogramSelectedWindow selectedWindow = null; - private int columnWidth = 0; - private int columnHeight = 0; + private int barsWidth = 0; + /** + * HistogramCanvasPaintListener constructor + * + * @param parentCanvas Related canvas + */ public HistogramCanvasPaintListener(HistogramCanvas parentCanvas) { histogramContent = parentCanvas.getHistogramContent(); } - public void paintControl(PaintEvent e) { + /** + * Function called when the canvas need to redraw.

+ * + * @param event The generated paint event when redraw is called. + */ + public void paintControl(PaintEvent event) { - clearDrawingSection(e); + // First clear the whole canvas to have a clean section where to draw + clearDrawingSection(event); + // If the content is null or has rady to draw we quit the function here if ( (histogramContent == null) || (histogramContent.getReadyUpToPosition() == 0) ) { return; } - if ( (e.height != columnHeight) && (columnHeight != 0) ) { - columnHeight = e.height; - } - - drawHistogram(e); + // Call the function that draw the bars + drawHistogram(event); + // If we have a selected window set to visible, call the function to draw it if ( (selectedWindow != null) && (selectedWindow.getSelectedWindowVisible() == true) ) { - drawSelectedWindow(e); + drawSelectedWindow(event); } } - public void clearDrawingSection(PaintEvent e) { - e.gc.setForeground(e.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR)); - e.gc.setBackground(e.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR)); - Rectangle allSection = new Rectangle(0, 0, e.width, e.height); - e.gc.fillRectangle(allSection); - e.gc.drawRectangle(allSection); + /** + * Clear the drawing section of the canvas

+ * This paint the whole background in EMPTY_BACKGROUND_COLOR, so we have something clean to draw on. + * + * @param event The generated paint event when redraw is called. + */ + public void clearDrawingSection(PaintEvent event) { + event.gc.setForeground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR)); + event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR)); + Rectangle allSection = new Rectangle(0, 0, event.width, event.height); + event.gc.fillRectangle(allSection); + event.gc.drawRectangle(allSection); } + // *** VERIFY *** // Is it good to put this synchronized? // - public synchronized void drawHistogram(PaintEvent e) { - e.gc.setForeground(e.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR)); - Rectangle allSection = new Rectangle(0, 0, histogramContent.getReadyUpToPosition()*columnWidth, e.height); - e.gc.fillRectangle(allSection); - e.gc.drawRectangle(allSection); + /** + * Draw the histogram bars in the canvas.

+ * Use existing elements in HistogramContent to draw bars on the cancas; + * the element table in content need to be populated and have consistent value. + * + * @param event The generated paint event when redraw is called. + */ + public synchronized void drawHistogram(PaintEvent event) { + // This will be the color for all the bars that wil be draw below. + event.gc.setBackground(event.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR)); + + // *** NOTE *** + // Y Position in a canvas is REVERSED, so "0" is on top of the screen and "MAX" is on bottom. + // Not very instinctive, isn't it? - e.gc.setBackground(e.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR)); + // Draw a bar from the left (pos X=0) until the pos=(NbBars*barWidth). If space is left, it will be blanked after. for ( int x=0; x + * This draw a square ober the selected section with a crosshair in the middle. + * The square cannot be smaller than "MINIMUM_WINDOW_WIDTH" + * + * @param event The generated paint event when redraw is called. + */ + public void drawSelectedWindow(PaintEvent event) { + // Attributes (color and width) of the lines + event.gc.setForeground(event.display.getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR)); + event.gc.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH); + // Get the window position... this would fail if the window is not initialized yet int positionCenter = selectedWindow.getWindowCenterXPosition(); int positionLeft = selectedWindow.getWindowPositionLeft(); int positionRight = selectedWindow.getWindowPositionRight(); + // Minimal size verification. if ( (positionRight - positionLeft) < HistogramConstant.MINIMUM_WINDOW_WIDTH ) { positionLeft = positionCenter - (HistogramConstant.MINIMUM_WINDOW_WIDTH/2); positionRight = positionCenter + (HistogramConstant.MINIMUM_WINDOW_WIDTH/2); } - e.gc.drawLine(positionLeft , 0 , positionLeft , e.height); - e.gc.drawLine(positionLeft , e.height, positionRight, e.height); - e.gc.drawLine(positionRight, e.height, positionRight, 0); - e.gc.drawLine(positionLeft , 0 , positionRight, 0); + // Draw the selection window square + event.gc.drawLine(positionLeft , 0 , positionLeft , event.height); + event.gc.drawLine(positionLeft , event.height, positionRight, event.height); + event.gc.drawLine(positionRight, event.height, positionRight, 0); + event.gc.drawLine(positionLeft , 0 , positionRight, 0); - - e.gc.drawLine(positionCenter + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, e.height/2, positionCenter - HistogramConstant.SELECTION_CROSSHAIR_LENGTH, e.height/2); - e.gc.drawLine(positionCenter, (e.height/2) + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, positionCenter, (e.height/2) - HistogramConstant.SELECTION_CROSSHAIR_LENGTH); + // Draw the crosshair section + event.gc.drawLine(positionCenter + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2, positionCenter - HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2); + event.gc.drawLine(positionCenter, (event.height/2) + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, positionCenter, (event.height/2) - HistogramConstant.SELECTION_CROSSHAIR_LENGTH); } - + /** + * Getter for the histogram content used by this paint listener. + * + * @return Histogram content currently tied to this paint listener + */ public HistogramContent getHistogramContent() { return histogramContent; } + /** + * Setter for the histogram content used by this paint listener.

+ * The new content will be displayed upon the next redraw (assuming the content is populated). + * + * @return Histogram content currently tied to this paint listener + */ public void setHistogramContent(HistogramContent newhistogramContent) { this.histogramContent = newhistogramContent; } - public int getColumnWidth() { - return columnWidth; + /** + * Getter for the bars witdh of this paint listener. + * + * @return Bars width we will use during draw. + */ + public int getBarWidth() { + return barsWidth; } - public void setColumnWidth(int newcolumnWidth) { - this.columnWidth = newcolumnWidth; + /** + * Getter for the bars witdh of this paint listener.

+ * NOTE : This MUST be set before any draw is done. + * + * @param newBarsWidth The new width to use for the bars + */ + public void setBarWidth(int newBarsWidth) { + this.barsWidth = newBarsWidth; } - public int getColumnHeight() { - return columnHeight; + /** + * Getter for the selection window used by this paint listener + * + * @return The selection window tied to this paint listener + */ + public HistogramSelectedWindow getSelectedWindow() { + return selectedWindow; } - public void setColumnHeight(int newcolumnHeight) { - this.columnHeight = newcolumnHeight; - } - + /** + * Setter for the selection window used by this paint listener.

+ * NOTE : a null selectedWindow or a selectedWindow with visible == false will be ignored (i.e. : not draw). + * + * @param newSelectedWindow The new selection window + */ public void setSelectedWindow(HistogramSelectedWindow newSelectedWindow) { this.selectedWindow = newSelectedWindow; } - - public HistogramSelectedWindow getSelectedWindow() { - return selectedWindow; - } } diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java index 86cda89b26..56d7d48057 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java @@ -23,10 +23,11 @@ public interface HistogramConstant { // Constants relative to requests final static int MAX_EVENTS_PER_READ = 1; final static int REDRAW_EVERY_NB_EVENTS = 10000; + final static boolean SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE = true; // Constant relative to the content - final static double DEFAULT_DIFFERENCE_TO_AVERAGE = 100.0; + final static double DEFAULT_DIFFERENCE_TO_AVERAGE = 1000.0; diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java index 1acac38bd3..5dfd0caa31 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java @@ -11,8 +11,13 @@ *******************************************************************************/ package org.eclipse.linuxtools.lttng.ui.views.histogram; -import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +/** + * HistogramContent + *

+ * This class hold the content that will be used to draw the Histograms. + *

+ */ public class HistogramContent { private Long startTime = 0L; @@ -22,27 +27,53 @@ public class HistogramContent { private Double heightFactor = 0.0; private Long heighestEventCount = 0L; private Integer maxHeight = 0; + + // This value is used to calculate at which point we should "cut" bar that are too tall. + // Default value is large enought so that no bar should be cut private Double maxDifferenceToAverage = HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE; private Integer readyUpToPosition = 0; - private Integer fullWindowSize = 0; + private Integer canvasFullSize = 0; private Integer averageNumberOfEvents = 0; private HistogramElement[] elementTable; - public HistogramContent(int tableSize, int newWindowsSize, int newMaxHeight) { - this(tableSize, newWindowsSize, newMaxHeight, HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE); - } - - public HistogramContent(int tableSize, int newWindowsSize, int newMaxHeight, double newDiffToAverage) { - fullWindowSize = newWindowsSize; + /** + * Default constructor for the HistogramContent. + * + * @param tableSize The size ofthe element table that will be created. + * @param newCanvasSize The full size of the canvas. Used for positionning; need to be consistent with canvas. + * @param newMaxHeight The maximum height of a bar, usually same as the height of the canvas. + */ + public HistogramContent(int tableSize, int newCanvasSize, int newMaxHeight) { + this(tableSize, newCanvasSize, newMaxHeight, HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE); + } + + /** + * Default constructor for the HistogramContent. + * + * @param tableSize The size ofthe element table that will be created. + * @param newCanvasSize The full size of the canvas. Used for positionning; need to be consistent with canvas. + * @param newMaxHeight The maximum height of a bar, usually same as the height of the canvas. + * @param newDiffToAverage This value at which point we "cut" bar that are too tall. + */ + public HistogramContent(int tableSize, int newCanvasSize, int newMaxHeight, double newDiffToAverage) { + canvasFullSize = newCanvasSize; maxHeight = newMaxHeight; maxDifferenceToAverage = newDiffToAverage; + // Create a new element table from the above value + // The table will not get initialized until resetTable() is called. createNewTable(tableSize); } + /** + * Create a new table to hold the content element.

+ * Note that the table is not initialized (and so unusable) until resetTable() is called. + * + * @param newTableSize The size (number of element) of the table. + */ public void createNewTable(int newTableSize) { elementTable = new HistogramElement[newTableSize]; @@ -52,6 +83,9 @@ public class HistogramContent { } } + /** + * Reset all HistogramContent attributes, but keep the elements table untouched.

+ */ public void resetContentData() { startTime = 0L; endTime = 0L; @@ -63,6 +97,10 @@ public class HistogramContent { readyUpToPosition = 0; } + /** + * Reset the data in the elements table.

+ * NOTE : For this to be consistent and usuable, "startTime" and "intervalTime" need to be set. + */ public void resetTable() { for ( int x=0; x + */ public void printTable() { for ( int x=0; x " + elementTable[x].intervalNbEvents + ":" + elementTable[x].intervalHeight); } } - public void recalculateEventHeight() { - - if ( getHeighestEventCount() > (maxDifferenceToAverage * averageNumberOfEvents) ) { - heightFactor = (double)maxHeight/( maxDifferenceToAverage * (double)averageNumberOfEvents); - } - else { - heightFactor = (double)maxHeight/(double)getHeighestEventCount(); - } - - for ( int x=0; x + * Null is returned if the index is out of range.

+ * Note that you can get an element past "readyUpToPosition", the index is NOT tested against it. + * + * @param index The index of the element (0 < index < nbElement) + * + * @return The element found or null if the index is wrong. + */ public HistogramElement getElementByIndex(int index) { - HistogramElement returnedElement = null; if ( (index >= 0) && (index < elementTable.length) ) { @@ -118,13 +152,22 @@ public class HistogramContent { return returnedElement; } - - public HistogramElement getElementFromXPosition(int position) { + /** + * Return the closest element to a X position on the canvas.

+ * Note : canvasFullSize need to be set correctly here, otherwise unexpected element might be returned.

+ *

+ * NOTE : This ALWAYS return an element; + * If calculation lead outside the table, the first or the last element will be returned. + * + * @param position The X position we are looking at (0 < pos < canvasWidth) + * + * @return The closest element found. + */ + public HistogramElement getClosestElementFromXPosition(int position) { - HistogramElement returnedElement = null; - - int index = (int)( ((double)elementTable.length)*((double)position/(double)fullWindowSize) ); + int index = (int)( ((double)elementTable.length)*((double)position/(double)canvasFullSize) ); + // If we are out of bound, return the closest border (first or last element) if ( index < 0) { index = 0; } @@ -132,156 +175,398 @@ public class HistogramContent { index = (elementTable.length -1); } - returnedElement = elementTable[index]; - - return returnedElement; - } - - public HistogramElement getElementFromTimestamp(TmfTimestamp timestamp) { - - HistogramElement returnedElement = null; - - int index = (int)( (timestamp.getValue() - startTime)/intervalTime ); + return elementTable[index]; + } + + /** + * Return the X position (relative to the canvas) of a certain element.

+ * Note : canvasFullSize need to be set correctly here, otherwise unexpected element might be returned.

+ * + * NOTE : This ALWAYS return an element; + * If calculation lead outside the table, the first or the last element will be returned. + * + * @param targetElement The element we are looking to find the position + * + * @return The closest found element. + */ + public int getXPositionFromElement(HistogramElement targetElement) { + return (int)( ((double)targetElement.position / (double)elementTable.length)*(double)canvasFullSize ); + } + + /** + * Return the closest element to a timestamp (long) given.

+ * Note : startTime and intervalTime need to be set correctly here, otherwise unexpected element might be returned.

+ *

+ * NOTE : This ALWAYS return an element; + * If calculation lead outside the table, the first or the last element will be returned. + * + * @param timestamp The timestamp (in nanosecond, as long) of the element we are looking for (startTime < timestamp < endTime) + * + * @return The closest element found. + */ + public HistogramElement getClosestElementFromTimestamp(long timestamp) { + int index = (int)( (timestamp - startTime)/intervalTime ); + // If we are out of bound, return the closest border (first or last element) if ( index < 0) { index = 0; } + else if ( index >= elementTable.length ) { + index = (elementTable.length -1); + } - returnedElement = elementTable[index]; - - return returnedElement; - } - - + return elementTable[index]; + } + + /** + * Return the closest element to an element and a time interval to this element.

+ * The time interval can be negative or positive (before or after the element). + * + * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.

+ * + * @param targetElement The element we compare the interval with. + * @param intervalToElement Time negative or positive time interval (in nanosecond) to this element. + * + * @return The closest found element, or null if given data are wrong. + */ public HistogramElement getClosestElementByElementAndTimeInterval(HistogramElement targetElement, Long intervalToElement) { - HistogramElement returnedElement = null; + // Get the timestamp of the target element + // This should always be valid as long the table is initialized + Long elementTime = targetElement.firstIntervalTimestamp; + elementTime = elementTime + intervalToElement; - if ( (targetElement != null) && (intervalTime > 0) ) { - Long elementTime = targetElement.position * intervalTime; - - elementTime = elementTime + intervalToElement; - - int newPos = (int)(elementTime / intervalTime ); - - if ( newPos < 0 ) { - newPos = 0; - } - - if ( newPos >= elementTable.length ) { - newPos = elementTable.length - 1; - } - - returnedElement = elementTable[newPos]; - } + return getClosestElementFromTimestamp(elementTime); + } + + /** + * Return the closest element to an element's timestamp (as long) and a time interval to this element.

+ * The time interval can be negative or positive (before or after the element). + * + * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.

+ * + * @param timestamp The timestamp (in nanoseconds, as long) of the element we want to compare from. + * @param intervalToElement Time negative or positive time interval (in nanosecond) to this element. + * + * @return The closest found element, or null if given data are wrong. + */ + public int getClosestElementByTimestampAndTimeInterval(Long timestamp, Long intervalToElement) { + HistogramElement targetElement = getClosestElementFromTimestamp(timestamp); + HistogramElement newElement = getClosestElementByElementAndTimeInterval(targetElement, intervalToElement); - return returnedElement; - } - + return getXPositionFromElement(newElement); + } + + /** + * Return the closest element to an element's position and a time interval to this element.

+ * The time interval can be negative or positive (before or after the element). + * + * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.

+ * + * @param targetPosition The position (relative to the canvas) of the element we want to compare from. + * @param intervalToElement Time negative or positive time interval (in nanosecond) to this element. + * + * @return The closest found element, or null if given data are wrong. + */ public int getXPositionByPositionAndTimeInterval(int targetPosition, Long intervalToElement) { - int returnedValue = 0; + HistogramElement targetElement = getClosestElementFromXPosition(targetPosition); + HistogramElement newElement = getClosestElementByElementAndTimeInterval(targetElement, intervalToElement); - HistogramElement targetElement = getElementFromXPosition(targetPosition); - - if ( targetElement != null ) { - HistogramElement newElement = getClosestElementByElementAndTimeInterval(targetElement, intervalToElement); - - if ( newElement != null ) { - returnedValue = getXPositionFromElement(newElement); - } - } - - return returnedValue; + return getXPositionFromElement(newElement); } - - public int getXPositionFromElement(HistogramElement targetElement) { - - int returnedPosition = (int)( ((double)targetElement.position / (double)elementTable.length)*(double)fullWindowSize ); - - return returnedPosition; + /** + * Getter for the number of element.

+ * The same as the value of tableSize given at construction. + * + * @return The number of element in the elements table. + */ + public int getNbElement() { + return elementTable.length; } - + /** + * Getter for the average number of events by interval in the content.

+ * + * Note : Might be set externally (instead of calculated internally), so consistency with the content is not guarantee. + * + * @return Average number of events we currently use in + */ public int getAverageNumberOfEvents() { return averageNumberOfEvents; } + /** + * Setter for averageNumberOfEvents.

+ * + * Note : this is used in some drawing calculation so make sure this number make sense. + * Note : you might want to call recalculateEventHeight() if you change this. + * + * @param newAverageNumberOfEvents The new average number of events to use. + */ public void setAverageNumberOfEvents(int newAverageNumberOfEvents) { this.averageNumberOfEvents = newAverageNumberOfEvents; } + /** + * Recalculate the average number of events by time interval.

+ * + * Note : This run over all the element so this is quite cpu intensive, use with care. + */ + public void recalculateAverageNumberOfEvents() { + + int nbInterval = 0; + int totalNbEvents = 0; + + // Go over the element up to readyUpToPosition (further position might not be ready) + for ( int x=0; x 0 ) { + nbInterval++; + } + } + else { + nbInterval++; + } + + totalNbEvents += elementTable[x].intervalNbEvents; + } + // Calculate the average here + averageNumberOfEvents = totalNbEvents / nbInterval; + } + + /** + * Getter for the start time of the content.

+ * + * @return The start time we currently use. + */ public Long getStartTime() { return startTime; } + /** + * Setter for the start time of the content.

+ * Note : You probably want to call "resetTable()" if you change this, otherwise data might be inconsistent. + * + * @param newStartTime the new start time + */ public void setStartTime(Long newStartTime) { this.startTime = newStartTime; } + /** + * Getter for the end time of the content.

+ * + * @return The end time we currently use. + */ public Long getEndTime() { return endTime; } - + + // *** TODO *** + // Implement a way to "compress" a table if the endtime change. + // That way, the end time could change without having to reset the table data. + /** + * Setter for the end time of the content.

+ * Note : You probably want to call "resetTable()" if you change this, otherwise data might be inconsistent. + * + * @param newStartTime the new end time + */ public void setEndTime(Long newEndTime) { this.endTime = newEndTime; } + /** + * Getter for the complete time interval of the content.

+ * Note : This return "endTime" minus "startTime", unlike getReadyTimeInterval() it won't check the actual time of elements. + * + * @return The complete time interval + */ public Long getCompleteTimeInterval() { return ( endTime - startTime ); } + /** + * Getter for the time interval for the element between first and readyUpToPosition

+ * Note : This return element[readyPosition].time - element[first].time , not the full interval like getCompleteTimeInterval() + * + * @return The time interval of the position that are ready. + */ + public Long getReadyTimeInterval() { + return ( elementTable[readyUpToPosition].firstIntervalTimestamp - elementTable[0].firstIntervalTimestamp ); + } + + /** + * Getter for the height factor of the bar.

+ * Note : height = "nb events in interval" * heightFactor + * + * @return Height factor currently used. + */ public Double getHeightFactor() { return heightFactor; } - public void setHeightFactor(Double newheightFactor) { - this.heightFactor = newheightFactor; + /** + * Recalculate the height of each bar in the elements table.

+ * Need to be called at least once, or when value of "maxHeight", "heighestEventCount" or "averageNumberOfEvents" changes. + */ + public void recalculateEventHeight() { + + // Recalculate the new HeightFactor for the element; + // the highest bar will get "maxHeight" and other bar a fraction of it. + // If a maxDifferenceToAverage exist, this is considered here + if ( heighestEventCount > (maxDifferenceToAverage * averageNumberOfEvents) ) { + heightFactor = (double)maxHeight/( maxDifferenceToAverage * (double)averageNumberOfEvents); + } + else { + heightFactor = (double)maxHeight/(double)heighestEventCount; + } + + // Recalculate the height of the bars up to "readyUpToPosition" + for ( int x=0; x + * This is used for the positionnal calculation so should be consistent with the real canvas size. + * + * @return Size of the canvas we currently use. + */ + public Integer getCanvasFullSize() { + return canvasFullSize; + } + + /** + * Getter for the heighest event count recorded so far for an interval.

+ * + * Note : Might be set externally (instead of calculated internally), so consistency with the content is not guarantee. + * + * @return Current heighestEventCount + */ public Long getHeighestEventCount() { return heighestEventCount; } - public void setHeighestEventCount(Long newheighestEventCount) { - this.heighestEventCount = newheighestEventCount; + /** + * Setter for setHeighestEventCount.

+ * + * Note : this is used in some drawing calculation so make sure this number make sense. + * Note : you might want to call recalculateEventHeight() if you change this. + * + * @param newHeighestEventCount Heighest event count for a single interval. + */ + public void setHeighestEventCount(Long newHeighestEventCount) { + this.heighestEventCount = newHeighestEventCount; + } + + /** + * Recalculate the heightest event count for a single time interval.

+ * + * Note : This run over all the element so this is quite cpu intensive, use with care. + */ + public void recalculateHeighestEventCount() { + // Go over the element up to readyUpToPosition (further position might not be ready) + for ( int x=0; x heighestEventCount ) { + this.heighestEventCount = elementTable[x].intervalNbEvents; + } + } } + /** + * Getter for the max height of a bar in the content.

+ * + * @return maximum height for a bar we currently use. + */ public Integer getMaxHeight() { return maxHeight; } - + + /** + * Setter for maxHeight.

+ * + * Note : this is used in some drawing calculation so make sure this number make sense. + * Note : you might want to call recalculateEventHeight() if you change this. + * + * @param maxHeight The new maximum height for a bar to use. + */ public void setMaxHeight(Integer maxHeight) { this.maxHeight = maxHeight; } - + /** + * Getter for the max difference to the average height a bar can have.

+ * This determine at which point a bar too tall is "cut". Set a very large value (like 1000.0) to ignore. + * + * @return maximum difference to the average we currently use. + */ public Double getMaxDifferenceToAverage() { return maxDifferenceToAverage; } + /** + * Setter for the max difference to the average height a bar can have.

+ * This determine at which point a bar too tall is "cut". Set a very large value (like 1000.0) to ignore. + * + * Note : this is used in some drawing calculation so make sure this number make sense. + * Note : you might want to call recalculateEventHeight() if you change this. + * + * @param newDiffToAverage The new maximum difference to the average to use. + */ public void setMaxDifferenceToAverage(Double newDiffToAverage) { maxDifferenceToAverage = newDiffToAverage; } - public int getReadyUpToPosition() { - return readyUpToPosition; - } - - public void setReadyUpToPosition(int newReadyUpToPosition) { - this.readyUpToPosition = newReadyUpToPosition; - } - - + /** + * Getter for the interval time of each interval.

+ * This is usually "(EndTime - StartTime) / NbElement" + * + * @return Currently used interval time. + */ public Long getIntervalTime() { return intervalTime; } + + /** + * Setter for the interval time of each interval.

+ * + * Note : this is used in some drawing calculation so make sure this number make sense. + * Note : you migth want to call resetTable() to to fill the element's table again if you change this. + * + * @return New interval time. + */ public void setIntervalTime(Long newInterval) { this.intervalTime = newInterval; } + + /** + * Getter for readyUpToPosition.

+ * This should tell to which point the content is filled, calculated and ready to use. + * + * @return Last position processed so far. + */ + public int getReadyUpToPosition() { + return readyUpToPosition; + } + + /** + * Setter for readyUpToPosition.

+ * Set a new point (position) up to where the content is filled, calculated and ready to use. + * + * @param newReadyUpToPosition The new position to use. + */ + public void setReadyUpToPosition(int newReadyUpToPosition) { + this.readyUpToPosition = newReadyUpToPosition; + } + } diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java index a78332df6c..aea4999383 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java @@ -17,10 +17,11 @@ package org.eclipse.linuxtools.lttng.ui.views.histogram; * This is used by the content to keep its data. * It would be a struct if such a thing would exist in java. *

+ * Each "element" should represent a certain time interval */ public class HistogramElement { - public Integer position = 0; - public Long firstIntervalTimestamp = 0L; - public Long intervalNbEvents = 0L; - public Integer intervalHeight = 0; + public Integer position = 0; // Position of the element in the table (table index, usually) + public Long firstIntervalTimestamp = 0L; // The first timestamp recorded for this interval + public Long intervalNbEvents = 0L; // Number of events recorded in this interval + public Integer intervalHeight = 0; // Height (in the canvas) of this element. Should be smaller than the canvas height. } diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java index 8f79b277f0..3c7e72771e 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java @@ -116,7 +116,7 @@ public class HistogramRequest extends TmfEventRequest { } // * NOTE * - // We save the time we have. This mean only the FIRST time read in an interval will be saved. + // We save the time we have here. This mean only the FIRST time read in an interval will be saved. histogramContent.getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime; histogramContent.setReadyUpToPosition(lastInterval); @@ -193,10 +193,19 @@ public class HistogramRequest extends TmfEventRequest { /** * Update the HistogramContent with the latest information.

- * This will perform some calculation that might be a bit harsh so it shouldnt be called too often. + * This will perform some calculation that might be a bit harsh so it should'nt be called too often. */ public void updateEventsInfo() { - int averageNumberOfEvents = nbEventRead / nbIntervalNotEmpty; + // *** Note *** + // The average number of event is calculated while skipping empty interval if asked + int averageNumberOfEvents = 0; + if ( HistogramConstant.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE ) { + averageNumberOfEvents = nbEventRead / nbIntervalNotEmpty; + } + else { + averageNumberOfEvents = nbEventRead / histogramContent.getNbElement(); + } + histogramContent.setAverageNumberOfEvents(averageNumberOfEvents); histogramContent.recalculateEventHeight(); } diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java index 0e9d690000..70a4b031e7 100644 --- a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java +++ b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java @@ -11,6 +11,20 @@ *******************************************************************************/ package org.eclipse.linuxtools.lttng.ui.views.histogram; +/** + * HistogramSelectedWindow + *

+ * Selection window represent the selected section of the trace in the HistogramCanvas. + *

+ * The selected window have 3 important attributes : + *

+ * The dimension are then deduced from the first 2 values. + * This mean the window is always a perfectly symetrical rectangle. + */ public class HistogramSelectedWindow { private int windowCenterXPosition = 0; @@ -19,68 +33,149 @@ public class HistogramSelectedWindow { private boolean isSelectedWindowVisible = false; private HistogramContent histogramContent = null; - + + /** + * Default constructor for HistogramSelectedWindow.

+ * Position and TimeWidth are both set to 0 + * + * @param newTraceContent HistogramContent to read window's data from + */ public HistogramSelectedWindow(HistogramContent newTraceContent) { histogramContent = newTraceContent; } + /** + * Default constructor for HistogramSelectedWindow.

+ * Position and TimeWidth are set to given value. + * + * @param newTraceContent HistogramContent to read window's data from + * @param centralPosition Central X Position of the selection window in the canvas (0 to canvasWidth) + * @param newWindowWidth Time width (size) of the window. (0 or greater) + */ public HistogramSelectedWindow(HistogramContent newTraceContent, int centralPosition, long newWindowWidth) { histogramContent = newTraceContent; windowCenterXPosition = centralPosition; windowTimeWidth = newWindowWidth; } - + /** + * Getter for the HistogramContent used by the window.

+ * + * @return HistogramContent tied to this selection window. + */ + public HistogramContent getTraceContent() { + return histogramContent; + } + + /** + * Setter for the HistogramContent used by the window.

+ * This need to be a valid, initialized HistogramContent; + * the data in the content are needed for positionning the window. + * + * @param newTraceContent A new HistogramContent + */ + public void setTraceContent(HistogramContent newTraceContent) { + this.histogramContent = newTraceContent; + } + + + /** + * Getter for the window visibility.

+ * + * @return true if the window is visible (will be draw), false otherwise + */ public boolean getSelectedWindowVisible() { return isSelectedWindowVisible; } + /** + * Setter for the window visibility.

+ * True means the window will be draw, false that it will be hidden. + * + * @param newIsSelectedWindowVisible The visibility value + */ public void setSelectedWindowVisible(boolean newIsSelectedWindowVisible) { this.isSelectedWindowVisible = newIsSelectedWindowVisible; } - + + /** + * Getter for the window time width (size) + * + * @return Window time width (size) + */ public long getWindowTimeWidth() { return windowTimeWidth; } + /** + * Setter for the window time width (size).

+ * Width need to be a time (in nanoseconds) that's coherent to the data we are looking at. + * + * @param newWindowTimeWidth The new time width + */ public void setWindowTimeWidth(long newWindowTimeWidth) { this.windowTimeWidth = newWindowTimeWidth; } - - public HistogramContent getTraceContent() { - return histogramContent; - } - - public void setTraceContent(HistogramContent newTraceContent) { - this.histogramContent = newTraceContent; - } - + /** + * Getter for the central position of the window.

+ * + * @return Center X position of this window on the canvas. + */ public int getWindowCenterXPosition() { return windowCenterXPosition; } + /** + * Setter for the central position of the window.

+ * The new position need to be valid on the canvas (0 to canvasWidth). + * + * @param newPosCenter The new central position. + */ public void setWindowCenterXPosition(int newPosCenter) { this.windowCenterXPosition = newPosCenter; } + /** + * Getter for the left border of the window.

+ * Compute the position from the HistogramContent data; may return 0 if the content data are wrong. + * + * @return The left position of the window, or 0 if it cannot compute it. + */ public int getWindowPositionLeft() { return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterXPosition, -(windowTimeWidth / 2) ); } + /** + * Getter for the right border of the window.

+ * Compute the position from the HistogramContent data; may return 0 if the content data are wrong. + * + * @return The right position of the window, or 0 if it cannot compute it. + */ public int getWindowPositionRight() { return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterXPosition, +(windowTimeWidth / 2) ); } + /** + * Getter for the timestamp of left border of the window.

+ * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong. + * + * @return The left timestamp of the window, or 0 if it cannot compute it. + */ public long getTimestampLeft() { - return histogramContent.getElementFromXPosition( getWindowPositionLeft() ).firstIntervalTimestamp; + return histogramContent.getClosestElementFromXPosition( getWindowPositionLeft() ).firstIntervalTimestamp; } + /** + * Getter for the timestamp of right border of the window.

+ * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong. + * + * @return The right timestamp of the window, or 0 if it cannot compute it. + */ public long getTimestampRight() { - return histogramContent.getElementFromXPosition( getWindowPositionRight() ).firstIntervalTimestamp; + return histogramContent.getClosestElementFromXPosition( getWindowPositionRight() ).firstIntervalTimestamp; } - } -- 2.34.1