import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
-public class HistogramCanvasPaintListener implements PaintListener {
+/**
+ * <b><u>HistogramCanvasPaintListener</u></b>
+ * <p>
+ * Implementation of a PaintListener for the need of the HistogramCanvas
+ * <p>
+ */
+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.<p>
+ *
+ * @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<p>
+ * 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.<p>
+ * 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<histogramContent.getReadyUpToPosition(); x++) {
- Rectangle rect = new Rectangle(columnWidth*x, columnHeight - histogramContent.getElementByIndex(x).intervalHeight, columnWidth, histogramContent.getElementByIndex(x).intervalHeight);
-
- e.gc.fillRectangle(rect);
+ Rectangle rect = new Rectangle(barsWidth*x, event.height - histogramContent.getElementByIndex(x).intervalHeight, barsWidth, histogramContent.getElementByIndex(x).intervalHeight);
+ event.gc.fillRectangle(rect);
}
- e.gc.setBackground(e.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
- Rectangle rect = new Rectangle(columnWidth*histogramContent.getNbElement(), 0, e.width, columnHeight);
- e.gc.fillRectangle(rect);
+ // Clear the remaining space in the canvas (if any) so it appears clean.
+ event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+ Rectangle rect = new Rectangle(barsWidth*histogramContent.getNbElement(), 0, event.width, event.height);
+ event.gc.fillRectangle(rect);
}
- public void drawSelectedWindow(PaintEvent e) {
-
- e.gc.setForeground(e.display.getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
- e.gc.setBackground(e.display.getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
-
- e.gc.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
+ /**
+ * Draw the selection window in the canvas.<p>
+ * 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.<p>
+ * 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.<p>
+ * 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.<p>
+ * 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;
- }
}
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
-import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+/**
+ * <b><u>HistogramContent</u></b>
+ * <p>
+ * This class hold the content that will be used to draw the Histograms.
+ * <p>
+ */
public class HistogramContent {
private Long startTime = 0L;
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.<p>
+ * 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];
}
}
+ /**
+ * Reset all HistogramContent attributes, but keep the elements table untouched.<p>
+ */
public void resetContentData() {
startTime = 0L;
endTime = 0L;
readyUpToPosition = 0;
}
+ /**
+ * Reset the data in the elements table.<p>
+ * NOTE : For this to be consistent and usuable, "startTime" and "intervalTime" need to be set.
+ */
public void resetTable() {
for ( int x=0; x<elementTable.length; x++) {
elementTable[x].position = x;
}
}
+ /**
+ * Print all HistogramContent attributes, but the elements table.
+ */
public void printContentInfo() {
System.out.println("startTime : " + startTime);
System.out.println("endTime : " + endTime );
System.out.println("readyUpToPosition : " + readyUpToPosition);
}
+ /**
+ * Print the data in the elements table.<p>
+ */
public void printTable() {
for ( int x=0; x<elementTable.length; x++) {
System.out.println("X:" + 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<elementTable.length; x++) {
- elementTable[x].intervalHeight = (int)(elementTable[x].intervalNbEvents * heightFactor);
- }
- }
-
- public int getNbElement() {
- return elementTable.length;
- }
-
+ /**
+ * Get an element in the table by its index.<p>
+ * Null is returned if the index is out of range.<p>
+ * 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) ) {
return returnedElement;
}
-
- public HistogramElement getElementFromXPosition(int position) {
+ /**
+ * Return the closest element to a X position on the canvas.<p>
+ * Note : canvasFullSize need to be set correctly here, otherwise unexpected element might be returned.<p>
+ * <p>
+ * NOTE : This <b>ALWAYS</b> 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 <i>closest</i> 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;
}
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.<p>
+ * Note : canvasFullSize need to be set correctly here, otherwise unexpected element might be returned.<p>
+ *
+ * NOTE : This <b>ALWAYS</b> 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 <i>closest</i> 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.<p>
+ * Note : startTime and intervalTime need to be set correctly here, otherwise unexpected element might be returned.<p>
+ * <p>
+ * NOTE : This <b>ALWAYS</b> 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 <i>closest</i> 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.<p>
+ * 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.<p>
+ *
+ * @param targetElement The element we compare the interval with.
+ * @param intervalToElement Time negative or positive time interval (in nanosecond) to this element.
+ *
+ * @return The <i>closest</i> 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.<p>
+ * 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.<p>
+ *
+ * @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 <i>closest</i> 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.<p>
+ * 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.<p>
+ *
+ * @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 <i>closest</i> 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.<p>
+ * 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.<p>
+ *
+ * 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.<p>
+ *
+ * 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.<p>
+ *
+ * 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<readyUpToPosition; x++) {
+ // Skip the empty interval if we were asked to do so.
+ if ( HistogramConstant.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE ) {
+ if ( elementTable[x].intervalNbEvents > 0 ) {
+ nbInterval++;
+ }
+ }
+ else {
+ nbInterval++;
+ }
+
+ totalNbEvents += elementTable[x].intervalNbEvents;
+ }
+ // Calculate the average here
+ averageNumberOfEvents = totalNbEvents / nbInterval;
+ }
+
+ /**
+ * Getter for the start time of the content.<p>
+ *
+ * @return The start time we currently use.
+ */
public Long getStartTime() {
return startTime;
}
+ /**
+ * Setter for the start time of the content.<p>
+ * 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.<p>
+ *
+ * @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.<p>
+ * 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.<p>
+ * 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<p>
+ * 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.<p>
+ * 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.<p>
+ * 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<readyUpToPosition; x++) {
+ elementTable[x].intervalHeight = (int)(elementTable[x].intervalNbEvents * heightFactor);
+ }
}
-
+ // *** TODO ***
+ // It is not possible for now to resize the canvas without creating a new content.
+ // We need to implement this somehow.
+ /**
+ * Getter for the full size of the canvas.<p>
+ * 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.<p>
+ *
+ * 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.<p>
+ *
+ * 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.<p>
+ *
+ * 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<readyUpToPosition; x++) {
+ if ( elementTable[x].intervalNbEvents > heighestEventCount ) {
+ this.heighestEventCount = elementTable[x].intervalNbEvents;
+ }
+ }
}
+ /**
+ * Getter for the max height of a bar in the content.<p>
+ *
+ * @return maximum height for a bar we currently use.
+ */
public Integer getMaxHeight() {
return maxHeight;
}
-
+
+ /**
+ * Setter for maxHeight.<p>
+ *
+ * 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.<p>
+ * 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.<p>
+ * 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.<p>
+ * This is usually "(EndTime - StartTime) / NbElement"
+ *
+ * @return Currently used interval time.
+ */
public Long getIntervalTime() {
return intervalTime;
}
+
+ /**
+ * Setter for the interval time of each interval.<p>
+ *
+ * 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.<p>
+ * 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.<p>
+ * 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;
+ }
+
}
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
+/**
+ * <b><u>HistogramSelectedWindow</u></b>
+ * <p>
+ * Selection window represent the selected section of the trace in the HistogramCanvas.
+ * <p>
+ * The selected window have 3 important attributes :
+ * <ul>
+ * <li>Its central position
+ * <li>Its time width
+ * <li>Its visibility (to determine if we should draw it or not)
+ * </ul>
+ * 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;
private boolean isSelectedWindowVisible = false;
private HistogramContent histogramContent = null;
-
+
+ /**
+ * Default constructor for HistogramSelectedWindow.<p>
+ * 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.<p>
+ * 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.<p>
+ *
+ * @return HistogramContent tied to this selection window.
+ */
+ public HistogramContent getTraceContent() {
+ return histogramContent;
+ }
+
+ /**
+ * Setter for the HistogramContent used by the window.<p>
+ * 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.<p>
+ *
+ * @return true if the window is visible (will be draw), false otherwise
+ */
public boolean getSelectedWindowVisible() {
return isSelectedWindowVisible;
}
+ /**
+ * Setter for the window visibility.<p>
+ * 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).<p>
+ * 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.<p>
+ *
+ * @return Center X position of this window on the canvas.
+ */
public int getWindowCenterXPosition() {
return windowCenterXPosition;
}
+ /**
+ * Setter for the central position of the window.<p>
+ * 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.<p>
+ * 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.<p>
+ * 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.<p>
+ * 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.<p>
+ * 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;
}
-
}