/* * Copyright (C) 2014 asksven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asksven.betterbatterystats.data; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.util.Log; import com.asksven.android.common.privateapiproxies.HistoryItem; /** * The data source for all series to plot * @author sven */ public class GraphSeriesFactory { ArrayList<HistoryItem> m_dataSource; static final String TAG = "GraphSeriesFactory"; private static Map<Integer, ArrayList<Datapoint>> m_serieStore = new HashMap<Integer, ArrayList<Datapoint>>(); public static final int SERIE_CHARGE = 1; public static final int SERIE_WAKELOCK = 2; public static final int SERIE_SCREENON = 3; public static final int SERIE_CHARGING = 4; public static final int SERIE_WIFI = 5; public static final int SERIE_GPS = 6; public static final int SERIE_BT = 7; public GraphSeriesFactory(ArrayList<HistoryItem> datasource) { m_dataSource = datasource; m_serieStore.clear(); if (m_dataSource != null) { long[] prev_my = {-1, -1, -1, -1, -1, -1, -1}; long[] prev_mx = {-1, -1, -1, -1, -1, -1, -1}; for (int index = 0; index < m_dataSource.size(); index++) { Datapoint data = new Datapoint(); HistoryItem item = m_dataSource.get(index); data.mX = getX(index); for (int iSerie = 1; iSerie <= 7; iSerie++) { switch (iSerie) { case SERIE_CHARGE: data.mY = item.getBatteryLevelInt(); //data.mY = 100; //Log.i(TAG, "Charge: x=" + data.mX + ", y=" + data.mY); break; case SERIE_WAKELOCK: data.mY = item.getWakelockInt(); //Log.i(TAG, "Awake: x=" + data.mX + ", y=" + data.mY); break; case SERIE_SCREENON: data.mY = item.getScreenOnInt(); //Log.i(TAG, "Screen on: x=" + data.mX + ", y=" + data.mY); break; case SERIE_CHARGING: data.mY = item.getChargingInt(); //Log.i(TAG, "Charging: x=" + data.mX + ", y=" + data.mY); break; case SERIE_WIFI: data.mY = item.getWifiRunningInt(); //Log.i(TAG, "Wifi: x=" + data.mX + ", y=" + data.mY); break; case SERIE_GPS: data.mY = item.getGpsOnInt(); //Log.i(TAG, "GPS: x=" + data.mX + ", y=" + data.mY); break; case SERIE_BT: data.mY = item.getBluetoothOnInt(); //Log.i(TAG, "BT: x=" + data.mX + ", y=" + data.mY); break; default: Log.e(TAG, "No serie found for " + iSerie); } // add only datapoints to series if the last datapoint does not have the same Y ArrayList<Datapoint> serie = m_serieStore.get(iSerie); if (serie == null) { // do we have data in the serie yet? m_serieStore.put(iSerie, new ArrayList<Datapoint>()); m_serieStore.get(iSerie).add(new Datapoint(data.mX, data.mY)); prev_my[iSerie-1] = data.mY; prev_mx[iSerie-1] = data.mX; //Log.i(TAG, "added to serie " + data); } else { // does the last stored value have a different Y or is the last of the serie? //Datapoint lastValue = m_serieStore.get(iSerie).get(m_serieStore.get(iSerie).size()-1); if ((prev_my[iSerie-1] != data.mY) || (index == m_dataSource.size() - 1)) { Datapoint prev = new Datapoint(); prev.mX = prev_mx[iSerie-1]; prev.mY = prev_my[iSerie-1]; if (prev.mY != -1) { m_serieStore.get(iSerie).add(new Datapoint(prev.mX, prev.mY)); // we need to consider a special case for when we represent binary (0|1) values if ((prev.mY == 1) || (prev.mY == 0)) { // the binary representation can not connect datapoint with anything else than // vertical or horizontal lines. In this case as Y varies // we need to add a datapoint to make sure that we do not draw 45° lines: // descending: on the previous datapoint // ascending: on the current datapoint if (prev.mY == 1) { m_serieStore.get(iSerie).add(new Datapoint(prev.mX, 0)); } else { m_serieStore.get(iSerie).add(new Datapoint(data.mX, 0)); } } } m_serieStore.get(iSerie).add(new Datapoint(data.mX, data.mY)); prev_my[iSerie-1] = data.mY; prev_mx[iSerie-1] = data.mX; //Log.i(TAG, "added to serie" + data); } else { //Log.i(TAG, "not added to serie" + data); prev_my[iSerie-1] = data.mY; prev_mx[iSerie-1] = data.mX; } } } } } // Object[] array = m_serieStore.keySet().toArray(); // Log.i(TAG, "Retrieved " + array.length + " series ot of " + m_dataSource.size() + " history items"); // for (int i=0; i < array.length; i++) // { // Log.i(TAG, "Serie " + (Integer)array[i] + " contains " + m_serieStore.get((Integer)array[i]).size() + " elements"); // Log.i(TAG, m_serieStore.get((Integer)array[i]).toString() ); // } } private long getX(int index) { return m_dataSource.get(index).getNormalizedTimeLong(); } public ArrayList<Datapoint> getValues(int serie) { ArrayList<Datapoint> ret = m_serieStore.get(serie); // if (ret != null) // { // Log.i(TAG, "getValues for serie " + serie + " returns " + ret.size() + " values: " + ret.toString()); // } // else // { // Log.i(TAG, "getValues for serie " + serie + " returns null"); // } return ret; } }