You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2014/11/29 11:06:01 UTC

svn commit: r1642410 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/visualizers/ src/core/org/apache/jmeter/gui/util/ src/core/org/apache/jmeter/resources/ xdocs/ xdocs/usermanual/

Author: pmouawad
Date: Sat Nov 29 10:06:00 2014
New Revision: 1642410

URL: http://svn.apache.org/r1642410
Log:
Bug 57217 - Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code)
Bugzilla Id: 57217

Modified:
    jmeter/trunk/bin/jmeter.properties
    jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java
    jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
    jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
    jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
    jmeter/trunk/xdocs/changes.xml
    jmeter/trunk/xdocs/usermanual/component_reference.xml

Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Sat Nov 29 10:06:00 2014
@@ -775,6 +775,20 @@ wmlParser.types=text/vnd.wap.wml 
 # Write messages to System.out
 #summariser.out=true
 
+
+#---------------------------------------------------------------------------
+# Aggregate Report and Aggregate Graph - configuration
+#---------------------------------------------------------------------------
+#
+# Percentiles to display in reports
+# Can be float value between 0 and 100
+# First percentile to display, defaults to 90%
+#aggregate_rpt_pct1=90
+# Second percentile to display, defaults to 95%
+#aggregate_rpt_pct2=95
+# Second percentile to display, defaults to 99%
+#aggregate_rpt_pct3=99
+
 #---------------------------------------------------------------------------
 # BeanShell configuration
 #---------------------------------------------------------------------------

Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java Sat Nov 29 10:06:00 2014
@@ -23,8 +23,6 @@ import java.awt.Color;
 
 import javax.swing.JCheckBox;
 
-import org.apache.jmeter.util.JMeterUtils;
-
 public class BarGraph {
     
     private String label;
@@ -34,13 +32,13 @@ public class BarGraph {
     private Color backColor;
 
     /**
-     * @param resString The label of this component
+     * @param label The label of this component
      * @param checked Flag whether the corresponding checkbox should be checked
      * @param backColor The color of the background
      */
-    public BarGraph(String resString, boolean checked, Color backColor) {
+    public BarGraph(String label, boolean checked, Color backColor) {
         super();
-        this.label = JMeterUtils.getResString(resString);
+        this.label = label;
         this.chkBox = new JCheckBox(this.label, checked);
         this.backColor = backColor;
     }

Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java Sat Nov 29 10:06:00 2014
@@ -28,6 +28,7 @@ import java.awt.event.ActionListener;
 import java.io.FileNotFoundException;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -65,6 +66,7 @@ import org.apache.jmeter.gui.action.Acti
 import org.apache.jmeter.gui.action.SaveGraphics;
 import org.apache.jmeter.gui.util.FileDialoger;
 import org.apache.jmeter.gui.util.FilePanel;
+import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer;
 import org.apache.jmeter.gui.util.VerticalPanel;
 import org.apache.jmeter.samplers.Clearable;
 import org.apache.jmeter.samplers.SampleResult;
@@ -92,24 +94,50 @@ import org.apache.log.Logger;
 public class StatGraphVisualizer extends AbstractVisualizer implements Clearable, ActionListener {
     private static final long serialVersionUID = 240L;
 
+    private static final String pct1Label = JMeterUtils.getPropDefault("aggregate_rpt_pct1", "90");
+    private static final String pct2Label = JMeterUtils.getPropDefault("aggregate_rpt_pct2", "95");
+    private static final String pct3Label = JMeterUtils.getPropDefault("aggregate_rpt_pct3", "99");
+    
+    private static final Float pct1Value = new Float(Float.parseFloat(pct1Label)/100);
+    private static final Float pct2Value =  new Float(Float.parseFloat(pct2Label)/100);
+    private static final Float pct3Value =  new Float(Float.parseFloat(pct3Label)/100);
+
     private static final Logger log = LoggingManager.getLoggerForClass();
 
-    private final String[] COLUMNS = { JMeterUtils.getResString("sampler_label"), //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_count"),         //$NON-NLS-1$
-            JMeterUtils.getResString("average"),                        //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_median"),        //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_90%_line"),      //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_min"),           //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_max"),           //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_error%"),        //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_rate"),          //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_bandwidth") };   //$NON-NLS-1$
-
-    private final String[] GRAPH_COLUMNS = {JMeterUtils.getResString("average"),//$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_median"),        //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_90%_line"),      //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_min"),           //$NON-NLS-1$
-            JMeterUtils.getResString("aggregate_report_max")};          //$NON-NLS-1$
+    static final String[] COLUMNS = { 
+            "sampler_label",                  //$NON-NLS-1$
+            "aggregate_report_count",         //$NON-NLS-1$
+            "average",                        //$NON-NLS-1$
+            "aggregate_report_median",        //$NON-NLS-1$
+            "aggregate_report_xx_pct1_line",      //$NON-NLS-1$
+            "aggregate_report_xx_pct2_line",      //$NON-NLS-1$
+            "aggregate_report_xx_pct3_line",      //$NON-NLS-1$
+            "aggregate_report_min",           //$NON-NLS-1$
+            "aggregate_report_max",           //$NON-NLS-1$
+            "aggregate_report_error%",        //$NON-NLS-1$
+            "aggregate_report_rate",          //$NON-NLS-1$
+            "aggregate_report_bandwidth" };   //$NON-NLS-1$
+    
+    static final Object[][] COLUMNS_MSG_PARAMETERS = { null, //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            new Object[]{pct1Label},                      //$NON-NLS-1$
+            new Object[]{pct2Label},                      //$NON-NLS-1$
+            new Object[]{pct3Label},                      //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null,                             //$NON-NLS-1$
+            null };                           //$NON-NLS-1$
+
+    private final String[] GRAPH_COLUMNS = {"average",//$NON-NLS-1$
+            "aggregate_report_median",        //$NON-NLS-1$
+            "aggregate_report_xx_pct1_line",      //$NON-NLS-1$
+            "aggregate_report_xx_pct2_line",      //$NON-NLS-1$
+            "aggregate_report_xx_pct3_line",      //$NON-NLS-1$
+            "aggregate_report_min",           //$NON-NLS-1$
+            "aggregate_report_max"};          //$NON-NLS-1$
 
     private final String TOTAL_ROW_LABEL =
         JMeterUtils.getResString("aggregate_report_total_label");       //$NON-NLS-1$
@@ -239,7 +267,24 @@ public class StatGraphVisualizer extends
 
     public StatGraphVisualizer() {
         super();
-        model = new ObjectTableModel(COLUMNS,
+        model = createObjectTableModel();
+        eltList.add(new BarGraph(JMeterUtils.getResString("average"), true, new Color(202, 0, 0)));
+        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_median"), false, new Color(49, 49, 181)));
+        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct1_line"),new Object[]{pct1Label}), false, new Color(42, 121, 42)));
+        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct2_line"),new Object[]{pct2Label}), false, new Color(242, 226, 8)));
+        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct3_line"),new Object[]{pct3Label}), false, new Color(202, 10 , 232)));
+        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_min"), false, Color.LIGHT_GRAY));
+        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_max"), false, Color.DARK_GRAY));
+        clearData();
+        init();
+    }
+
+    /**
+     * Creates that Table model 
+     * @return ObjectTableModel
+     */
+    static ObjectTableModel createObjectTableModel() {
+        return new ObjectTableModel(COLUMNS,
                 SamplingStatCalculator.class,
                 new Functor[] {
                 new Functor("getLabel"),                    //$NON-NLS-1$
@@ -247,37 +292,37 @@ public class StatGraphVisualizer extends
                 new Functor("getMeanAsNumber"),                //$NON-NLS-1$
                 new Functor("getMedian"),                    //$NON-NLS-1$
                 new Functor("getPercentPoint",                //$NON-NLS-1$
-                new Object[] { new Float(.900) }),
+                        new Object[] { pct1Value }),
+                new Functor("getPercentPoint",                //$NON-NLS-1$
+                        new Object[] { pct2Value }),
+                new Functor("getPercentPoint",                //$NON-NLS-1$
+                        new Object[] { pct3Value }),
                 new Functor("getMin"),                        //$NON-NLS-1$
                 new Functor("getMax"),                         //$NON-NLS-1$
                 new Functor("getErrorPercentage"),            //$NON-NLS-1$
                 new Functor("getRate"),                        //$NON-NLS-1$
                 new Functor("getKBPerSecond") },            //$NON-NLS-1$
-                new Functor[] { null, null, null, null, null, null, null, null,    null, null },
-                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class, Long.class,
-                Long.class, String.class, String.class, String.class });
-        eltList.add(new BarGraph("average", true, new Color(202, 0, 0)));
-        eltList.add(new BarGraph("aggregate_report_median", false, new Color(49, 49, 181)));
-        eltList.add(new BarGraph("aggregate_report_90%_line", false, new Color(42, 121, 42)));
-        eltList.add(new BarGraph("aggregate_report_min", false, Color.LIGHT_GRAY));
-        eltList.add(new BarGraph("aggregate_report_max", false, Color.DARK_GRAY));
-        clearData();
-        init();
+                new Functor[] { null, null, null, null, null, null, null, null, null, null, null, null },
+                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class, 
+                            Long.class, Long.class, Long.class, Long.class, String.class, 
+                            String.class, String.class });
     }
 
     // Column renderers
-    private static final TableCellRenderer[] RENDERERS =
+    static final TableCellRenderer[] RENDERERS =
         new TableCellRenderer[]{
             null, // Label
             null, // count
             null, // Mean
             null, // median
             null, // 90%
+            null, // 95%
+            null, // 99%
             null, // Min
             null, // Max
-            new NumberRenderer("#0.00%"), // Error %age
-            new RateRenderer("#.0"),      // Throughpur
-            new NumberRenderer("#.0"),    // pageSize
+            new NumberRenderer("#0.00%"), // Error %age //$NON-NLS-1$
+            new RateRenderer("#.0"),      // Throughput //$NON-NLS-1$
+            new NumberRenderer("#.0"),    // pageSize   //$NON-NLS-1$
         };
 
     public static boolean testFunctors(){
@@ -347,7 +392,9 @@ public class StatGraphVisualizer extends
         mainPanel.add(makeTitlePanel());
 
         myJTable = new JTable(model);
-        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 80));
+        // Fix centering of titles
+        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer(COLUMNS_MSG_PARAMETERS));
+        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
         RendererUtils.applyRenderers(myJTable, RENDERERS);
         myScrollPane = new JScrollPane(myJTable);
 
@@ -424,7 +471,7 @@ public class StatGraphVisualizer extends
         graphPanel.setMaxLength(maxLength);
         graphPanel.setMaxYAxisScale(maxYAxisScale);
         graphPanel.setXAxisLabels(getAxisLabels());
-        graphPanel.setXAxisTitle((String) columnsList.getSelectedItem());
+        graphPanel.setXAxisTitle(JMeterUtils.getResString((String) columnsList.getSelectedItem()));
         graphPanel.setYAxisLabels(this.yAxisLabel);
         graphPanel.setYAxisTitle(this.yAxisTitle);
         graphPanel.setLegendLabels(getLegendLabels());

Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java Sat Nov 29 10:06:00 2014
@@ -37,7 +37,6 @@ import javax.swing.JScrollPane;
 import javax.swing.JTable;
 import javax.swing.border.Border;
 import javax.swing.border.EmptyBorder;
-import javax.swing.table.TableCellRenderer;
 
 import org.apache.jmeter.gui.util.FileDialoger;
 import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer;
@@ -47,11 +46,8 @@ import org.apache.jmeter.save.CSVSaveSer
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
-import org.apache.jorphan.gui.NumberRenderer;
 import org.apache.jorphan.gui.ObjectTableModel;
-import org.apache.jorphan.gui.RateRenderer;
 import org.apache.jorphan.gui.RendererUtils;
-import org.apache.jorphan.reflect.Functor;
 import org.apache.jorphan.util.JOrphanUtils;
 
 /**
@@ -69,18 +65,6 @@ public class StatVisualizer extends Abst
 
     private static final String SAVE_HEADERS   = "saveHeaders"; //$NON-NLS-1$
 
-    private static final String[] COLUMNS = {
-            "sampler_label",                 //$NON-NLS-1$
-            "aggregate_report_count",        //$NON-NLS-1$
-            "average",                       //$NON-NLS-1$
-            "aggregate_report_median",       //$NON-NLS-1$
-            "aggregate_report_90%_line",     //$NON-NLS-1$
-            "aggregate_report_min",          //$NON-NLS-1$
-            "aggregate_report_max",          //$NON-NLS-1$
-            "aggregate_report_error%",       //$NON-NLS-1$
-            "aggregate_report_rate",         //$NON-NLS-1$
-            "aggregate_report_bandwidth" };  //$NON-NLS-1$
-
     private final String TOTAL_ROW_LABEL
         = JMeterUtils.getResString("aggregate_report_total_label");  //$NON-NLS-1$
 
@@ -109,43 +93,11 @@ public class StatVisualizer extends Abst
 
     public StatVisualizer() {
         super();
-        model = new ObjectTableModel(COLUMNS,
-                SamplingStatCalculator.class,
-                new Functor[] {
-                    new Functor("getLabel"),   //$NON-NLS-1$
-                    new Functor("getCount"),  //$NON-NLS-1$
-                    new Functor("getMeanAsNumber"),   //$NON-NLS-1$
-                    new Functor("getMedian"),  //$NON-NLS-1$
-                    new Functor("getPercentPoint",  //$NON-NLS-1$
-                            new Object[] { new Float(.900) }),
-                    new Functor("getMin"),  //$NON-NLS-1$
-                    new Functor("getMax"),   //$NON-NLS-1$
-                    new Functor("getErrorPercentage"),   //$NON-NLS-1$
-                    new Functor("getRate"),  //$NON-NLS-1$
-                    new Functor("getKBPerSecond")   //$NON-NLS-1$
-                },
-                new Functor[] { null, null, null, null, null, null, null, null, null, null },
-                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class,
-                              Long.class, Long.class, String.class, String.class, String.class });
+        model = StatGraphVisualizer.createObjectTableModel();
         clearData();
         init();
     }
 
-    // Column renderers
-    private static final TableCellRenderer[] RENDERERS =
-        new TableCellRenderer[]{
-            null, // Label
-            null, // count
-            null, // Mean
-            null, // median
-            null, // 90%
-            null, // Min
-            null, // Max
-            new NumberRenderer("#0.00%"), // Error %age //$NON-NLS-1$
-            new RateRenderer("#.0"),      // Throughput //$NON-NLS-1$
-            new NumberRenderer("#.0"),    // pageSize   //$NON-NLS-1$
-        };
-
     /** @deprecated - only for use in testing */
     @Deprecated
     public static boolean testFunctors(){
@@ -219,9 +171,9 @@ public class StatVisualizer extends Abst
         // SortFilterModel mySortedModel =
         // new SortFilterModel(myStatTableModel);
         myJTable = new JTable(model);
-        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer());
+        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer(StatGraphVisualizer.COLUMNS_MSG_PARAMETERS));
         myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
-        RendererUtils.applyRenderers(myJTable, RENDERERS);
+        RendererUtils.applyRenderers(myJTable, StatGraphVisualizer.RENDERERS);
         myScrollPane = new JScrollPane(myJTable);
         this.add(mainPanel, BorderLayout.NORTH);
         this.add(myScrollPane, BorderLayout.CENTER);

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java Sat Nov 29 10:06:00 2014
@@ -19,6 +19,7 @@
 package org.apache.jmeter.gui.util;
 
 import java.awt.Component;
+import java.text.MessageFormat;
 
 import javax.swing.JTable;
 import javax.swing.SwingConstants;
@@ -34,9 +35,21 @@ import org.apache.jmeter.util.JMeterUtil
 public class HeaderAsPropertyRenderer extends DefaultTableCellRenderer {
 
     private static final long serialVersionUID = 240L;
+    private Object[][] columnsMsgParameters;
 
+    /**
+     * 
+     */
     public HeaderAsPropertyRenderer() {
+        this(null);
+    }
+    
+    /**
+     * @param columnsMsgParameters Optional parameters of i18n keys
+     */
+    public HeaderAsPropertyRenderer(Object[][] columnsMsgParameters) {
         super();
+        this.columnsMsgParameters = columnsMsgParameters;
     }
 
     @Override
@@ -68,6 +81,10 @@ public class HeaderAsPropertyRenderer ex
         if (value == null){
             return "";
         }
-        return JMeterUtils.getResString(value.toString());
+        if(columnsMsgParameters != null && columnsMsgParameters[column] != null) {
+            return MessageFormat.format(JMeterUtils.getResString(value.toString()), columnsMsgParameters[column]);
+        } else {
+            return JMeterUtils.getResString(value.toString());
+        }
     }
 }

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sat Nov 29 10:06:00 2014
@@ -77,8 +77,10 @@ aggregate_graph_xaxis_group=X Axis
 aggregate_graph_yaxis_group=Y Axis (milli-seconds)
 aggregate_graph_yaxis_max_value=Scale maximum value\:
 aggregate_report=Aggregate Report
+aggregate_report_xx_pct1_line={0}% Line
+aggregate_report_xx_pct2_line={0}% Line
+aggregate_report_xx_pct3_line={0}% Line
 aggregate_report_90=90%
-aggregate_report_90%_line=90% Line
 aggregate_report_bandwidth=KB/sec
 aggregate_report_count=# Samples
 aggregate_report_error=Error

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Sat Nov 29 10:06:00 2014
@@ -71,8 +71,10 @@ aggregate_graph_xaxis_group=Abscisses
 aggregate_graph_yaxis_group=Ordonn\u00E9es (milli-secondes)
 aggregate_graph_yaxis_max_value=Echelle maximum \:
 aggregate_report=Rapport agr\u00E9g\u00E9
+aggregate_report_xx_pct1_line={0}% centile
+aggregate_report_xx_pct2_line={0}% centile
+aggregate_report_xx_pct3_line={0}% centile
 aggregate_report_90=90%
-aggregate_report_90%_line=90e centile
 aggregate_report_bandwidth=Ko/sec
 aggregate_report_count=\# Echantillons
 aggregate_report_error=Erreur

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Sat Nov 29 10:06:00 2014
@@ -190,6 +190,7 @@ See  <bugzilla>56357</bugzilla> for deta
 <ul>
 <li><bugzilla>55932</bugzilla> - Create a Async BackendListener to allow easy plug of new listener (Graphite, JDBC, Console,...)</li>
 <li><bugzilla>57246</bugzilla> - BackendListener : Create a Graphite implementation</li>
+<li><bugzilla>57217</bugzilla> - Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code). Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
 </ul>
 
 <h3>Timers, Assertions, Config, Pre- &amp; Post-Processors</h3>
@@ -223,6 +224,7 @@ See  <bugzilla>56357</bugzilla> for deta
 We also thank bug reporters who helped us improve JMeter. <br/>
 For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes:
 <ul>
+<li><a href="http://ubikloadpack.com">Ubik Load Pack</a></li>
 </ul>
 
 Apologies if we have omitted anyone else.

Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1642410&r1=1642409&r2=1642410&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/component_reference.xml Sat Nov 29 10:06:00 2014
@@ -2905,7 +2905,7 @@ compiled code must be available to JMete
 </p>
 </component>
 
-<component name="Aggregate Report" index="&sect-num;.3.7"  width="784" height="287" screenshot="aggregate_report.png">
+<component name="Aggregate Report" index="&sect-num;.3.7"  width="1140" height="266" screenshot="aggregate_report.png">
 <description>The aggregate report creates a table row for each differently named request in your
 test.  For each request, it totals the response information and provides request count, min, max,
 average, error rate, approximate throughput (request/second) and Kilobytes per second throughput.
@@ -2922,12 +2922,20 @@ the Aggregate Report.
 </p>
 <p>
 Calculation of the <a href="glossary.html#Median">Median</a> and 90% Line (90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>) values requires additional memory.
-For JMeter 2.3.4 and earlier, details of each sample were saved separately, which meant a lot of memory was needed.
 JMeter now combines samples with the same elapsed time, so far less memory is used.
 However, for samples that take more than a few seconds, the probability is that fewer samples will have identical times,
 in which case more memory will be needed.
+Note you can use this listener afterwards to reload a CSV or XML results file which is the recommended way to avoid performance impacts.
 See the <complink name="Summary Report"/> for a similar Listener that does not store individual samples and so needs constant memory.
 </p>
+<note>
+Starting with JMeter 2.12, you can configure the 3 percentile values you want to compute, this can be done by setting properties:
+<ul>
+    <li>aggregate_rpt_pct1: defaults to 90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
+    <li>aggregate_rpt_pct2: defaults to 95<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
+    <li>aggregate_rpt_pct3: defaults to 99<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
+</ul>
+</note>
 <ul>
 <li>Label - The label of the sample.
 If "Include group name in label?" is selected, then the name of the thread group is added as a prefix.
@@ -2939,6 +2947,10 @@ This allows identical labels from differ
 50% of the samples took no more than this time; the remainder took at least as long.</li>
 <li>90% Line - 90% of the samples took no more than this time.
 The remaining samples took at least as long as this. (90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
+<li>95% Line - 95% of the samples took no more than this time.
+The remaining samples took at least as long as this. (95<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
+<li>99% Line - 99% of the samples took no more than this time.
+The remaining samples took at least as long as this. (99<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
 <li>Min - The shortest time for the samples with the same label</li>
 <li>Max - The longest time for the samples with the same label</li>
 <li>Error % - Percent of requests with errors</li>
@@ -2954,7 +2966,7 @@ i.e. 30.0 requests/minute is saved as 0.
 <div align="center">
 <p>
     The figure below shows an example of selecting the "Include group name" checkbox.
-<figure width="784" height="287" image="aggregate_report_grouped.png">Sample "Include group name" display</figure>
+<figure width="1140" height="276" image="aggregate_report_grouped.png">Sample "Include group name" display</figure>
 </p>
 </div>
 </component>
@@ -3034,7 +3046,7 @@ know for sure is to use a profiling tool
 </description>
 </component>
 
-<component name="Aggregate Graph" index="&sect-num;.3.12"  width="893" height="713" screenshot="aggregate_graph.png">
+<component name="Aggregate Graph" index="&sect-num;.3.12"  width="1132" height="872" screenshot="aggregate_graph.png">
 <description>The aggregate graph is similar to the aggregate report. The primary
 difference is the aggregate graph provides an easy way to generate bar graphs and save
 the graph as a PNG file.</description>



Re: svn commit: r1642410 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/visualizers/ src/core/org/apache/jmeter/gui/util/ src/core/org/apache/jmeter/resources/ xdocs/ xdocs/usermanual/

Posted by sebb <se...@gmail.com>.
On 29 November 2014 at 10:06,  <pm...@apache.org> wrote:
> Author: pmouawad
> Date: Sat Nov 29 10:06:00 2014
> New Revision: 1642410
>
> URL: http://svn.apache.org/r1642410
> Log:
> Bug 57217 - Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code)
> Bugzilla Id: 57217
>
> Modified:
>     jmeter/trunk/bin/jmeter.properties
>     jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java
>     jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
>     jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
>     jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java
>     jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>     jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>     jmeter/trunk/xdocs/changes.xml
>     jmeter/trunk/xdocs/usermanual/component_reference.xml
>
> Modified: jmeter/trunk/bin/jmeter.properties
> URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/bin/jmeter.properties (original)
> +++ jmeter/trunk/bin/jmeter.properties Sat Nov 29 10:06:00 2014
> @@ -775,6 +775,20 @@ wmlParser.types=text/vnd.wap.wml
>  # Write messages to System.out
>  #summariser.out=true
>
> +
> +#---------------------------------------------------------------------------
> +# Aggregate Report and Aggregate Graph - configuration
> +#---------------------------------------------------------------------------
> +#
> +# Percentiles to display in reports
> +# Can be float value between 0 and 100
> +# First percentile to display, defaults to 90%
> +#aggregate_rpt_pct1=90
> +# Second percentile to display, defaults to 95%
> +#aggregate_rpt_pct2=95
> +# Second percentile to display, defaults to 99%
> +#aggregate_rpt_pct3=99
> +

OK as it stands, but it would be better to allow for multiple entries.
e.g. rather than

aggregate_rpt_pct1|2|3

one could have

aggregate_rpt_pcts=90,95,99,...

This would require the GUI arrays to be dynamically created, but that
is not particularly difficult.


>  #---------------------------------------------------------------------------
>  # BeanShell configuration
>  #---------------------------------------------------------------------------
>
> Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java (original)
> +++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/BarGraph.java Sat Nov 29 10:06:00 2014
> @@ -23,8 +23,6 @@ import java.awt.Color;
>
>  import javax.swing.JCheckBox;
>
> -import org.apache.jmeter.util.JMeterUtils;
> -
>  public class BarGraph {
>
>      private String label;
> @@ -34,13 +32,13 @@ public class BarGraph {
>      private Color backColor;
>
>      /**
> -     * @param resString The label of this component
> +     * @param label The label of this component
>       * @param checked Flag whether the corresponding checkbox should be checked
>       * @param backColor The color of the background
>       */
> -    public BarGraph(String resString, boolean checked, Color backColor) {
> +    public BarGraph(String label, boolean checked, Color backColor) {
>          super();
> -        this.label = JMeterUtils.getResString(resString);
> +        this.label = label;
>          this.chkBox = new JCheckBox(this.label, checked);
>          this.backColor = backColor;
>      }
>
> Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java (original)
> +++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java Sat Nov 29 10:06:00 2014
> @@ -28,6 +28,7 @@ import java.awt.event.ActionListener;
>  import java.io.FileNotFoundException;
>  import java.io.FileWriter;
>  import java.io.IOException;
> +import java.text.MessageFormat;
>  import java.util.ArrayList;
>  import java.util.List;
>  import java.util.Map;
> @@ -65,6 +66,7 @@ import org.apache.jmeter.gui.action.Acti
>  import org.apache.jmeter.gui.action.SaveGraphics;
>  import org.apache.jmeter.gui.util.FileDialoger;
>  import org.apache.jmeter.gui.util.FilePanel;
> +import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer;
>  import org.apache.jmeter.gui.util.VerticalPanel;
>  import org.apache.jmeter.samplers.Clearable;
>  import org.apache.jmeter.samplers.SampleResult;
> @@ -92,24 +94,50 @@ import org.apache.log.Logger;
>  public class StatGraphVisualizer extends AbstractVisualizer implements Clearable, ActionListener {
>      private static final long serialVersionUID = 240L;
>
> +    private static final String pct1Label = JMeterUtils.getPropDefault("aggregate_rpt_pct1", "90");
> +    private static final String pct2Label = JMeterUtils.getPropDefault("aggregate_rpt_pct2", "95");
> +    private static final String pct3Label = JMeterUtils.getPropDefault("aggregate_rpt_pct3", "99");
> +
> +    private static final Float pct1Value = new Float(Float.parseFloat(pct1Label)/100);
> +    private static final Float pct2Value =  new Float(Float.parseFloat(pct2Label)/100);
> +    private static final Float pct3Value =  new Float(Float.parseFloat(pct3Label)/100);
> +
>      private static final Logger log = LoggingManager.getLoggerForClass();
>
> -    private final String[] COLUMNS = { JMeterUtils.getResString("sampler_label"), //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_count"),         //$NON-NLS-1$
> -            JMeterUtils.getResString("average"),                        //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_median"),        //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_90%_line"),      //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_min"),           //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_max"),           //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_error%"),        //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_rate"),          //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_bandwidth") };   //$NON-NLS-1$
> -
> -    private final String[] GRAPH_COLUMNS = {JMeterUtils.getResString("average"),//$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_median"),        //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_90%_line"),      //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_min"),           //$NON-NLS-1$
> -            JMeterUtils.getResString("aggregate_report_max")};          //$NON-NLS-1$
> +    static final String[] COLUMNS = {
> +            "sampler_label",                  //$NON-NLS-1$
> +            "aggregate_report_count",         //$NON-NLS-1$
> +            "average",                        //$NON-NLS-1$
> +            "aggregate_report_median",        //$NON-NLS-1$
> +            "aggregate_report_xx_pct1_line",      //$NON-NLS-1$
> +            "aggregate_report_xx_pct2_line",      //$NON-NLS-1$
> +            "aggregate_report_xx_pct3_line",      //$NON-NLS-1$
> +            "aggregate_report_min",           //$NON-NLS-1$
> +            "aggregate_report_max",           //$NON-NLS-1$
> +            "aggregate_report_error%",        //$NON-NLS-1$
> +            "aggregate_report_rate",          //$NON-NLS-1$
> +            "aggregate_report_bandwidth" };   //$NON-NLS-1$
> +
> +    static final Object[][] COLUMNS_MSG_PARAMETERS = { null, //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            new Object[]{pct1Label},                      //$NON-NLS-1$
> +            new Object[]{pct2Label},                      //$NON-NLS-1$
> +            new Object[]{pct3Label},                      //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null,                             //$NON-NLS-1$
> +            null };                           //$NON-NLS-1$
> +
> +    private final String[] GRAPH_COLUMNS = {"average",//$NON-NLS-1$
> +            "aggregate_report_median",        //$NON-NLS-1$
> +            "aggregate_report_xx_pct1_line",      //$NON-NLS-1$
> +            "aggregate_report_xx_pct2_line",      //$NON-NLS-1$
> +            "aggregate_report_xx_pct3_line",      //$NON-NLS-1$
> +            "aggregate_report_min",           //$NON-NLS-1$
> +            "aggregate_report_max"};          //$NON-NLS-1$
>
>      private final String TOTAL_ROW_LABEL =
>          JMeterUtils.getResString("aggregate_report_total_label");       //$NON-NLS-1$
> @@ -239,7 +267,24 @@ public class StatGraphVisualizer extends
>
>      public StatGraphVisualizer() {
>          super();
> -        model = new ObjectTableModel(COLUMNS,
> +        model = createObjectTableModel();
> +        eltList.add(new BarGraph(JMeterUtils.getResString("average"), true, new Color(202, 0, 0)));
> +        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_median"), false, new Color(49, 49, 181)));
> +        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct1_line"),new Object[]{pct1Label}), false, new Color(42, 121, 42)));
> +        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct2_line"),new Object[]{pct2Label}), false, new Color(242, 226, 8)));
> +        eltList.add(new BarGraph(MessageFormat.format(JMeterUtils.getResString("aggregate_report_xx_pct3_line"),new Object[]{pct3Label}), false, new Color(202, 10 , 232)));
> +        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_min"), false, Color.LIGHT_GRAY));
> +        eltList.add(new BarGraph(JMeterUtils.getResString("aggregate_report_max"), false, Color.DARK_GRAY));
> +        clearData();
> +        init();
> +    }
> +
> +    /**
> +     * Creates that Table model
> +     * @return ObjectTableModel
> +     */
> +    static ObjectTableModel createObjectTableModel() {
> +        return new ObjectTableModel(COLUMNS,
>                  SamplingStatCalculator.class,
>                  new Functor[] {
>                  new Functor("getLabel"),                    //$NON-NLS-1$
> @@ -247,37 +292,37 @@ public class StatGraphVisualizer extends
>                  new Functor("getMeanAsNumber"),                //$NON-NLS-1$
>                  new Functor("getMedian"),                    //$NON-NLS-1$
>                  new Functor("getPercentPoint",                //$NON-NLS-1$
> -                new Object[] { new Float(.900) }),
> +                        new Object[] { pct1Value }),
> +                new Functor("getPercentPoint",                //$NON-NLS-1$
> +                        new Object[] { pct2Value }),
> +                new Functor("getPercentPoint",                //$NON-NLS-1$
> +                        new Object[] { pct3Value }),
>                  new Functor("getMin"),                        //$NON-NLS-1$
>                  new Functor("getMax"),                         //$NON-NLS-1$
>                  new Functor("getErrorPercentage"),            //$NON-NLS-1$
>                  new Functor("getRate"),                        //$NON-NLS-1$
>                  new Functor("getKBPerSecond") },            //$NON-NLS-1$
> -                new Functor[] { null, null, null, null, null, null, null, null,    null, null },
> -                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class, Long.class,
> -                Long.class, String.class, String.class, String.class });
> -        eltList.add(new BarGraph("average", true, new Color(202, 0, 0)));
> -        eltList.add(new BarGraph("aggregate_report_median", false, new Color(49, 49, 181)));
> -        eltList.add(new BarGraph("aggregate_report_90%_line", false, new Color(42, 121, 42)));
> -        eltList.add(new BarGraph("aggregate_report_min", false, Color.LIGHT_GRAY));
> -        eltList.add(new BarGraph("aggregate_report_max", false, Color.DARK_GRAY));
> -        clearData();
> -        init();
> +                new Functor[] { null, null, null, null, null, null, null, null, null, null, null, null },
> +                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class,
> +                            Long.class, Long.class, Long.class, Long.class, String.class,
> +                            String.class, String.class });
>      }
>
>      // Column renderers
> -    private static final TableCellRenderer[] RENDERERS =
> +    static final TableCellRenderer[] RENDERERS =
>          new TableCellRenderer[]{
>              null, // Label
>              null, // count
>              null, // Mean
>              null, // median
>              null, // 90%
> +            null, // 95%
> +            null, // 99%
>              null, // Min
>              null, // Max
> -            new NumberRenderer("#0.00%"), // Error %age
> -            new RateRenderer("#.0"),      // Throughpur
> -            new NumberRenderer("#.0"),    // pageSize
> +            new NumberRenderer("#0.00%"), // Error %age //$NON-NLS-1$
> +            new RateRenderer("#.0"),      // Throughput //$NON-NLS-1$
> +            new NumberRenderer("#.0"),    // pageSize   //$NON-NLS-1$
>          };
>
>      public static boolean testFunctors(){
> @@ -347,7 +392,9 @@ public class StatGraphVisualizer extends
>          mainPanel.add(makeTitlePanel());
>
>          myJTable = new JTable(model);
> -        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 80));
> +        // Fix centering of titles
> +        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer(COLUMNS_MSG_PARAMETERS));
> +        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
>          RendererUtils.applyRenderers(myJTable, RENDERERS);
>          myScrollPane = new JScrollPane(myJTable);
>
> @@ -424,7 +471,7 @@ public class StatGraphVisualizer extends
>          graphPanel.setMaxLength(maxLength);
>          graphPanel.setMaxYAxisScale(maxYAxisScale);
>          graphPanel.setXAxisLabels(getAxisLabels());
> -        graphPanel.setXAxisTitle((String) columnsList.getSelectedItem());
> +        graphPanel.setXAxisTitle(JMeterUtils.getResString((String) columnsList.getSelectedItem()));
>          graphPanel.setYAxisLabels(this.yAxisLabel);
>          graphPanel.setYAxisTitle(this.yAxisTitle);
>          graphPanel.setLegendLabels(getLegendLabels());
>
> Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java (original)
> +++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java Sat Nov 29 10:06:00 2014
> @@ -37,7 +37,6 @@ import javax.swing.JScrollPane;
>  import javax.swing.JTable;
>  import javax.swing.border.Border;
>  import javax.swing.border.EmptyBorder;
> -import javax.swing.table.TableCellRenderer;
>
>  import org.apache.jmeter.gui.util.FileDialoger;
>  import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer;
> @@ -47,11 +46,8 @@ import org.apache.jmeter.save.CSVSaveSer
>  import org.apache.jmeter.testelement.TestElement;
>  import org.apache.jmeter.util.JMeterUtils;
>  import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
> -import org.apache.jorphan.gui.NumberRenderer;
>  import org.apache.jorphan.gui.ObjectTableModel;
> -import org.apache.jorphan.gui.RateRenderer;
>  import org.apache.jorphan.gui.RendererUtils;
> -import org.apache.jorphan.reflect.Functor;
>  import org.apache.jorphan.util.JOrphanUtils;
>
>  /**
> @@ -69,18 +65,6 @@ public class StatVisualizer extends Abst
>
>      private static final String SAVE_HEADERS   = "saveHeaders"; //$NON-NLS-1$
>
> -    private static final String[] COLUMNS = {
> -            "sampler_label",                 //$NON-NLS-1$
> -            "aggregate_report_count",        //$NON-NLS-1$
> -            "average",                       //$NON-NLS-1$
> -            "aggregate_report_median",       //$NON-NLS-1$
> -            "aggregate_report_90%_line",     //$NON-NLS-1$
> -            "aggregate_report_min",          //$NON-NLS-1$
> -            "aggregate_report_max",          //$NON-NLS-1$
> -            "aggregate_report_error%",       //$NON-NLS-1$
> -            "aggregate_report_rate",         //$NON-NLS-1$
> -            "aggregate_report_bandwidth" };  //$NON-NLS-1$
> -
>      private final String TOTAL_ROW_LABEL
>          = JMeterUtils.getResString("aggregate_report_total_label");  //$NON-NLS-1$
>
> @@ -109,43 +93,11 @@ public class StatVisualizer extends Abst
>
>      public StatVisualizer() {
>          super();
> -        model = new ObjectTableModel(COLUMNS,
> -                SamplingStatCalculator.class,
> -                new Functor[] {
> -                    new Functor("getLabel"),   //$NON-NLS-1$
> -                    new Functor("getCount"),  //$NON-NLS-1$
> -                    new Functor("getMeanAsNumber"),   //$NON-NLS-1$
> -                    new Functor("getMedian"),  //$NON-NLS-1$
> -                    new Functor("getPercentPoint",  //$NON-NLS-1$
> -                            new Object[] { new Float(.900) }),
> -                    new Functor("getMin"),  //$NON-NLS-1$
> -                    new Functor("getMax"),   //$NON-NLS-1$
> -                    new Functor("getErrorPercentage"),   //$NON-NLS-1$
> -                    new Functor("getRate"),  //$NON-NLS-1$
> -                    new Functor("getKBPerSecond")   //$NON-NLS-1$
> -                },
> -                new Functor[] { null, null, null, null, null, null, null, null, null, null },
> -                new Class[] { String.class, Long.class, Long.class, Long.class, Long.class,
> -                              Long.class, Long.class, String.class, String.class, String.class });
> +        model = StatGraphVisualizer.createObjectTableModel();
>          clearData();
>          init();
>      }
>
> -    // Column renderers
> -    private static final TableCellRenderer[] RENDERERS =
> -        new TableCellRenderer[]{
> -            null, // Label
> -            null, // count
> -            null, // Mean
> -            null, // median
> -            null, // 90%
> -            null, // Min
> -            null, // Max
> -            new NumberRenderer("#0.00%"), // Error %age //$NON-NLS-1$
> -            new RateRenderer("#.0"),      // Throughput //$NON-NLS-1$
> -            new NumberRenderer("#.0"),    // pageSize   //$NON-NLS-1$
> -        };
> -
>      /** @deprecated - only for use in testing */
>      @Deprecated
>      public static boolean testFunctors(){
> @@ -219,9 +171,9 @@ public class StatVisualizer extends Abst
>          // SortFilterModel mySortedModel =
>          // new SortFilterModel(myStatTableModel);
>          myJTable = new JTable(model);
> -        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer());
> +        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer(StatGraphVisualizer.COLUMNS_MSG_PARAMETERS));
>          myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
> -        RendererUtils.applyRenderers(myJTable, RENDERERS);
> +        RendererUtils.applyRenderers(myJTable, StatGraphVisualizer.RENDERERS);
>          myScrollPane = new JScrollPane(myJTable);
>          this.add(mainPanel, BorderLayout.NORTH);
>          this.add(myScrollPane, BorderLayout.CENTER);
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/gui/util/HeaderAsPropertyRenderer.java Sat Nov 29 10:06:00 2014
> @@ -19,6 +19,7 @@
>  package org.apache.jmeter.gui.util;
>
>  import java.awt.Component;
> +import java.text.MessageFormat;
>
>  import javax.swing.JTable;
>  import javax.swing.SwingConstants;
> @@ -34,9 +35,21 @@ import org.apache.jmeter.util.JMeterUtil
>  public class HeaderAsPropertyRenderer extends DefaultTableCellRenderer {
>
>      private static final long serialVersionUID = 240L;
> +    private Object[][] columnsMsgParameters;
>
> +    /**
> +     *
> +     */
>      public HeaderAsPropertyRenderer() {
> +        this(null);
> +    }
> +
> +    /**
> +     * @param columnsMsgParameters Optional parameters of i18n keys
> +     */
> +    public HeaderAsPropertyRenderer(Object[][] columnsMsgParameters) {
>          super();
> +        this.columnsMsgParameters = columnsMsgParameters;
>      }
>
>      @Override
> @@ -68,6 +81,10 @@ public class HeaderAsPropertyRenderer ex
>          if (value == null){
>              return "";
>          }
> -        return JMeterUtils.getResString(value.toString());
> +        if(columnsMsgParameters != null && columnsMsgParameters[column] != null) {
> +            return MessageFormat.format(JMeterUtils.getResString(value.toString()), columnsMsgParameters[column]);
> +        } else {
> +            return JMeterUtils.getResString(value.toString());
> +        }
>      }
>  }
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sat Nov 29 10:06:00 2014
> @@ -77,8 +77,10 @@ aggregate_graph_xaxis_group=X Axis
>  aggregate_graph_yaxis_group=Y Axis (milli-seconds)
>  aggregate_graph_yaxis_max_value=Scale maximum value\:
>  aggregate_report=Aggregate Report
> +aggregate_report_xx_pct1_line={0}% Line
> +aggregate_report_xx_pct2_line={0}% Line
> +aggregate_report_xx_pct3_line={0}% Line
>  aggregate_report_90=90%
> -aggregate_report_90%_line=90% Line
>  aggregate_report_bandwidth=KB/sec
>  aggregate_report_count=# Samples
>  aggregate_report_error=Error
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Sat Nov 29 10:06:00 2014
> @@ -71,8 +71,10 @@ aggregate_graph_xaxis_group=Abscisses
>  aggregate_graph_yaxis_group=Ordonn\u00E9es (milli-secondes)
>  aggregate_graph_yaxis_max_value=Echelle maximum \:
>  aggregate_report=Rapport agr\u00E9g\u00E9
> +aggregate_report_xx_pct1_line={0}% centile
> +aggregate_report_xx_pct2_line={0}% centile
> +aggregate_report_xx_pct3_line={0}% centile

No need to have 3 different properties; the same one can be shared as
the values are identical (and have the same function)

>  aggregate_report_90=90%
> -aggregate_report_90%_line=90e centile

This needs to be removed from the other language property files.

>  aggregate_report_bandwidth=Ko/sec
>  aggregate_report_count=\# Echantillons
>  aggregate_report_error=Erreur
>
> Modified: jmeter/trunk/xdocs/changes.xml
> URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/xdocs/changes.xml (original)
> +++ jmeter/trunk/xdocs/changes.xml Sat Nov 29 10:06:00 2014
> @@ -190,6 +190,7 @@ See  <bugzilla>56357</bugzilla> for deta
>  <ul>
>  <li><bugzilla>55932</bugzilla> - Create a Async BackendListener to allow easy plug of new listener (Graphite, JDBC, Console,...)</li>
>  <li><bugzilla>57246</bugzilla> - BackendListener : Create a Graphite implementation</li>
> +<li><bugzilla>57217</bugzilla> - Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code). Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
>  </ul>
>
>  <h3>Timers, Assertions, Config, Pre- &amp; Post-Processors</h3>
> @@ -223,6 +224,7 @@ See  <bugzilla>56357</bugzilla> for deta
>  We also thank bug reporters who helped us improve JMeter. <br/>
>  For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes:
>  <ul>
> +<li><a href="http://ubikloadpack.com">Ubik Load Pack</a></li>
>  </ul>
>
>  Apologies if we have omitted anyone else.
>
> Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
> URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1642410&r1=1642409&r2=1642410&view=diff
> ==============================================================================
> --- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
> +++ jmeter/trunk/xdocs/usermanual/component_reference.xml Sat Nov 29 10:06:00 2014
> @@ -2905,7 +2905,7 @@ compiled code must be available to JMete
>  </p>
>  </component>
>
> -<component name="Aggregate Report" index="&sect-num;.3.7"  width="784" height="287" screenshot="aggregate_report.png">
> +<component name="Aggregate Report" index="&sect-num;.3.7"  width="1140" height="266" screenshot="aggregate_report.png">
>  <description>The aggregate report creates a table row for each differently named request in your
>  test.  For each request, it totals the response information and provides request count, min, max,
>  average, error rate, approximate throughput (request/second) and Kilobytes per second throughput.
> @@ -2922,12 +2922,20 @@ the Aggregate Report.
>  </p>
>  <p>
>  Calculation of the <a href="glossary.html#Median">Median</a> and 90% Line (90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>) values requires additional memory.
> -For JMeter 2.3.4 and earlier, details of each sample were saved separately, which meant a lot of memory was needed.
>  JMeter now combines samples with the same elapsed time, so far less memory is used.
>  However, for samples that take more than a few seconds, the probability is that fewer samples will have identical times,
>  in which case more memory will be needed.
> +Note you can use this listener afterwards to reload a CSV or XML results file which is the recommended way to avoid performance impacts.
>  See the <complink name="Summary Report"/> for a similar Listener that does not store individual samples and so needs constant memory.
>  </p>
> +<note>
> +Starting with JMeter 2.12, you can configure the 3 percentile values you want to compute, this can be done by setting properties:
> +<ul>
> +    <li>aggregate_rpt_pct1: defaults to 90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
> +    <li>aggregate_rpt_pct2: defaults to 95<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
> +    <li>aggregate_rpt_pct3: defaults to 99<sup>th</sup> <a href="glossary.html#Percentile">percentile</a></li>
> +</ul>
> +</note>
>  <ul>
>  <li>Label - The label of the sample.
>  If "Include group name in label?" is selected, then the name of the thread group is added as a prefix.
> @@ -2939,6 +2947,10 @@ This allows identical labels from differ
>  50% of the samples took no more than this time; the remainder took at least as long.</li>
>  <li>90% Line - 90% of the samples took no more than this time.
>  The remaining samples took at least as long as this. (90<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
> +<li>95% Line - 95% of the samples took no more than this time.
> +The remaining samples took at least as long as this. (95<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
> +<li>99% Line - 99% of the samples took no more than this time.
> +The remaining samples took at least as long as this. (99<sup>th</sup> <a href="glossary.html#Percentile">percentile</a>)</li>
>  <li>Min - The shortest time for the samples with the same label</li>
>  <li>Max - The longest time for the samples with the same label</li>
>  <li>Error % - Percent of requests with errors</li>
> @@ -2954,7 +2966,7 @@ i.e. 30.0 requests/minute is saved as 0.
>  <div align="center">
>  <p>
>      The figure below shows an example of selecting the "Include group name" checkbox.
> -<figure width="784" height="287" image="aggregate_report_grouped.png">Sample "Include group name" display</figure>
> +<figure width="1140" height="276" image="aggregate_report_grouped.png">Sample "Include group name" display</figure>
>  </p>
>  </div>
>  </component>
> @@ -3034,7 +3046,7 @@ know for sure is to use a profiling tool
>  </description>
>  </component>
>
> -<component name="Aggregate Graph" index="&sect-num;.3.12"  width="893" height="713" screenshot="aggregate_graph.png">
> +<component name="Aggregate Graph" index="&sect-num;.3.12"  width="1132" height="872" screenshot="aggregate_graph.png">
>  <description>The aggregate graph is similar to the aggregate report. The primary
>  difference is the aggregate graph provides an easy way to generate bar graphs and save
>  the graph as a PNG file.</description>
>
>