/*******************************************************************************
* Copyright (c) 2008-2011 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;
}
}