~igor-cali/bilancio/stable

« back to all changes in this revision

Viewing changes to android/API24/main/java/com/igisw/openmoneybox/ChartFragment.java

  • Committer: Igor Calì
  • Date: 2019-04-07 16:24:48 UTC
  • Revision ID: igor.cali0@gmail.com-20190407162448-5mfwr7c39y3kzz6u
 v3.3.1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************
2
 
 * Name:
3
 
 * Purpose:   Chart fragment for OpenMoneyBox Application
4
 
 * Author:    Igor Calì (igor.cali0@gmail.com)
5
 
 * Created:   2018-07-23
6
 
 * Copyright: Igor Calì (igor.cali0@gmail.com)
7
 
 * License:             GNU
8
 
 **************************************************************/
9
 
 
10
 
package com.igisw.openmoneybox;
11
 
 
12
 
import android.content.Context;
13
 
import android.graphics.Bitmap;
14
 
import android.graphics.Color;
15
 
import android.net.Uri;
16
 
import android.os.Bundle;
17
 
import android.support.v4.app.Fragment;
18
 
import android.view.LayoutInflater;
19
 
import android.view.View;
20
 
import android.view.ViewGroup;
21
 
 
22
 
import com.github.mikephil.charting.charts.LineChart;
23
 
import com.github.mikephil.charting.charts.PieChart;
24
 
import com.github.mikephil.charting.components.YAxis;
25
 
import com.github.mikephil.charting.data.Entry;
26
 
import com.github.mikephil.charting.data.LineData;
27
 
import com.github.mikephil.charting.data.LineDataSet;
28
 
import com.github.mikephil.charting.data.PieData;
29
 
import com.github.mikephil.charting.data.PieDataSet;
30
 
import com.github.mikephil.charting.data.PieEntry;
31
 
import com.github.mikephil.charting.highlight.Highlight;
32
 
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
33
 
 
34
 
import java.io.File;
35
 
import java.io.FileNotFoundException;
36
 
import java.io.FileOutputStream;
37
 
import java.io.IOException;
38
 
import java.io.OutputStream;
39
 
import java.text.NumberFormat;
40
 
import java.text.ParseException;
41
 
import java.util.ArrayList;
42
 
import java.util.Calendar;
43
 
import java.util.GregorianCalendar;
44
 
import java.util.List;
45
 
import java.util.Locale;
46
 
 
47
 
 
48
 
/**
49
 
 * A simple {@link Fragment} subclass.
50
 
 * Activities that contain this fragment must implement the
51
 
 * {@link ChartFragment.OnFragmentInteractionListener} interface
52
 
 * to handle interaction events.
53
 
 * Use the {@link ChartFragment#newInstance} factory method to
54
 
 * create an instance of this fragment.
55
 
 */
56
 
public class ChartFragment extends Fragment {
57
 
    // TODO: Rename parameter arguments, choose names that match
58
 
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
59
 
    private static final String ARG_PARAM1 = "param1";
60
 
    private static final String ARG_PARAM2 = "param2";
61
 
 
62
 
 
63
 
    private OnFragmentInteractionListener mListener;
64
 
 
65
 
    private mainactivity activity;
66
 
    private View view;
67
 
 
68
 
    public ChartFragment() {
69
 
        // Required empty public constructor
70
 
    }
71
 
 
72
 
    /**
73
 
     * Use this factory method to create a new instance of
74
 
     * this fragment using the provided parameters.
75
 
     *
76
 
     * @param param1 Parameter 1.
77
 
     * @param param2 Parameter 2.
78
 
     * @return A new instance of fragment ChartFragment.
79
 
     */
80
 
    // TODO: Rename and change types and number of parameters
81
 
    public static ChartFragment newInstance(String param1, String param2) {
82
 
        ChartFragment fragment = new ChartFragment();
83
 
        Bundle args = new Bundle();
84
 
        args.putString(ARG_PARAM1, param1);
85
 
        args.putString(ARG_PARAM2, param2);
86
 
        fragment.setArguments(args);
87
 
        return fragment;
88
 
    }
89
 
 
90
 
    @Override
91
 
    public void onCreate(Bundle savedInstanceState) {
92
 
        super.onCreate(savedInstanceState);
93
 
        if (getArguments() != null) {
94
 
            String mParam1 = getArguments().getString(ARG_PARAM1);
95
 
            String mParam2 = getArguments().getString(ARG_PARAM2);
96
 
        }
97
 
    }
98
 
 
99
 
    @Override
100
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
101
 
                             Bundle savedInstanceState) {
102
 
        activity = (mainactivity) getActivity();
103
 
 
104
 
        // Inflate the layout for this fragment
105
 
        view = inflater.inflate(R.layout.fragment_chart, container, false);
106
 
 
107
 
        paintChart();
108
 
 
109
 
        return view;
110
 
    }
111
 
 
112
 
    /*
113
 
    // TODO: Rename method, update argument and hook method into UI event
114
 
    public void onButtonPressed(Uri uri) {
115
 
        if (mListener != null) {
116
 
            mListener.onFragmentInteraction(uri);
117
 
        }
118
 
    }
119
 
    */
120
 
 
121
 
    @Override
122
 
    public void onAttach(Context context) {
123
 
        super.onAttach(context);
124
 
        if (context instanceof OnFragmentInteractionListener) {
125
 
            mListener = (OnFragmentInteractionListener) context;
126
 
        } else {
127
 
            throw new RuntimeException(context.toString()
128
 
                    + " must implement OnFragmentInteractionListener");
129
 
        }
130
 
    }
131
 
 
132
 
    @Override
133
 
    public void onDetach() {
134
 
        super.onDetach();
135
 
        mListener = null;
136
 
    }
137
 
 
138
 
    /**
139
 
     * This interface must be implemented by activities that contain this
140
 
     * fragment to allow an interaction in this fragment to be communicated
141
 
     * to the activity and potentially other fragments contained in that
142
 
     * activity.
143
 
     * <p>
144
 
     * See the Android Training lesson <a href=
145
 
     * "http://developer.android.com/training/basics/fragments/communicating.html"
146
 
     * >Communicating with Other Fragments</a> for more information.
147
 
     */
148
 
    public interface OnFragmentInteractionListener {
149
 
        // TODO: Update argument type and name
150
 
        void onFragmentInteraction(Uri uri);
151
 
    }
152
 
 
153
 
    private void paintChart(){
154
 
 
155
 
        boolean default_is_small = false;
156
 
        int i;
157
 
        double percent, sum_small_funds = 0;
158
 
        String color;
159
 
 
160
 
        // Fund Chart construction
161
 
        List<PieEntry> pie_entries = new ArrayList<>();
162
 
        PieChart FundPlot = view.findViewById(R.id.fund_graph);
163
 
 
164
 
        //FundPlot.removeSlices();
165
 
        int inserted_entries = 0;
166
 
        int default_entry = -1;
167
 
 
168
 
        for(i = 0; i < activity.Data.NFun; i++){
169
 
            percent = activity.Data.Funds.get(i).Value / activity.Data.GetTot(omb31core.TTypeVal.tvFou) * 100;
170
 
            if(percent > 1) {
171
 
                pie_entries.add(new PieEntry((float) activity.Data.Funds.get(i).Value, activity.Data.Funds.get(i).Name));
172
 
                inserted_entries++;
173
 
                if(activity.Data.Funds.get(i).Name.compareToIgnoreCase(activity.Data.FileData.DefFund) == 0)
174
 
                    default_entry = inserted_entries - 1;
175
 
            }
176
 
            else{
177
 
                sum_small_funds += activity.Data.Funds.get(i).Value;
178
 
                if(activity.Data.Funds.get(i).Name.compareToIgnoreCase(activity.Data.FileData.DefFund) == 0) default_is_small = true;
179
 
            }
180
 
        }
181
 
        if(sum_small_funds > 0){
182
 
            pie_entries.add(new PieEntry((float) sum_small_funds, getResources().getString(R.string.fund_others)));
183
 
            inserted_entries++;
184
 
            if(default_is_small)default_entry = inserted_entries - 1;
185
 
        }
186
 
        PieDataSet set = new PieDataSet(pie_entries, getResources().getString(R.string.fund_chart));
187
 
 
188
 
        set.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
189
 
        set.setValueLinePart1OffsetPercentage(100.f);
190
 
        set.setValueLinePart1Length(0.8f);
191
 
        set.setValueLinePart2Length(0.8f);
192
 
 
193
 
        for(i = 1; i < 7; i++){
194
 
            switch(i){
195
 
                case 1:
196
 
                    color = "#FFFF99";
197
 
                    break;
198
 
                case 2:
199
 
                    color = "#3DEB3D";
200
 
                    break;
201
 
                case 3:
202
 
                    color = "#FF0000";
203
 
                    break;
204
 
                case 4:
205
 
                    color = "#00FF00";
206
 
                    break;
207
 
                case 5:
208
 
                    color = "#0000FF";
209
 
                    break;
210
 
                default:
211
 
                    color = "#99CCFF";
212
 
            }
213
 
            if(i == 1) set.setColor(Color.parseColor(color));
214
 
            else set.addColor(Color.parseColor(color));
215
 
        }
216
 
 
217
 
        PieData data = new PieData(set);
218
 
        FundPlot.setData(data);
219
 
        FundPlot.getDescription().setEnabled(false);
220
 
        FundPlot.setEntryLabelColor(Color.parseColor("#000000"));
221
 
        FundPlot.setEntryLabelTextSize(7f);
222
 
 
223
 
        // Highlight default fund
224
 
        Highlight h = new Highlight((float) default_entry, 0, 0); // dataset index for piechart is always 0
225
 
        FundPlot.highlightValues(new Highlight[] { h });
226
 
        FundPlot.setDrawHoleEnabled(false);
227
 
        FundPlot.invalidate(); // refresh
228
 
 
229
 
        // Trend chart construction
230
 
        GregorianCalendar month = activity.Data.Day;
231
 
        GregorianCalendar lastday = month;
232
 
        month.set(Calendar.MONTH, (int) activity.Data.FileData.Month);
233
 
        int number_of_days = month.getActualMaximum(Calendar.DAY_OF_MONTH);
234
 
        List<Entry> trendvalues = new ArrayList<>();
235
 
        double  LastValue = 0 /*, MinValue = 0, MaxValue = 0 */;
236
 
        //int j = 0;
237
 
 
238
 
        NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
239
 
        String value;
240
 
 
241
 
        for(i = 0; i < activity.Data.NLin; i++){
242
 
            if(activity.Data.isDate(i)){
243
 
                lastday = activity.Data.Lines.get(i).Date;
244
 
 
245
 
                // Robustness code to handle localized or unlocalized strings
246
 
                value = activity.Data.Lines.get(i).Value;
247
 
                if(value.contains(".")) LastValue = Double.parseDouble(value);
248
 
                else{
249
 
                    try {
250
 
                        LastValue = nf.parse(value).doubleValue();
251
 
                    } catch (ParseException e) {
252
 
                        // TODO Auto-generated catch block
253
 
                        e.printStackTrace();
254
 
                    }
255
 
                }
256
 
                Entry day_entry = new Entry((float) lastday.getTimeInMillis(), (float) LastValue);
257
 
                trendvalues.add(day_entry);
258
 
            }}
259
 
 
260
 
        LineChart TrendPlot = view.findViewById(R.id.trend_graph);
261
 
        LineDataSet setComp1 = new LineDataSet(trendvalues, getResources().getString(R.string.trend_chart));
262
 
        setComp1.setAxisDependency(YAxis.AxisDependency.LEFT);
263
 
        setComp1.setColor(Color.parseColor("#000000"));
264
 
        // use the interface ILineDataSet
265
 
        List<ILineDataSet> dataSets = new ArrayList<>();
266
 
        dataSets.add(setComp1);
267
 
 
268
 
        if(! activity.Data.FileData.ReadOnly){
269
 
            // trend addition
270
 
            double currenttotal = activity.Data.GetTot(omb31core.TTypeVal.tvFou);
271
 
            month.set(Calendar.DAY_OF_MONTH, number_of_days);
272
 
            List<Entry> trendtrendvalues = new ArrayList<>();
273
 
            trendtrendvalues.add(new Entry((float) lastday.getTimeInMillis(), (float) LastValue));
274
 
            trendtrendvalues.add(new Entry((float) month.getTimeInMillis(), (float) currenttotal));
275
 
            LineDataSet setComp2 = new LineDataSet(trendtrendvalues, getResources().getString(R.string.trend_last));
276
 
            setComp2.setAxisDependency(YAxis.AxisDependency.LEFT);
277
 
            dataSets.add(setComp2);
278
 
 
279
 
            if(LastValue == currenttotal) color = "#FFFF00";
280
 
            else if(LastValue < currenttotal) color = "#006400";
281
 
            else color = "#FF0000";
282
 
            setComp2.setColor(Color.parseColor(color));
283
 
        }
284
 
 
285
 
        LineData trenddata = new LineData(dataSets);
286
 
 
287
 
        TrendPlot.getXAxis().setValueFormatter(new DateAxisValueFormatter(null));
288
 
 
289
 
        TrendPlot.setData(trenddata);
290
 
        TrendPlot.getDescription().setEnabled(false);
291
 
        TrendPlot.invalidate(); // refresh
292
 
 
293
 
    }
294
 
 
295
 
    public void saveChart(int id, File filename){
296
 
        View plot = view.findViewById(id);
297
 
        plot.setDrawingCacheEnabled (true);
298
 
        plot.buildDrawingCache(true);
299
 
        Bitmap b = Bitmap.createBitmap(plot.getDrawingCache());
300
 
        OutputStream os = null;
301
 
        try {
302
 
            os = new FileOutputStream(filename);
303
 
        } catch (FileNotFoundException e) {
304
 
            // TODO Auto-generated catch block
305
 
            e.printStackTrace();
306
 
        }
307
 
        b.compress(Bitmap.CompressFormat.PNG, 100, os);
308
 
        plot.destroyDrawingCache();
309
 
        try {
310
 
            os.close();
311
 
        } catch (IOException e) {
312
 
            // TODO Auto-generated catch block
313
 
            e.printStackTrace();
314
 
        }
315
 
    }
316
 
 
317
 
}