avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/altprofile/profiler/gui LineChart.java
Date Tue, 05 Mar 2002 03:52:56 GMT
leif        02/03/04 19:52:56

  Modified:    src/scratchpad/org/apache/avalon/excalibur/altprofile/profiler/gui
                        LineChart.java
  Log:
  Made a lot of changes to variable names.  Added a bunch of comments and
    reworked the code a bit.  All to make the code actually be readable,
  Fixed a problem with charts that were displaying very large numbers.  They were
    wrapping when hitting the limits of integer numbers when multiplied by the chart
    height.
  Added better formatting of large numbers in labels so that they are more readable.
  
  Revision  Changes    Path
  1.4       +196 -153  jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/altprofile/profiler/gui/LineChart.java
  
  Index: LineChart.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/altprofile/profiler/gui/LineChart.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LineChart.java	4 Mar 2002 09:17:02 -0000	1.3
  +++ LineChart.java	5 Mar 2002 03:52:56 -0000	1.4
  @@ -15,6 +15,7 @@
   import java.awt.event.MouseEvent;
   import java.awt.event.MouseListener;
   import java.awt.event.MouseMotionListener;
  +import java.text.DecimalFormat;
   import java.text.MessageFormat;
   import java.util.Calendar;
   import java.util.Date;
  @@ -24,7 +25,7 @@
    * Draws a nice pretty chart given a set of data.
    *
    * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
  - * @version CVS $Revision: 1.3 $ $Date: 2002/03/04 09:17:02 $
  + * @version CVS $Revision: 1.4 $ $Date: 2002/03/05 03:52:56 $
    * @since 4.1
    */
   
  @@ -80,6 +81,12 @@
       /** Maximum value in m_values. */
       private int m_max;
       
  +    /** Integer number format. */
  +    private DecimalFormat m_intFormat = new DecimalFormat( "###,###,###,##0" );
  +    
  +    /** Decimal number format. */
  +    private DecimalFormat m_floatFormat = new DecimalFormat( "###,###,###,##0.00" );
  +    
       private boolean m_mouseOver;
       private boolean m_mousePressed;
       private int m_mouseX;
  @@ -276,6 +283,11 @@
           return format;
       }
       
  +    /**
  +     * Paints the component.
  +     *
  +     * @param g Graphics to paint the chart onto.
  +     */
       public synchronized void paintComponent( Graphics g )
       {
           Dimension size = getSize();
  @@ -286,38 +298,43 @@
               size.height - insets.top - insets.bottom );
           
           // Resolve the vertical interval
  -        int vInt = 1;
  -        while ( ( m_max - m_min ) / vInt > 20)
  +        int yLabelInterval = 1;
  +        while ( ( m_max - m_min ) / yLabelInterval > 20)
           {
  -            vInt *= 10;
  +            yLabelInterval *= 10;
           }
           
  -        FontMetrics fm = g.getFontMetrics();
  -        int hlw = fm.stringWidth( Integer.toString( m_max ) );
  -        int fh = fm.getAscent();
  -        int hh = fh / 2;
  +        FontMetrics fontMetrics = g.getFontMetrics();
  +        int maxYLabelWidth = fontMetrics.stringWidth( m_intFormat.format( m_max ) );
  +        int fontHeight = fontMetrics.getAscent();
  +        int fontHalfHeight = fontHeight / 2;
               
  -        int l = insets.left + hlw + 5;
  -        int t = insets.top + 5;
  -        int w = size.width - l - insets.right - 1 - 5;
  -        int h = size.height - t - insets.bottom - 1 - fh;
  +        int chartLeft = insets.left + maxYLabelWidth + 5;
  +        int chartTop = insets.top + 5;
  +        int chartWidth = size.width - chartLeft - insets.right - 1 - 5;
  +        int chartHeight = size.height - chartTop - insets.bottom - 1 - fontHeight;
   
  -        // Draw the vertical grid (Left to Right lines)
  -        int lInt = (int)Math.ceil( (float)fh / ( vInt * h / ( m_max - m_min ) ) );
  -        int lNum = 0;
  -        for ( int i = ( (int)Math.ceil( (float)m_min / vInt ) ) * vInt; i < m_max; i
+= vInt )
  -        {
  -            int y = t + h - ( h * ( i - m_min ) / ( m_max - m_min ) );
  +        // Draw the horizontal grid (Left to Right lines)
  +        int horizonalLineLabeledInterval = (int)Math.ceil( 
  +            (float)fontHeight / ( yLabelInterval * chartHeight / ( m_max - m_min ) ) );
  +        int horizontalLineNumber = 0;
  +        for ( int i = ( (int)Math.ceil( (float)m_min / yLabelInterval ) ) * yLabelInterval;
  +            i < m_max; i += yLabelInterval )
  +        {
  +            // Calculate the location of the line on the y-axis.  Be careful of very large
numbers
  +            int y = chartTop + chartHeight - 
  +                (int)( (long)chartHeight * ( i - m_min ) / ( m_max - m_min ) );
               
  -            if ( lNum >= lInt )
  +            if ( horizontalLineNumber >= horizonalLineLabeledInterval )
               {
  -                lNum = 0;
  +                horizontalLineNumber = 0;
               }
  -            if ( lNum == 0 )
  +            if ( horizontalLineNumber == 0 )
               {
  -                String lbl = Integer.toString( i );
  +                String lbl = m_intFormat.format( i );
                   g.setColor( m_frameColor );
  -                g.drawString( lbl, l - 5 - fm.stringWidth( lbl ), y + hh );
  +                g.drawString( lbl, chartLeft - 5 - fontMetrics.stringWidth( lbl ),
  +                    y + fontHalfHeight );
   
                   g.setColor( m_darkGridColor );
               }
  @@ -325,27 +342,29 @@
               {
                   g.setColor( m_lightGridColor );
               }
  -            lNum++;
  +            horizontalLineNumber++;
               
  -            g.drawLine( l, y, l + w, y );
  +            g.drawLine( chartLeft, y, chartLeft + chartWidth, y );
           }
           
           
           
  -        // Draw the horizontal grid (Top to Bottom lines)
  +        // Draw the vertical grid (Top to Bottom lines)
           
           // Figure out how wide a label is for formatting.
           String format = MessageFormat.format( m_format, new String[] { "00", "00","00",
"00" } );
  -        int fw = fm.stringWidth( format ) + 10;
  +        int fw = fontMetrics.stringWidth( format ) + 10;
           
           // Figure out what internal of lines we can place labels under.
  -        if ( ( m_values.length > 0 ) && ( w > 0 ) )
  +        int verticalLineLabeledInterval;
  +        if ( ( m_values.length > 0 ) && ( chartWidth > 0 ) )
           {
  -            lInt = (int)Math.ceil( (float)fw / ( m_lineSampleInterval * w / ( m_values.length
) ) );
  +            verticalLineLabeledInterval = (int)Math.ceil( (float)fw /
  +                ( m_lineSampleInterval * chartWidth / ( m_values.length ) ) );
           }
           else
           {
  -            lInt = 1;
  +            verticalLineLabeledInterval = 1;
           }
           
           // Calculate a base time for drawing the vertical lines.
  @@ -354,26 +373,28 @@
               ( m_sampleInterval * m_lineSampleInterval );
           
           // Draw each of the lines.
  -        lNum = 0;
  +        int verticalLineNumber = 0;
           for ( int i = 0; i < m_values.length; i++ )
           {
               long time = m_time - ( m_values.length - i - 1 ) * m_sampleInterval;
               if ( ( ( ( time - baseTime ) / m_sampleInterval ) % m_lineSampleInterval )
== 0 )
               {
  -                int x = l + i * w / ( m_values.length - 1 );
  +                int x = chartLeft + i * chartWidth / ( m_values.length - 1 );
                   
                   // Draw a label under the line if line should have a label.
  -                if ( ( lNum >= lInt ) || ( lNum == 0 ) )
  +                if ( ( verticalLineNumber >= verticalLineLabeledInterval ) ||
  +                    ( verticalLineNumber == 0 ) )
                   {
                       format = getFormattedTime( new Date( time ), false );
                       
  -                    if ( x - fm.stringWidth( format ) / 2 >= l )
  +                    if ( x - fontMetrics.stringWidth( format ) / 2 >= chartLeft )
                       {
                           g.setColor( m_frameColor );
  -                        g.drawString( format, x - fm.stringWidth( format ) / 2, t + h +
fh );
  +                        g.drawString( format, x - fontMetrics.stringWidth( format ) / 2,
  +                            chartTop + chartHeight + fontHeight );
                   
                           g.setColor( m_darkGridColor );
  -                        lNum = 1;
  +                        verticalLineNumber = 1;
                       }
                       else
                       {
  @@ -383,11 +404,11 @@
                   else
                   {
                       g.setColor( m_lightGridColor );
  -                    lNum++;
  +                    verticalLineNumber++;
                   }
                   
                   // Draw the vertical line
  -                g.drawLine( x, t, x, t + h );
  +                g.drawLine( x, chartTop, x, chartTop + chartHeight );
               }
           }
           
  @@ -395,10 +416,13 @@
           
           // Draw the frame
           g.setColor( m_frameColor );
  -        g.drawLine( l, t, l, t + h );
  -        g.drawLine( l, t + h, l + w, t + h );
  +        g.drawLine( chartLeft, chartTop, chartLeft, chartTop + chartHeight );
  +        g.drawLine( chartLeft, chartTop + chartHeight, chartLeft + chartWidth,
  +            chartTop + chartHeight );
           
  -        // Draw the counts
  +        
  +        
  +        // Draw the the values that make up the data of the chart.
           if ( ( m_averageWindow > 0 ) && ( m_mousePressed ) )
           {
               g.setColor( m_lightLineColor );
  @@ -408,164 +432,183 @@
               g.setColor( m_lineColor );
           }
           
  -        int lx = 0;
  -        int ly = 0;
  +        int lastX = 0;
  +        int lastY = 0;
           for ( int i = 0; i < m_values.length; i++ )
           {
  -            int x = l + i * w / ( m_values.length - 1 );
  -            int y = t + h - ( h * ( m_values[i] - m_min ) / ( m_max - m_min ) );
  +            // Calculate the location of the point on the x-axis.
  +            int x = chartLeft + i * chartWidth / ( m_values.length - 1 );
  +            
  +            // Calculate the location of the line on the y-axis.  Be careful of very large
numbers
  +            int y = chartTop + chartHeight - 
  +                (int)( (long)chartHeight * ( m_values[i] - m_min ) / ( m_max - m_min )
);
               
               if ( i > 0 )
               {
  -                g.drawLine( lx, ly, x, y );
  +                g.drawLine( lastX, lastY, x, y );
               }
               
  -            lx = x;
  -            ly = y;
  +            lastX = x;
  +            lastY = y;
           }
           
  -        // Draw the average chart
  +        // Draw the averaged values of the chart
           if ( ( m_averageWindow > 0 ) && ( m_mousePressed ) )
           {
               g.setColor( m_lineColor );
  -            lx = 0;
  -            ly = 0;
  +            lastX = 0;
  +            lastY = 0;
               for ( int i = m_averageWindow; i < m_averageWindowValues.length; i++ )
               {
  -                int x = l + i * w / ( m_averageWindowValues.length - 1 );
  -                int y = t + h - (int)( h * ( m_averageWindowValues[i] - m_min ) /
  +                // Calculate the location of the point on the x-axis.
  +                int x = chartLeft + i * chartWidth / ( m_averageWindowValues.length - 1
);
  +                
  +                // Calculate the location of the line on the y-axis.  Be careful of very
large
  +                //  numbers.  The float value average valus makes this easy here.
  +                int y = chartTop + chartHeight - 
  +                    (int)( chartHeight * ( m_averageWindowValues[i] - m_min ) /
                       ( m_max - m_min ) );
                   
                   if ( i > m_averageWindow )
                   {
  -                    g.drawLine( lx, ly, x, y );
  +                    g.drawLine( lastX, lastY, x, y );
                   }
                   
  -                lx = x;
  -                ly = y;
  +                lastX = x;
  +                lastY = y;
               }
           }
           
           // Make the label visible if the user tracks over any part of the chart.
  -        if ( ( m_mouseOver ) && ( m_mouseX >= l ) && ( m_mouseX <=
l + w ) )
  +        if ( ( m_mouseOver ) && ( m_mouseX >= chartLeft ) &&
  +            ( m_mouseX <= chartLeft + chartWidth ) )
           {
  -            // Figure out where the mouse is
  -            int index = (int)Math.round( (float)( m_values.length - 1 ) * ( m_mouseX -
l ) / w );
  +            // Figure out the index of the data point where the mouse is.
  +            int index = (int)Math.round( 
  +                (float)( m_values.length - 1 ) * ( m_mouseX - chartLeft ) / chartWidth
);
  +            
  +            // Draw the label
  +            int mouseDataPointX = 0;
  +            int mouseDataPointY = 0;
  +            String mouseDataPointValue = null;
  +            long mouseDataPointTime = 0;
  +            boolean showLabel = false;
  +            
               if ( ( m_averageWindow > 0 ) && ( m_mousePressed ) )
               {
  -                // Draw the label for the average data
                   if ( ( index >= m_averageWindow ) && ( index < m_averageWindowValues.length
) )
                   {
  -                    int mx = l + index * w / ( m_averageWindowValues.length - 1 );
  -                    int my = t + h - (int)( h * ( m_averageWindowValues[index] - m_min
) /
  +                    // Draw the label for the average data
  +                    
  +                    // Calculate the location of the point on the x-axis.
  +                    mouseDataPointX = chartLeft + index * chartWidth /
  +                        ( m_averageWindowValues.length - 1 );
  +                    
  +                    // Calculate the location of the line on the y-axis.  Be careful of
very large
  +                    //  numbers.  The float value average valus makes this easy here.
  +                    mouseDataPointY = chartTop + chartHeight -
  +                        (int)( chartHeight * ( m_averageWindowValues[index] - m_min ) /
                           ( m_max - m_min ) );
  -                    float mc = (float)( (int)( m_averageWindowValues[index] * 100 ) ) /
100;
  -                    long mt = m_time - ( m_averageWindowValues.length - index - 1 ) * m_sampleInterval;
                       
  -                    g.setColor( m_crossColor );
  -                    g.drawLine( mx, t, mx, t + h );
  -                    g.drawLine( l, my, l + w, my );
  -                    format = mc + " : " + getFormattedTime( new Date( mt ), true );
  -                    int tw = fm.stringWidth( format );
  -                    int ll, lt;
  +                    // Round the average value to 2 decimal places.
  +                    mouseDataPointValue = m_floatFormat.format( m_averageWindowValues[index]
);
                       
  -                    // Decide where to put the label
  -                    if ( mx + 5 + tw < l + w )
  -                    {
  -                        // Ok on the right
  -                        ll = mx + 4;
  -                        if ( my + 5 + fh < t + h )
  -                        {
  -                            // Ok on the bottom
  -                            lt = my + 4;
  -                        }
  -                        else
  -                        {
  -                            // Must go on the top
  -                            lt = my - 4 - fh;
  -                        }
  -                    }
  -                    else
  -                    {
  -                        // Must go on the left
  -                        ll = mx - 4 - tw;
  -                        if ( my + 5 + fh < t + h )
  -                        {
  -                            // Ok on the bottom
  -                            lt = my + 4;
  -                        }
  -                        else
  -                        {
  -                            // Must go on the top
  -                            lt = my - 4 - fh;
  -                        }
  -                    }
  +                    // Get the time at the mouse data point
  +                    mouseDataPointTime = m_time - 
  +                        ( m_averageWindowValues.length - index - 1 ) * m_sampleInterval;
                       
  -                    // Paint the label
  -                    g.setColor( m_maskFrameColor );
  -                    g.drawRect( ll - 1, lt - 1, tw + 2, fh + 2 );
  -                    g.setColor( m_maskColor );
  -                    g.fillRect( ll - 1, lt - 1, tw + 2, fh + 2 );
  -                    g.setColor( m_crossColor );
  -                    g.drawString( format, ll, lt + fh );
  +                    showLabel = true;
                   }
               }
               else
               {
  -                // Draw the label for the regular data
                   if ( ( index >= 0 ) && ( index < m_values.length ) )
                   {
  -                    int mx = l + index * w / ( m_values.length - 1 );
  -                    int my = t + h - ( h * ( m_values[index] - m_min ) / ( m_max - m_min
) );
  -                    int mc = m_values[index];
  -                    long mt = m_time - ( m_values.length - index - 1 ) * m_sampleInterval;
  -                    
  -                    g.setColor( m_crossColor );
  -                    g.drawLine( mx, t, mx, t + h );
  -                    g.drawLine( l, my, l + w, my );
  -                    format = mc + " : " + getFormattedTime( new Date( mt ), true );
  -                    int tw = fm.stringWidth( format );
  -                    int ll, lt;
  +                    // Draw the label for the regular data.
  +                    
  +                    // Calculate the location of the point on the x-axis.
  +                    mouseDataPointX = chartLeft + index * chartWidth / ( m_values.length
- 1 );
  +                    
  +                    // Calculate the location of the line on the y-axis.  Be careful of
very large
  +                    //  numbers.
  +                    mouseDataPointY = chartTop + chartHeight - 
  +                        (int)( (long)chartHeight * ( m_values[index] - m_min ) /
  +                        ( m_max - m_min ) );
  +                    
  +                    // Get the average value.
  +                    mouseDataPointValue = m_intFormat.format( m_values[index] );
  +                    
  +                    // Get the time at the mouse data point
  +                    mouseDataPointTime = m_time - ( m_values.length - index - 1 ) *
  +                        m_sampleInterval;
                       
  -                    // Decide where to put the label
  -                    if ( mx + 5 + tw < l + w )
  +                    showLabel = true;
  +                }
  +            }
  +            
  +            if ( showLabel )
  +            {
  +                // Draw a cross at the point being to be labeled.
  +                g.setColor( m_crossColor );
  +                g.drawLine( mouseDataPointX, chartTop, mouseDataPointX, chartTop + chartHeight
);
  +                g.drawLine( chartLeft, mouseDataPointY, chartLeft + chartWidth, mouseDataPointY
);
  +                
  +                // Get the text of the label
  +                String mouseDataPointLabel = mouseDataPointValue + " : " + 
  +                    getFormattedTime( new Date( mouseDataPointTime ), true );
  +                int mouseDataPointLabelWidth = fontMetrics.stringWidth( mouseDataPointLabel
);
  +                int mouseDataPointLabelLeft;
  +                int mouseDataPointLabelTop;
  +                
  +                // If the point is near the edges of the chart, then it would run off the
chart.
  +                //  To avoid this, the label is moved around relative to the location of
the cross.
  +                //  Decide where it should go.
  +                if ( mouseDataPointX + 5 + mouseDataPointLabelWidth < chartLeft + chartWidth
)
  +                {
  +                    // Ok on the right
  +                    mouseDataPointLabelLeft = mouseDataPointX + 4;
  +                    if ( mouseDataPointY + 5 + fontHeight < chartTop + chartHeight )
                       {
  -                        // Ok on the right
  -                        ll = mx + 4;
  -                        if ( my + 5 + fh < t + h )
  -                        {
  -                            // Ok on the bottom
  -                            lt = my + 4;
  -                        }
  -                        else
  -                        {
  -                            // Must go on the top
  -                            lt = my - 4 - fh;
  -                        }
  +                        // Ok on the bottom
  +                        mouseDataPointLabelTop = mouseDataPointY + 4;
                       }
                       else
                       {
  -                        // Must go on the left
  -                        ll = mx - 4 - tw;
  -                        if ( my + 5 + fh < t + h )
  -                        {
  -                            // Ok on the bottom
  -                            lt = my + 4;
  -                        }
  -                        else
  -                        {
  -                            // Must go on the top
  -                            lt = my - 4 - fh;
  -                        }
  +                        // Must go on the top
  +                        mouseDataPointLabelTop = mouseDataPointY - 4 - fontHeight;
                       }
  -                    // Paint the label
  -                    g.setColor( m_maskFrameColor );
  -                    g.drawRect( ll - 1, lt - 1, tw + 2, fh + 2 );
  -                    g.setColor( m_maskColor );
  -                    g.fillRect( ll - 1, lt - 1, tw + 2, fh + 2 );
  -                    g.setColor( m_crossColor );
  -                    g.drawString( format, ll, lt + fh );
                   }
  +                else
  +                {
  +                    // Must go on the left
  +                    mouseDataPointLabelLeft = mouseDataPointX - 4 - mouseDataPointLabelWidth;
  +                    if ( mouseDataPointY + 5 + fontHeight < chartTop + chartHeight )
  +                    {
  +                        // Ok on the bottom
  +                        mouseDataPointLabelTop = mouseDataPointY + 4;
  +                    }
  +                    else
  +                    {
  +                        // Must go on the top
  +                        mouseDataPointLabelTop = mouseDataPointY - 4 - fontHeight;
  +                    }
  +                }
  +                
  +                // Draw an outline around the location of the label.
  +                g.setColor( m_maskFrameColor );
  +                g.drawRect( mouseDataPointLabelLeft - 1, mouseDataPointLabelTop - 1,
  +                    mouseDataPointLabelWidth + 2, fontHeight + 2 );
  +                
  +                // Draw the background of the label.  By default this is partly transparent
and
  +                //  looks better on top of the outline.
  +                g.setColor( m_maskColor );
  +                g.fillRect( mouseDataPointLabelLeft - 1, mouseDataPointLabelTop - 1,
  +                    mouseDataPointLabelWidth + 2, fontHeight + 2 );
  +                
  +                // Draw the text of the label.
  +                g.setColor( m_crossColor );
  +                g.drawString( mouseDataPointLabel, mouseDataPointLabelLeft,
  +                    mouseDataPointLabelTop + fontHeight );
               }
           }
       }
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message