krysalis-jcharts/src/java/org/krysalis/jcharts/axisChart RegressionChart.java,NONE,1.1
"Nathaniel G. Auvil" <[email protected]> Fri, 13 Aug 2004 01:47:22 +0000
| Newsgroups | gmane.comp.krysalis.jcharts.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/jcharts/krysalis-jcharts/src/java/org/krysalis/jcharts/axisChart
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20451/src/java/org/krysalis/jcharts/axisChart
Added Files:
RegressionChart.java
Log Message:
--- NEW FILE: RegressionChart.java ---
/*****************************************************************************************
* File Info: $Id: RegressionChart.java,v 1.1 2004/08/13 01:47:19 nathaniel_auvil Exp $
* Copyright (C) 2002 Author: Nathaniel G. Auvil Contributor(s):
*
* Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved.
*
* Redistribution and use of this software and associated documentation ("Software"), with
* or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and notices.
* Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote
* products derived from this Software without prior written permission of Nathaniel G.
* Auvil. For written permission, please contact [email protected]
*
* 4. Products derived from this Software may not be called "jCharts" nor may "jCharts"
* appear in their names without prior written permission of Nathaniel G. Auvil. jCharts
* is a registered trademark of Nathaniel G. Auvil.
*
* 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/).
*
* THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
****************************************************************************************/
package org.krysalis.jcharts.axisChart;
import java.awt.*;
import java.awt.geom.*;
import java.util.Vector;
import java.util.Enumeration;
import org.krysalis.jcharts.axisChart.axis.YAxis;
import org.krysalis.jcharts.chartData.interfaces.IAxisChartDataSet;
import org.krysalis.jcharts.chartData.interfaces.IDataSeries;
import org.krysalis.jcharts.imageMap.CircleMapArea;
import org.krysalis.jcharts.properties.LineChartProperties;
import org.krysalis.jcharts.properties.PropertyException;
public class RegressionChart
{
// STUFF FOR REGRESSION
int numberLocs = 0;
int sumxx = 0;
int sumyy = 0;
int sumxy = 0;
int sumx = 0;
int sumy = 0;
double Sxx, Sxy, Syy;
double a, b; //regression coefficients
Vector v = new Vector(); //vector of points
Vector residuals = new Vector(); //vector of residuals
public RegressionChart()
{
};
private double figureY( YAxis yAxis, double num )
{
return yAxis.computeAxisCoordinate( yAxis.getOrigin(), num, yAxis.getScaleCalculator().getMinValue() );
}
/***************************************************************************************
* Draws the chart
*
* @param axisChart
* @param iAxisChartDataSet
* @throws PropertyException
**************************************************************************************/
public void render( AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet ) throws PropertyException
{
Graphics2D g2d = axisChart.getGraphics2D();
LineChartProperties lineChartProperties = (LineChartProperties) iAxisChartDataSet.getChartTypeProperties();
lineChartProperties.validate( iAxisChartDataSet );
//DataAxisProperties dataAxisProperties= (DataAxisProperties)
// axisChart.getAxisProperties().getYAxisProperties();
IDataSeries iDataSeries = (IDataSeries) axisChart.getIAxisDataSeries();
//---cache the computed values
float[][] yAxisCoordinates = new float[iAxisChartDataSet.getNumberOfDataSets()][iAxisChartDataSet.getNumberOfDataItems()];
//---need this for image map calculation
float xMapCoordinate = axisChart.getXAxis().getTickStart();
//LOOP
for( int j = 0; j < iAxisChartDataSet.getNumberOfDataItems(); j++ )
{
//LOOP
for( int i = 0; i < yAxisCoordinates.length; i++ )
{
if( iAxisChartDataSet.getValue( i, j ) != Double.NaN )
{
yAxisCoordinates[i][j] = axisChart.getYAxis().computeAxisCoordinate( axisChart.getYAxis().getOrigin(),
iAxisChartDataSet.getValue( i, j ),
axisChart .getYAxis()
.getScaleCalculator()
.getMinValue() );
addLoc( new Loc( j, iAxisChartDataSet.getValue( i, j ) ) );
//---if we are generating an ImageMap, store the image coordinates
if( axisChart.getGenerateImageMapFlag() )
{
String label;
if( axisChart.getXAxis().getAxisLabelsGroup() != null )
{
label = axisChart.getXAxis().getAxisLabelsGroup().getTextTag( j ).getText();
}
else
{
label = null;
}
axisChart.getImageMap().addImageMapArea( new CircleMapArea( xMapCoordinate,
yAxisCoordinates[i][j],
iAxisChartDataSet.getValue( i, j ),
label,
iAxisChartDataSet.getLegendLabel( i ) ) );
}
}
else
{
yAxisCoordinates[i][j] = Float.NaN;
}
}
xMapCoordinate += axisChart.getXAxis().getScalePixelWidth();
}
AffineTransform originalTransform = null;
double[] cornerXOffset = null;
double[] cornerYOffset = null;
//---check if there are any points to display
if( lineChartProperties.getShapes() != null )
{
//---when centering the shapes on the points, need x and y offset to do this
cornerXOffset = new double[iAxisChartDataSet.getNumberOfDataSets()];
cornerYOffset = new double[iAxisChartDataSet.getNumberOfDataSets()];
//---get the original transform so can reset it.
originalTransform = g2d.getTransform();
Rectangle2D rectangle;
//LOOP
//---pre-compute the dimensions of each Shape so do not do it in loop.
for( int i = 0; i < iAxisChartDataSet.getNumberOfDataSets(); i++ )
{
if( lineChartProperties.getShapes()[i] != null )
{
rectangle = lineChartProperties.getShapes()[i].getBounds2D();
cornerXOffset[i] = rectangle.getWidth() / 2;
cornerYOffset[i] = rectangle.getHeight() / 2;
Vector v = regress();
// y = yoffset + slope(x)
double yoffset, slope; // round to 5 places
yoffset = (Math.round( 1.0E5 * a )) * 1.0E-5;
slope = (Math.round( 1.0E5 * b )) * 1.0E-5;
g2d.setPaint( iAxisChartDataSet.getPaint( i ) );
//g2d.fill( lineChartProperties.getShapes()[ i ] );
g2d.setStroke( lineChartProperties.getLineStrokes()[i] );
//Line2D.Double line = new Line2D.Double(start.x, start.y, end.x, end.y);
Line2D.Double line = new Line2D.Double( axisChart.getXAxis().getTickStart(),
figureY( axisChart.getYAxis(), (yoffset + slope * 0) ),
axisChart.getXAxis().getTickStart()
+ axisChart.getXAxis().getScalePixelWidth() * (v.size()-1),
figureY( axisChart.getYAxis(), (yoffset + slope * v.size()) ) );
//g2d.fill( line );
g2d.draw( line );
g2d.setTransform( originalTransform );
}
}
}
//String form = "formula y = "+String.valueOf(yoffset)+" +
// "+String.valueOf(slope)+"x";
//g2d.drawString(form , 151, 156);
//---init for first segment
/*
* Line2D.Float line=new Line2D.Float( axisChart.getXAxis().getTickStart(),
* yAxisCoordinates[ 0 ][ 0 ], axisChart.getXAxis().getTickStart(), yAxisCoordinates[
* 0 ][ 0 ] );
*/
//---make sure not plotting a chart with only one data point.
/*
* if( yAxisCoordinates[ 0 ].length > 1 ) { line.y2= yAxisCoordinates[ 0 ][ 1 ]; }
*/
//LOOP
//---draw each line to the image
/*
* for( int i=0; i < yAxisCoordinates.length; i++ ) {
* line.x1=axisChart.getXAxis().getTickStart(); line.y1=yAxisCoordinates[ i ][ 0 ];
* line.x2=line.x1;
*
* //LOOP for( int j=1; j < yAxisCoordinates[ 0 ].length; j++ ) { //---if current
* point on line should be drawn if( !Float.isNaN( yAxisCoordinates[ i ][ j ] ) ) {
* //---if the previous point was not drawn, no line if( Float.isNaN(
* yAxisCoordinates[ i ][ j - 1 ] ) ) {
* line.x2+=axisChart.getXAxis().getScalePixelWidth(); line.x1=line.x2;
* line.y1=yAxisCoordinates[ i ][ j ]; line.y2=yAxisCoordinates[ i ][ j ];
*
* continue; }
*
*
* line.x2+=axisChart.getXAxis().getScalePixelWidth(); line.y2=yAxisCoordinates[ i ][
* j ];
*
* g2d.setPaint( iAxisChartDataSet.getPaint( i ) ); g2d.setStroke(
* lineChartProperties.getLineStrokes()[ i ] ); g2d.draw( line );
*
* //---plot the Point if( lineChartProperties.getShapes()[ i ] != null ) {
* //---translate the Shape into position. g2d.translate( line.x1 - cornerXOffset[ i ],
* line.y1 - cornerYOffset[ i ] );
*
* g2d.setPaint( iAxisChartDataSet.getPaint( i ) ); g2d.fill(
* lineChartProperties.getShapes()[ i ] );
*
* //---translate back to the original position g2d.setTransform( originalTransform ); }
*
* line.x1=line.x2; line.y1=line.y2; } else { if( ( !Float.isNaN( yAxisCoordinates[ i ][
* j - 1 ] ) ) && ( lineChartProperties.getShapes()[ i ] != null ) ) { //---translate
* the Shape into position. g2d.translate( line.x1 - cornerXOffset[ i ], line.y1 -
* cornerYOffset[ i ] );
*
* g2d.setPaint( iAxisChartDataSet.getPaint( i ) ); g2d.fill(
* lineChartProperties.getShapes()[ i ] );
*
* //---translate back to the original position g2d.setTransform( originalTransform ); }
*
* line.x2+=axisChart.getXAxis().getScalePixelWidth(); line.x1=line.x2; } }
*
*
* //---put the last shape on the line if( ( !Float.isNaN( yAxisCoordinates[ i ][
* yAxisCoordinates[ i ].length - 1 ] ) ) && ( lineChartProperties.getShapes()[ i ] !=
* null ) ) { //---translate the Shape into position. g2d.translate( line.x2 -
* cornerXOffset[ i ], line.y2 - cornerYOffset[ i ] );
*
* g2d.setPaint( iAxisChartDataSet.getPaint( i ) ); g2d.fill(
* lineChartProperties.getShapes()[ i ] );
*
* //---translate back to the original position g2d.setTransform( originalTransform ); } }
*/
}
private Vector regress()
{
Vector resid = new Vector();
Loc p, q;
double currentResidual;
double n = (double) numberLocs;
Sxx = sumxx - sumx * sumx / n;
Syy = sumyy - sumy * sumy / n;
Sxy = sumxy - sumx * sumy / n;
b = Sxy / Sxx;
a = (sumy - b * sumx) / n;
for( Enumeration e = v.elements(); e.hasMoreElements(); )
{
p = (Loc) e.nextElement();
currentResidual = p.y - (a + b * p.x);
q = new Loc( p.x, (int) currentResidual );
resid.addElement( q );
}
return resid;
}
private void calculate( int numLocs )
{
if( numberLocs > 1 )
{
residuals = regress();
}
}
private void addLoc( Loc p )
{
v.addElement( p );
numberLocs++;
sumx += p.x;
sumy += p.y;
sumxx += p.x * p.x;
sumyy += p.y * p.y;
sumxy += p.x * p.y;
}
private static class Loc
{
public double x;
public double y;
public Loc( double x, double y )
{
this.x = x;
this.y = y;
}
public String toString()
{
return "[" + this.x + ", " + this.y + "]";
}
}
}
-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285