/******************************************************************************* * 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 base class for compressor providing default implementations. */ public abstract class Compress implements ICompress { /** the previous X grid index */ protected int previousXGridIndex; /** the previous Y grid index */ protected int previousYGridIndex; /** the configuration for compressor */ protected CompressConfig config; /** the previous configuration for compressor */ protected CompressConfig prevConfig; /** the flag indicating whether the data is compressed */ protected boolean compressed; /** the source X series to be compressed */ protected double[] xSeries = null; /** the source Y series to be compressed */ protected double[] ySeries = null; /** the compressed X series */ protected transient double[] compressedXSeries = null; /** the compressed Y series */ protected transient double[] compressedYSeries = null; /** the compressed series indexes */ protected transient int[] compressedIndexes = null; /** the lower value of x range */ protected double xLower; /** the upper value of x range */ protected double xUpper; /** the lower value of y range */ protected double yLower; /** the upper value of y range */ protected double yUpper; /** the state indicating if x axis is log scale */ private boolean isXLogScale; /** the state indicating if y axis is log scale */ private boolean isYLogScale; /** the plot area width in pixels */ private long widthInPixel; /** the plot area height in pixels */ private long heightInPixel; /* * @see ICompress#setXSeries(double[]) */ public void setXSeries ( double[] xSeries ) { double[] copiedSeries = new double[xSeries.length]; System.arraycopy ( xSeries, 0, copiedSeries, 0, xSeries.length ); this.xSeries = copiedSeries; compressedXSeries = copiedSeries; compressedIndexes = new int[xSeries.length]; for ( int i = 0; i < xSeries.length; i++ ) { compressedIndexes[i] = i; } compressed = false; } /* * @see ICompress#setYSeries(double[]) */ public void setYSeries ( double[] ySeries ) { double[] copiedSeries = new double[ySeries.length]; System.arraycopy ( ySeries, 0, copiedSeries, 0, ySeries.length ); this.ySeries = copiedSeries; compressedYSeries = copiedSeries; compressed = false; } /* * @see ICompress#getCompressedXSeries() */ public double[] getCompressedXSeries () { double[] copiedSeries = new double[compressedXSeries.length]; System.arraycopy ( compressedXSeries, 0, copiedSeries, 0, compressedXSeries.length ); return copiedSeries; } /* * @see ICompress#getCompressedYSeries() */ public double[] getCompressedYSeries () { double[] copiedSeries = new double[compressedYSeries.length]; System.arraycopy ( compressedYSeries, 0, copiedSeries, 0, compressedYSeries.length ); return copiedSeries; } /* * @see ICompress#getCompressedIndexes() */ public int[] getCompressedIndexes () { int[] copiedSeries = new int[compressedIndexes.length]; System.arraycopy ( compressedIndexes, 0, copiedSeries, 0, compressedIndexes.length ); return copiedSeries; } /* * @see ICompress#compress(CompressConfig) */ final public boolean compress ( CompressConfig compressConfig ) { if ( ( compressConfig.equals ( prevConfig ) && compressed ) || xSeries == null || ySeries == null ) { return false; } // store the previous configuration prevConfig = new CompressConfig ( compressConfig ); this.config = compressConfig; // store into fields to improve performance xLower = config.getXLowerValue (); xUpper = config.getXUpperValue (); yLower = config.getYLowerValue (); yUpper = config.getYUpperValue (); isXLogScale = config.isXLogScale (); isYLogScale = config.isYLogScale (); widthInPixel = config.getWidthInPixel (); heightInPixel = config.getHeightInPixel (); previousXGridIndex = -1; previousYGridIndex = -1; ArrayList<Double> xList = new ArrayList<Double> (); ArrayList<Double> yList = new ArrayList<Double> (); ArrayList<Integer> indexList = new ArrayList<Integer> (); // add necessary plots to the array addNecessaryPlots ( xList, yList, indexList ); compressedXSeries = new double[xList.size ()]; compressedYSeries = new double[yList.size ()]; compressedIndexes = new int[indexList.size ()]; for ( int i = 0; i < xList.size (); i++ ) { compressedXSeries[i] = xList.get ( i ); compressedYSeries[i] = yList.get ( i ); compressedIndexes[i] = indexList.get ( i ); } compressed = true; return true; } /** * Adds the necessary plots. * * @param xList * the array in which x coordinate for necessary plot is stored * @param yList * the array in which y coordinate for necessary plot is stored * @param indexList * the array in which series index for necessary plot is stored */ abstract protected void addNecessaryPlots ( ArrayList<Double> xList, ArrayList<Double> yList, ArrayList<Integer> indexList ); /** * Adds the given coordinate to list. * * @param xList * the list to store the X coordinate * @param yList * the list to store the Y coordinate * @param indexList * the list to store the series index * @param x * the X coordinate * @param y * the Y coordinate * @param index * the series index */ protected void addToList ( ArrayList<Double> xList, ArrayList<Double> yList, ArrayList<Integer> indexList, double x, double y, int index ) { xList.add ( x ); yList.add ( y ); indexList.add ( index ); } /** * Checks if the given coordinate is in the same grid as previous. * * @param x * the X coordinate * @param y * the Y coordinate * @return true if the given coordinate is in the same grid as previous */ protected boolean isInSameGridAsPrevious ( double x, double y ) { int xGridIndex; int yGridIndex; // calculate the X grid index if ( isXLogScale ) { double lower = Math.log10 ( xLower ); double upper = Math.log10 ( xUpper ); xGridIndex = (int) ( ( Math.log10 ( x ) - lower ) / ( upper - lower ) * widthInPixel ); } else { xGridIndex = (int) ( ( x - xLower ) / ( xUpper - xLower ) * widthInPixel ); } // calculate the Y grid index if ( isYLogScale ) { double lower = Math.log10 ( yLower ); double upper = Math.log10 ( yUpper ); yGridIndex = (int) ( ( Math.log10 ( y ) - lower ) / ( upper - lower ) * heightInPixel ); } else { yGridIndex = (int) ( ( y - yLower ) / ( yUpper - yLower ) * heightInPixel ); } // check if the grid index is the same as previous boolean isInSameGridAsPrevious = ( xGridIndex == previousXGridIndex && yGridIndex == previousYGridIndex ); // store the previous grid index previousXGridIndex = xGridIndex; previousYGridIndex = yGridIndex; return isInSameGridAsPrevious; } }