You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by mi...@apache.org on 2012/08/14 17:30:33 UTC
svn commit: r1372926 - in /jmeter/trunk: bin/
src/components/org/apache/jmeter/visualizers/
src/components/org/apache/jmeter/visualizers/utils/
src/core/org/apache/jmeter/resources/ xdocs/ xdocs/usermanual/
Author: milamber
Date: Tue Aug 14 15:30:32 2012
New Revision: 1372926
URL: http://svn.apache.org/viewvc?rev=1372926&view=rev
Log:
Add a new visualizer to draw a line graph showing the evolution of response time for a test
Bugzilla Id: 53718
Added:
jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/
jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties (with props)
Modified:
jmeter/trunk/bin/saveservice.properties
jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphProperties.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/saveservice.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/saveservice.properties?rev=1372926&r1=1372925&r2=1372926&view=diff
==============================================================================
--- jmeter/trunk/bin/saveservice.properties (original)
+++ jmeter/trunk/bin/saveservice.properties Tue Aug 14 15:30:32 2012
@@ -186,6 +186,7 @@ LDAPExtSampler=org.apache.jmeter.protoco
LdapExtTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapExtTestSamplerGui
LDAPSampler=org.apache.jmeter.protocol.ldap.sampler.LDAPSampler
LdapTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapTestSamplerGui
+LGraphVisualizer=org.apache.jmeter.visualizers.LGraphVisualizer
LineChart=org.apache.jmeter.testelement.LineChart
LineGraphGui=org.apache.jmeter.report.gui.LineGraphGui
LogicControllerGui=org.apache.jmeter.control.gui.LogicControllerGui
Added: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java?rev=1372926&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java Tue Aug 14 15:30:32 2012
@@ -0,0 +1,365 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jmeter.visualizers;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.LayoutManager;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.math.BigDecimal;
+
+import javax.swing.JPanel;
+
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+import org.jCharts.axisChart.AxisChart;
+import org.jCharts.chartData.AxisChartDataSet;
+import org.jCharts.chartData.ChartDataException;
+import org.jCharts.chartData.DataSeries;
+import org.jCharts.properties.AxisProperties;
+import org.jCharts.properties.ChartProperties;
+import org.jCharts.properties.DataAxisProperties;
+import org.jCharts.properties.LabelAxisProperties;
+import org.jCharts.properties.LegendAreaProperties;
+import org.jCharts.properties.LegendProperties;
+import org.jCharts.properties.LineChartProperties;
+import org.jCharts.properties.PointChartProperties;
+import org.jCharts.properties.PropertyException;
+import org.jCharts.properties.util.ChartFont;
+import org.jCharts.types.ChartType;
+
+public class LGraphChart extends JPanel {
+
+ private static final long serialVersionUID = 280L;
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ protected double[][] data = null;
+ protected String title, xAxisTitle, yAxisTitle, yAxisLabel;
+ protected String[] xAxisLabels;
+ protected int width, height;
+
+ protected String[] legendLabels = { JMeterUtils.getResString("aggregate_graph_legend") };
+
+ protected int maxYAxisScale;
+
+ protected Font titleFont;
+
+ protected Font legendFont;
+
+ protected Color[] color;
+
+ protected boolean showGrouping = true;
+
+ protected int legendPlacement = LegendProperties.BOTTOM;
+
+ protected Shape pointShape = PointChartProperties.SHAPE_CIRCLE;
+
+ protected float strokeWidth = 3.5f;
+
+ /**
+ *
+ */
+ public LGraphChart() {
+ super();
+ }
+
+ /**
+ * @param layout
+ */
+ public LGraphChart(LayoutManager layout) {
+ super(layout);
+ }
+
+ /**
+ * @param layout
+ * @param isDoubleBuffered
+ */
+ public LGraphChart(LayoutManager layout, boolean isDoubleBuffered) {
+ super(layout, isDoubleBuffered);
+ }
+
+ public void setData(double[][] data) {
+ this.data = data;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setXAxisTitle(String title) {
+ this.xAxisTitle = title;
+ }
+
+ public void setYAxisTitle(String title) {
+ this.yAxisTitle = title;
+ }
+
+ public void setXAxisLabels(String[] labels) {
+ this.xAxisLabels = labels;
+ }
+
+ public void setYAxisLabels(String label) {
+ this.yAxisLabel = label;
+ }
+
+ public void setLegendLabels(String[] labels) {
+ this.legendLabels = labels;
+ }
+
+ public void setWidth(int w) {
+ this.width = w;
+ }
+
+ public void setHeight(int h) {
+ this.height = h;
+ }
+
+ /**
+ * @return the maxYAxisScale
+ */
+ public int getMaxYAxisScale() {
+ return maxYAxisScale;
+ }
+
+ /**
+ * @param maxYAxisScale the maxYAxisScale to set
+ */
+ public void setMaxYAxisScale(int maxYAxisScale) {
+ this.maxYAxisScale = maxYAxisScale;
+ }
+
+ /**
+ * @return the color
+ */
+ public Color[] getColor() {
+ return color;
+ }
+
+ /**
+ * @param color the color to set
+ */
+ public void setColor(Color[] color) {
+ this.color = color;
+ }
+
+ /**
+ * @return the titleFont
+ */
+ public Font getTitleFont() {
+ return titleFont;
+ }
+
+ /**
+ * @param titleFont the titleFont to set
+ */
+ public void setTitleFont(Font titleFont) {
+ this.titleFont = titleFont;
+ }
+
+ /**
+ * @return the legendFont
+ */
+ public Font getLegendFont() {
+ return legendFont;
+ }
+
+ /**
+ * @param legendFont the legendFont to set
+ */
+ public void setLegendFont(Font legendFont) {
+ this.legendFont = legendFont;
+ }
+
+ /**
+ * @return the legendPlacement
+ */
+ public int getLegendPlacement() {
+ return legendPlacement;
+ }
+
+ /**
+ * @param legendPlacement the legendPlacement to set
+ */
+ public void setLegendPlacement(int legendPlacement) {
+ this.legendPlacement = legendPlacement;
+ }
+
+ /**
+ * @return the pointShape
+ */
+ public Shape getPointShape() {
+ return pointShape;
+ }
+
+ /**
+ * @param pointShape the pointShape to set
+ */
+ public void setPointShape(Shape pointShape) {
+ this.pointShape = pointShape;
+ }
+
+ /**
+ * @return the strokeWidth
+ */
+ public float getStrokeWidth() {
+ return strokeWidth;
+ }
+
+ /**
+ * @param strokeWidth the strokeWidth to set
+ */
+ public void setStrokeWidth(float strokeWidth) {
+ this.strokeWidth = strokeWidth;
+ }
+
+ /**
+ * @return the showGrouping
+ */
+ public boolean isShowGrouping() {
+ return showGrouping;
+ }
+
+ /**
+ * @param showGrouping the showGrouping to set
+ */
+ public void setShowGrouping(boolean showGrouping) {
+ this.showGrouping = showGrouping;
+ }
+
+ private void drawSample(String _title, String[] _xAxisLabels, String _xAxisTitle2,
+ String _yAxisTitle, String[] _legendLabels, double[][] _data, int _width, int _height, Color[] _color, Font font, Graphics g) {
+
+ double max = maxYAxisScale > 0 ? maxYAxisScale : findMax(_data); // define max scale y axis
+ try {
+ // if the title graph is empty, we can assume some default
+ if (_title.length() == 0 ) {
+ _title = JMeterUtils.getResString("graph_line_title"); //$NON-NLS-1$
+ }
+ this.setPreferredSize(new Dimension(_width,_height));
+ DataSeries dataSeries = new DataSeries( _xAxisLabels, null, _yAxisTitle, _title ); // replace _xAxisTitle to null (don't display x axis title)
+
+ // Stroke and shape line settings
+ Stroke[] strokes = new Stroke[_legendLabels.length];
+ for (int i = 0; i < _legendLabels.length; i++) {
+ strokes[i] = new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 5f);
+ }
+ Shape[] shapes = new Shape[_legendLabels.length];
+ for (int i = 0; i < _legendLabels.length; i++) {
+ shapes[i] = pointShape;
+ }
+ LineChartProperties lineChartProperties= new LineChartProperties(strokes, shapes);
+
+ // Lines colors
+ Paint[] paints = new Paint[_color.length];
+ for (int i = 0; i < _color.length; i++) {
+ paints[i] = _color[i] ;
+ }
+
+ // Define chart type (line)
+ AxisChartDataSet axisChartDataSet =
+ new AxisChartDataSet( _data, _legendLabels, paints, ChartType.LINE, lineChartProperties );
+ dataSeries.addIAxisPlotDataSet(axisChartDataSet);
+
+ ChartProperties chartProperties= new ChartProperties();
+ LabelAxisProperties xaxis = new LabelAxisProperties();
+ DataAxisProperties yaxis = new DataAxisProperties();
+ yaxis.setUseCommas(showGrouping);
+
+ if (legendFont != null) {
+ yaxis.setAxisTitleChartFont(new ChartFont(legendFont, new Color(20)));
+ yaxis.setScaleChartFont(new ChartFont(legendFont, new Color(20)));
+ xaxis.setAxisTitleChartFont(new ChartFont(legendFont, new Color(20)));
+ xaxis.setScaleChartFont(new ChartFont(legendFont, new Color(20)));
+ }
+ if (titleFont != null) {
+ chartProperties.setTitleFont(new ChartFont(titleFont, new Color(0)));
+ }
+
+ // Y Axis ruler
+ try {
+ BigDecimal round = new BigDecimal(max / 1000d);
+ round = round.setScale(0, BigDecimal.ROUND_UP);
+ double topValue = round.doubleValue() * 1000;
+ yaxis.setUserDefinedScale(0, 500);
+ yaxis.setNumItems((int) (topValue / 500)+1);
+ yaxis.setShowGridLines(1);
+ } catch (PropertyException e) {
+ log.warn("",e);
+ }
+
+ AxisProperties axisProperties= new AxisProperties(xaxis, yaxis);
+ axisProperties.setXAxisLabelsAreVertical(true);
+ LegendProperties legendProperties= new LegendProperties();
+ legendProperties.setBorderStroke(null);
+ legendProperties.setPlacement(legendPlacement);
+ legendProperties.setIconBorderPaint(Color.WHITE);
+ legendProperties.setIconBorderStroke(new BasicStroke(0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE));
+ // Manage legend placement
+ legendProperties.setNumColumns(LegendProperties.COLUMNS_FIT_TO_IMAGE);
+ if (legendPlacement == LegendAreaProperties.RIGHT || legendPlacement == LegendAreaProperties.LEFT) {
+ legendProperties.setNumColumns(1);
+ }
+ if (legendFont != null) {
+ legendProperties.setFont(legendFont);
+ }
+ AxisChart axisChart = new AxisChart(
+ dataSeries, chartProperties, axisProperties,
+ legendProperties, _width, _height );
+ axisChart.setGraphics2D((Graphics2D) g);
+ axisChart.render();
+ } catch (ChartDataException e) {
+ log.warn("", e);
+ } catch (PropertyException e) {
+ log.warn("", e);
+ }
+ }
+
+ @Override
+ public void paintComponent(Graphics graphics) {
+ if (data != null && this.title != null && this.xAxisLabels != null &&
+ this.yAxisLabel != null && this.yAxisTitle != null) {
+ drawSample(this.title, this.xAxisLabels,
+ this.xAxisTitle, this.yAxisTitle, this.legendLabels,
+ this.data, this.width, this.height, this.color,
+ this.legendFont, graphics);
+ }
+ }
+
+ private double findMax(double _data[][]) {
+ double max = 0;
+ max = _data[0][0];
+ for (int i = 0; i < _data.length; i++) {
+ for (int j = 0; j < _data[i].length; j++) {
+ if (Double.isNaN(max) || ((_data[i][j] != Double.NaN) && (_data[i][j] > max))) {
+ max = _data[i][j];
+ }
+ }
+ }
+ return max;
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphChart.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java?rev=1372926&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java Tue Aug 14 15:30:32 2012
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jmeter.visualizers;
+
+import java.awt.Color;
+
+public class LGraphLineBean {
+
+ private String label;
+
+ private Color lineColor;
+
+ /**
+ * @param label
+ * @param lineColor
+ */
+ public LGraphLineBean(String label, Color lineColor) {
+ super();
+ this.label = label;
+ this.lineColor = lineColor;
+ }
+
+ /**
+ * @return the label
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * @param label the label to set
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * @return the lineColor
+ */
+ public Color getLineColor() {
+ return lineColor;
+ }
+
+ /**
+ * @param lineColor the lineColor to set
+ */
+ public void setLineColor(Color lineColor) {
+ this.lineColor = lineColor;
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphLineBean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java?rev=1372926&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java Tue Aug 14 15:30:32 2012
@@ -0,0 +1,715 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ *
+ */
+package org.apache.jmeter.visualizers;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.jmeter.gui.action.ActionNames;
+import org.apache.jmeter.gui.action.ActionRouter;
+import org.apache.jmeter.gui.action.SaveGraphics;
+import org.apache.jmeter.gui.util.FilePanel;
+import org.apache.jmeter.gui.util.VerticalPanel;
+import org.apache.jmeter.samplers.Clearable;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
+import org.apache.jmeter.visualizers.utils.Colors;
+import org.apache.jorphan.gui.JLabeledTextField;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+public class LGraphVisualizer extends AbstractVisualizer implements ActionListener, Clearable {
+
+ private static final long serialVersionUID = 280L;
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private final Font FONT_SMALL = new Font("SansSerif", Font.PLAIN, 10);
+
+ private final Border MARGIN = new EmptyBorder(0, 5, 0, 5);
+
+ private final String yAxisLabel = JMeterUtils.getResString("aggregate_graph_response_time");//$NON-NLS-1$
+
+ private final String yAxisTitle = JMeterUtils.getResString("aggregate_graph_ms"); //$NON-NLS-1$
+
+ private LGraphChart graphPanel = null;
+
+ private JPanel settingsPane = null;
+
+ private final JTabbedPane tabbedGraph = new JTabbedPane(JTabbedPane.TOP);
+
+ private boolean saveGraphToFile = false;
+
+ private final int defaultWidth = 400;
+
+ private final int defaultHeight = 300;
+
+ private final static int INTERVAL_DEFAULT = 10000; // in milli-seconds // TODO: properties?
+
+ private int intervalValue = INTERVAL_DEFAULT;
+
+ private final JLabeledTextField intervalField =
+ new JLabeledTextField(JMeterUtils.getResString("graph_line_interval_label"), 7); //$NON-NLS-1$
+
+ private final JButton intervalButton = new JButton(JMeterUtils.getResString("graph_line_interval_reload")); // $NON-NLS-1$
+
+ private final JButton displayButton =
+ new JButton(JMeterUtils.getResString("aggregate_graph_display")); //$NON-NLS-1$
+
+ private JButton saveGraph =
+ new JButton(JMeterUtils.getResString("aggregate_graph_save")); //$NON-NLS-1$
+
+ private final JCheckBox samplerSelection = new JCheckBox(JMeterUtils.getResString("graph_line_series_selection"), false); //$NON-NLS-1$
+
+ private final JTextField samplerMatchLabel = new JTextField();
+
+ private final JButton reloadButton = new JButton(JMeterUtils.getResString("aggregate_graph_reload_data")); // $NON-NLS-1$
+
+ private final JCheckBox caseChkBox = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_case"), false); // $NON-NLS-1$
+
+ private final JCheckBox regexpChkBox = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_regexp"), true); // $NON-NLS-1$
+
+ private final JComboBox titleFontNameList = new JComboBox(StatGraphProperties.getFontNameMap().keySet().toArray());
+
+ private final JComboBox titleFontSizeList = new JComboBox(StatGraphProperties.fontSize);
+
+ private final JComboBox titleFontStyleList = new JComboBox(StatGraphProperties.getFontStyleMap().keySet().toArray());
+
+ private final JComboBox fontNameList = new JComboBox(StatGraphProperties.getFontNameMap().keySet().toArray());
+
+ private final JComboBox fontSizeList = new JComboBox(StatGraphProperties.fontSize);
+
+ private final JComboBox fontStyleList = new JComboBox(StatGraphProperties.getFontStyleMap().keySet().toArray());
+
+ private final JComboBox legendPlacementList = new JComboBox(StatGraphProperties.getPlacementNameMap().keySet().toArray());
+
+ private final JComboBox pointShapeLine = new JComboBox(StatGraphProperties.getPointShapeMap().keySet().toArray());
+
+ private final JComboBox strokeWidthList = new JComboBox(StatGraphProperties.strokeWidth);
+
+ private final JCheckBox numberShowGrouping = new JCheckBox(JMeterUtils.getResString("aggregate_graph_number_grouping"), true); // Default checked // $NON-NLS-1$
+
+ private final JButton syncWithName =
+ new JButton(JMeterUtils.getResString("aggregate_graph_sync_with_name")); //$NON-NLS-1$
+
+ private final JLabeledTextField graphTitle =
+ new JLabeledTextField(JMeterUtils.getResString("graph_line_title_label")); //$NON-NLS-1$
+
+ private final JLabeledTextField xAxisTimeFormat =
+ new JLabeledTextField(JMeterUtils.getResString("graph_line_xaxis_time_format"), 10); //$NON-NLS-1$ $NON-NLS-2$
+
+ private final JLabeledTextField maxValueYAxisLabel =
+ new JLabeledTextField(JMeterUtils.getResString("aggregate_graph_yaxis_max_value"), 8); //$NON-NLS-1$
+
+ /**
+ * checkbox for use dynamic graph size
+ */
+ private final JCheckBox dynamicGraphSize = new JCheckBox(JMeterUtils.getResString("aggregate_graph_dynamic_size")); // $NON-NLS-1$
+
+ private final JLabeledTextField graphWidth =
+ new JLabeledTextField(JMeterUtils.getResString("aggregate_graph_width"), 6); //$NON-NLS-1$
+ private final JLabeledTextField graphHeight =
+ new JLabeledTextField(JMeterUtils.getResString("aggregate_graph_height"), 6); //$NON-NLS-1$
+
+ private int minStartTime = Integer.MAX_VALUE;
+
+ private int maxStartTime = Integer.MIN_VALUE;
+
+ private final HashMap<String, LGraphLineBean> seriesNames = new HashMap<String, LGraphLineBean>();
+
+ private final LinkedHashMap<String, LinkedHashMap<Integer, Long>> pList = new LinkedHashMap<String, LinkedHashMap<Integer, Long>>();
+
+ private int durationTest = 0;
+
+ private int colorIdx = 0;
+
+ private final List<Color> listColors = Colors.getColors();
+
+ public LGraphVisualizer() {
+ init();
+ }
+
+ public synchronized void add(final SampleResult sampleResult) {
+ final String sampleLabel = sampleResult.getSampleLabel();
+ Matcher matcher = null;
+ // Sampler selection
+ if (samplerSelection.isSelected() && samplerMatchLabel.getText() != null
+ && samplerMatchLabel.getText().length() > 0) {
+ Pattern pattern = createPattern(samplerMatchLabel.getText());
+ matcher = pattern.matcher(sampleLabel);
+ }
+ if ((matcher == null) || (matcher.find())) {
+ final long startTimeMS = sampleResult.getStartTime();
+ final int startTimeInterval = (int) startTimeMS / intervalValue;
+ JMeterUtils.runSafe(new Runnable() {
+ public void run() {
+ // Use for x-axis scale
+ if (startTimeInterval < minStartTime) {
+ minStartTime = startTimeInterval;
+ } else if (startTimeInterval > maxStartTime) {
+ maxStartTime = startTimeInterval;
+ }
+ // Generate x-axis label and associated color
+ if (!seriesNames.containsKey(sampleLabel)) {
+ seriesNames.put(sampleLabel,
+ new LGraphLineBean(sampleLabel, listColors.get(colorIdx++)));
+ // reset colors index
+ if (colorIdx >= listColors.size()) {
+ colorIdx = 0;
+ }
+ }
+ // List of value by sampler
+ if (pList.containsKey(sampleLabel)) {
+ LinkedHashMap<Integer, Long> subList = pList.get(sampleLabel);
+ long respTime = sampleResult.getTime();
+ if (subList.containsKey(startTimeInterval)) {
+ respTime = (subList.get(startTimeInterval) + respTime) / 2;
+ }
+ subList.put(startTimeInterval, respTime);
+ } else {
+ LinkedHashMap<Integer, Long> newSubList = new LinkedHashMap<Integer, Long>();
+ newSubList.put(startTimeInterval, sampleResult.getTime());
+ pList.put(sampleLabel, newSubList);
+ }
+ }
+ });
+ }
+ }
+
+ public void makeGraph() {
+ // Calculate the test duration. Needs to xAxis Labels and getData.
+ durationTest = maxStartTime - minStartTime;
+ if (durationTest <= 0) {
+ JOptionPane.showMessageDialog(null, JMeterUtils
+ .getResString("aggregate_graph_no_values_to_graph"), // $NON-NLS-1$
+ JMeterUtils.getResString("aggregate_graph_no_values_to_graph"), // $NON-NLS-1$
+ JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+ Dimension size = graphPanel.getSize();
+ // canvas size
+ int width = (int) size.getWidth();
+ int height = (int) size.getHeight();
+ if (!dynamicGraphSize.isSelected()) {
+ String wstr = graphWidth.getText();
+ String hstr = graphHeight.getText();
+ if (wstr.length() != 0) {
+ width = Integer.parseInt(wstr);
+ }
+ if (hstr.length() != 0) {
+ height = Integer.parseInt(hstr);
+ }
+ }
+
+ String yAxisStr = maxValueYAxisLabel.getText();
+ int maxYAxisScale = yAxisStr.length() == 0 ? 0 : Integer.parseInt(yAxisStr);
+
+ graphPanel.setData(this.getData());
+ graphPanel.setTitle(graphTitle.getText());
+ graphPanel.setMaxYAxisScale(maxYAxisScale);
+
+ graphPanel.setYAxisLabels(this.yAxisLabel);
+ graphPanel.setYAxisTitle(this.yAxisTitle);
+ graphPanel.setXAxisLabels(getXAxisLabels());
+ graphPanel.setLegendLabels(getLegendLabels());
+ graphPanel.setColor(getLinesColors());
+ graphPanel.setShowGrouping(numberShowGrouping.isSelected());
+ graphPanel.setLegendPlacement(StatGraphProperties.getPlacementNameMap()
+ .get(legendPlacementList.getSelectedItem()).intValue());
+ graphPanel.setPointShape(StatGraphProperties.getPointShapeMap().get(pointShapeLine.getSelectedItem()));
+ graphPanel.setStrokeWidth(Float.parseFloat((String) strokeWidthList.getSelectedItem()));
+
+ graphPanel.setTitleFont(new Font(StatGraphProperties.getFontNameMap().get(titleFontNameList.getSelectedItem()),
+ StatGraphProperties.getFontStyleMap().get(titleFontStyleList.getSelectedItem()).intValue(),
+ Integer.parseInt((String) titleFontSizeList.getSelectedItem())));
+ graphPanel.setLegendFont(new Font(StatGraphProperties.getFontNameMap().get(fontNameList.getSelectedItem()),
+ StatGraphProperties.getFontStyleMap().get(fontStyleList.getSelectedItem()).intValue(),
+ Integer.parseInt((String) fontSizeList.getSelectedItem())));
+
+ graphPanel.setHeight(height);
+ graphPanel.setWidth(width);
+ // Draw the graph
+ graphPanel.repaint();
+ }
+
+ /**
+ * Generate the data for the jChart API
+ * @return array of array of data to draw
+ */
+ public double[][] getData() {
+ int size = pList.size();
+ int max = durationTest;
+
+ double[][] data = new double[size][max];
+
+ double nanLast = 0;
+ double nanBegin = 0;
+ ArrayList<Double> nanList = new ArrayList<Double>();
+ Set<String> pointsKeys = pList.keySet();
+ int s = 0;
+ for (String pointKey : pointsKeys) {
+ LinkedHashMap<Integer, Long> subList = pList.get(pointKey);
+
+ int idx = 0;
+ while (idx < durationTest) {
+ int keyShift = minStartTime + idx;
+ if (subList.containsKey(keyShift)) {
+ nanLast = subList.get(keyShift);
+
+ data[s][idx] = nanLast;
+
+ // Calculate intermediate values (if needed)
+ int nlsize = nanList.size();
+ if (nlsize > 0) {
+ double valPrev = nanBegin;
+ for (int cnt = 0; cnt < nlsize; cnt++) {
+ int pos = idx - (nlsize - cnt);
+ if (pos < 0) { pos = 0; }
+ valPrev = (valPrev + ((nanLast - nanBegin) / (nlsize + 2)));
+ data[s][pos] = valPrev;
+ }
+ nanList.clear();
+ }
+ } else {
+ nanList.add(Double.NaN);
+ nanBegin = nanLast;
+ data[s][idx] = Double.NaN;
+ }
+ // log.debug("data["+s+"]["+idx+"]: " + data[s][idx]);
+ idx++;
+ }
+ s++;
+ }
+ return data;
+ }
+
+ public String getLabelResource() {
+ return "graph_line_title"; // $NON-NLS-1$
+ }
+
+ public synchronized void clearData() {
+ seriesNames.clear();
+ pList.clear();
+ minStartTime = Integer.MAX_VALUE;
+ maxStartTime = Integer.MIN_VALUE;
+ durationTest = 0;
+ colorIdx = 0;
+ }
+
+ /**
+ * Initialize the GUI.
+ */
+ private void init() {
+ this.setLayout(new BorderLayout());
+
+ // MAIN PANEL
+ JPanel mainPanel = new JPanel();
+ Border margin = new EmptyBorder(10, 10, 5, 10);
+ Border margin2 = new EmptyBorder(10, 10, 5, 10);
+
+ mainPanel.setBorder(margin);
+ mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
+ mainPanel.add(makeTitlePanel());
+
+ settingsPane = new VerticalPanel();
+ settingsPane.setBorder(margin2);
+
+ graphPanel = new LGraphChart();
+ graphPanel.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
+
+ settingsPane.add(createGraphActionsPane());
+ settingsPane.add(createGraphSettingsPane());
+ settingsPane.add(createGraphTitlePane());
+ settingsPane.add(createLinePane());
+ settingsPane.add(createGraphDimensionPane());
+ JPanel axisPane = new JPanel(new BorderLayout());
+ axisPane.add(createGraphXAxisPane(), BorderLayout.WEST);
+ axisPane.add(createGraphYAxisPane(), BorderLayout.CENTER);
+ settingsPane.add(axisPane);
+ settingsPane.add(createLegendPane());
+
+ tabbedGraph.addTab(JMeterUtils.getResString("aggregate_graph_tab_settings"), settingsPane); //$NON-NLS-1$
+ tabbedGraph.addTab(JMeterUtils.getResString("aggregate_graph_tab_graph"), graphPanel); //$NON-NLS-1$
+
+ this.add(mainPanel, BorderLayout.NORTH);
+ this.add(tabbedGraph, BorderLayout.CENTER);
+
+ }
+
+ @Override
+ public JComponent getPrintableComponent() {
+ if (saveGraphToFile == true) {
+ saveGraphToFile = false;
+ graphPanel.setBounds(graphPanel.getLocation().x,graphPanel.getLocation().y,
+ graphPanel.width,graphPanel.height);
+ return graphPanel;
+ }
+ return this;
+ }
+
+ private JPanel createGraphActionsPane() {
+ JPanel buttonPanel = new JPanel(new BorderLayout());
+ JPanel displayPane = new JPanel();
+ displayPane.add(displayButton);
+ displayButton.addActionListener(this);
+ buttonPanel.add(displayPane, BorderLayout.WEST);
+
+ JPanel savePane = new JPanel();
+ savePane.add(saveGraph);
+ saveGraph.addActionListener(this);
+ syncWithName.addActionListener(this);
+ buttonPanel.add(savePane, BorderLayout.EAST);
+
+ return buttonPanel;
+ }
+
+ public String[] getXAxisLabels() {
+ SimpleDateFormat formatter = new SimpleDateFormat(xAxisTimeFormat.getText()); //$NON-NLS-1$
+ String[] xAxisLabels = new String[durationTest];
+ for (int j = 0; j < durationTest; j++) {
+ xAxisLabels[j] = formatter.format(new Date((minStartTime + j) * intervalValue));
+ }
+ return xAxisLabels;
+ }
+
+ private String[] getLegendLabels() {
+ String[] legends = new String[seriesNames.size()];
+ int i = 0;
+ for (String key : seriesNames.keySet()) {
+ LGraphLineBean val = seriesNames.get(key);
+ legends[i] = val.getLabel();
+ i++;
+ }
+ return legends;
+ }
+
+ private Color[] getLinesColors() {
+ Color[] linesColors = new Color[seriesNames.size()];
+ int i = 0;
+ for (String key : seriesNames.keySet()) {
+ LGraphLineBean val = seriesNames.get(key);
+ linesColors[i] = val.getLineColor();
+ i++;
+ }
+ return linesColors;
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ final Object eventSource = event.getSource();
+ if (eventSource == displayButton) {
+ actionMakeGraph();
+ } else if (eventSource == saveGraph) {
+ saveGraphToFile = true;
+ try {
+ ActionRouter.getInstance().getAction(
+ ActionNames.SAVE_GRAPHICS,SaveGraphics.class.getName()).doAction(
+ new ActionEvent(this,1,ActionNames.SAVE_GRAPHICS));
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ }
+ } else if (eventSource == syncWithName) {
+ graphTitle.setText(namePanel.getName());
+ } else if (eventSource == dynamicGraphSize) {
+ // if use dynamic graph size is checked, we disable the dimension fields
+ if (dynamicGraphSize.isSelected()) {
+ graphWidth.setEnabled(false);
+ graphHeight.setEnabled(false);
+ } else {
+ graphWidth.setEnabled(true);
+ graphHeight.setEnabled(true);
+ }
+ } else if (eventSource == samplerSelection) {
+ if (samplerSelection.isSelected()) {
+ samplerMatchLabel.setEnabled(true);
+ reloadButton.setEnabled(true);
+ caseChkBox.setEnabled(true);
+ regexpChkBox.setEnabled(true);
+ } else {
+ samplerMatchLabel.setEnabled(false);
+ reloadButton.setEnabled(false);
+ caseChkBox.setEnabled(false);
+ regexpChkBox.setEnabled(false);
+ }
+ } else if (eventSource == reloadButton || eventSource == intervalButton) {
+ if (eventSource == intervalButton) {
+ intervalValue = Integer.parseInt(intervalField.getText());
+ }
+ if (getFile() != null && getFile().length() > 0) {
+ clearData();
+ FilePanel filePanel = (FilePanel) getFilePanel();
+ filePanel.actionPerformed(event);
+ }
+ }
+
+ }
+
+ private void actionMakeGraph() {
+ String msgErr = null;
+ // Calculate the test duration. Needs to xAxis Labels and getData.
+ durationTest = maxStartTime - minStartTime;
+ if (seriesNames.size() <= 0) {
+ msgErr = JMeterUtils.getResString("aggregate_graph_no_values_to_graph"); // $NON-NLS-1$
+ } else if (durationTest <= 1) {
+ msgErr = JMeterUtils.getResString("graph_line_no_duration"); // $NON-NLS-1$
+ }
+ if (msgErr == null) {
+ makeGraph();
+ tabbedGraph.setSelectedIndex(1);
+ } else {
+ JOptionPane.showMessageDialog(null, msgErr, msgErr, JOptionPane.WARNING_MESSAGE);
+ }
+ }
+
+ private JComponent createLabelCombo(String label, JComboBox comboBox) {
+ JPanel labelCombo = new JPanel();
+ labelCombo.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ JLabel caption = new JLabel(label);
+ caption.setBorder(MARGIN);
+ labelCombo.add(caption);
+ labelCombo.add(comboBox);
+ return labelCombo;
+ }
+
+ private JPanel createGraphSettingsPane() {
+ JPanel settingsPane = new JPanel(new BorderLayout());
+ settingsPane.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("graph_line_settings_pane"))); // $NON-NLS-1$
+
+ JPanel intervalPane = new JPanel();
+ intervalPane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ intervalField.setText(String.valueOf(INTERVAL_DEFAULT));
+ intervalPane.add(intervalField);
+
+ // Button
+ intervalButton.setFont(FONT_SMALL);
+ intervalButton.addActionListener(this);
+ intervalPane.add(intervalButton);
+
+ settingsPane.add(intervalPane, BorderLayout.NORTH);
+ settingsPane.add(createGraphSelectionSubPane(), BorderLayout.SOUTH);
+
+ return settingsPane;
+ }
+
+ private JPanel createGraphSelectionSubPane() {
+ // Search field
+ JPanel searchPanel = new JPanel();
+ searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.X_AXIS));
+ searchPanel.setBorder(BorderFactory.createEmptyBorder(3, 0, 3, 0));
+
+ searchPanel.add(samplerSelection);
+ samplerMatchLabel.setEnabled(false);
+ reloadButton.setEnabled(false);
+ caseChkBox.setEnabled(false);
+ regexpChkBox.setEnabled(false);
+ samplerSelection.addActionListener(this);
+
+ searchPanel.add(samplerMatchLabel);
+ searchPanel.add(Box.createRigidArea(new Dimension(5,0)));
+
+ // Button
+ reloadButton.setFont(FONT_SMALL);
+ reloadButton.addActionListener(this);
+ searchPanel.add(reloadButton);
+
+ // checkboxes
+ caseChkBox.setFont(FONT_SMALL);
+ searchPanel.add(caseChkBox);
+ regexpChkBox.setFont(FONT_SMALL);
+ searchPanel.add(regexpChkBox);
+
+ return searchPanel;
+ }
+
+ private JPanel createGraphTitlePane() {
+ JPanel titleNamePane = new JPanel(new BorderLayout());
+ syncWithName.setFont(FONT_SMALL);
+ titleNamePane.add(graphTitle, BorderLayout.CENTER);
+ titleNamePane.add(syncWithName, BorderLayout.EAST);
+
+ JPanel titleStylePane = new JPanel();
+ titleStylePane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
+ titleStylePane.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_font"), //$NON-NLS-1$
+ titleFontNameList));
+ titleFontNameList.setSelectedIndex(0); // default: sans serif
+ titleStylePane.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_size"), //$NON-NLS-1$
+ titleFontSizeList));
+ titleFontSizeList.setSelectedItem(StatGraphProperties.fontSize[6]); // default: 16
+ titleStylePane.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_style"), //$NON-NLS-1$
+ titleFontStyleList));
+ titleFontStyleList.setSelectedItem(JMeterUtils.getResString("fontstyle.bold")); // default: bold
+
+ JPanel titlePane = new JPanel(new BorderLayout());
+ titlePane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("aggregate_graph_title_group"))); // $NON-NLS-1$
+ titlePane.add(titleNamePane, BorderLayout.NORTH);
+ titlePane.add(titleStylePane, BorderLayout.SOUTH);
+ return titlePane;
+ }
+
+ private JPanel createLinePane() {
+ JPanel lineStylePane = new JPanel();
+ lineStylePane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ lineStylePane.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("graph_line_settings_line"))); // $NON-NLS-1$
+ lineStylePane.add(createLabelCombo(JMeterUtils.getResString("graph_line_stroke_width"), //$NON-NLS-1$
+ strokeWidthList));
+ strokeWidthList.setSelectedItem(StatGraphProperties.strokeWidth[4]); // default: 3.0f
+ lineStylePane.add(createLabelCombo(JMeterUtils.getResString("graph_line_shape_label"), //$NON-NLS-1$
+ pointShapeLine));
+ pointShapeLine.setSelectedIndex(0); // default: circle
+ return lineStylePane;
+ }
+
+ private JPanel createGraphDimensionPane() {
+ JPanel dimensionPane = new JPanel();
+ dimensionPane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ dimensionPane.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("aggregate_graph_dimension"))); // $NON-NLS-1$
+
+ dimensionPane.add(dynamicGraphSize);
+ dynamicGraphSize.setSelected(true); // default option
+ graphWidth.setEnabled(false);
+ graphHeight.setEnabled(false);
+ dynamicGraphSize.addActionListener(this);
+ dimensionPane.add(Box.createRigidArea(new Dimension(10,0)));
+ dimensionPane.add(graphWidth);
+ dimensionPane.add(Box.createRigidArea(new Dimension(5,0)));
+ dimensionPane.add(graphHeight);
+ return dimensionPane;
+ }
+
+ /**
+ * Create pane for X Axis options
+ * @return X Axis pane
+ */
+ private JPanel createGraphXAxisPane() {
+ JPanel xAxisPane = new JPanel();
+ xAxisPane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ xAxisPane.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("aggregate_graph_xaxis_group"))); // $NON-NLS-1$
+ xAxisTimeFormat.setText("HH:mm:ss"); // $NON-NLS-1$
+ xAxisPane.add(xAxisTimeFormat);
+ return xAxisPane;
+ }
+
+ /**
+ * Create pane for Y Axis options
+ * @return Y Axis pane
+ */
+ private JPanel createGraphYAxisPane() {
+ JPanel yAxisPane = new JPanel();
+ yAxisPane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ yAxisPane.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("aggregate_graph_yaxis_group"))); // $NON-NLS-1$
+ yAxisPane.add(maxValueYAxisLabel);
+
+ yAxisPane.add(numberShowGrouping);
+ return yAxisPane;
+ }
+
+ /**
+ * Create pane for legend settings
+ * @return Legend pane
+ */
+ private JPanel createLegendPane() {
+ JPanel legendPanel = new JPanel();
+ legendPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ legendPanel.setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(),
+ JMeterUtils.getResString("aggregate_graph_legend"))); // $NON-NLS-1$
+
+ legendPanel.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_legend_placement"), //$NON-NLS-1$
+ legendPlacementList));
+ legendPlacementList.setSelectedItem(JMeterUtils.getResString("aggregate_graph_legend.placement.bottom")); // default: bottom
+ legendPanel.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_font"), //$NON-NLS-1$
+ fontNameList));
+ fontNameList.setSelectedIndex(0); // default: sans serif
+ legendPanel.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_size"), //$NON-NLS-1$
+ fontSizeList));
+ fontSizeList.setSelectedItem(StatGraphProperties.fontSize[2]); // default: 10
+ legendPanel.add(createLabelCombo(JMeterUtils.getResString("aggregate_graph_style"), //$NON-NLS-1$
+ fontStyleList));
+ fontStyleList.setSelectedItem(JMeterUtils.getResString("fontstyle.normal")); // default: normal
+
+ return legendPanel;
+ }
+
+ /**
+ * @param textToFind
+ * @return pattern ready to search
+ */
+ private Pattern createPattern(String textToFind) {
+ String textToFindQ = Pattern.quote(textToFind);
+ if (regexpChkBox.isSelected()) {
+ textToFindQ = textToFind;
+ }
+ Pattern pattern = null;
+ try {
+ if (caseChkBox.isSelected()) {
+ pattern = Pattern.compile(textToFindQ);
+ } else {
+ pattern = Pattern.compile(textToFindQ, Pattern.CASE_INSENSITIVE);
+ }
+ } catch (PatternSyntaxException pse) {
+ return null;
+ }
+ return pattern;
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/LGraphVisualizer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphProperties.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphProperties.java?rev=1372926&r1=1372925&r2=1372926&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphProperties.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphProperties.java Tue Aug 14 15:30:32 2012
@@ -20,11 +20,14 @@
package org.apache.jmeter.visualizers;
import java.awt.Font;
+import java.awt.Shape;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.jmeter.util.JMeterUtils;
import org.jCharts.properties.LegendAreaProperties;
+import org.jCharts.properties.PointChartProperties;
public class StatGraphProperties {
@@ -55,4 +58,17 @@ public class StatGraphProperties {
placementNameMap.put(JMeterUtils.getResString("aggregate_graph_legend.placement.top"), LegendAreaProperties.TOP);
return placementNameMap;
}
+
+ @SuppressWarnings("boxing")
+ public static Map<String, Shape> getPointShapeMap() {
+ Map<String, Shape> pointShapeMap = new LinkedHashMap<String, Shape>();
+ pointShapeMap.put(JMeterUtils.getResString("graph_pointshape_circle"), PointChartProperties.SHAPE_CIRCLE);
+ pointShapeMap.put(JMeterUtils.getResString("graph_pointshape_diamond"), PointChartProperties.SHAPE_DIAMOND);
+ pointShapeMap.put(JMeterUtils.getResString("graph_pointshape_square"), PointChartProperties.SHAPE_SQUARE);
+ pointShapeMap.put(JMeterUtils.getResString("graph_pointshape_triangle"), PointChartProperties.SHAPE_TRIANGLE);
+ pointShapeMap.put(JMeterUtils.getResString("graph_pointshape_none"), null);
+ return pointShapeMap;
+ }
+
+ public static final String[] strokeWidth = { "1.0f", "1.5f", "2.0f", "2.5f", "3.0f", "3.5f", "4.0f", "4.5f", "5.0f", "5.5f", "6.0f", "6.5f"};
}
Added: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java?rev=1372926&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java Tue Aug 14 15:30:32 2012
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jmeter.visualizers.utils;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.swing.JOptionPane;
+
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+public class Colors {
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private static final String ENTRY_SEP = ","; //$NON-NLS-1$
+
+ private static final String ORDER_PROP_NAME = "order"; //$NON-NLS-1$
+
+ protected static final String DEFAULT_COLORS_PROPERTY_FILE = "org/apache/jmeter/visualizers/utils/colors.properties"; //$NON-NLS-1$
+
+ protected static final String USER_DEFINED_COLORS_PROPERTY_FILE = "jmeter.colors"; //$NON-NLS-1$
+
+ private static final String COLORS_ORDER = "jmeter.order";
+
+ /**
+ * Parse icon set file.
+ * @return List of icons/action definition
+ */
+ public static List<Color> getColors() {
+ Properties defaultProps = JMeterUtils.loadProperties(DEFAULT_COLORS_PROPERTY_FILE);
+ if (defaultProps == null) {
+ JOptionPane.showMessageDialog(null,
+ JMeterUtils.getResString("toolbar_icon_set_not_found"), // $NON-NLS-1$
+ JMeterUtils.getResString("toolbar_icon_set_not_found"), // $NON-NLS-1$
+ JOptionPane.WARNING_MESSAGE);
+ return null;
+ }
+ Properties p;
+ String userProp = JMeterUtils.getProperty(USER_DEFINED_COLORS_PROPERTY_FILE);
+ if (userProp != null){
+ p = JMeterUtils.loadProperties(userProp, defaultProps);
+ } else {
+ p=defaultProps;
+ }
+
+ String order = JMeterUtils.getPropDefault(COLORS_ORDER, p.getProperty(ORDER_PROP_NAME));
+
+ if (order == null) {
+ log.warn("Could not find order list");
+ JOptionPane.showMessageDialog(null,
+ JMeterUtils.getResString("toolbar_icon_set_not_found"), // $NON-NLS-1$
+ JMeterUtils.getResString("toolbar_icon_set_not_found"), // $NON-NLS-1$
+ JOptionPane.WARNING_MESSAGE);
+ return null;
+ }
+
+ String[] oList = order.split(ENTRY_SEP);
+
+ List<Color> listColors = new ArrayList<Color>();
+ for (String key : oList) {
+ String trimmed = key.trim();
+ String property = p.getProperty(trimmed);
+ try {
+ String[] lcol = property.split(ENTRY_SEP);
+ Color itb = new Color(Integer.parseInt(lcol[0]), Integer.parseInt(lcol[1]), Integer.parseInt(lcol[2]));
+ listColors.add(itb);
+ } catch (java.lang.Exception e) {
+ log.warn("Error in colors.properties, current property=" + property); // $NON-NLS-1$
+ }
+ }
+ return listColors;
+ }
+
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/Colors.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties?rev=1372926&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties Tue Aug 14 15:30:32 2012
@@ -0,0 +1,49 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Color order. Keys separate by comma.
+order=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
+
+# R,G,B code
+1=7,4,56
+2=220,20,60
+3=0,139,69
+4=255,193,37
+5=139,0,139
+6=91,91,91
+7=255,106,106
+8=205,91,69
+9=0,205,205
+10=176,23,31
+11=0,178,238
+12=139,139,0
+13=238,0,238
+14=3,168,158
+15=139,54,38
+16=143,188,143
+17=184,184,184
+18=113,198,113
+19=255,105,180
+20=135,206,255
+21=124,252,0
+22=79,148,205
+23=10,10,10
+24=139,131,120
+25=64,224,208
+26=198,113,113
+27=255,0,255
+28=205,104,137
+29=192,255,62
+30=197,193,170
\ No newline at end of file
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/components/org/apache/jmeter/visualizers/utils/colors.properties
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1372926&r1=1372925&r2=1372926&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Tue Aug 14 15:30:32 2012
@@ -318,6 +318,22 @@ get_xml_from_file=File with SOAP XML Dat
get_xml_from_random=Message(s) Folder
graph_choose_graphs=Graphs to Display
graph_full_results_title=Graph Full Results
+graph_line_interval_label=Interval (ms):
+graph_line_interval_reload=Apply interval
+graph_line_no_duration=Test with no duration. Unable to graph.
+graph_line_series_selection=Sampler label selection:
+graph_line_settings_line=Line settings
+graph_line_settings_pane=Graph settings
+graph_line_shape_label=Shape point:
+graph_line_stroke_width=Stroke width:
+graph_line_title=Line Graph
+graph_line_title_label=Graph title:
+graph_line_xaxis_time_format=Time format (SimpleDateFormat):
+graph_pointshape_circle=Circle
+graph_pointshape_diamond=Diamond
+graph_pointshape_square=Square
+graph_pointshape_triangle=Triangle
+graph_pointshape_none=None
graph_results_average=Average
graph_results_data=Data
graph_results_deviation=Deviation
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=1372926&r1=1372925&r2=1372926&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 Tue Aug 14 15:30:32 2012
@@ -312,6 +312,22 @@ get_xml_from_file=Fichier avec les donn\
get_xml_from_random=R\u00E9pertoire contenant les fichier(s) \:
graph_choose_graphs=Graphique \u00E0 afficher
graph_full_results_title=Graphique de r\u00E9sultats complets
+graph_line_interval_label=Interval (ms) \:
+graph_line_interval_reload=Appliquer l'interval
+graph_line_no_duration=Test sans dur\u00E9e. Impossible de dessiner le graphique.
+graph_line_series_selection=S\u00E9lection des \u00E9chantillons par libell\u00E9 \:
+graph_line_settings_line=Param\u00E9tres de la courbe
+graph_line_settings_pane=Param\u00E9tres du graphique
+graph_line_shape_label=Forme de la jonction \:
+graph_line_stroke_width=Largeur de ligne \:
+graph_line_title=Graphique \u00E9volution temps de r\u00E9ponses
+graph_line_title_label=Titre du graphique \:
+graph_line_xaxis_time_format=Formatage heure (SimpleDateFormat) \:
+graph_pointshape_circle=Cercle
+graph_pointshape_diamond=Diamant
+graph_pointshape_none=Aucun
+graph_pointshape_square=Carr\u00E9
+graph_pointshape_triangle=Triangle
graph_results_average=Moyenne
graph_results_data=Donn\u00E9es
graph_results_deviation=Ecart type
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1372926&r1=1372925&r2=1372926&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Tue Aug 14 15:30:32 2012
@@ -134,6 +134,7 @@ JSR223 Test Elements using Script file a
<ul>
<li><bugzilla>53566</bugzilla> - Don't log partial responses to the jmeter log</li>
<li><bugzilla>53716</bugzilla> - Small improvements in aggregate graph: legend at left or right is now on 1 column (instead of 1 large line), no border to the reference's square color, reduce width on some fields</li>
+<li><bugzilla>53718</bugzilla> - Add a new visualizer to draw a line graph showing the evolution of response time for a test</li>
</ul>
<h3>Timers, Assertions, Config, Pre- & Post-Processors</h3>
Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1372926&r1=1372925&r2=1372926&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/component_reference.xml Tue Aug 14 15:30:32 2012
@@ -2734,6 +2734,15 @@ the graph as a PNG file.</description>
</div>
</component>
+<component name="Line Graph" index="§-num;.3.12" >
+<description>To do</description>
+<div align="center">
+<p>
+ The figure below shows an example of settings to draw this graph.
+</p>
+</div>
+</component>
+
<component name="Mailer Visualizer" index="§-num;.3.13" width="860" height="463" screenshot="mailervisualizer.png">
<description><p>The mailer visualizer can be set up to send email if a test run receives too many
failed responses from the server.</p></description>