/*******************************************************************************
* Copyright (c) 2008-2009 SWTChart project. All rights reserved.
*
* This code is distributed under the terms of the Eclipse Public License v1.0
* which is available at http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.swtchart.internal.compress;
import java.util.ArrayList;
/**
* A compressor for line series data.
*/
public class CompressLineSeries extends Compress
{
/** the state indicating the relation between previous and current data points */
enum STATE
{
/** stepping over x range */
SteppingOverXRange,
/** stepping over y range */
SteppingOverYRange,
/** out of range again */
OutOfRangeAgain,
/** stepping out of x range */
SteppingOutOfXRange,
/** stepping in x range */
SteppingInXRange,
/** stepping out of y range */
SteppingOutOfYRange,
/** stepping out of range */
SteppingOutOfRange,
/** in range again */
InRangeAgain,
/** stepping in range */
SteppingInRange;
}
/** the flag indicating whether the previous point is out of range */
private boolean isPrevOutOfRange;
/*
* @see Compress#addNecessaryPlots(ArrayList, ArrayList, ArrayList)
*/
@Override
protected void addNecessaryPlots ( ArrayList<Double> xList, ArrayList<Double> yList, ArrayList<Integer> indexList )
{
isPrevOutOfRange = true;
for ( int i = 0; i < xSeries.length; i++ )
{
STATE state = getState ( i );
switch ( state )
{
case SteppingOutOfYRange:
addToList ( xList, yList, indexList, xSeries[i], ySeries[i], i );
break;
case SteppingOverYRange:
case SteppingInRange:
case SteppingInXRange:
addToList ( xList, yList, indexList, xSeries[i - 1], ySeries[i - 1], i - 1 );
addToList ( xList, yList, indexList, xSeries[i], ySeries[i], i );
break;
case SteppingOverXRange:
case SteppingOutOfXRange:
addToList ( xList, yList, indexList, xSeries[i - 1], ySeries[i - 1], i - 1 );
addToList ( xList, yList, indexList, xSeries[i], ySeries[i], i );
i = xSeries.length;
break;
case SteppingOutOfRange:
addToList ( xList, yList, indexList, xSeries[i], ySeries[i], i );
i = xSeries.length;
break;
case InRangeAgain:
if ( !isInSameGridAsPrevious ( xSeries[i], ySeries[i] ) )
{
addToList ( xList, yList, indexList, xSeries[i], ySeries[i], i );
}
break;
case OutOfRangeAgain:
break;
default:
break;
}
}
}
/**
* Gets the state for each plot.
*
* @param index
* the index for plot
* @return the state of plot for the given index
*/
private STATE getState ( int index )
{
STATE state;
if ( xLower <= xSeries[index] && xSeries[index] <= xUpper )
{
if ( yLower <= ySeries[index] && ySeries[index] <= yUpper )
{
if ( index > 0 && isPrevOutOfRange )
{
state = STATE.SteppingInRange;
}
else
{
state = STATE.InRangeAgain;
}
}
else
{
if ( isPrevOutOfRange )
{
if ( index > 0 && ySeries[index - 1] < yLower && ySeries[index] > yUpper )
{
state = STATE.SteppingOverYRange;
}
else if ( index > 0 && xSeries[index - 1] < xLower && xSeries[index] > xLower )
{
state = STATE.SteppingInXRange;
}
else
{
state = STATE.OutOfRangeAgain;
}
}
else
{
state = STATE.SteppingOutOfYRange;
}
}
}
else
{
if ( !isPrevOutOfRange )
{
state = STATE.SteppingOutOfRange;
}
else if ( index > 0 && xSeries[index - 1] < xUpper && xSeries[index] > xUpper )
{
state = STATE.SteppingOutOfXRange;
}
else if ( index > 0 && xSeries[index - 1] < xLower && xSeries[index] > xUpper )
{
state = STATE.SteppingOverXRange;
}
else
{
state = STATE.OutOfRangeAgain;
}
}
// set flag
if ( xLower <= xSeries[index] && xSeries[index] <= xUpper && yLower <= ySeries[index] && ySeries[index] <= yUpper )
{
isPrevOutOfRange = false;
}
else
{
isPrevOutOfRange = true;
}
return state;
}
}