/******************************************************************************* * 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 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) { if (xSeries == null) { return; } 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) { if (ySeries == null) { return; } 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; } }