custom charts: Add formatter for the charts
authorGabriel-Andrew Pollo-Guilbert <gabrielpolloguilbert@gmail.com>
Mon, 11 Jul 2016 16:11:56 +0000 (12:11 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Fri, 12 Aug 2016 02:12:58 +0000 (22:12 -0400)
This patch adds some formatter used in the chart.
All of them comes from *.lami.* packages, but with
some modifications to work with our interfaces.

Change-Id: I57ac9edffdd39792e787ead5c15838b3888c920d
Signed-off-by: Gabriel-Andrew Pollo-Guilbert <gabrielpolloguilbert@gmail.com>
Reviewed-on: https://git.eclipse.org/r/77157
Reviewed-by: Hudson CI
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
tmf/org.eclipse.tracecompass.tmf.chart.ui/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRange.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRangeMap.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartDecimalUnitFormat.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartTimeStampFormat.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/LabelFormat.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/package-info.java [new file with mode: 0644]

index 7155d5365f17520377b0040a42fb51e3e7cb7230..a27bd601dd4f1ef4b1ec87174f7acf9c9e689862 100644 (file)
@@ -11,5 +11,9 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
  org.eclipse.jface,
- org.eclipse.tracecompass.common.core
-Export-Package: org.eclipse.tracecompass.internal.tmf.chart.ui;x-internal:=true
+ org.eclipse.tracecompass.common.core,
+ org.eclipse.tracecompass.tmf.core
+Export-Package: org.eclipse.tracecompass.internal.tmf.chart.ui;x-internal:=true,
+ org.eclipse.tracecompass.internal.tmf.chart.ui.data;x-internal:=true,
+ org.eclipse.tracecompass.internal.tmf.chart.ui.format;x-internal:=true
+Import-Package: com.google.common.collect
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRange.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRange.java
new file mode 100644 (file)
index 0000000..2c1ac0f
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Jonathan Rajotte-Julien
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.chart.ui.data;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.math.BigDecimal;
+
+/**
+ * BigDecimal based range representation
+ *
+ * @author Jonathan Rajotte-Julien
+ */
+public class ChartRange {
+
+    // ------------------------------------------------------------------------
+    // Members
+    // ------------------------------------------------------------------------
+
+    private BigDecimal fMinimum;
+    private BigDecimal fMaximum;
+    private BigDecimal fRange;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor.
+     */
+    public ChartRange() {
+        fMinimum = checkNotNull(BigDecimal.ZERO);
+        fMaximum = checkNotNull(BigDecimal.ONE);
+        fRange = checkNotNull(getMaximum().subtract(getMinimum()));
+    }
+
+    /**
+     * Constructor with minimum and maximum values supplied.
+     *
+     * @param minimum
+     *            The minimum value of the range
+     * @param maximum
+     *            The maximum value of the range
+     */
+    public ChartRange(BigDecimal minimum, BigDecimal maximum) {
+        fMinimum = minimum;
+        fMaximum = maximum;
+        fRange = checkNotNull(maximum.subtract(minimum));
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Accessor that returns the lower bound of the range.
+     *
+     * @return The minimum value of the range
+     */
+    public BigDecimal getMinimum() {
+        return fMinimum;
+    }
+
+    /**
+     * Accessor that returns the upper bound of the range.
+     *
+     * @return The maximum value of the range
+     */
+    public BigDecimal getMaximum() {
+        return fMaximum;
+    }
+
+    /**
+     * Accessor that returns the difference between the lower and the upper
+     * bounds of the range.
+     *
+     * @return The range delta
+     */
+    public BigDecimal getDelta() {
+        return fRange;
+    }
+
+    /**
+     * Method that checks if the delta is equal to zero.
+     *
+     * @return {@code true} if the delta is null, else {@code false}
+     */
+    public boolean isDeltaNull() {
+        return getDelta().compareTo(BigDecimal.ZERO) == 0;
+    }
+
+    // ------------------------------------------------------------------------
+    // Mutators
+    // ------------------------------------------------------------------------
+
+    /**
+     * Mutator that sets the minimum value of the range.
+     *
+     * @param minimum
+     *            The new minimum value
+     */
+    public void setMinimum(BigDecimal minimum) {
+        fMinimum = minimum;
+        fRange = checkNotNull(getMaximum().subtract(getMinimum()));
+    }
+
+    /**
+     * Mutator that sets the maximum value of the range.
+     *
+     * @param maximum
+     *            The new maximum value
+     */
+    public void setMaximum(BigDecimal maximum) {
+        fMaximum = maximum;
+        fRange = checkNotNull(getMaximum().subtract(getMinimum()));
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    /**
+     * This method clamps the positive minimum value of this range down to zero.
+     * It returns the current object back with the minimum value modified.
+     *
+     * @return The current range map
+     */
+    public ChartRange clamp() {
+        fMinimum = fMinimum.min(BigDecimal.ZERO);
+
+        return this;
+    }
+
+}
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRangeMap.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/data/ChartRangeMap.java
new file mode 100644 (file)
index 0000000..0878d63
--- /dev/null
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.chart.ui.data;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.math.BigDecimal;
+
+/**
+ * Simple class that maps two {@link ChartRange} together. The first one is the
+ * plotted range: it represents the range of the chart in which the data will be
+ * plotted. The second one is the input data range: it represents the range of
+ * the incoming data that will be plotted.
+ * <p>
+ * This map is used for mapping values that might be too big for a chart. Values
+ * that are in the external range are mapped to fit the internal range.
+ *
+ * @author Gabriel-Andrew Pollo-Guilbert
+ */
+public class ChartRangeMap {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    private static final int BIG_DECIMAL_DIVISION_SCALE = 22;
+
+    // ------------------------------------------------------------------------
+    // Members
+    // ------------------------------------------------------------------------
+
+    private ChartRange fPlottedRange;
+    private ChartRange fInputDataRange;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor.
+     */
+    public ChartRangeMap() {
+        fPlottedRange = new ChartRange();
+        fInputDataRange = new ChartRange();
+    }
+
+    /**
+     * Surcharged constructor with the input data range.
+     *
+     * @param input
+     *            The range of the input data
+     */
+    public ChartRangeMap(ChartRange input) {
+        fPlottedRange = new ChartRange();
+        fInputDataRange = input;
+    }
+
+    /**
+     * Surcharged constructor with the plotted and input data ranges.
+     *
+     * @param plotted
+     *            The plotted range
+     * @param input
+     *            The range of the input data
+     */
+    public ChartRangeMap(ChartRange plotted, ChartRange input) {
+        fPlottedRange = plotted;
+        fInputDataRange = input;
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Accessor that returns the plotted range of the map.
+     *
+     * @return The plotted range
+     */
+    public ChartRange getPlottedRange() {
+        return fPlottedRange;
+    }
+
+    /**
+     * Accessor that returns the input data range of the map.
+     *
+     * @return The input data range
+     */
+    public ChartRange getInputDataRange() {
+        return fInputDataRange;
+    }
+
+    // ------------------------------------------------------------------------
+    // Mutators
+    // ------------------------------------------------------------------------
+
+    /**
+     * Mutator that sets the plotted range of the map.
+     *
+     * @param plotted
+     *            The new plotted range
+     */
+    public void setPlottedRange(ChartRange plotted) {
+        fPlottedRange = plotted;
+    }
+
+    /**
+     * Mutator that sets the input data range of the map.
+     *
+     * @param input
+     *            The new input data range
+     */
+    public void setInputDataRange(ChartRange input) {
+        fInputDataRange = input;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    /**
+     * This method transforms a number from the input data range into a number
+     * that fits in the plotted range.
+     * <p>
+     * Incoming numbers from the data might be bigger than the numbers that the
+     * chart library supports (e.g. SWT supports Double and we can pass Long).
+     * While processing the numbers, a loss of precision might occur. In order
+     * to minimize this, we transform the raw values to an internal
+     * representation based on a linear transformation.
+     * <p>
+     * Let <i>e_val</i>, <i>e_min</i>, <i>e_Δ</i> be the external value,
+     * external minimum and external delta respectively and <i>i_min</i>,
+     * <i>i_Δ</i> be the internal minimum and the internal delta. The internal
+     * value <i>i_val</i> is given by the formula:
+     * <p>
+     * i_val=(e_val-e_min)*(i_Δ/e_Δ)+i_min
+     *
+     * @param number
+     *            A number to transform
+     * @return The transformed value
+     */
+    public Number getInternalValue(Number number) {
+        BigDecimal value = new BigDecimal(number.toString());
+        ChartRange internal = getPlottedRange();
+        ChartRange external = getInputDataRange();
+
+        /* Apply the formula */
+        BigDecimal internalValue = value
+                .subtract(external.getMinimum())
+                .multiply(internal.getDelta())
+                .divide(external.getDelta(), BIG_DECIMAL_DIVISION_SCALE, BigDecimal.ROUND_DOWN)
+                .add(internal.getMinimum());
+
+        return checkNotNull(internalValue);
+    }
+
+    /**
+     * Util method that transforms an plotted value back into its original
+     * range.
+     * <p>
+     * It is very similar to {@link #getInternalValue(Number)}, except that is
+     * apply the formula in reverse in order to obtain the original value while
+     * minimizing lost in precision.
+     *
+     * @param number
+     *            A number to transform
+     * @return A BigDecimal representation of the external value
+     */
+    public BigDecimal getExternalValue(Number number) {
+        ChartRange internal = getPlottedRange();
+        ChartRange external = getInputDataRange();
+
+        /* Apply the formula in reverse */
+        BigDecimal externalValue = (new BigDecimal(number.toString()))
+                .subtract(internal.getMinimum())
+                .multiply(external.getDelta())
+                .divide(internal.getDelta(), BIG_DECIMAL_DIVISION_SCALE, BigDecimal.ROUND_DOWN)
+                .add(external.getMinimum());
+
+        return checkNotNull(externalValue);
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartDecimalUnitFormat.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartDecimalUnitFormat.java
new file mode 100644 (file)
index 0000000..1f3b8bf
--- /dev/null
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Jonathan Rajotte-Julien
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.chart.ui.format;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.text.FieldPosition;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.format.DecimalUnitFormat;
+import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRange;
+import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRangeMap;
+
+/**
+ * Decimal formatter for graph
+ *
+ * Since the graph use normalized internal value the initial (external)
+ * representation needs to be obtained. Subsequent formatting is done based on a
+ * Double. Loss of precision could occurs based on the size. For now, loss of
+ * precision for decimal values is not a big concern. If it ever become one the
+ * use of Long while formatting might come in handy.
+ *
+ * @author Jonathan Rajotte-Julien
+ * @author Gabriel-Andrew Pollo-Guilbert
+ */
+public class ChartDecimalUnitFormat extends DecimalUnitFormat {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    private static final long serialVersionUID = -4288059349658845257L;
+
+    // ------------------------------------------------------------------------
+    // Members
+    // ------------------------------------------------------------------------
+
+    private @Nullable ChartRangeMap fRangeMap;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor with a range map supplied.
+     *
+     * @param map
+     *            A chart range map for mapping values
+     */
+    public ChartDecimalUnitFormat(@Nullable ChartRangeMap map) {
+        super();
+        fRangeMap = map;
+    }
+
+    /**
+     * Constructor with a multiplication factor and range map.
+     *
+     * @param factor
+     *            A multiplication factor to apply to the value
+     * @param map
+     *            A chart range map for mapping values
+     */
+    public ChartDecimalUnitFormat(double factor, @Nullable ChartRangeMap map) {
+        super(factor);
+        fRangeMap = map;
+    }
+
+    // ------------------------------------------------------------------------
+    // Mutators
+    // ------------------------------------------------------------------------
+
+    /**
+     * Mutators that sets the chart range map of this formatter.
+     *
+     * @param map
+     *            The new chart range map
+     */
+    public void setRangeMap(ChartRangeMap map) {
+        fRangeMap = map;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    public StringBuffer format(@Nullable Object obj, @Nullable StringBuffer toAppendTo, @Nullable FieldPosition pos) {
+        if (!(obj instanceof Number) || toAppendTo == null) {
+            throw new IllegalArgumentException("Cannot format given Object as a Number: " + obj); //$NON-NLS-1$
+        }
+
+        Number number = (Number) obj;
+
+        /* If no map was provided, format with the number unchanged */
+        ChartRangeMap rangeMap = fRangeMap;
+        if (rangeMap == null) {
+            StringBuffer buffer = super.format(number, toAppendTo, pos);
+            return (buffer == null ? new StringBuffer() : buffer);
+        }
+
+        ChartRange internalRange = rangeMap.getPlottedRange();
+        ChartRange externalRange = rangeMap.getInputDataRange();
+
+        /* If any range's delta is null, format with the external bounds */
+        if (internalRange.isDeltaNull() || externalRange.isDeltaNull()) {
+            StringBuffer buffer = super.format(externalRange.getMinimum().doubleValue(), toAppendTo, pos);
+            return (buffer == null ? new StringBuffer() : buffer);
+        }
+
+        /* Find external value before formatting */
+        Double externalValue = checkNotNull(fRangeMap).getExternalValue(number).doubleValue();
+        StringBuffer buffer = super.format(externalValue, toAppendTo, pos);
+        return (buffer == null ? new StringBuffer() : buffer);
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartTimeStampFormat.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/ChartTimeStampFormat.java
new file mode 100644 (file)
index 0000000..2711286
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 EfficiOS Inc. and 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.chart.ui.format;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.math.BigDecimal;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRange;
+import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRangeMap;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
+
+/**
+ * Formatter for timestamps.
+ *
+ * @author Michael Jeanson
+ * @author Gabriel-Andrew Pollo-Guilbert
+ */
+public class ChartTimeStampFormat extends Format {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    private static final long serialVersionUID = 8102026791684954897L;
+
+    // ------------------------------------------------------------------------
+    // Members
+    // ------------------------------------------------------------------------
+
+    private final TmfTimestampFormat fFormat;
+    private @Nullable ChartRangeMap fRangeMap;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor with a range map supplied.
+     *
+     * @param map
+     *            A internal and external ranges map
+     */
+    public ChartTimeStampFormat(@Nullable ChartRangeMap map) {
+        fFormat = checkNotNull(TmfTimestampFormat.getDefaulTimeFormat());
+        fRangeMap = map;
+    }
+
+    /**
+     * Constructor with a pattern and a range map supplied.
+     *
+     * @param pattern
+     *            The format pattern
+     * @param map
+     *            A chart range map for mapping values
+     */
+    public ChartTimeStampFormat(String pattern, @Nullable ChartRangeMap map) {
+        fFormat = new TmfTimestampFormat(pattern);
+        fRangeMap = map;
+    }
+
+    // ------------------------------------------------------------------------
+    // Mutators
+    // ------------------------------------------------------------------------
+
+    /**
+     * Mutators that sets the chart range map of this formatter.
+     *
+     * @param map
+     *            The new chart range map
+     */
+    public void setRangeMap(ChartRangeMap map) {
+        fRangeMap = map;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    public StringBuffer format(@Nullable Object obj, @Nullable StringBuffer toAppendTo, @Nullable FieldPosition pos) {
+        if (!(obj instanceof Number) || toAppendTo == null) {
+            throw new IllegalArgumentException("Cannot format given Object as a Number: " + obj); //$NON-NLS-1$
+        }
+
+        Number number = (Number) obj;
+
+        /* If no range was provided, format with the number unchanged */
+        ChartRangeMap rangeMap = fRangeMap;
+        if (rangeMap == null) {
+            long time = ((Number) obj).longValue();
+            return checkNotNull(toAppendTo.append(fFormat.format(time)));
+        }
+
+        ChartRange internalRange = rangeMap.getPlottedRange();
+        ChartRange externalRange = rangeMap.getInputDataRange();
+
+        /* If any range's delta is null, format with the external bounds */
+        if (internalRange.isDeltaNull() || externalRange.isDeltaNull()) {
+            return checkNotNull(toAppendTo.append(fFormat.format(externalRange.getMinimum().doubleValue())));
+        }
+
+        /* Find external value before formatting */
+        BigDecimal externalValue = checkNotNull(fRangeMap).getExternalValue(number);
+        return checkNotNull(toAppendTo.append(fFormat.format(externalValue.longValue())));
+    }
+
+    @Override
+    public @Nullable Object parseObject(@Nullable String source, @Nullable ParsePosition pos) {
+        return null;
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/LabelFormat.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/LabelFormat.java
new file mode 100644 (file)
index 0000000..f46bcb4
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.chart.ui.format;
+
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.common.collect.BiMap;
+
+/**
+ * Format label based on a given Map<String, Integer>.
+ *
+ * @author Jonathan Rajotte-Julien
+ * @author Gabriel-Andrew Pollo-Guilbert
+ */
+public class LabelFormat extends Format {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    private static final long serialVersionUID = -7046922375212377647L;
+    private static final String CHART_EMPTY_LABEL = " "; //$NON-NLS-1$
+
+    // ------------------------------------------------------------------------
+    // Members
+    // ------------------------------------------------------------------------
+
+    private final BiMap<String, Integer> fMap;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor.
+     *
+     * @param map
+     *            Map of labels and indices
+     */
+    public LabelFormat(BiMap<String, Integer> map) {
+        super();
+
+        fMap = map;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    public @Nullable StringBuffer format(@Nullable Object obj, @Nullable StringBuffer toAppendTo, @Nullable FieldPosition pos) {
+        if (obj == null || toAppendTo == null) {
+            return new StringBuffer(CHART_EMPTY_LABEL);
+        }
+
+        Double doubleObj = (Double) obj;
+
+        /* If the key is not contained in the map, format a empty label */
+        if ((doubleObj % 1 != 0) || !fMap.containsValue((doubleObj.intValue()))) {
+            return new StringBuffer(CHART_EMPTY_LABEL);
+        }
+
+        /* If the value is null in the map, format an unknown label */
+        String key = fMap.inverse().get(doubleObj.intValue());
+
+        return toAppendTo.append(key);
+    }
+
+    @Override
+    public @Nullable Object parseObject(@Nullable String source, @Nullable ParsePosition pos) {
+        return fMap.get(source);
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/package-info.java b/tmf/org.eclipse.tracecompass.tmf.chart.ui/src/org/eclipse/tracecompass/internal/tmf/chart/ui/format/package-info.java
new file mode 100644 (file)
index 0000000..faeda50
--- /dev/null
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.internal.tmf.chart.ui.format;
This page took 0.051465 seconds and 5 git commands to generate.