package com.dailystudio.dailylife.plugin.feeling;
import java.util.ArrayList;
import java.util.List;
import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import com.dailystudio.dailylife.R;
import com.dailystudio.dailylife.ui.CurrentTimeView;
import com.dailystudio.development.Logger;
import com.dailystudio.utils.ActivityLauncher;
import com.dailystudio.utils.CalendarHelper;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class FeelingChartActivity extends Activity {
private class ChartData {
private int hour;
private int totalLvl;
private int count;
@Override
public String toString() {
return String.format("%s(0x%08x): hour(%d), totalLvl(%d), count(%d)",
this.getClass().getSimpleName(),
hashCode(),
hour,
totalLvl,
count);
}
};
private class FeelingsLoader extends AsyncTask<Context, ChartData, Integer> {
private List<ChartData> mChartData;
public FeelingsLoader(List<ChartData> data) {
mChartData = data;
}
@Override
protected Integer doInBackground(Context... params) {
if (params.length <= 0) {
return 0;
}
final Context context = params[0];
if (context == null) {
return 0;
}
DailyFeelingReader reader = new DailyFeelingReader(
context,
"feeling.db");
final long start = CalendarHelper.getDayStart(mBaseTime);
final long end = CalendarHelper.getDayEnd(mBaseTime);
List<DailyFeeling> feelings =
reader.queryFeelingsForPeroid(start, end, true);
if (feelings == null) {
return 0;
}
final int curreHour = CalendarHelper.getHour(mBaseTime);
ChartData data;
for (int i = 0; i <= curreHour; i++) {
data = new ChartData();
data.hour = i;
data.totalLvl = 0;
data.count = 0;
mChartData.add(data);
}
final int N = feelings.size();
long time = 0;
int dataIndex = 0;
DailyFeeling feeling = null;
for (int i = 0; i < N; i++) {
feeling = feelings.get(i);
time = feeling.getTime();
dataIndex = CalendarHelper.getHour(time);
Logger.debug("feeling(%s), dataIndex(%d)",
feeling,
dataIndex);
if (dataIndex < 0 || dataIndex >= mChartData.size()) {
continue;
}
data = mChartData.get(dataIndex);
data.totalLvl += Feelings.getFeelingLevel(feeling.getFeeling());
data.count++;
}
printData();
return N;
}
private void printData() {
for (ChartData data: mChartData) {
Logger.debug("%s", data);
}
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
Runnable runnable = new GenerateChartRunnable(mChartData);
if (runnable != null) {
mHandler.post(runnable);
}
}
@Override
protected void onProgressUpdate(ChartData... values) {
super.onProgressUpdate(values);
}
}
public static final String EXTRA_BASE_TIME = "base-time";
private FeelingsLoader mLoader = null;
private TextView mDateView = null;
private ViewGroup mChartStub = null;
private Button mButtonFeelingList = null;
private long mBaseTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_feeling_chart);
setupViews();
Intent i = getIntent();
if (i != null) {
mBaseTime = i.getLongExtra(EXTRA_BASE_TIME, 0);
}
if (mBaseTime == 0) {
mBaseTime = System.currentTimeMillis();
}
Logger.debug("baseTime(%s)", CalendarHelper.timeToReadableString(mBaseTime));
if (mDateView != null) {
final String dateStr =
CalendarHelper.timeToReadableStringWithoutTime(mBaseTime);
if (dateStr != null) {
mDateView.setText(dateStr);
}
}
List<ChartData> data = new ArrayList<ChartData>();
mLoader = new FeelingsLoader(data);
if (mLoader != null) {
mLoader.execute(this);
}
}
private void setupViews() {
mDateView = (TextView) findViewById(R.id.fchart_time);
mChartStub = (ViewGroup) findViewById(R.id.fchart_chartStub);
mButtonFeelingList = (Button) findViewById(R.id.fchart_btn_show_flist);
if (mButtonFeelingList != null) {
mButtonFeelingList.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.dailystudio.dailylife",
"com.dailystudio.dailylife.plugin.feeling.FeelingListActivity"));
intent.putExtra(FeelingListActivity.EXTRA_PEROID_START,
CalendarHelper.getDayStart(mBaseTime));
intent.putExtra(FeelingListActivity.EXTRA_PEROID_END,
CalendarHelper.getDayEnd(mBaseTime));
ActivityLauncher.launchActivity(
FeelingChartActivity.this, intent);
}
});
}
}
private void showChart(View chartView) {
if (mChartStub == null || chartView == null) {
return;
}
mChartStub.addView(chartView);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mLoader != null) {
mLoader.cancel(true);
}
}
protected void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle,
String yTitle, double xMin, double xMax, double yMin, double yMax, int axesColor,
int labelsColor) {
renderer.setChartTitle(title);
renderer.setXTitle(xTitle);
renderer.setYTitle(yTitle);
renderer.setXAxisMin(xMin);
renderer.setXAxisMax(xMax);
renderer.setYAxisMin(yMin);
renderer.setYAxisMax(yMax);
renderer.setAxesColor(axesColor);
renderer.setLabelsColor(labelsColor);
}
private XYMultipleSeriesDataset buildDataset(List<ChartData> data) {
if (data == null) {
return null;
}
XYSeries series = new XYSeries("Feelings");
if (series == null) {
return null;
}
int avgLvl = 0;
ChartData prev = null;
int prevLvl = 0;
for (ChartData d: data) {
avgLvl = 0;
if (d.count != 0) {
avgLvl = (int)Math.round((double)d.totalLvl / d.count);
} else {
if (prev != null) {
avgLvl = prevLvl;
}
}
series.add(d.hour, avgLvl);
prev = d;
prevLvl = avgLvl;
}
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
if (dataset != null) {
dataset.addSeries(series);
}
return dataset;
}
private XYMultipleSeriesRenderer buildRenderer() {
XYSeriesRenderer r = new XYSeriesRenderer();
if (r == null) {
return null;
}
r.setColor(Color.BLUE);
r.setPointStyle(PointStyle.DIAMOND);
r.setFillPoints(true);
r.setLineWidth(2);
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
if (renderer != null) {
renderer.addSeriesRenderer(r);
// renderer.setChartTitle("Feeling Chart");
renderer.setXTitle("Hour");
renderer.setYTitle("Feeling Level");
renderer.setYAxisMin(Feelings.getMinFeelingLevel() - 1);
renderer.setYAxisMax(Feelings.getMaxFeelingLevel() + 1);
renderer.setAxesColor(Color.GRAY);
renderer.setLabelsColor(Color.LTGRAY);
renderer.setPointSize(5);
}
return renderer;
}
private Handler mHandler = new Handler();
private class GenerateChartRunnable implements Runnable {
private List<ChartData> mData = null;
public GenerateChartRunnable(List<ChartData> data) {
mData = data;
}
@Override
public void run() {
if (mData == null) {
return;
}
XYMultipleSeriesDataset dataset = buildDataset(mData);
if (dataset == null) {
return;
}
XYMultipleSeriesRenderer renderer = buildRenderer();
if (renderer == null) {
return;
}
final int N = mData.size();
if (N <= 0) {
return;
}
renderer.setXAxisMin(0);
renderer.setXAxisMax(24);
renderer.setShowGrid(true);
renderer.setXLabelsAlign(Align.RIGHT);
renderer.setYLabelsAlign(Align.RIGHT);
renderer.setXLabels(24);
renderer.setYLabels(Feelings.getMaxFeelingLevel() - Feelings.getMinFeelingLevel());
renderer.setPanEnabled(false, false);
renderer.setPanLimits(new double[] {
0, 24,
Feelings.getMinFeelingLevel(),
Feelings.getMaxFeelingLevel() });
renderer.setZoomEnabled(false, false);
View chart = ChartFactory.getLineChartView(
FeelingChartActivity.this,
dataset,
renderer);
showChart(chart);
}
};
}
|