weighted tree: Fix pie chart bugs

* The pie chart displays no data when the selection does not have
  children
* References to an eventual secondary pie are now gone, if we ever
  support it, it will come back

Change-Id: I5625ccf1752b7702e02adc511b96e13ee547ab2b
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/156370
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreePieChartViewer.java b/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreePieChartViewer.java
index f00c89d..7a95f2f 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreePieChartViewer.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreePieChartViewer.java
@@ -58,7 +58,6 @@
      * The pie chart containing global information about the trace
      */
     private @Nullable PieChart fGlobalPC = null;
-    private @Nullable PieChart fSecondaryPc = null;
 
     /**
      * The listener for the mouse movement event.
@@ -197,57 +196,60 @@
      * @param treeProvider
      */
     synchronized void updateGlobalPieChart(Set<WeightedTree<?>> trees, IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider) {
+        long totalWeight = getTotalWeight(trees);
+
         PieChart pie = getGlobalPC();
-        if (pie == null) {
-            pie = new PieChart(getParent(), SWT.NONE);
-            Color backgroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_BACKGROUND);
-            Color foregroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_FOREGROUND);
-            pie.getTitle().setText(treeProvider.getTitle());
-            pie.getTitle().setForeground(foregroundColor);
-            pie.setBackground(backgroundColor);
-            pie.setForeground(foregroundColor);
-            // Hide the title over the legend
-            pie.getAxisSet().getXAxis(0).getTitle().setText(StringUtils.EMPTY);
-            pie.getAxisSet().getXAxis(0).getTitle().setForeground(foregroundColor);
-            pie.getLegend().setVisible(true);
-            pie.getLegend().setPosition(SWT.RIGHT);
-            pie.getLegend().setBackground(backgroundColor);
-            pie.getLegend().setForeground(foregroundColor);
-            pie.addListener(SWT.MouseMove, fMouseMoveListener);
-            pie.addMouseListener(fMouseClickListener);
-            fGlobalPC = pie;
+        if (pie == null || totalWeight == 0) {
+            pie = createPieChart(treeProvider);
+            setGlobalPC(pie);
             fWeightType = treeProvider.getWeightType();
         }
 
-        updatePieChartWithData(pie, trees, treeProvider);
+        if (totalWeight > 0) {
+            updatePieChartWithData(pie, trees, treeProvider, totalWeight);
+        }
         pie.redraw();
     }
 
-    synchronized void updateSecondaryPieChart(Collection<WeightedTree<?>> trees, IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider) {
-        PieChart pie = getSecondaryPc();
-        if (pie == null) {
-            pie = new PieChart(getParent(), SWT.NONE);
-            Color backgroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_BACKGROUND);
-            Color foregroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_FOREGROUND);
-            pie.getTitle().setText(treeProvider.getTitle());
-            pie.getTitle().setForeground(foregroundColor);
-            pie.setBackground(backgroundColor);
-            pie.setForeground(foregroundColor);
-            // Hide the title over the legend
-            pie.getAxisSet().getXAxis(0).getTitle().setText(StringUtils.EMPTY);
-            pie.getAxisSet().getXAxis(0).getTitle().setForeground(foregroundColor);
-            pie.getLegend().setVisible(true);
-            pie.getLegend().setPosition(SWT.RIGHT);
-            pie.getLegend().setBackground(backgroundColor);
-            pie.getLegend().setForeground(foregroundColor);
-            pie.addListener(SWT.MouseMove, fMouseMoveListener);
-            pie.addMouseListener(fMouseClickListener);
-            fGlobalPC = pie;
-            fWeightType = treeProvider.getWeightType();
-        }
+    private PieChart createPieChart(IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider) {
+        PieChart pie = new PieChart(getParent(), SWT.NONE);
+        Color backgroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_BACKGROUND);
+        Color foregroundColor = fColorScheme.getColor(TimeGraphColorScheme.TOOL_FOREGROUND);
+        pie.getTitle().setText(treeProvider.getTitle());
+        pie.getTitle().setForeground(foregroundColor);
+        pie.setBackground(backgroundColor);
+        pie.setForeground(foregroundColor);
+        // Hide the title over the legend
+        pie.getAxisSet().getXAxis(0).getTitle().setText(StringUtils.EMPTY);
+        pie.getAxisSet().getXAxis(0).getTitle().setForeground(foregroundColor);
+        pie.getLegend().setVisible(true);
+        pie.getLegend().setPosition(SWT.RIGHT);
+        pie.getLegend().setBackground(backgroundColor);
+        pie.getLegend().setForeground(foregroundColor);
+        pie.addListener(SWT.MouseMove, fMouseMoveListener);
+        pie.addMouseListener(fMouseClickListener);
+        return pie;
+    }
 
-        updatePieChartWithData(pie, trees, treeProvider);
-        pie.redraw();
+    /**
+     * Calculates the total weight of the trees. If the treeset is empty, or if
+     * they all have a weight of 0, then 0 is returned and it means there is no
+     * data to display in the pie and it should be reset
+     *
+     * @param trees
+     * @return The total weight. If <code>0</code>, then the pie should be
+     *         reset.
+     */
+    private static long getTotalWeight(Collection<WeightedTree<?>> trees) {
+        if (trees.isEmpty()) {
+            return 0;
+        }
+        // Get the total weights
+        long totalWeight = 0;
+        for (WeightedTree<?> tree : trees) {
+            totalWeight += tree.getWeight();
+        }
+        return totalWeight;
     }
 
     /**
@@ -258,30 +260,19 @@
     private static void updatePieChartWithData(
             final PieChart chart,
             final Collection<WeightedTree<?>> trees,
-            IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider) {
-
-        if (trees.isEmpty()) {
-            return;
-        }
-        // Get the total weights
-        long totalWeight = 0;
-        for (WeightedTree<?> tree : trees) {
-            totalWeight += tree.getWeight();
-        }
-        if (totalWeight == 0) {
-            // Children have no weight, return
-            return;
-        }
+            IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider, long totalWeight) {
 
         long otherWeight = 0;
         // Add to the list only the trees that would be visible (> threshold),
         // add the rest to an "other" element
+        WeightedTree<?> otherTree = null;
         List<WeightedTree<?>> list = new ArrayList<>();
         for (WeightedTree<?> tree : trees) {
             if ((float) tree.getWeight() / (float) totalWeight > MIN_PRECENTAGE_TO_SHOW_SLICE) {
                 list.add(tree);
             } else {
                 otherWeight += tree.getWeight();
+                otherTree = tree;
             }
         }
         Collections.sort(list, Collections.reverseOrder());
@@ -296,7 +287,13 @@
             i++;
         }
         if (otherWeight != 0) {
-            sliceNames[list.size()] = Messages.WeightedTreeViewer_Other;
+            // Compare with the otherTree's weight. If there's only one other,
+            // display it as is
+            if (otherTree != null && otherTree.getWeight() == otherWeight) {
+                sliceNames[list.size()] = treeProvider.toDisplayString(otherTree);
+            } else {
+                sliceNames[list.size()] = Messages.WeightedTreeViewer_Other;
+            }
             sliceValues[list.size()][0] = otherWeight;
         }
 
@@ -341,11 +338,12 @@
         return fGlobalPC;
     }
 
-    /**
-     * @return the time-range selection piechart
-     */
-    synchronized @Nullable PieChart getSecondaryPc() {
-        return fSecondaryPc;
+    private synchronized void setGlobalPC(PieChart pie) {
+        PieChart pc = fGlobalPC;
+        if (pc != null) {
+            pc.dispose();
+        }
+        fGlobalPC = pie;
     }
 
     // ------------------------------------------------------------------------
@@ -374,16 +372,4 @@
 
     }
 
-    /**
-     * An element has been selected
-     *
-     * @param collection
-     *            The selected elements
-     * @param treeProvider
-     *            The tree provider for the selected trees
-     */
-    public void secondarySelection(Collection<WeightedTree<?>> collection, IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider) {
-        updateSecondaryPieChart(collection, treeProvider);
-    }
-
 }
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreeViewer.java b/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreeViewer.java
index 37e8e9d..8726206 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreeViewer.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.ui/src/org/eclipse/tracecompass/incubator/internal/callstack/ui/views/weightedtree/WeightedTreeViewer.java
@@ -114,6 +114,9 @@
                     if (selection instanceof TmfTreeViewerEntry) {
                         Set<WeightedTree<?>> trees = new HashSet<>();
                         IWeightedTreeProvider<?, ?, WeightedTree<?>> treeProvider = null;
+                        if (selection instanceof TreeNodeEntry) {
+                            treeProvider = ((TreeNodeEntry) selection).fTreeProvider;
+                        }
                         for (ITmfTreeViewerEntry entry : ((TmfTreeViewerEntry) selection).getChildren()) {
                             // FIXME: Should we aggregate all children trees of all children elements?
                             if (!(entry instanceof TreeNodeEntry)) {