You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by wo...@apache.org on 2004/05/28 04:35:12 UTC
cvs commit: jakarta-jmeter/src/components/org/apache/jmeter/visualizers DistributionGraph.java DistributionGraphVisualizer.java GraphModel.java
woolfel 2004/05/27 19:35:12
Modified: src/components/org/apache/jmeter/visualizers GraphModel.java
Added: src/components/org/apache/jmeter/visualizers
DistributionGraph.java
DistributionGraphVisualizer.java
Log:
checking in the changes for the new Distribution Graph. I've left the
title as "alpha" for now.
Revision Changes Path
1.15 +6 -2 jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java
Index: GraphModel.java
===================================================================
RCS file: /home/cvs/jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- GraphModel.java 13 Feb 2004 01:48:46 -0000 1.14
+++ GraphModel.java 28 May 2004 02:35:12 -0000 1.15
@@ -301,4 +301,8 @@
samples.add(s);
return s;
}
+
+ public StatCalculator getStatCalc(){
+ return this.statCalc;
+ }
}
1.1 jakarta-jmeter/src/components/org/apache/jmeter/visualizers/DistributionGraph.java
Index: DistributionGraph.java
===================================================================
// $Header:
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.Collection;
import javax.swing.JComponent;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import org.apache.jmeter.samplers.Clearable;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.apache.jorphan.math.NumberComparator;
import org.apache.jorphan.math.StatCalculator;
/**
* New graph for drawing distribution graph of the results. It is
* intended as a way to view the data after the stress has been
* performed. Although it can be used at runtime, it is not
* recommended, since it is rather intensive.
* The graph will draw a red line at 90% and an orange line at
* 50%. I like distribution graphs because they allow me to see
* how the data clumps. In general, the data will tend to clump
* in predictable ways when the application is well designed
* and implemented. Data that generates erratic graphs are
* generally not desirable.
*
*/
public class DistributionGraph
extends JComponent
implements Scrollable, GraphListener, Clearable
{
private static Logger log = LoggingManager.getLoggerForClass();
private GraphModel model;
private static int width = 600;
private int xborder = 30;
/**
* the granularity for the distribution
* graph. it can only be whole numbers.
*/
private int granularity = 5;
/**
* there's an option to delay drawing
*/
private boolean delay = false;
/**
* delay redraw
*/
private int counter = 20;
private static int total = -1;
/**
* Constructor for the Graph object.
*/
public DistributionGraph()
{
init();
}
/**
* Constructor for the Graph object.
*/
public DistributionGraph(GraphModel model)
{
this();
setModel(model);
}
public void init(){
repaint();
}
/**
* Gets the ScrollableTracksViewportWidth attribute of the Graph object.
*
* @return the ScrollableTracksViewportWidth value
*/
public boolean getScrollableTracksViewportWidth()
{
return true;
}
/**
* Gets the ScrollableTracksViewportHeight attribute of the Graph object.
*
* @return the ScrollableTracksViewportHeight value
*/
public boolean getScrollableTracksViewportHeight()
{
return true;
}
/**
* Sets the Model attribute of the Graph object.
*/
private void setModel(Object model)
{
this.model = (GraphModel) model;
repaint();
}
/**
* Gets the PreferredScrollableViewportSize attribute of the Graph object.
*
* @return the PreferredScrollableViewportSize value
*/
public Dimension getPreferredScrollableViewportSize()
{
return this.getPreferredSize();
}
/**
* Gets the ScrollableUnitIncrement attribute of the Graph object.
*@return the ScrollableUnitIncrement value
*/
public int getScrollableUnitIncrement(
Rectangle visibleRect,
int orientation,
int direction)
{
return 5;
}
/**
* Gets the ScrollableBlockIncrement attribute of the Graph object.
* @return the ScrollableBlockIncrement value
*/
public int getScrollableBlockIncrement(
Rectangle visibleRect,
int orientation,
int direction)
{
return (int) (visibleRect.width * .9);
}
/**
* Clears this graph.
*/
public void clear()
{}
/**
* method simply calls repaint()
*/
public void updateGui()
{
repaint();
}
/**
* updateGui is called by GraphModel. Unlike Graph
* class, distribution graph can delay drawing
* the graph.
*/
public void updateGui(final Sample oneSample)
{
final GraphModel m = this.model;
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Graphics g = getGraphics();
if (g != null)
{
synchronized(m){
drawSample(m, g);
}
}
}
});
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
final GraphModel m = this.model;
synchronized (m)
{
drawSample(m, g);
}
}
private void drawSample(GraphModel model, Graphics g)
{
width = getWidth();
double height = (double)getHeight() - 1.0;
// first lets draw the grid
for (int y=0; y < 4; y++){
int q1 = (int)(height - (height * 0.25 * y));
g.setColor(Color.lightGray);
g.drawLine(xborder,q1,width,q1);
g.setColor(Color.black);
g.drawString(String.valueOf((25 * y) + "%"),0,q1);
}
g.setColor(Color.black);
// draw the X axis
g.drawLine(xborder,(int)height,width,(int)height);
// draw the Y axis
g.drawLine(xborder,0,xborder,(int)height);
// the test plan has to have more than 200 samples
// for it to generate half way decent distribution
// graph. the larger the sample, the better the
// results.
if (model != null && model.getSampleCount() > 50){
// now draw the bar chart
StatCalculator sc = model.getStatCalc();
Number ninety = sc.getPercentPoint(0.90);
Number fifty = sc.getPercentPoint(0.50);
total = sc.getCount();
Collection values = sc.getDistribution().values();
Object[] objval = new Object[values.size()];
objval = values.toArray(objval);
// we sort the objects
Arrays.sort(objval,new NumberComparator());
int len = objval.length;
for (int count=0; count < len; count++){
// calculate the height
Number[] num = (Number[])objval[count];
double iper = (double)num[1].intValue()/(double)total;
double iheight = height * iper;
// if the height is less than one, we set it
// to one pixel
if (iheight < 1){
iheight = 1.0;
}
int ix = (count * 4) + xborder + 5;
int dheight = (int)(height - iheight);
g.setColor(Color.blue);
g.drawLine(ix -1,(int)height,ix -1,dheight);
g.drawLine(ix,(int)height,ix,dheight);
g.setColor(Color.black);
// draw a red line for 90% point
if (num[0].longValue() == ninety.longValue()){
g.setColor(Color.red);
g.drawLine(ix,(int)height,ix,55);
g.drawLine(ix,(int)35,ix,0);
g.drawString("90%",ix - 30,20);
g.drawString(String.valueOf(num[0].longValue()),ix + 8, 20);
}
// draw an orange line for 50% point
if (num[0].longValue() == fifty.longValue()){
g.setColor(Color.orange);
g.drawLine(ix,(int)height,ix,30);
g.drawString("50%",ix - 30,50);
g.drawString(String.valueOf(num[0].longValue()),ix + 8, 50);
}
}
}
}
}
1.1 jakarta-jmeter/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java
Index: DistributionGraphVisualizer.java
===================================================================
// $Header: /home/cvs/jakarta-jmeter/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java,v 1.1 2004/05/28 02:35:12 woolfel Exp $
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
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;
/**
* This class implements the visualizer for displaying the distribution
* graph. Distribution graphs are useful for standard benchmarks and
* viewing the distribution of data points. Results tend to clump
* together.
*
* Created May 25, 2004
* @version $Revision:
*/
public class DistributionGraphVisualizer extends AbstractVisualizer
implements ImageVisualizer, ItemListener, GraphListener, Clearable
{
GraphModel model;
private JPanel graphPanel = null;
private JTextField noSamplesField = null;
String minute = JMeterUtils.getResString("minute");
private DistributionGraph graph;
private JTextField noteField;
private int delay = 10;
private int counter = 0;
private int cwidth = 0;
private int cheight = 0;
/**
* Constructor for the GraphVisualizer object.
*/
public DistributionGraphVisualizer()
{
model = new GraphModel();
model.addGraphListener(this);
graph = new DistributionGraph(model);
graph.setBackground(Color.white);
init();
}
/**
* Gets the Image attribute of the GraphVisualizer object.
*
* @return the Image value
*/
public Image getImage()
{
Image result = graph.createImage(graph.getWidth(), graph.getHeight());
graph.paintComponent(result.getGraphics());
return result;
}
public synchronized void updateGui()
{
if (graph.getWidth() < 10){
graph.setPreferredSize(new Dimension(getWidth() - 40, getHeight() - 160));
}
graphPanel.updateUI();
graph.updateGui();
}
public synchronized void updateGui(Sample s)
{
// We have received one more sample
if (delay == counter){
graphPanel.updateUI();
graph.updateGui(s);
counter = 0;
} else {
counter++;
}
}
public void add(SampleResult res)
{
model.addSample(res);
}
public String getLabelResource()
{
return "distribution_graph_title";
}
public void itemStateChanged(ItemEvent e)
{
this.graph.repaint();
}
public synchronized void clear()
{
this.graph.clear();
model.clear();
repaint();
}
public String toString()
{
return "Show the samples in a distribution graph";
}
/**
* Initialize the GUI.
*/
private void init()
{
this.setLayout(new BorderLayout());
// MAIN PANEL
Border margin = new EmptyBorder(10, 10, 5, 10);
this.setBorder(margin);
// Set up the graph with header, footer, Y axis and graph display
JPanel graphPanel = new JPanel(new BorderLayout());
graphPanel.add(createGraphPanel(), BorderLayout.CENTER);
graphPanel.add(createGraphInfoPanel(), BorderLayout.SOUTH);
// Add the main panel and the graph
this.add(makeTitlePanel(), BorderLayout.NORTH);
this.add(graphPanel, BorderLayout.CENTER);
}
// Methods used in creating the GUI
/**
* Creates a check box configured to be used to in the choose panel
* allowing the user to select whether or not a particular kind of
* graph data will be displayed.
*
* @param labelResourceName the name of the label resource.
* This is used to look up the label text using
* {@link JMeterUtils#getResString(String)}.
* @param color the color used for the checkbox text. By
* convention this is the same color that is used
* to draw the graph and for the corresponding
* info field.
*
* @return a checkbox allowing the user to select whether or
* not a kind of graph data will be displayed
*/
private JCheckBox createChooseCheckBox(
String labelResourceName,
Color color)
{
JCheckBox checkBox = new JCheckBox(
JMeterUtils.getResString(labelResourceName));
checkBox.setSelected(true);
checkBox.addItemListener(this);
checkBox.setForeground(color);
return checkBox;
}
/**
* Creates a scroll pane containing the actual graph of
* the results.
*
* @return a scroll pane containing the graph
*/
private Component createGraphPanel()
{
graphPanel = new JPanel();
graphPanel.setBorder(BorderFactory.createBevelBorder(
BevelBorder.LOWERED,Color.lightGray,Color.darkGray));
graphPanel.add(graph);
graphPanel.setBackground(Color.white);
return graphPanel;
}
/**
* Creates one of the fields used to display the graph's current
* values.
*
* @param color the color used to draw the value. By convention
* this is the same color that is used to draw the
* graph for this value and in the choose panel.
* @param length the number of digits which the field should be
* able to display
*
* @return a text field configured to display one of the
* current graph values
*/
private JTextField createInfoField(Color color, int length)
{
JTextField field = new JTextField(length);
field.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
field.setEditable(false);
field.setForeground(color);
field.setBackground(getBackground());
// The text field should expand horizontally, but have
// a fixed height
field.setMaximumSize(new Dimension(
field.getMaximumSize().width,
field.getPreferredSize().height));
return field;
}
/**
* Creates a label for one of the fields used to display the graph's
* current values. Neither the label created by this method or the
* <code>field</code> passed as a parameter is added to the GUI here.
*
* @param labelResourceName the name of the label resource.
* This is used to look up the label text using
* {@link JMeterUtils#getResString(String)}.
* @param field the field this label is being created for.
*/
private JLabel createInfoLabel(String labelResourceName, JTextField field)
{
JLabel label = new JLabel(
JMeterUtils.getResString(labelResourceName));
label.setForeground(field.getForeground());
label.setLabelFor(field);
return label;
}
/**
* Creates the information Panel at the bottom
* @return
*/
private Box createGraphInfoPanel()
{
Box graphInfoPanel = Box.createHorizontalBox();
this.noteField = new JTextField();
graphInfoPanel.add(
this.createInfoLabel("distribution_note1",this.noteField)
);
return graphInfoPanel;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org