/* @(#)SleepChartData.java * *======================================================================== * Copyright 2011 by Zeo Inc. All Rights Reserved *======================================================================== * * Date: $Date$ * Author: Jon Willis * Author: Brandon Edens <brandon.edens@myzeo.com> * Version: $Revision$ */ package com.androsz.electricsleepbeta.widget; import java.util.List; import org.achartengine.model.PointD; import org.achartengine.model.XYMultipleSeriesDataset; import org.achartengine.model.XYSeries; import org.achartengine.renderer.XYMultipleSeriesRenderer; import org.achartengine.renderer.XYSeriesRenderer; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import com.androsz.electricsleepbeta.R; import com.androsz.electricsleepbeta.app.SleepMonitoringService; /** * Data container for sleep chart points and information. This class is * parcelable and is the method by which sleep chart data is saved across screen * rotates. * * @author Jon Willis * @author Brandon Edens * @version $Revision$ */ public class SleepChartData implements Parcelable { private static final String TAG = SleepChartData.class.getSimpleName(); /** * Flag that indicates sleep chart needs a clear prior to insertion of new * data. */ private boolean mNeedsClear; private XYSeries mXYSeriesMovement; private XYSeries mXYSeriesCalibration; private XYSeriesRenderer mXYSeriesCalibrationRenderer; private XYSeriesRenderer mXYSeriesMovementRenderer; private float mCalibrationLevel; public float getCalibrationLevel() { return mCalibrationLevel; } public void setCalibrationLevel(float calibrationLevel) { mCalibrationLevel = calibrationLevel; } public static final Parcelable.Creator<SleepChartData> CREATOR = new Parcelable.Creator<SleepChartData>() { public SleepChartData createFromParcel(Parcel in) { return new SleepChartData(in); } public SleepChartData[] newArray(int size) { return new SleepChartData[size]; } }; /** * Build sleep chart data from the given context. The context is used to * extract default strings used for movement and calibration legends. */ public SleepChartData(final Context context) { mXYSeriesMovement = new XYSeries( context.getString(R.string.legend_movement)); // WARNING - the movement must be populated with some initial data in // order for this view to // properly render. mNeedsClear = true; mXYSeriesMovement.add(0, 0); mXYSeriesMovementRenderer = new XYSeriesRenderer(); mXYSeriesMovementRenderer.setFillBelowLine(true); mXYSeriesMovementRenderer.setLineWidth(3); mXYSeriesCalibration = new XYSeries( context.getString(R.string.legend_light_sleep_trigger)); mXYSeriesCalibrationRenderer = new XYSeriesRenderer(); mXYSeriesCalibrationRenderer.setFillBelowLine(true); mXYSeriesCalibrationRenderer.setLineWidth(3); } private SleepChartData(Parcel in) { mXYSeriesMovement = (XYSeries) in.readSerializable(); mXYSeriesMovementRenderer = (XYSeriesRenderer) in.readSerializable(); mXYSeriesCalibration = (XYSeries) in.readSerializable(); mXYSeriesCalibrationRenderer = (XYSeriesRenderer) in.readSerializable(); mCalibrationLevel = in.readFloat(); } public void add(double x, double y) { synchronized (mXYSeriesMovement) { if (mNeedsClear) { mXYSeriesMovement.clear(); mNeedsClear = false; } if (mXYSeriesMovement.getItemCount() >= SleepMonitoringService.MAX_POINTS_IN_A_GRAPH) { mXYSeriesMovement.remove(0); } mXYSeriesMovement.add(x, y); } } public double getLeftMostTime() { return mXYSeriesMovement.getX(0); } public double getRightMostTime() { synchronized (mXYSeriesMovement) { return mXYSeriesMovement.getX(mXYSeriesMovement.getItemCount() - 1); } } /** * Return the duration or the last timestamp minus the first timestamp. */ public double getDuration() { final double firstX; final double lastX; synchronized (mXYSeriesMovement) { firstX = mXYSeriesMovement.getX(0); lastX = mXYSeriesMovement .getX(mXYSeriesMovement.getItemCount() - 1); } final long duration = (long) (lastX - firstX); return duration; } public void set(List<PointD> points) { mXYSeriesMovement.setXY(points); } public void setupCalibrationSpan(double left, double right) { final float calibrationLevel = getCalibrationLevel(); synchronized (mXYSeriesCalibration) { // reconfigure the calibration line.. mXYSeriesCalibration.clear(); mXYSeriesCalibration.add(left, calibrationLevel); mXYSeriesCalibration.add(right, calibrationLevel); } } public void clear() { Log.d(TAG, "Clearing sleep chart."); mXYSeriesMovement.clear(); mXYSeriesCalibration.clear(); } @Override public int describeContents() { Log.d(TAG, "Describing contents as 0."); return 0; } public boolean hasTwoOrMorePoints() { return mXYSeriesMovement.getItemCount() > 1; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeSerializable(mXYSeriesMovement); dest.writeSerializable(mXYSeriesMovementRenderer); dest.writeSerializable(mXYSeriesCalibration); dest.writeSerializable(mXYSeriesCalibrationRenderer); dest.writeFloat(mCalibrationLevel); } public void attachToDataset(XYMultipleSeriesDataset dataset) { dataset.addSeries(mXYSeriesMovement); dataset.addSeries(mXYSeriesCalibration); } public void attachToRenderer(XYMultipleSeriesRenderer mRenderer) { // set up the dataset renderer mRenderer.addSeriesRenderer(mXYSeriesMovementRenderer); mRenderer.addSeriesRenderer(mXYSeriesCalibrationRenderer); } public void setSeriesColors(int mMovementColor, int mMovementBorderColor, int mCalibrationColor, int mCalibrationBorderColor) { // SleepChart_movementColor mXYSeriesMovementRenderer.setFillBelowLineColor(mMovementColor); // SleepChart_movementBorderColor mXYSeriesMovementRenderer.setColor(mMovementBorderColor); // SleepChart_calibrationColor mXYSeriesCalibrationRenderer.setFillBelowLineColor(mCalibrationColor); // SleepChart_calibrationBorderColor mXYSeriesCalibrationRenderer.setColor(mCalibrationBorderColor); } }