fix #428919: Support multi-trace histograms
authorXavier Raynaud <xavier.raynaud@kalray.eu>
Wed, 5 Mar 2014 10:21:39 +0000 (11:21 +0100)
committerXavier Raynaud <xavier.raynaud@kalray.eu>
Thu, 6 Mar 2014 08:46:26 +0000 (03:46 -0500)
When displaying a multi-trace experiment, colorize the histograms,
in order to know the origin of the events.

Change-Id: I9436a4b8d08250e41b7e68a46757b85a9797d658
Signed-off-by: Xavier Raynaud <xavier.raynaud@kalray.eu>
Reviewed-on: https://git.eclipse.org/r/22442
Tested-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
IP-Clean: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
12 files changed:
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/histogram/HistogramDataModelTest.java
org.eclipse.linuxtools.tmf.ui/icons/elcl16/show_hist_traces.gif [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/ITmfImageConstants.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramDataModel.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramRequest.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramScaledData.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramView.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/IHistogramDataModel.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Messages.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/messages.properties

index 83d08740c2718549495054009c1890a5a6d6e98a..3799c51acd6f463e410ca346bbd74081d9bfc094 100644 (file)
@@ -22,6 +22,8 @@ import static org.junit.Assert.fail;
 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramBucket;
 import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramDataModel;
 import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramScaledData;
 import org.eclipse.linuxtools.tmf.ui.views.histogram.IHistogramModelListener;
@@ -34,6 +36,14 @@ public class HistogramDataModelTest {
 
     private static final double DELTA = 1e-15;
 
+    private final static HistogramBucket _0 = new HistogramBucket(new int[] {0});
+    private final static HistogramBucket _1 = new HistogramBucket(new int[] {1});
+    private final static HistogramBucket _2 = new HistogramBucket(new int[] {2});
+    private final static HistogramBucket _4 = new HistogramBucket(new int[] {4});
+    private final static HistogramBucket _9 = new HistogramBucket(new int[] {9});
+    private final static HistogramBucket _20 = new HistogramBucket(new int[] {20});
+    private final static HistogramBucket _24 = new HistogramBucket(new int[] {24});
+
     /**
      * Test method for {@link HistogramDataModel#HistogramDataModel()}.
      */
@@ -43,6 +53,16 @@ public class HistogramDataModelTest {
         testModelConsistency(model, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
     }
 
+    /**
+     * Test method for {@link HistogramDataModel#HistogramDataModel(HistogramDataModel)}.
+     */
+    @Test
+    public void testHistogramDataModelCopyConstructor() {
+        HistogramDataModel model = new HistogramDataModel();
+        HistogramDataModel copy = new HistogramDataModel(model);
+        testModelConsistency(copy, HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS,0, 1, 0 , 0 , 0 , HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
+    }
+
     /**
      * Test method for {@link HistogramDataModel#HistogramDataModel(int)}.
      */
@@ -54,31 +74,31 @@ public class HistogramDataModelTest {
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)}.
+     * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}.
      */
     @Test
     public void testClear() {
         final int nbBuckets = 100;
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
-        model.countEvent(0, -1);
+        model.countEvent(0, -1, null);
 
         testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets);
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)}.
+     * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)}.
      */
     @Test
     public void testCountEvent_0() {
         final int nbBuckets = 100;
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
-        model.countEvent(0, -1);
+        model.countEvent(0, -1, null);
 
         testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets);
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)} and
+     * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and
      * {@link HistogramDataModel#scaleTo(int,int,int)}.
      */
     @Test
@@ -91,14 +111,14 @@ public class HistogramDataModelTest {
         HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
 
         for (int i = 0; i < result.fData.length; i++) {
-            assertEquals(0, result.fData[i]);
+            assertEquals(_0, result.fData[i]);
         }
 
         testModelConsistency(model, nbBuckets, 0, 1, 0, 0, 0, nbBuckets);
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)} and
+     * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and
      * {@link HistogramDataModel#scaleTo(int,int,int)}.
      */
     @Test
@@ -107,10 +127,10 @@ public class HistogramDataModelTest {
         final int maxHeight = 10;
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
-        model.countEvent(0, 1);
+        model.countEvent(0, 1, null);
 
         HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
-        assertEquals(1, result.fData[0]);
+        assertEquals(_1, result.fData[0]);
 
         assertArrayEqualsInt(0, result.fData,1);
 
@@ -118,7 +138,7 @@ public class HistogramDataModelTest {
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)} and
+     * Test methods for {@link HistogramDataModel#countEvent(long,long, ITmfTrace)} and
      * {@link HistogramDataModel#scaleTo(int,int,int)}.
      */
     @Test
@@ -137,7 +157,7 @@ public class HistogramDataModelTest {
     }
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)} and
+     * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and
      * {@link HistogramDataModel#scaleTo(int,int,int)}.
      */
     @Test
@@ -148,8 +168,8 @@ public class HistogramDataModelTest {
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         // to different to call elsewhere
         for (int i = 0; i < nbBuckets; i++) {
-            model.countEvent(i, i);
-            model.countEvent(i + 1, i);
+            model.countEvent(i, i, null);
+            model.countEvent(i + 1, i, null);
         }
 
         HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
@@ -161,7 +181,7 @@ public class HistogramDataModelTest {
 
 
     /**
-     * Test methods for {@link HistogramDataModel#countEvent(long,long)} and
+     * Test methods for {@link HistogramDataModel#countEvent(long,long,ITmfTrace)} and
      * {@link HistogramDataModel#scaleTo(int,int,int)}.
      */
     @Test
@@ -172,7 +192,7 @@ public class HistogramDataModelTest {
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         for (int i = startTime; i < startTime + nbBuckets; i++) {
-            model.countEvent(i, i);
+            model.countEvent(i, i, null);
         }
 
         HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
@@ -212,7 +232,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 10;
         final int maxHeight = 10;
         final int nbEvents = nbBuckets / 2;
-        final int[] expectedResult = new int[] { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _0, _0, _0, _0, _0 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -232,7 +252,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 10;
         final int maxHeight = 10;
         final int nbEvents = nbBuckets;
-        final int[] expectedResult = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _1, _1, _1, _1, _1, _1, _1, _1, _1, _1 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -252,7 +272,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 10;
         final int maxHeight = 10;
         final int nbEvents = 2 * nbBuckets;
-        final int[] expectedResult = new int[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _2, _2, _2, _2, _2, _2, _2, _2, _2, _2 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -272,7 +292,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 10;
         final int maxHeight = 10;
         final int nbEvents = 3 * nbBuckets;
-        final int[] expectedResult = new int[] { 4, 4, 4, 4, 4, 4, 4, 2, 0, 0 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -292,7 +312,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 100;
         final int maxHeight = 20;
         final int nbEvents = 2 * nbBuckets;
-        final int[] expectedResult = new int[] { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _20, _20, _20, _20, _20, _20, _20, _20, _20, _20 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -312,7 +332,7 @@ public class HistogramDataModelTest {
         final int nbBuckets = 100;
         final int maxHeight = 24;
         final int nbEvents = 2 * nbBuckets + 1;
-        final int[] expectedResult = new int[] { 24, 24, 24, 24, 24, 24, 24, 24, 9, 0 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _24, _24, _24, _24, _24, _24, _24, _24, _9, _0 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -344,7 +364,7 @@ public class HistogramDataModelTest {
         // -> buckets per bar = 50 / 2 + 1 = 26
         // -> first entry in expected result is 26 * 4 = 104
         // -> second entry in expected result is 22 * 4 + 9 = 97
-        final int[] expectedResult = new int[] { 104, 97 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {104}) , new HistogramBucket(new int[] {97}) };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countEventsInModel(nbEvents, model);
@@ -387,7 +407,7 @@ public class HistogramDataModelTest {
         // buckets in (model) per bar = last bucket id / nbBars + 1 (plus 1 to
         // cover all used buckets)
         // -> buckets per bar = 50 / 10 + 1 = 6
-        final int[] expectedResult = new int[] { 21, 24, 24, 24, 24, 24, 24, 24, 12, 0 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { new HistogramBucket(new int[] {21}), _24, _24, _24, _24, _24, _24, _24, new HistogramBucket(new int[] {12}), _0 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
         countInvertedEvents(nbEvents, model);
@@ -416,7 +436,7 @@ public class HistogramDataModelTest {
 
     private static void countInvertedEvents(final int nbEvents, HistogramDataModel model) {
         for (int i = nbEvents - 1; i >= 0; i--) {
-            model.countEvent(i, i);
+            model.countEvent(i, i, null);
         }
     }
 
@@ -514,7 +534,7 @@ public class HistogramDataModelTest {
         final int nbLostEvents_0 = 4;
         final int nbLostEvents_1 = 9;
         final int nbCombinedEvents = nbEvents + 2;
-        final int[] expectedResult = new int[] { 4, 4, 4, 4, 4, 4, 4, 2, 0, 0 };
+        final HistogramBucket[] expectedResult = new HistogramBucket[] { _4, _4, _4, _4, _4, _4, _4, _2, _0, _0 };
         final int[] expectedLostEventsResult = new int[] { 0, 2, 2, 0, 3, 3, 3, 0, 0, 0 };
 
         HistogramDataModel model = new HistogramDataModel(nbBuckets);
@@ -656,7 +676,7 @@ public class HistogramDataModelTest {
 
     private static void countEventsInModel(final int nbEvents, HistogramDataModel model, int offset, int startTime) {
         for (int i = startTime; i < nbEvents + startTime; i++) {
-            model.countEvent(i + offset, i);
+            model.countEvent(i + offset, i, null);
         }
     }
 
@@ -670,13 +690,13 @@ public class HistogramDataModelTest {
         assertEquals(timeLimit, model.getTimeLimit());
     }
 
-    private static void assertArrayEqualsInt(final int val , int[] result) {
+    private static void assertArrayEqualsInt(final int val , HistogramBucket[] result) {
         assertArrayEqualsInt(val, result, 0);
     }
 
-    private static void assertArrayEqualsInt(final int val , int[] result, int startVal ) {
+    private static void assertArrayEqualsInt(final int val , HistogramBucket[] result, int startVal ) {
         for (int i = startVal; i < result.length; i++) {
-            assertEquals(val, result[i]);
+            assertEquals(val, result[i].getNbEvents());
         }
     }
 
diff --git a/org.eclipse.linuxtools.tmf.ui/icons/elcl16/show_hist_traces.gif b/org.eclipse.linuxtools.tmf.ui/icons/elcl16/show_hist_traces.gif
new file mode 100644 (file)
index 0000000..40febb2
Binary files /dev/null and b/org.eclipse.linuxtools.tmf.ui/icons/elcl16/show_hist_traces.gif differ
index 1d1f450e4574138dc072553e5e7cd7c1f8f942fa..9d21ec9b7b36573e222bffc5ed589596ae545273 100755 (executable)
@@ -46,6 +46,7 @@ public interface ITmfImageConstants {
     public static final String IMG_UI_FOLLOW_ARROW_FORWARD = ICONS_PATH + "elcl16/follow_arrow_fwd.gif";
     public static final String IMG_UI_FOLLOW_ARROW_BACKWARD = ICONS_PATH + "elcl16/follow_arrow_bwd.gif";
     public static final String IMG_UI_SHOW_LOST_EVENTS = ICONS_PATH + "elcl16/hide_lost_events.gif";
+    public static final String IMG_UI_SHOW_HIST_TRACES = ICONS_PATH + "elcl16/show_hist_traces.gif";
 
     /* eview16 */
     public static final String IMG_UI_SEQ_DIAGRAM_OBJ = ICONS_PATH + "eview16/sequencediagram_view.gif";
index 9c13c0a822dcfd730bbcc35f34ad7f301c49a149..c9c904da877e83a6e6d48d985435621b14ba36af 100644 (file)
@@ -11,6 +11,7 @@
  *   Bernd Hufmann - Changed to updated histogram data model
  *   Francois Chouinard - Reformat histogram labels on format change
  *   Patrick Tasse - Support selection range
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
@@ -108,8 +109,31 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
     private final Color fFillColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
 
     // Application colors, they need to be disposed
+    private final Color[] fHistoBarColors = new Color[] {new Color(Display.getDefault(), 90, 90, 255), // blue
+            new Color(Display.getDefault(), 0, 240, 0), // green
+            new Color(Display.getDefault(), 255, 0, 0), // red
+            new Color(Display.getDefault(), 0, 255, 255), // cyan
+            new Color(Display.getDefault(), 255, 80, 255), // magenta
+            new Color(Display.getDefault(), 200, 200, 0), // yellow
+            new Color(Display.getDefault(), 200, 150, 0), // brown
+            new Color(Display.getDefault(), 150, 255, 150), // light green
+            new Color(Display.getDefault(), 200, 80, 80), // dark red
+            new Color(Display.getDefault(), 30, 150, 150), // dark cyan
+            new Color(Display.getDefault(), 200, 200, 255), // light blue
+            new Color(Display.getDefault(), 0, 120, 0), // dark green
+            new Color(Display.getDefault(), 255, 150, 150), // lighter red
+            new Color(Display.getDefault(), 140, 80, 140), // dark magenta
+            new Color(Display.getDefault(), 150, 100, 50), // brown
+            new Color(Display.getDefault(), 255, 80, 80), // light red
+            new Color(Display.getDefault(), 200, 200, 200), // light grey
+            new Color(Display.getDefault(), 255, 200, 80), // orange
+            new Color(Display.getDefault(), 255, 255, 80), // pale yellow
+            new Color(Display.getDefault(), 255, 200, 200), // pale red
+            new Color(Display.getDefault(), 255, 200, 255), // pale magenta
+            new Color(Display.getDefault(), 255, 255, 200), // pale pale yellow
+            new Color(Display.getDefault(), 200, 255, 255), // pale pale blue
+    };
     private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
-    private final Color fHistoBarColor = new Color(Display.getDefault(), 74, 112, 139);
     private final Color fLostEventColor = new Color(Display.getCurrent(), 208, 62, 120);
 
     // Drag states
@@ -203,6 +227,12 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
      */
     private int fOffset = 0;
 
+    /**
+     * show the traces or not
+     * @since 3.0
+     */
+    static boolean showTraces = true;
+
     // ------------------------------------------------------------------------
     // Construction
     // ------------------------------------------------------------------------
@@ -236,9 +266,10 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
      */
     public void dispose() {
         TmfSignalManager.deregister(this);
-
-        fHistoBarColor.dispose();
         fLostEventColor.dispose();
+        for (Color c : fHistoBarColors) {
+            c.dispose();
+        }
         fTimeRangeColor.dispose();
         fFont.dispose();
         fDataModel.removeHistogramListener(this);
@@ -414,6 +445,36 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
         return fMaxNbEventsText;
     }
 
+    /**
+     * Return <code>true</code> if the traces must be displayed in the histogram,
+     * <code>false</code> otherwise.
+     * @return whether the traces should be displayed
+     * @since 3.0
+     */
+    public boolean showTraces() {
+        return showTraces && fDataModel.getNbTraces() < getMaxNbTraces();
+    }
+
+    /**
+     * Returns the maximum number of traces the histogram can display with separate colors.
+     * If there is more traces, histogram will use only one color to display them.
+     * @return the maximum number of traces the histogram can display.
+     * @since 3.0
+     */
+    public int getMaxNbTraces() {
+        return fHistoBarColors.length;
+    }
+
+    /**
+     * Returns the color used to display the trace at the given index.
+     * @param traceIndex a trace index
+     * @return a {@link Color}
+     * @since 3.0
+     */
+    public Color getTraceColor(int traceIndex) {
+        return fHistoBarColors[traceIndex % fHistoBarColors.length];
+    }
+
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
@@ -443,16 +504,6 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
         }
     }
 
-    /**
-     * Increase the histogram bucket corresponding to [timestamp]
-     *
-     * @param eventCount The new event count
-     * @param timestamp The latest timestamp
-     */
-    public void countEvent(final long eventCount, final long timestamp) {
-        fDataModel.countEvent(eventCount, timestamp);
-    }
-
     /**
      * Sets the current selection time range and refresh the display
      *
@@ -517,7 +568,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
 
         case SWT.HOME:
             index = 0;
-            while (index < fScaledData.fLastBucket && fScaledData.fData[index] == 0) {
+            while (index < fScaledData.fLastBucket && fScaledData.fData[index].isEmpty()) {
                 index++;
             }
             if (index < fScaledData.fLastBucket) {
@@ -527,7 +578,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
 
         case SWT.ARROW_RIGHT:
             index = Math.max(0, fScaledData.fSelectionBeginBucket + 1);
-            while (index < fScaledData.fWidth && fScaledData.fData[index] == 0) {
+            while (index < fScaledData.fWidth && fScaledData.fData[index].isEmpty()) {
                 index++;
             }
             if (index < fScaledData.fLastBucket) {
@@ -537,7 +588,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
 
         case SWT.END:
             index = fScaledData.fLastBucket;
-            while (index >= 0 && fScaledData.fData[index] == 0) {
+            while (index >= 0 && fScaledData.fData[index].isEmpty()) {
                 index--;
             }
             if (index >= 0) {
@@ -547,7 +598,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
 
         case SWT.ARROW_LEFT:
             index = Math.min(fScaledData.fLastBucket - 1, fScaledData.fSelectionBeginBucket - 1);
-            while (index >= 0 && fScaledData.fData[index] == 0) {
+            while (index >= 0 && fScaledData.fData[index].isEmpty()) {
                 index--;
             }
             if (index >= 0) {
@@ -703,8 +754,11 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
             // Draw the histogram bars
             final int limit = width < scaledData.fWidth ? width : scaledData.fWidth;
             double factor = HistogramScaledData.hideLostEvents ? scaledData.fScalingFactor : scaledData.fScalingFactorCombined;
+            final boolean showTracesColors = showTraces();
             for (int i = 0; i < limit; i++) {
-                final int value = (int) Math.ceil(scaledData.fData[i] * factor);
+                HistogramBucket hb = scaledData.fData[i];
+                int totalNbEvents = hb.getNbEvents();
+                int value = (int) Math.ceil(totalNbEvents * factor);
                 int x = i + fOffset;
 
                 // in Linux, the last pixel in a line is not drawn,
@@ -720,8 +774,24 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
                 }
 
                 // then draw normal events second, to overwrite that extra pixel
-                imageGC.setForeground(fHistoBarColor);
-                imageGC.drawLine(x, height - value, x, height);
+                if (!hb.isEmpty()) {
+                    if (showTracesColors) {
+                        for (int traceIndex = 0; traceIndex < hb.getNbTraces(); traceIndex++) {
+                            int nbEventsForTrace = hb.getNbEvent(traceIndex);
+                            if (nbEventsForTrace > 0) {
+                                Color c = fHistoBarColors[traceIndex % fHistoBarColors.length];
+                                imageGC.setForeground(c);
+                                imageGC.drawLine(x, height - value, x, height);
+                                totalNbEvents -= nbEventsForTrace;
+                                value = (int) Math.ceil(totalNbEvents * scaledData.fScalingFactor);
+                            }
+                        }
+                    } else {
+                        Color c = fHistoBarColors[0];
+                        imageGC.setForeground(c);
+                        imageGC.drawLine(x, height - value, x, height);
+                    }
+                }
             }
 
             // Draw the selection bars
@@ -919,7 +989,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
             startTime = 0;
         }
         final long endTime = fScaledData.getBucketEndTime(index);
-        final int nbEvents = (index >= 0) ? fScaledData.fData[index] : 0;
+        final int nbEvents = (index >= 0) ? fScaledData.fData[index].getNbEvents() : 0;
         final String newLine = System.getProperty("line.separator"); //$NON-NLS-1$
         final StringBuffer buffer = new StringBuffer();
         int selectionBeginBucket = Math.min(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket);
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/HistogramBucket.java
new file mode 100644 (file)
index 0000000..feb15ed
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.tmf.ui.views.histogram;
+
+import java.util.Arrays;
+
+/**
+ * This class counts events for a particular time range, taking into account origin of the event.
+ * @author Xavier Raynaud
+ * @since 3.0
+ */
+public class HistogramBucket {
+
+    private int fNbEvents = 0;
+    private int fEvents[];
+
+    /**
+     * Constructor
+     * @param traceCount number of traces of the experiment.
+     */
+    public HistogramBucket(int traceCount) {
+        fEvents = new int[traceCount];
+    }
+
+    /**
+     * Constructor
+     * @param values list of values
+     */
+    public HistogramBucket(int... values) {
+        fEvents = values;
+        for (int i: fEvents) {
+            fNbEvents +=i;
+        }
+    }
+
+    /**
+     * Copy Constructor
+     * @param b a HistogramBucket to copy
+     */
+    public HistogramBucket(HistogramBucket b) {
+        add(b);
+    }
+
+    /**
+     * Merge Constructor
+     * @param b1 a HistogramBucket
+     * @param b2 another HistogramBucket
+     */
+    public HistogramBucket(HistogramBucket b1, HistogramBucket b2) {
+        add(b1);
+        add(b2);
+    }
+
+    /**
+     * @return the number of events in this bucket
+     */
+    public int getNbEvents() {
+        return fNbEvents;
+    }
+
+    /**
+     * Add an event in this bucket
+     * @param traceIndex a trace index - see {@link HistogramDataModel#setTraces}.
+     */
+    public void addEvent(int traceIndex) {
+        this.fNbEvents++;
+        ensureCapacity(traceIndex+1);
+        fEvents[traceIndex]++;
+    }
+
+    private void ensureCapacity(int len) {
+        if (fEvents == null) {
+            fEvents = new int[len];
+        } else if (fEvents.length<len) {
+            int[] oldArray = fEvents;
+            fEvents = new int[len];
+            System.arraycopy(oldArray, 0, fEvents, 0, oldArray.length);
+        }
+    }
+
+    /**
+     * Gets the number of event in this bucket belonging to given trace
+     * @param traceIndex a trace index
+     * @return the number of events in this bucket belonging to the given trace
+     */
+    public int getNbEvent(int traceIndex) {
+        if (fEvents == null || fEvents.length<= traceIndex) {
+            return 0;
+        }
+        return fEvents[traceIndex];
+    }
+
+    /**
+     * @return the number of traces in this bucket
+     */
+    public int getNbTraces() {
+        if (fEvents == null) {
+            return 0;
+        }
+        return fEvents.length;
+    }
+
+    /**
+     * Merge the given bucket in this one.
+     * @param histogramBucket a bucket to merge in this one.
+     */
+    public void add(HistogramBucket histogramBucket) {
+        if (histogramBucket != null && histogramBucket.fNbEvents != 0) {
+            fNbEvents += histogramBucket.fNbEvents;
+            ensureCapacity(histogramBucket.fEvents.length);
+            for (int i = 0; i<histogramBucket.fEvents.length; i++) {
+                fEvents[i] += histogramBucket.fEvents[i];
+            }
+        }
+    }
+
+    /**
+     * @return <code>true</code> if this bucket contains no event, <code>false</code> otherwise.
+     */
+    public boolean isEmpty() {
+        return fNbEvents == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(fEvents);
+        result = prime * result + fNbEvents;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        HistogramBucket other = (HistogramBucket) obj;
+        if (fNbEvents != other.fNbEvents) {
+            return false;
+        }
+        if (fNbEvents != 0 && !Arrays.equals(fEvents, other.fEvents)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(fNbEvents);
+        sb.append(": "); //$NON-NLS-1$
+        sb.append(Arrays.toString(fEvents));
+        return sb.toString();
+    }
+
+}
index 5fcbdf3d67a7c047d401283a9829966359cdc805..e4f7099c684feea3d4a3db6cf0b9e61255d57310 100644 (file)
  *   Francois Chouinard - Added support for empty initial buckets
  *   Patrick Tasse - Support selection range
  *   Jean-Christian Kouamé, Simon Delisle - Added support to manage lost events
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
 
 import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
 
 /**
  * Histogram-independent data model.
@@ -85,9 +90,13 @@ public class HistogramDataModel implements IHistogramDataModel {
     // Attributes
     // ------------------------------------------------------------------------
 
+    // Trace management
+    private ITmfTrace fTrace = null;
+    private final Map<ITmfTrace, Integer> fTraceMap = new LinkedHashMap<>();
+
     // Bucket management
     private final int fNbBuckets;
-    private final long[] fBuckets;
+    private final HistogramBucket[] fBuckets;
     private final long[] fLostEventsBuckets;
     private long fBucketDuration;
     private long fNbEvents;
@@ -148,7 +157,7 @@ public class HistogramDataModel implements IHistogramDataModel {
     public HistogramDataModel(long startTime, int nbBuckets) {
         fFirstBucketTime = fFirstEventTime = fEndTime = startTime;
         fNbBuckets = nbBuckets;
-        fBuckets = new long[nbBuckets];
+        fBuckets = new HistogramBucket[nbBuckets];
         fLostEventsBuckets = new long[nbBuckets];
         fModelListeners = new ListenerList();
         clear();
@@ -162,7 +171,10 @@ public class HistogramDataModel implements IHistogramDataModel {
      */
     public HistogramDataModel(HistogramDataModel other) {
         fNbBuckets = other.fNbBuckets;
-        fBuckets = Arrays.copyOf(other.fBuckets, fNbBuckets);
+        fBuckets = new HistogramBucket[fNbBuckets];
+        for (int i = 0; i < fNbBuckets; i++) {
+            fBuckets[i] = new HistogramBucket(other.fBuckets[i]);
+        }
         fLostEventsBuckets = Arrays.copyOf(other.fLostEventsBuckets, fNbBuckets);
         fBucketDuration = Math.max(other.fBucketDuration, 1);
         fNbEvents = other.fNbEvents;
@@ -229,6 +241,65 @@ public class HistogramDataModel implements IHistogramDataModel {
         return fFirstEventTime;
     }
 
+    /**
+     * Sets the trace of this model.
+     * @param trace - a {@link ITmfTrace}
+     * @since 3.0
+     */
+    public void setTrace(ITmfTrace trace) {
+        this.fTrace = trace;
+        fTraceMap.clear();
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+        if (traces != null) {
+            int i = 0;
+            for (ITmfTrace tr : traces) {
+                fTraceMap.put(tr, i);
+                i++;
+            }
+        }
+    }
+
+    /**
+     * Gets the trace of this model.
+     * @return a {@link ITmfTrace}
+     * @since 3.0
+     */
+    public ITmfTrace getTrace() {
+        return this.fTrace;
+    }
+
+    /**
+     * Gets the traces names of this model.
+     * @return an array of trace names
+     * @since 3.0
+     */
+    public String[] getTraceNames() {
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+        if (traces == null) {
+            return new String[0];
+        }
+        String[] traceNames = new String[traces.length];
+        int i = 0;
+        for (ITmfTrace tr : traces) {
+            traceNames[i] = tr.getName();
+            i++;
+        }
+        return traceNames;
+    }
+
+    /**
+     * Gets the number of traces of this model.
+     * @return the number of traces of this model.
+     * @since 3.0
+     */
+    public int getNbTraces() {
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+        if (traces == null) {
+            return 1; //
+        }
+        return traces.length;
+    }
+
     /**
      * Sets the model start time
      *
@@ -354,7 +425,7 @@ public class HistogramDataModel implements IHistogramDataModel {
      */
     @Override
     public void clear() {
-        Arrays.fill(fBuckets, 0);
+        Arrays.fill(fBuckets, null);
         Arrays.fill(fLostEventsBuckets, 0);
         fNbEvents = 0;
         fFirstBucketTime = 0;
@@ -403,10 +474,12 @@ public class HistogramDataModel implements IHistogramDataModel {
      *            The current event Count (for notification purposes)
      * @param timestamp
      *            The timestamp of the event to count
-     *
+     * @param trace
+     *            The event trace
+     * @since 3.0
      */
     @Override
-    public void countEvent(long eventCount, long timestamp) {
+    public void countEvent(long eventCount, long timestamp, ITmfTrace trace) {
 
         // Validate
         if (timestamp < 0) {
@@ -414,7 +487,7 @@ public class HistogramDataModel implements IHistogramDataModel {
         }
 
         // Set the start/end time if not already done
-        if ((fFirstBucketTime == 0) && (fLastBucket == 0) && (fBuckets[0] == 0) && (timestamp > 0)) {
+        if ((fFirstBucketTime == 0) && (fLastBucket == 0) && (fBuckets[0] == null) && (timestamp > 0)) {
             fFirstBucketTime = timestamp;
             fFirstEventTime = timestamp;
             updateEndTime();
@@ -456,7 +529,14 @@ public class HistogramDataModel implements IHistogramDataModel {
 
         // Increment the right bucket
         int index = (int) ((timestamp - fFirstBucketTime) / fBucketDuration);
-        fBuckets[index]++;
+        if (fBuckets[index] == null) {
+            fBuckets[index] = new HistogramBucket(getNbTraces());
+        }
+        Integer traceIndex = fTraceMap.get(trace);
+        if (traceIndex == null) {
+            traceIndex = 0;
+        }
+        fBuckets[index].addEvent(traceIndex);
         fNbEvents++;
         if (fLastBucket < index) {
             fLastBucket = index;
@@ -546,14 +626,17 @@ public class HistogramDataModel implements IHistogramDataModel {
         for (int i = 0; i < nbBars; i++) {
             int count = 0;
             int countLostEvent = 0;
+            result.fData[i] = new HistogramBucket(getNbTraces());
             for (int j = i * bucketsPerBar; j < ((i + 1) * bucketsPerBar); j++) {
                 if (fNbBuckets <= j) {
                     break;
                 }
-                count += fBuckets[j];
+                if (fBuckets[j] != null) {
+                    count += fBuckets[j].getNbEvents();
+                    result.fData[i].add(fBuckets[j]);
+                }
                 countLostEvent += fLostEventsBuckets[j];
             }
-            result.fData[i] = count;
             result.fLostEventsData[i] = countLostEvent;
             result.fLastBucket = i;
             if (result.fMaxValue < count) {
@@ -592,10 +675,10 @@ public class HistogramDataModel implements IHistogramDataModel {
 
     private void mergeBuckets() {
         for (int i = 0; i < (fNbBuckets / 2); i++) {
-            fBuckets[i] = fBuckets[2 * i] + fBuckets[(2 * i) + 1];
+            fBuckets[i] = new HistogramBucket(fBuckets[2 * i], fBuckets[(2 * i) + 1]);
             fLostEventsBuckets[i] = fLostEventsBuckets[2 * i] + fLostEventsBuckets[(2 * i) + 1];
         }
-        Arrays.fill(fBuckets, fNbBuckets / 2, fNbBuckets, 0);
+        Arrays.fill(fBuckets, fNbBuckets / 2, fNbBuckets, null);
         Arrays.fill(fLostEventsBuckets, fNbBuckets / 2, fNbBuckets, 0);
         fBucketDuration *= 2;
         updateEndTime();
@@ -604,12 +687,12 @@ public class HistogramDataModel implements IHistogramDataModel {
 
     private void moveBuckets(int offset) {
         for (int i = fNbBuckets - 1; i >= offset; i--) {
-            fBuckets[i] = fBuckets[i - offset];
+            fBuckets[i] = new HistogramBucket(fBuckets[i - offset]);
             fLostEventsBuckets[i] = fLostEventsBuckets[i - offset];
         }
 
         for (int i = 0; i < offset; i++) {
-            fBuckets[i] = 0;
+            fBuckets[i] = null;
             fLostEventsBuckets[i] = 0;
         }
     }
index cdadea9c4b646ac36633bf94556d0365413dffa9..d946cc43bfdc03a65d084e0294ed98bbd5e964f4 100644 (file)
@@ -12,6 +12,7 @@
  *   Francois Chouinard - Cleanup and refactoring
  *   Francois Chouinard - Moved from LTTng to TMF
  *   Simon Delisle - Added a new parameter to the constructor
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
@@ -97,7 +98,7 @@ public class HistogramRequest extends TmfEventRequest {
 
             } else { /* handle lost event */
                 long timestamp = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                fHistogram.countEvent(getNbRead(), timestamp);
+                fHistogram.countEvent(getNbRead(), timestamp, event.getTrace());
             }
         }
     }
index 488bb7913befb74a5b3bfc45b5856598e34b9c23..4a10cc4af0b79827cde66a3df1893bf50cadea1c 100644 (file)
@@ -12,6 +12,7 @@
  *   Francois Chouinard - Moved from LTTng to TMF
  *   Patrick Tasse - Support selection range
  *   Jean-Christian Kouamé - Support to manage lost events
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
@@ -53,7 +54,7 @@ public class HistogramScaledData {
     /**
      * Array of scaled values
      */
-    public int[] fData;
+    public HistogramBucket[] fData;
     /**
      * Array of scaled values combined including the lost events.
      * This array contains the number of lost events for each bar in the histogram
@@ -112,6 +113,7 @@ public class HistogramScaledData {
      * @since 2.2
      */
     public static volatile boolean hideLostEvents = false;
+
     // ------------------------------------------------------------------------
     // Constructor
     // ------------------------------------------------------------------------
@@ -126,7 +128,7 @@ public class HistogramScaledData {
         fWidth = width;
         fHeight = height;
         fBarWidth = barWidth;
-        fData = new int[width / fBarWidth];
+        fData = new HistogramBucket[width / fBarWidth];
         fLostEventsData = new int[width / fBarWidth];
         fBucketDuration = 1;
         fMaxValue = 0;
index 5e337c6c0d912049552b5386cde6dd1f358ce3fd..f25e01b39f9794001032c970dbd352d7bedd213b 100644 (file)
@@ -14,6 +14,7 @@
  *   Francois Chouinard - Cleanup and refactoring
  *   Francois Chouinard - Moved from LTTng to TMF
  *   Patrick Tasse - Update for mouse wheel zoom
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
@@ -38,18 +39,23 @@ import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
 import org.eclipse.linuxtools.tmf.ui.views.TmfView;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseWheelListener;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.IActionBars;
@@ -118,12 +124,18 @@ public class HistogramView extends TmfView {
     private static TimeRangeHistogram fTimeRangeHistogram;
     private HistogramRequest fTimeRangeRequest;
 
+    // Legend area
+    private Composite fLegendArea;
+    private Image[] fLegendImages;
+
     // Throttlers for the time sync and time-range sync signals
     private final TmfSignalThrottler fTimeSyncThrottle;
     private final TmfSignalThrottler fTimeRangeSyncThrottle;
 
     // Action for toggle showing the lost events
     private Action hideLostEventsAction;
+    // Action for toggle showing the traces
+    private Action showTraceAction;
 
     // ------------------------------------------------------------------------
     // Constructor
@@ -291,6 +303,10 @@ public class HistogramView extends TmfView {
         // Histogram
         fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
 
+        fLegendArea = new Composite(viewComposite, SWT.FILL);
+        fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1));
+        fLegendArea.setLayout(new RowLayout());
+
         // Add mouse wheel listener to time span control
         MouseWheelListener listener = fFullTraceHistogram.getZoom();
         fTimeSpanControl.addMouseWheelListener(listener);
@@ -370,6 +386,32 @@ public class HistogramView extends TmfView {
         return hideLostEventsAction;
     }
 
+    /**
+     * get the show trace action
+     *
+     * @return The action object
+     * @since 3.0
+     */
+    public Action getShowTraceAction() {
+        if (showTraceAction == null) {
+            /* show lost events */
+            showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) {
+                @Override
+                public void run() {
+                    Histogram.showTraces = showTraceAction.isChecked();
+                    fFullTraceHistogram.fCanvas.redraw();
+                    fTimeRangeHistogram.fCanvas.redraw();
+                    updateLegendArea();
+                }
+            };
+            showTraceAction.setChecked(true);
+            showTraceAction.setText(Messages.HistogramView_showTraces);
+            showTraceAction.setToolTipText(Messages.HistogramView_showTraces);
+            showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES));
+        }
+        return showTraceAction;
+    }
+
     // ------------------------------------------------------------------------
     // Operations
     // ------------------------------------------------------------------------
@@ -537,6 +579,18 @@ public class HistogramView extends TmfView {
         fSelectionEndControl.setValue(Long.MIN_VALUE);
 
         fTimeSpanControl.setValue(Long.MIN_VALUE);
+
+        for (Control c: fLegendArea.getChildren()) {
+            c.dispose();
+        }
+        if (fLegendImages != null) {
+            for (Image i: fLegendImages) {
+                i.dispose();
+            }
+        }
+        fLegendImages = null;
+        fLegendArea.layout();
+        fLegendArea.getParent().layout();
     }
 
     /**
@@ -671,6 +725,7 @@ public class HistogramView extends TmfView {
         fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
         fTimeRangeHistogram.setTimeRange(startTime, duration);
         fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime);
+        fTimeRangeHistogram.fDataModel.setTrace(fTrace);
 
         if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
             fFullTraceRequest.cancel();
@@ -679,6 +734,7 @@ public class HistogramView extends TmfView {
         fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
         fFullTraceHistogram.setTimeRange(startTime, duration);
         fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime);
+        fFullTraceHistogram.fDataModel.setTrace(fTrace);
 
         fWindowStartTime = startTime;
         fWindowSpan = duration;
@@ -691,12 +747,51 @@ public class HistogramView extends TmfView {
 
         fTimeSpanControl.setValue(duration);
 
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+        if (traces != null) {
+            this.showTraceAction.setEnabled(traces.length < fFullTraceHistogram.getMaxNbTraces());
+        }
+        updateLegendArea();
+
         if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) {
             sendTimeRangeRequest(startTime, startTime + duration);
             sendFullRangeRequest(fullRange);
         }
     }
 
+    private void updateLegendArea() {
+        for (Control c: fLegendArea.getChildren()) {
+            c.dispose();
+        }
+        if (fLegendImages != null) {
+            for (Image i: fLegendImages) {
+                i.dispose();
+            }
+        }
+        fLegendImages = null;
+        if (fFullTraceHistogram.showTraces()) {
+            ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+            fLegendImages = new Image[traces.length];
+            int traceIndex = 0;
+            for (ITmfTrace trace : traces) {
+                fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16);
+                GC gc = new GC(fLegendImages[traceIndex]);
+                gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex));
+                gc.fillRectangle(0, 0, 15, 15);
+                gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK));
+                gc.drawRectangle(0, 0, 15, 15);
+                gc.dispose();
+
+                CLabel label = new CLabel(fLegendArea, SWT.NONE);
+                label.setText(trace.getName());
+                label.setImage(fLegendImages[traceIndex]);
+                traceIndex++;
+            }
+        }
+        fLegendArea.layout();
+        fLegendArea.getParent().layout();
+    }
+
     private void updateDisplayedSelectionTime(long beginTime, long endTime) {
         fSelectionBeginTime = beginTime;
         fSelectionEndTime = endTime;
@@ -761,6 +856,7 @@ public class HistogramView extends TmfView {
     private void contributeToActionBars() {
         IActionBars bars = getViewSite().getActionBars();
         bars.getToolBarManager().add(getShowLostEventsAction());
+        bars.getToolBarManager().add(getShowTraceAction());
         bars.getToolBarManager().add(new Separator());
     }
 
index d386484b19f8af16b44f51cb316e7c742e370d31..d18d07e65adb27b08b61959eb231a91e9b676f10 100644 (file)
@@ -9,10 +9,12 @@
  * Contributors:
  *   Bernd Hufmann - Initial API and implementation
  *   Francois Chouinard - Moved from LTTng to TMF
+ *   Xavier Raynaud - Support multi-trace coloring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.histogram;
 
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
 import org.eclipse.linuxtools.tmf.ui.views.distribution.model.IBaseDistributionModel;
 
 /**
@@ -27,8 +29,11 @@ public interface IHistogramDataModel extends IBaseDistributionModel {
      *
      * @param eventCount the event to count
      * @param timestamp the timestamp of the event to count
+     * @param trace the trace corresponding to given events
+     * @since 3.0
      */
-    void countEvent(long eventCount, long timestamp);
+    void countEvent(long eventCount, long timestamp, ITmfTrace trace);
+
     /**
      * Scale the model data to the width, height and bar width requested.
      *
index c9af1351b1208f4f2b862dedf19a1d268784de03..4841a42beace5839a7a477a344e28462d94003d9 100644 (file)
@@ -32,6 +32,11 @@ public class Messages extends NLS {
 
     private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.histogram.messages"; //$NON-NLS-1$
 
+    /**
+     * @since 3.0
+     */
+    public static String HistogramView_showTraces;
+
     /**
      * @since 2.2
      */
index b02a4deffaf3e91de76aec3ba95521feda2d3a63..116ec9acc335d86bc53e5cb36425b3c4855a8c94 100644 (file)
@@ -11,6 +11,7 @@
 ###############################################################################
 
 HistogramView_hideLostEvents=Hide Lost Events
+HistogramView_showTraces=Activate Trace Coloring
 HistogramView_selectionStartLabel=Selection Start
 HistogramView_selectionEndLabel=Selection End
 HistogramView_windowSpanLabel=Window Span
This page took 0.0435449999999999 seconds and 5 git commands to generate.