2015-07-29 16:30:19 +02:00
package nodomain.freeyourgadget.gadgetbridge.activities ;
import android.content.BroadcastReceiver ;
import android.content.Context ;
import android.content.Intent ;
import android.content.IntentFilter ;
import android.graphics.Color ;
import android.os.Bundle ;
import android.support.v4.content.LocalBroadcastManager ;
import android.view.LayoutInflater ;
import android.view.View ;
import android.view.ViewGroup ;
import com.github.mikephil.charting.charts.BarLineChartBase ;
import com.github.mikephil.charting.charts.Chart ;
import com.github.mikephil.charting.charts.PieChart ;
import com.github.mikephil.charting.components.LimitLine ;
import com.github.mikephil.charting.components.XAxis ;
import com.github.mikephil.charting.components.YAxis ;
import com.github.mikephil.charting.data.BarData ;
import com.github.mikephil.charting.data.BarDataSet ;
import com.github.mikephil.charting.data.BarEntry ;
import com.github.mikephil.charting.data.Entry ;
import com.github.mikephil.charting.data.PieData ;
import com.github.mikephil.charting.data.PieDataSet ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import java.text.NumberFormat ;
import java.util.ArrayList ;
import java.util.Calendar ;
import java.util.List ;
import java.util.Locale ;
import nodomain.freeyourgadget.gadgetbridge.ControlCenter ;
import nodomain.freeyourgadget.gadgetbridge.GBDevice ;
import nodomain.freeyourgadget.gadgetbridge.R ;
import nodomain.freeyourgadget.gadgetbridge.charts.ActivityAnalysis ;
2015-08-03 01:17:02 +02:00
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler ;
2015-07-29 18:49:16 +02:00
import nodomain.freeyourgadget.gadgetbridge.miband.MiBandCoordinator ;
2015-07-29 16:30:19 +02:00
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample ;
public class WeekStepsChartFragment extends AbstractChartFragment {
protected static final Logger LOG = LoggerFactory . getLogger ( WeekStepsChartFragment . class ) ;
private Locale mLocale ;
2015-07-29 18:49:16 +02:00
private int mTargetSteps = 10000 ;
2015-07-29 16:30:19 +02:00
private BarLineChartBase mWeekStepsChart ;
private PieChart mTodayStepsChart ;
private GBDevice mGBDevice = null ;
private BroadcastReceiver mReceiver = new BroadcastReceiver ( ) {
@Override
public void onReceive ( Context context , Intent intent ) {
String action = intent . getAction ( ) ;
if ( action . equals ( ACTION_REFRESH ) ) {
refresh ( ) ;
}
}
} ;
2015-08-03 01:17:02 +02:00
@Override
protected void refreshInBackground ( DBHandler db ) {
2015-07-29 16:30:19 +02:00
Calendar day = Calendar . getInstance ( ) ;
//NB: we could have omitted the day, but this way we can move things to the past easily
2015-08-03 01:17:02 +02:00
refreshDaySteps ( db , mTodayStepsChart , day ) ;
refreshWeekBeforeSteps ( db , mWeekStepsChart , day ) ;
}
2015-07-29 16:30:19 +02:00
2015-08-03 01:17:02 +02:00
@Override
protected void renderCharts ( ) {
2015-07-29 16:30:19 +02:00
mWeekStepsChart . invalidate ( ) ;
mTodayStepsChart . invalidate ( ) ;
}
2015-08-03 01:17:02 +02:00
private void refreshWeekBeforeSteps ( DBHandler db , BarLineChartBase barChart , Calendar day ) {
2015-07-29 16:30:19 +02:00
ActivityAnalysis analysis = new ActivityAnalysis ( ) ;
day . add ( Calendar . DATE , - 7 ) ;
List < BarEntry > entries = new ArrayList < > ( ) ;
List < String > labels = new ArrayList < > ( ) ;
for ( int counter = 0 ; counter < 7 ; counter + + ) {
2015-08-03 01:17:02 +02:00
entries . add ( new BarEntry ( analysis . calculateTotalSteps ( getSamplesOfDay ( db , day ) ) , counter ) ) ;
2015-07-29 16:30:19 +02:00
labels . add ( day . getDisplayName ( Calendar . DAY_OF_WEEK , Calendar . SHORT , mLocale ) ) ;
day . add ( Calendar . DATE , 1 ) ;
}
BarDataSet set = new BarDataSet ( entries , " " ) ;
set . setColor ( akActivity . color ) ;
BarData data = new BarData ( labels , set ) ;
2015-08-03 18:34:58 +02:00
data . setValueTextColor ( Color . GRAY ) ; //prevent tearing other graph elements with the black text. Another approach would be to hide the values cmpletely with data.setDrawValues(false);
2015-07-29 16:30:19 +02:00
LimitLine target = new LimitLine ( mTargetSteps ) ;
barChart . getAxisLeft ( ) . addLimitLine ( target ) ;
setupLegend ( barChart ) ;
barChart . setData ( data ) ;
barChart . getLegend ( ) . setEnabled ( false ) ;
}
2015-08-03 01:17:02 +02:00
private void refreshDaySteps ( DBHandler db , PieChart pieChart , Calendar day ) {
2015-07-29 16:30:19 +02:00
ActivityAnalysis analysis = new ActivityAnalysis ( ) ;
2015-08-03 01:17:02 +02:00
int totalSteps = analysis . calculateTotalSteps ( getSamplesOfDay ( db , day ) ) ;
2015-07-29 16:30:19 +02:00
pieChart . setCenterText ( NumberFormat . getNumberInstance ( mLocale ) . format ( totalSteps ) ) ;
PieData data = new PieData ( ) ;
List < Entry > entries = new ArrayList < > ( ) ;
List < Integer > colors = new ArrayList < > ( ) ;
entries . add ( new Entry ( totalSteps , 0 ) ) ;
colors . add ( akActivity . color ) ;
2015-07-29 18:07:35 +02:00
//we don't want labels on the pie chart
2015-07-29 16:30:19 +02:00
data . addXValue ( " " ) ;
2015-07-29 18:07:35 +02:00
if ( totalSteps < mTargetSteps ) {
entries . add ( new Entry ( ( mTargetSteps - totalSteps ) , 1 ) ) ;
colors . add ( Color . GRAY ) ;
//we don't want labels on the pie chart
data . addXValue ( " " ) ;
}
2015-07-29 16:30:19 +02:00
PieDataSet set = new PieDataSet ( entries , " " ) ;
set . setColors ( colors ) ;
data . setDataSet ( set ) ;
2015-07-29 18:07:35 +02:00
//this hides the values (numeric) added to the set. These would be shown aside the strings set with addXValue above
2015-07-29 16:30:19 +02:00
data . setDrawValues ( false ) ;
pieChart . setData ( data ) ;
pieChart . getLegend ( ) . setEnabled ( false ) ;
}
@Override
public View onCreateView ( LayoutInflater inflater , ViewGroup container ,
Bundle savedInstanceState ) {
mLocale = getResources ( ) . getConfiguration ( ) . locale ;
View rootView = inflater . inflate ( R . layout . fragment_sleepchart , container , false ) ;
Bundle extras = getActivity ( ) . getIntent ( ) . getExtras ( ) ;
if ( extras ! = null ) {
mGBDevice = extras . getParcelable ( GBDevice . EXTRA_DEVICE ) ;
}
2015-07-29 18:49:16 +02:00
if ( mGBDevice ! = null ) {
mTargetSteps = MiBandCoordinator . getFitnessGoal ( mGBDevice . getAddress ( ) ) ;
}
2015-07-29 16:30:19 +02:00
IntentFilter filter = new IntentFilter ( ) ;
filter . addAction ( ControlCenter . ACTION_QUIT ) ;
filter . addAction ( ACTION_REFRESH ) ;
LocalBroadcastManager . getInstance ( getActivity ( ) ) . registerReceiver ( mReceiver , filter ) ;
mWeekStepsChart = ( BarLineChartBase ) rootView . findViewById ( R . id . sleepchart ) ;
mTodayStepsChart = ( PieChart ) rootView . findViewById ( R . id . sleepchart_pie_light_deep ) ;
setupWeekStepsChart ( ) ;
setupTodayStepsChart ( ) ;
refresh ( ) ;
return rootView ;
}
private void setupTodayStepsChart ( ) {
mTodayStepsChart . setBackgroundColor ( BACKGROUND_COLOR ) ;
mTodayStepsChart . setDescriptionColor ( DESCRIPTION_COLOR ) ;
mTodayStepsChart . setDescription ( " Steps today, target: " + mTargetSteps ) ;
mTodayStepsChart . setNoDataTextDescription ( " " ) ;
mTodayStepsChart . setNoDataText ( " " ) ;
}
@Override
public void onDestroy ( ) {
LocalBroadcastManager . getInstance ( getActivity ( ) ) . unregisterReceiver ( mReceiver ) ;
super . onDestroy ( ) ;
}
private void setupWeekStepsChart ( ) {
mWeekStepsChart . setBackgroundColor ( BACKGROUND_COLOR ) ;
mWeekStepsChart . setDescriptionColor ( DESCRIPTION_COLOR ) ;
mWeekStepsChart . setDescription ( " " ) ;
configureBarLineChartDefaults ( mWeekStepsChart ) ;
XAxis x = mWeekStepsChart . getXAxis ( ) ;
x . setDrawLabels ( true ) ;
x . setDrawGridLines ( false ) ;
x . setEnabled ( true ) ;
x . setTextColor ( CHART_TEXT_COLOR ) ;
x . setDrawLimitLinesBehindData ( true ) ;
YAxis y = mWeekStepsChart . getAxisLeft ( ) ;
y . setDrawGridLines ( false ) ;
y . setDrawTopYLabelEntry ( false ) ;
y . setTextColor ( CHART_TEXT_COLOR ) ;
y . setEnabled ( true ) ;
YAxis yAxisRight = mWeekStepsChart . getAxisRight ( ) ;
yAxisRight . setDrawGridLines ( false ) ;
yAxisRight . setEnabled ( false ) ;
yAxisRight . setDrawLabels ( false ) ;
yAxisRight . setDrawTopYLabelEntry ( false ) ;
yAxisRight . setTextColor ( CHART_TEXT_COLOR ) ;
}
protected void setupLegend ( Chart chart ) {
List < Integer > legendColors = new ArrayList < > ( 1 ) ;
List < String > legendLabels = new ArrayList < > ( 1 ) ;
legendColors . add ( akActivity . color ) ;
legendLabels . add ( " Steps " ) ;
chart . getLegend ( ) . setColors ( legendColors ) ;
chart . getLegend ( ) . setLabels ( legendLabels ) ;
chart . getLegend ( ) . setTextColor ( LEGEND_TEXT_COLOR ) ;
}
2015-08-03 01:17:02 +02:00
private List < ActivitySample > getSamplesOfDay ( DBHandler db , Calendar day ) {
2015-07-29 16:30:19 +02:00
int startTs ;
int endTs ;
day . set ( Calendar . HOUR_OF_DAY , 0 ) ;
day . set ( Calendar . MINUTE , 0 ) ;
day . set ( Calendar . SECOND , 0 ) ;
startTs = ( int ) ( day . getTimeInMillis ( ) / 1000 ) ;
day . set ( Calendar . HOUR_OF_DAY , 23 ) ;
day . set ( Calendar . MINUTE , 59 ) ;
day . set ( Calendar . SECOND , 59 ) ;
endTs = ( int ) ( day . getTimeInMillis ( ) / 1000 ) ;
2015-08-03 01:17:02 +02:00
return getSamples ( db , mGBDevice , startTs , endTs ) ;
2015-07-29 16:30:19 +02:00
}
@Override
2015-08-03 01:17:02 +02:00
protected List < ActivitySample > getSamples ( DBHandler db , GBDevice device , int tsFrom , int tsTo ) {
return super . getAllSamples ( db , device , tsFrom , tsTo ) ;
2015-07-29 16:30:19 +02:00
}
}