Back to project page budget-envelopes.
The source code is released under:
GNU General Public License
If you think the Android project budget-envelopes listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * This file is a part of Budget with Envelopes. * Copyright 2013 Michael Howell <michael@notriddle.com> *//from w w w . j a va 2 s. c om * Budget is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Budget is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Budget. If not, see <http://www.gnu.org/licenses/>. */ package com.notriddle.budget; import android.app.Activity; import android.app.Fragment; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; import android.content.ContentValues; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.Paint; import android.graphics.Path; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import java.text.DateFormat; import java.util.Date; public class GraphFragment extends Fragment implements LoaderCallbacks<Cursor>, TitleFragment { public static GraphFragment newInstance() { return new GraphFragment(); } @Override public void onCreate(Bundle state) { super.onCreate(state); getLoaderManager().initLoader(0, null, this); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup cont, Bundle state) { ImageView retVal = new ImageView(getActivity()); int cardSpacing = getActivity().getResources() .getDimensionPixelSize(R.dimen.cardSpacing); int cardPadding = getActivity().getResources() .getDimensionPixelSize(R.dimen.cardPadding); int width = getActivity().getWindow().getWindowManager().getDefaultDisplay().getWidth()-2*(cardSpacing)-2*(cardPadding); Log.d("Budget", "GraphFragment.onCreateVeiw(): width="+width); int height = getActivity().getResources() .getDimensionPixelSize(R.dimen.graphHeight); Log.d("Budget", "GraphFragment.onCreateView(): height="+height); ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(width, height); retVal.setLayoutParams(params); return retVal; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String time = Long.toString(System.currentTimeMillis()-5184000000l); SQLiteLoader retVal = new SQLiteLoader( getActivity(), new EnvelopesOpenHelper(getActivity()), "SELECT (SELECT sum(l2.cents) FROM log as l2 WHERE l2.envelope = l.envelope AND l2.time <= l.time), e._id, e.color, l.time, e.name, l.cents FROM log as l LEFT JOIN envelopes AS e ON (e._id = l.envelope) WHERE e.color <> 0 AND l.time > "+time+" ORDER BY e._id, l.time asc" ); retVal.setNotificationUri(EnvelopesOpenHelper.URI); return retVal; } @Override public void onLoadFinished(Loader<Cursor> ldr, final Cursor data) { final int cardSpacing = getActivity().getResources() .getDimensionPixelSize(R.dimen.cardSpacing); final int cardPadding = getActivity().getResources() .getDimensionPixelSize(R.dimen.cardPadding); final int textSize = cardPadding*2; final int width = getActivity().getWindow().getWindowManager().getDefaultDisplay().getWidth()-2*(cardSpacing)-2*(cardPadding); Log.d("Budget", "GraphFragment.onLoadFinished(): width="+width); final int height = getActivity().getResources() .getDimensionPixelSize(R.dimen.graphHeight); Log.d("Budget", "GraphFragment.onLoadFinished(): height="+height); (new AsyncTask<Object, Object, Bitmap>() { protected Bitmap doInBackground(Object... o) { return generateBitmap(data, cardSpacing, cardPadding, textSize, width, height); } protected void onPostExecute(Bitmap chart) { ImageView view = (ImageView)getView(); if (view != null) { view.setImageBitmap(chart); } } }).execute();; } private Bitmap generateBitmap(Cursor data, int cardSpacing, int cardPadding, int textSize, int width, int height) { int l = data.getCount(); data.moveToFirst(); long maxCents = 0; long minCents = Long.MAX_VALUE; long maxTime = 0; long minTime = Long.MAX_VALUE; for (int i = 0; i != l; ++i) { long cents = data.getLong(0); if (cents > maxCents) maxCents = cents; if (cents < minCents) minCents = cents; long time = data.getLong(3); if (time > maxTime) maxTime = time; if (time < minTime) minTime = time; data.moveToNext(); } Bitmap chart = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888 ); Canvas chartCanvas = new Canvas(chart); chartCanvas.drawColor(Color.TRANSPARENT); Paint pen = new Paint(); pen.setColor(0xFF000000); pen.setTextAlign(Paint.Align.CENTER); pen.setTextSize(textSize); Paint brush = new Paint(); brush.setDither(true); brush.setHinting(Paint.HINTING_ON); brush.setStyle(Paint.Style.STROKE); float stroke = getActivity() .getResources() .getDimension(R.dimen.graphStroke); brush.setStrokeWidth(stroke); int currentEnvelope = -1; Path currentPath = null; float usableHeight = height-(2*stroke)-textSize-cardPadding; float usableWidth = width-(2*stroke)-textSize; data.moveToFirst(); for (int i = 0; i != l; ++i) { int envelope = data.getInt(1); long cents = data.getLong(0); long time = data.getLong(3); float pointHeight = usableHeight-(float)((cents-minCents)*usableHeight/((double)(maxCents-minCents)))+stroke; float pointPosition = (float)((time-minTime)*usableWidth/((double)(maxTime-minTime)))+stroke+textSize; Log.d("Budget", "GraphFragment.onLoadFinished(): envelope="+envelope); Log.d("Budget", "GraphFragment.onLoadFinished(): envelope.name="+data.getString(4)); Log.d("Budget", "GraphFragment.onLoadFinished(): cents="+cents); Log.d("Budget", "GraphFragment.onLoadFinished(): pointHeight="+pointHeight); Log.d("Budget", "GraphFragment.onLoadFinished(): time="+time); Log.d("Budget", "GraphFragment.onLoadFinished(): pointPosition="+pointPosition); if (envelope != currentEnvelope) { if (currentPath != null) { currentPath.rLineTo(usableWidth, 0); chartCanvas.drawPath(currentPath, brush); } int color = data.getInt(2); //brush = new Paint(brush); brush.setColor(color); currentEnvelope = envelope; currentPath = new Path(); int transactionCents = data.getInt(5); Log.d("Budget", "GraphFragment.onLoadFinished(): first transaction? "+(transactionCents == cents)); if (transactionCents != cents) { currentPath.moveTo(stroke+textSize, pointHeight); currentPath.lineTo(pointPosition, pointHeight); } else { currentPath.moveTo(pointPosition, pointHeight); } } else { currentPath.lineTo(pointPosition, pointHeight); } data.moveToNext(); } if (currentPath != null) { currentPath.rLineTo(usableWidth, 0); chartCanvas.drawPath(currentPath, brush); } Path side = new Path(); side.moveTo(textSize, height); side.lineTo(textSize, 0); chartCanvas.drawTextOnPath(getActivity().getString(R.string.envelopeDetails_balance), side, 0, 0, pen); Path bottom = new Path(); bottom.moveTo(0, height-cardPadding); bottom.lineTo(width, height-cardPadding); chartCanvas.drawTextOnPath(getActivity().getString(R.string.graph_time), bottom, 0, 0, pen); if (maxTime != 0) { Date maxTimeD = new Date(maxTime); Date minTimeD = new Date(minTime); DateFormat timeFormat = android.text.format.DateFormat.getDateFormat(getActivity()); pen.setTextAlign(Paint.Align.LEFT); chartCanvas.drawTextOnPath(timeFormat.format(minTimeD), bottom, 0, 0, pen); pen.setTextAlign(Paint.Align.RIGHT); chartCanvas.drawTextOnPath(timeFormat.format(maxTimeD), bottom, 0, 0, pen); } return chart; } @Override public void onLoaderReset(Loader<Cursor> ldr) { // Do nothing. } @Override public String getTitle() { return getActivity().getString(R.string.graph_name); } };