TMF: Add vertical events (links) to time graph view
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Wed, 10 Jul 2013 15:07:41 +0000 (11:07 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Mon, 5 Aug 2013 12:24:45 +0000 (08:24 -0400)
Add a new interface ILinkEvent and class TimeLinkEvent, for events that occur
between two entries instead of in one entry only.
Add the getLinkList method to AbstractTimeGraphView to get the links for a
given zoom level and other methods to propagate those changes to the time graph
control

Change-Id: I5be30c4a27a10645a57ebfc13b4d1c71a55e06bd
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/15105
Tested-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
IP-Clean: Patrick Tasse <patrick.tasse@gmail.com>

org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java

index ed5497be4e36fcd88858ee383c7dc1ef5dc1ed79..96e030c5c9f1a5cd22dbc0d9a7b47520c4aafbb5 100644 (file)
@@ -53,6 +53,6 @@ public class CallStackEvent extends TimeEvent {
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + " value=" + fValue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        return getClass().getSimpleName() + " start=" + getTime() + " end=" + (getTime() + getDuration()) + " duration=" + getDuration() + " value=" + fValue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
     }
 }
index b054c9232d1e554b407898b8d577a75de290831a..ae8cc3bffd635a311d30f2829c557ef2730fb2f9 100644 (file)
@@ -11,6 +11,7 @@
  *   Bernd Hufmann - Updated signal handling
  *   Geneviève Bastien - Move code to provide base classes for time graph view
  *   Marc-Andre Laperle - Add time zone preference
+ *   Geneviève Bastien - Add event links between entries
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.timegraph;
@@ -53,6 +54,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProv
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
@@ -273,6 +275,7 @@ public abstract class AbstractTimeGraphView extends TmfView {
      *            the trace to add
      * @param list
      *            The list of time graph entries
+     * @since 2.1
      */
     protected void putEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
         synchronized(fEntryListMap) {
@@ -446,6 +449,10 @@ public abstract class AbstractTimeGraphView extends TmfView {
                 }
                 zoom(entry, fMonitor);
             }
+            /* Refresh the arrows when zooming */
+            List<ILinkEvent> events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor);
+            fTimeGraphCombo.setLinks(events);
+            redraw();
         }
 
         private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) {
@@ -694,6 +701,7 @@ public abstract class AbstractTimeGraphView extends TmfView {
 
     /**
      * @param signal the format of the timestamps was updated.
+     * @since 2.1
      */
     @TmfSignalHandler
     public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){
@@ -763,6 +771,27 @@ public abstract class AbstractTimeGraphView extends TmfView {
             long startTime, long endTime, long resolution,
             IProgressMonitor monitor);
 
+    /**
+     * Gets the list of links (displayed as arrows) for a trace in a given
+     * timerange.  Default implementation returns an empty list.
+     *
+     * @param startTime
+     *            Start of the time range
+     * @param endTime
+     *            End of the time range
+     * @param resolution
+     *            The resolution
+     * @param monitor
+     *            The progress monitor object
+     * @return The list of link events
+     * @since 2.1
+     */
+    protected List<ILinkEvent> getLinkList(long startTime, long endTime,
+            long resolution, IProgressMonitor monitor) {
+        return new ArrayList<ILinkEvent>();
+    }
+
+
     /**
      * Refresh the display
      */
index 2c695fc491370706b45da90e980b8a1ee4696c88..1497de7f91794cdc6606b1f683223067fb03f41c 100644 (file)
@@ -9,6 +9,7 @@
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
  *   François Rajotte - Filter implementation
+ *   Geneviève Bastien - Add event links between entries
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph;
@@ -36,6 +37,7 @@ import org.eclipse.linuxtools.internal.tmf.ui.Activator;
 import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
 import org.eclipse.linuxtools.internal.tmf.ui.Messages;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
@@ -830,6 +832,16 @@ public class TimeGraphCombo extends Composite {
         fTimeGraphViewer.setInput(input);
     }
 
+    /**
+     * Sets or clears the list of links to display on this combo
+     *
+     * @param links the links to display in this time graph combo
+     * @since 2.1
+     */
+    public void setLinks(List<ILinkEvent> links) {
+        fTimeGraphViewer.setLinks(links);
+    }
+
     /**
      * @param filter The filter object to be attached to the view
      * @since 2.0
index 16bcab2856336e6ee50d402da328bb23ef716ffd..cbbb5b2190f2ff4400d32c3f9eebae820b9bdfb7 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (c) 2007, 2013 Intel Corporation, Ericsson
+ * Copyright (c) 2007, 2013 Intel Corporation, Ericsson, others
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -11,6 +11,7 @@
  *   Alexander N. Alexeev, Intel - Add monitors statistics support
  *   Alvaro Sanchez-Leon - Adapted for TMF
  *   Patrick Tasse - Refactoring
+ *   Geneviève Bastien - Add event links between entries
  *****************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph;
@@ -25,6 +26,7 @@ import org.eclipse.linuxtools.internal.tmf.ui.Activator;
 import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
 import org.eclipse.linuxtools.internal.tmf.ui.Messages;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider2;
@@ -157,6 +159,19 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener {
         }
     }
 
+    /**
+     * Sets (or clears if null) the list of links to display on this combo
+     *
+     * @param links
+     *            the links to display in this time graph combo
+     * @since 2.1
+     */
+    public void setLinks(List<ILinkEvent> links) {
+        if (fTimeGraphCtrl != null) {
+            fTimeGraphCtrl.refreshArrows(links);
+        }
+    }
+
     /**
      * Refresh the view
      */
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java
new file mode 100644 (file)
index 0000000..cdb9461
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2013 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model;
+
+/**
+ * Interface for time event that allows to specify the destination entry of the
+ * event
+ *
+ * @since 2.1
+ */
+public interface ILinkEvent extends ITimeEvent {
+
+    /**
+     * Get this event's destination entry
+     *
+     * @return The destination entry
+     */
+    ITimeGraphEntry getDestinationEntry();
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java
new file mode 100644 (file)
index 0000000..0f2cb97
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2013 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model;
+
+/**
+ * TimeEvent implementation for events that do not involve only one entry, they
+ * have a source entry and destination entry
+ *
+ * @since 2.1
+ */
+public class TimeLinkEvent extends TimeEvent implements ILinkEvent {
+
+    /** TimeGraphEntry matching the destination this time event */
+    private ITimeGraphEntry fDestEntry;
+
+    /**
+     * Standard constructor
+     *
+     * @param src
+     *            The source entry of this event
+     * @param dst
+     *            The destination entry of this event
+     * @param time
+     *            The timestamp of this event
+     * @param duration
+     *            The duration of the event
+     */
+    public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration) {
+        super(src, time, duration);
+        fDestEntry = dst;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param src
+     *            The source entry of this event
+     * @param dst
+     *            The destination entry of this event
+     * @param time
+     *            The timestamp of this event
+     * @param duration
+     *            The duration of this event
+     * @param value
+     *            The status assigned to the event
+     */
+    public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration,
+            int value) {
+        super(src, time, duration, value);
+        fDestEntry = dst;
+    }
+
+    @Override
+    public ITimeGraphEntry getDestinationEntry() {
+        return fDestEntry;
+    }
+
+}
index 52f24d4192824e41a5522a92d3d44f1066808acc..0ec43a63415929e2a232e2c42b635cf09e9ecbb2 100644 (file)
@@ -13,6 +13,7 @@
  *   Patrick Tasse, Ericsson - Refactoring
  *   Geneviève Bastien, École Polytechnique de Montréal - Move code to
  *                            provide base classes for time graph view
+ *                            Add display of links between items
  *****************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
@@ -37,6 +38,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationPro
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.swt.SWT;
@@ -374,6 +376,16 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
         redraw();
     }
 
+    /**
+     * Refresh the links (arrows) of this widget
+     *
+     * @param events The link events to refresh
+     * @since 2.1
+     */
+    public void refreshArrows(List<ILinkEvent> events) {
+        fItemData.refreshArrows(events);
+    }
+
     /**
      * Adjust the scoll bars
      */
@@ -1174,6 +1186,8 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
 
         // draw items
         drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc);
+        drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc);
+        fTimeGraphProvider.postDrawControl(bounds, gc);
 
         int alpha = gc.getAlpha();
         gc.setAlpha(100);
@@ -1276,7 +1290,6 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
             Item item = items[i];
             drawItem(item, bounds, timeProvider, i, nameSpace, gc);
         }
-        fTimeGraphProvider.postDrawControl(bounds, gc);
     }
 
     /**
@@ -1370,6 +1383,131 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
         fTimeGraphProvider.postDrawEntry(entry, rect, gc);
     }
 
+    /**
+     * Draw the links
+     *
+     * @param bounds
+     *            The rectangle of the area
+     * @param timeProvider
+     *            The time provider
+     * @param links
+     *            The array items to draw
+     * @param nameSpace
+     *            The width reserved for the names
+     * @param gc
+     *            Reference to the SWT GC object
+     * @since 2.1
+     */
+    public void drawLinks(Rectangle bounds, ITimeDataProvider timeProvider,
+            List<ILinkEvent> links, int nameSpace, GC gc) {
+        for (ILinkEvent event : links) {
+            drawLink(event, bounds, timeProvider, nameSpace, gc);
+        }
+    }
+
+    /**
+     * Draws the link type events of this item
+     *
+     * @param event
+     *            the item to draw
+     * @param bounds
+     *            the container rectangle
+     * @param timeProvider
+     *            Time provider
+     * @param nameSpace
+     *            the name space
+     * @param gc
+     *            Graphics context
+     * @since 2.1
+     */
+    protected void drawLink(ILinkEvent event, Rectangle bounds, ITimeDataProvider timeProvider, int nameSpace, GC gc) {
+        int srcIndex = fItemData.findItemIndex(event.getEntry());
+        int destIndex = fItemData.findItemIndex(event.getDestinationEntry());
+
+        if ((srcIndex == -1) || (destIndex == -1)) {
+            return;
+        }
+
+        Rectangle src = getStatesRect(bounds, srcIndex, nameSpace);
+        Rectangle dst = getStatesRect(bounds, destIndex, nameSpace);
+
+        int x0 = getXForTime(event.getTime());
+        int x1 = getXForTime(event.getTime() + event.getDuration());
+        int y0 = src.y + src.height / 2;
+        int y1 = dst.y + dst.height / 2;
+        drawArrow(getColorScheme(), event, new Rectangle(x0, y0, x1 - x0, y1 - y0), gc);
+    }
+
+    /**
+     * Draw the state (color fill)
+     *
+     * @param colors
+     *            Color scheme
+     * @param event
+     *            Time event for which we're drawing the state
+     * @param rect
+     *            Where to draw
+     * @param gc
+     *            Graphics context
+     * @return true if the state was drawn
+     * @since 2.1
+     */
+    protected boolean drawArrow(TimeGraphColorScheme colors, ITimeEvent event,
+            Rectangle rect, GC gc) {
+
+        int colorIdx = fTimeGraphProvider.getStateTableIndex(event);
+        if (colorIdx < 0) {
+            return false;
+        }
+        boolean visible = ((rect.height == 0) && (rect.width == 0)) ? false : true;
+
+        if (visible) {
+            Color stateColor = null;
+            if (colorIdx < fEventColorMap.length) {
+                stateColor = fEventColorMap[colorIdx];
+            } else {
+                stateColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);
+            }
+
+            gc.setForeground(stateColor);
+            gc.setBackground(stateColor);
+
+            /* Draw the arrow */
+            gc.drawLine(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
+            drawArrowHead(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, gc);
+
+        }
+        fTimeGraphProvider.postDrawEvent(event, rect, gc);
+        return visible;
+    }
+
+    /*
+     * @author Francis Giraldeau
+     *
+     * Inspiration:
+     * http://stackoverflow.com/questions/3010803/draw-arrow-on-line-algorithm
+     *
+     * The algorithm was taken from this site, not the code itself
+     */
+    private static void drawArrowHead(int x0, int y0, int x1, int y1, GC gc)
+    {
+        int factor = 10;
+        double cos = 0.9510;
+        double sin = 0.3090;
+        int lenx = x1 - x0;
+        int leny = y1 - y0;
+        double len = Math.sqrt(lenx * lenx + leny * leny);
+
+        double dx = factor * lenx / len;
+        double dy = factor * leny / len;
+        int end1X = (int) Math.round((x1 - (dx * cos + dy * -sin)));
+        int end1Y = (int) Math.round((y1 - (dx * sin + dy * cos)));
+        int end2X = (int) Math.round((x1 - (dx * cos + dy * sin)));
+        int end2Y = (int) Math.round((y1 - (dx * -sin + dy * cos)));
+        int[] arrow = new int[] { x1, y1, end1X, end1Y, end2X, end2Y, x1, y1 };
+        gc.fillPolygon(arrow);
+    }
+
     /**
      * Draw the name of an item.
      *
@@ -2211,6 +2349,7 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
         private Item[] fExpandedItems = new Item[0];
         private Item[] fItems = new Item[0];
         private ITimeGraphEntry fTraces[] = new ITimeGraphEntry[0];
+        private List<ILinkEvent> fLinks = new ArrayList<ILinkEvent>();
         private boolean fTraceFilter[] = new boolean[0];
         private final ArrayList<ITimeGraphEntry> fFilteredOut = new ArrayList<ITimeGraphEntry>();
 
@@ -2329,6 +2468,15 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
             refreshData();
         }
 
+        public void refreshArrows(List<ILinkEvent> events) {
+            /* If links are null, reset the list */
+            if (events != null) {
+                fLinks = events;
+            } else {
+                fLinks = new ArrayList<ILinkEvent>();
+            }
+        }
+
         public ITimeGraphEntry[] getTraces() {
             return fTraces;
         }
This page took 0.044851 seconds and 5 git commands to generate.