Best Android App InstaSquare Lite for full-size publication of photos in Instagram, Facebook, Twitter. Run the android application on PC. You can through the android emulator Droid4X.

root/trunk/rapidandroid/org.rapidandroid/src/org/rapidandroid/activity/chart/form/FormDataBroker.java @ 113

Revision 113, 16.0 KB (checked in by czue, 16 months ago)

move the legend axis off center and add the click event to turn on the tooltip. This is not that smooth in execution and we may just want to turn it off.

Line 
1package org.rapidandroid.activity.chart.form;
2
3import java.util.Calendar;
4import java.util.Date;
5import java.util.Random;
6
7import org.json.JSONArray;
8import org.json.JSONException;
9import org.json.JSONObject;
10import org.rapidandroid.activity.chart.ChartBroker;
11import org.rapidandroid.activity.chart.JSONGraphData;
12import org.rapidandroid.activity.chart.ChartBroker.DateDisplayTypes;
13import org.rapidandroid.data.RapidSmsDBConstants;
14import org.rapidandroid.data.controller.ParsedDataReporter;
15import org.rapidsms.java.core.Constants;
16import org.rapidsms.java.core.model.Field;
17import org.rapidsms.java.core.model.Form;
18import org.rapidsms.java.core.model.Message;
19
20import android.app.Activity;
21import android.app.ProgressDialog;
22import android.database.Cursor;
23import android.database.sqlite.SQLiteDatabase;
24import android.util.Log;
25import android.webkit.WebView;
26
27public class FormDataBroker extends ChartBroker {
28        public static final int PLOT_ALL_MESSAGES_FOR_FORM = 0;
29        public static final int PLOT_NUMERIC_FIELD_VALUE = 1;
30        public static final int PLOT_NUMERIC_FIELD_ADDITIVE = 2;
31        public static final int PLOT_WORD_HISTOGRAM = 3;
32        public static final int PLOT_NUMERIC_FIELD_COUNT_HISTOGRAM = 4;
33
34        private Form mForm;
35        private Field fieldToPlot;
36        private int mPlotMethod;
37        private ProgressDialog mProgress;
38
39        public FormDataBroker(Activity parentActivity, WebView appView, Form form, Date startDate, Date endDate) {
40                super(parentActivity,appView,startDate,endDate);
41                mForm = form;
42                // by default, do all messages for form
43                mPlotMethod = PLOT_ALL_MESSAGES_FOR_FORM;
44
45                mVariableStrings= new String[mForm.getFields().length+1];
46                mVariableStrings[0] = "Messages over time";
47                for (int i = 1; i < mVariableStrings.length; i++) {
48                        Field f = mForm.getFields()[i-1];
49                        mVariableStrings[i] = f.getName();
50                }               
51        }
52
53        public void doLoadGraph() {
54                //mProgress = ProgressDialog.show(mAppView.getContext(), "Rendering Graph...", "Please Wait",true,false);
55                JSONGraphData allData  = null;
56               
57                if (fieldToPlot == null) {
58                        //we're going to do all messages over timereturn;
59                        allData = loadMessageOverTimeHistogram();
60                } else if (fieldToPlot.getFieldType().getItemType().equals("word")) {
61                        allData = loadHistogramFromField(); 
62                } else {
63                        allData = loadNumericLine(); 
64                        //data.put(loadNumericLine());
65                }
66                if (allData != null) {
67                        mGraphData = allData.getData();
68                        mGraphOptions = allData.getOptions();
69                } 
70                Log.d("FormDataBroker",mGraphData.toString());
71                Log.d("FormDataBroker",mGraphOptions.toString());               
72        }
73
74       
75        private JSONGraphData loadNumericLine() {
76                JSONObject result = new JSONObject();
77                SQLiteDatabase db = rawDB.getReadableDatabase();
78
79                String fieldcol = RapidSmsDBConstants.FormData.COLUMN_PREFIX
80                                + fieldToPlot.getName();
81                StringBuilder rawQuery = new StringBuilder();
82                rawQuery.append("select rapidandroid_message.time, " + fieldcol);
83                rawQuery.append(" from ");
84                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX
85                                + mForm.getPrefix());
86
87                rawQuery.append(" join rapidandroid_message on (");
88                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX
89                                + mForm.getPrefix());
90                rawQuery.append(".message_id = rapidandroid_message._id");
91                rawQuery.append(") ");
92               
93                if(mStartDate.compareTo(Constants.NULLDATE) != 0 && mEndDate.compareTo(Constants.NULLDATE) != 0) {
94                        rawQuery.append(" WHERE rapidandroid_message.time > '" + Message.SQLDateFormatter.format(mStartDate) + "' AND rapidandroid_message.time < '" + Message.SQLDateFormatter.format(mEndDate) + "' ");
95                }
96
97                rawQuery.append(" order by rapidandroid_message.time ASC");
98
99                // the string value is column 0
100                // the magnitude is column 1
101
102                Cursor cr = db.rawQuery(rawQuery.toString(), null);
103                int barCount = cr.getCount();
104
105                if (barCount == 0) {
106                        cr.close();
107                } else {
108                        Date[] xVals = new Date[barCount];
109                        int[] yVals = new int[barCount];
110                        cr.moveToFirst();
111                        int i = 0;
112                        do {
113                                try {
114                                        xVals[i] = Message.SQLDateFormatter.parse(cr.getString(0));
115                                        yVals[i] = cr.getInt(1);
116                                } catch (Exception ex) {
117
118                                }
119                                i++;
120                        } while (cr.moveToNext());
121
122                        // xaxis: { ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"],
123                        // [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]]},
124
125                        try {
126//                              result.put("label", fieldToPlot.getName());
127//                              result.put("data", prepareDateData(xVals, yVals));
128//                              result.put("label", fieldToPlot.getName());
129//                              result.put("lines", getShowTrue());
130//                              result.put("points", getShowTrue());
131//                              result.put("xaxis", getDateOptions());
132                                return new JSONGraphData(prepareDateData(xVals, yVals),loadOptionsForDateGraph(xVals, false) );
133                        } catch (Exception ex) {
134
135                        }
136                        finally {
137                                if (!cr.isClosed()) {
138                                        cr.close();
139                                }
140                        }
141                       
142                }
143                // either there was no data or something bad happened
144                return new JSONGraphData(getEmptyData(), new JSONObject());     
145        }
146
147       
148        private JSONArray getEmptyData() {
149                JSONArray toReturn = new JSONArray();
150                JSONArray innerArray = new JSONArray();
151                innerArray.put(0);
152                innerArray.put(0);
153                toReturn.put(innerArray);
154                return toReturn;
155        }
156
157        private JSONObject getDateOptions() {
158                JSONObject rootxaxis = new JSONObject();
159
160                try {
161                        rootxaxis.put("mode", "time");
162                } catch (Exception ex) {
163
164                }
165                return rootxaxis;
166        }
167
168        private JSONArray prepareDateHistogramData(DateDisplayTypes displayType, Date[] xvals, int[] yvals, String legend) throws JSONException {
169                JSONArray outerArray = new JSONArray();
170                JSONArray innerArray = new JSONArray();
171                int datalen = xvals.length;
172                Date prevVal = null;
173                for (int i = 0; i < datalen; i++) {
174                        Date thisVal = xvals[i];
175                        if (prevVal != null) {
176                                // add logic to fill in zeros
177                                Date nextInSeries = getNextValue(displayType, prevVal);
178                                while (isBefore(displayType, nextInSeries, thisVal))
179                                {
180                                        JSONArray elem = new JSONArray();
181                                        elem.put(nextInSeries.getTime());
182                                        elem.put(0);
183                                        innerArray.put(elem);
184                                        nextInSeries = getNextValue(displayType, nextInSeries);
185                                }
186                        }
187                        JSONArray elem = new JSONArray();
188                        elem.put(xvals[i].getTime());
189                        elem.put(yvals[i]);
190                        innerArray.put(elem);
191                        prevVal = thisVal;
192                }
193                JSONObject finalObj = new JSONObject();
194                finalObj.put("data", innerArray);
195                finalObj.put("label", legend);
196                outerArray.put(finalObj);
197                return outerArray;
198        }
199       
200        private JSONArray prepareDateData(Date[] xvals, int[] yvals) {
201                JSONArray outerArray = new JSONArray();
202                JSONArray innerArray = new JSONArray();
203                int datalen = xvals.length;
204                for (int i = 0; i < datalen; i++) {
205                        JSONArray elem = new JSONArray();
206                        elem.put(xvals[i].getTime());
207                        elem.put(yvals[i]);
208                        innerArray.put(elem);
209                }
210                outerArray.put(innerArray);
211                return outerArray;
212        }
213       
214        private JSONGraphData loadMessageOverTimeHistogram() {
215                SQLiteDatabase db = rawDB.getReadableDatabase();
216               
217                //Date firstDateFromForm = ParsedDataReporter.getOldestMessageDate(rawDB, mForm);
218                Date startDateToUse = mStartDate;
219//              if (firstDateFromForm.after(mStartDate)) {
220//                      // first date in the form is more recent than the start date, so just go with that.
221//                      startDateToUse = firstDateFromForm;
222//              }
223                DateDisplayTypes displayType = this.getDisplayType(startDateToUse, mEndDate);
224               
225                String legend = getLegendString(displayType);
226                String selectionArg = getSelectionString(displayType);
227               
228                StringBuilder rawQuery = new StringBuilder();
229               
230                rawQuery.append("select time, count(*) from  ");
231                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX + mForm.getPrefix());
232               
233                rawQuery.append(" join rapidandroid_message on (");
234                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX + mForm.getPrefix());
235                rawQuery.append(".message_id = rapidandroid_message._id");
236                rawQuery.append(") ");
237                if(startDateToUse.compareTo(Constants.NULLDATE) != 0 && mEndDate.compareTo(Constants.NULLDATE) != 0) {
238                        rawQuery.append(" WHERE rapidandroid_message.time > '" + Message.SQLDateFormatter.format(startDateToUse) + "' AND rapidandroid_message.time < '" + Message.SQLDateFormatter.format(mEndDate) + "' ");
239                }
240               
241                rawQuery.append(" group by ").append(selectionArg);             
242                rawQuery.append("order by ").append(selectionArg).append(" ASC");
243               
244       
245                // the X date value is column 0
246                // the y value magnitude is column 1
247
248                Cursor cr = db.rawQuery(rawQuery.toString(), null);
249                int barCount = cr.getCount();
250
251                if (barCount == 0) {
252                        db.close();
253                        cr.close();
254                } else {
255                        Date[] xVals = new Date[barCount];
256                        int[] yVals = new int[barCount];
257                        cr.moveToFirst();
258                        int i = 0;
259                        do {
260                                xVals[i] = getDate(displayType, cr.getString(0));
261                                yVals[i] = cr.getInt(1);
262                                i++;
263                        } while (cr.moveToNext());
264
265                        try {
266                                //result.put("label", fieldToPlot.getName());
267                                //result.put("data", prepareData(xVals, yVals));
268                                //result.put("bars", getShowTrue());
269                                //result.put("xaxis", getXaxisOptions(xVals));
270                                // todo
271                                return new JSONGraphData(prepareDateHistogramData(displayType, xVals, yVals, legend),loadOptionsForDateGraph(xVals, true) );
272                               
273                        } catch (Exception ex) {
274
275                        } finally {
276                                if (!cr.isClosed()) {
277                                       
278                                        cr.close();
279                                }
280                                if(db.isOpen()) {
281                                        db.close();
282                                }
283                        }
284                }
285                // either there was no data or something bad happened
286                return new JSONGraphData(getEmptyData(), new JSONObject());     
287        }
288       
289
290       
291       
292        /**
293         * Should return a two element array - the first element is the data,
294         * the second are the options
295         * @return
296         */
297        private JSONGraphData loadHistogramFromField() {
298                //JSONObject result = new JSONObject();
299                SQLiteDatabase db = rawDB.getReadableDatabase();
300
301                String fieldcol = RapidSmsDBConstants.FormData.COLUMN_PREFIX
302                                + fieldToPlot.getName();
303                StringBuilder rawQuery = new StringBuilder();
304                rawQuery.append("select " + fieldcol);
305                rawQuery.append(", count(*) from ");
306                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX
307                                + mForm.getPrefix());
308               
309                rawQuery.append(" join rapidandroid_message on (");
310                rawQuery.append(RapidSmsDBConstants.FormData.TABLE_PREFIX
311                                + mForm.getPrefix());
312                rawQuery.append(".message_id = rapidandroid_message._id");
313                rawQuery.append(") ");
314               
315                if(mStartDate.compareTo(Constants.NULLDATE) != 0 && mEndDate.compareTo(Constants.NULLDATE) != 0) {
316                        rawQuery.append(" WHERE rapidandroid_message.time > '" + Message.SQLDateFormatter.format(mStartDate) + "' AND rapidandroid_message.time < '" + Message.SQLDateFormatter.format(mEndDate) + "' ");
317                }
318
319               
320                rawQuery.append(" group by " + fieldcol);
321                rawQuery.append(" order by " + fieldcol);
322
323                // the string value is column 0
324                // the magnitude is column 1
325
326                Cursor cr = db.rawQuery(rawQuery.toString(), null);
327                int barCount = cr.getCount();
328
329                if (barCount != 0) {
330                        String[] xVals = new String[barCount];
331                        int[] yVals = new int[barCount];
332                        cr.moveToFirst();
333                        int i = 0;
334                        do {
335                                xVals[i] = cr.getString(0);
336                                yVals[i] = cr.getInt(1);
337                                i++;
338                        } while (cr.moveToNext());
339
340                        // xaxis: { ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"],
341                        // [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]]},
342
343                        try {
344                                //result.put("label", fieldToPlot.getName());
345                                //result.put("data", prepareData(xVals, yVals));
346                                //result.put("bars", getShowTrue());
347                                //result.put("xaxis", getXaxisOptions(xVals));
348                                return new JSONGraphData(prepareHistogramData(xVals, yVals),loadOptionsForHistogram(xVals) );
349                        } catch (Exception ex) {
350
351                        } finally {
352                                if (!cr.isClosed()) {
353                                        cr.close();
354                                }
355                                if(db.isOpen()) {
356                                        db.close();
357                                }
358                        }
359                }
360                // either there was no data or something bad happened
361                return new JSONGraphData(getEmptyData(), new JSONObject());
362        }
363
364        private JSONArray prepareHistogramData(String[] names, int[] counts) throws JSONException {
365                // TODO Auto-generated method stub
366                JSONArray arr = new JSONArray();
367                int datalen = names.length;
368                for (int i = 0; i < datalen; i++) {
369                       
370                        JSONObject elem = new JSONObject();
371                        // values will just be an array of length 1 with a single value
372                        JSONArray values = new JSONArray();
373                        JSONArray value = new JSONArray();
374                        value.put(i);
375                        value.put(counts[i]);
376                        values.put(value);
377                        elem.put("data", values);
378                        elem.put("bars", getShowTrue());
379                        elem.put("label", names[i]);
380                        arr.put(elem);
381                }
382                return arr;
383        }
384       
385        private JSONObject loadOptionsForDateGraph(Date[] vals, boolean displayLegend) throws JSONException {
386
387                JSONObject toReturn = new JSONObject();
388                //bars: { show: true }, points: { show: false }, xaxis: { mode: "time", timeformat:"%y/%m/%d" }
389                toReturn.put("bars", getShowFalse());
390                toReturn.put("lines", getShowTrue());
391                toReturn.put("points", getShowFalse());
392                toReturn.put("xaxis", getXaxisOptionsForDate());
393                if (displayLegend) {
394                        toReturn.put("legend", getShowTrue());
395                } 
396                toReturn.put("grid", getJSONObject("clickable", false));
397                return toReturn;
398        }
399       
400        private JSONObject getXaxisOptionsForDate() throws JSONException {
401                JSONObject toReturn = new JSONObject();
402                toReturn.put("mode", "time");
403                toReturn.put("timeformat", "%m/%d/%y");
404                return toReturn;
405        }
406
407        private JSONObject loadOptionsForHistogram(String[] labels) throws JSONException {
408               
409                JSONObject toReturn = new JSONObject();
410                toReturn.put("xaxis", this.getXaxisOptions(labels));
411                toReturn.put("grid", getJSONObject("clickable", true));
412                return toReturn;
413        }
414
415        private JSONObject getJSONObject(String string, Object o) {
416                JSONObject toReturn = new JSONObject();
417                try {
418                        toReturn.put(string, o);
419                } catch (Exception ex) {
420                }
421                return toReturn;
422        }
423
424        // puts the yvalues into the json array for the given x values (defined by
425        // the array indices)
426        // so output format is [[x0,y0],[x1,y1]...etc]
427        // in reality is [[0,values[0]],[1,values[1], etc]
428        private JSONArray prepareData(int[] values) {
429                JSONArray arr = new JSONArray();
430                int datalen = values.length;
431                for (int i = 0; i < datalen; i++) {
432                        JSONArray elem = new JSONArray();
433                        elem.put(i);
434                        elem.put(values[i]);
435                        arr.put(elem);
436                }
437                return arr;
438        }
439
440        private JSONObject getXaxisOptions(String[] tickvalues) {
441                JSONObject rootxaxis = new JSONObject();
442                JSONArray arr = new JSONArray();
443                int ticklen = tickvalues.length;
444
445                for (int i = 0; i < ticklen; i++) {
446                        JSONArray elem = new JSONArray();
447                        elem.put(i);
448                        elem.put(tickvalues[i]);
449                        arr.put(elem);
450                }
451
452                try {
453                        rootxaxis.put("min", 0);
454                        rootxaxis.put("max", tickvalues.length + tickvalues.length / 5 + 1);
455                        rootxaxis.put("ticks", arr);
456                        rootxaxis.put("tickFormatter", "string");
457                } catch (Exception ex) {
458
459                }
460                return rootxaxis;
461        }
462
463        private JSONArray getRandomData() {
464                Random rand = new Random();
465                JSONArray arr = new JSONArray();
466                int priorval = rand.nextInt(100);
467                for (int i = 0; i < 100; i++) {
468                        JSONArray elem = new JSONArray();
469                        elem.put(i);
470                        if (rand.nextBoolean()) {
471                                priorval += rand.nextInt(10);
472                        } else {
473                                priorval -= rand.nextInt(10);
474                        }
475                        elem.put(priorval);
476                        arr.put(elem);
477                }
478                return arr;
479        }
480
481        private JSONObject getLineOptionsJSON() {
482                JSONObject ret = new JSONObject();
483                try {
484                        ret.put("show", true);
485                } catch (Exception ex) {
486
487                }
488                return ret;
489        }
490
491        private JSONObject getShowTrue() {
492                JSONObject ret = new JSONObject();
493                try {
494                        ret.put("show", true);
495                } catch (Exception ex) {
496
497                }
498                return ret;
499        }
500
501        private JSONObject getShowFalse() {
502                JSONObject ret = new JSONObject();
503                try {
504                        ret.put("show", false);
505                } catch (Exception ex) {
506
507                }
508                return ret;
509        }
510
511        public String getGraphTitle() {
512                return "my line baby";
513        }
514
515        /*
516         * (non-Javadoc)
517         *
518         * @see org.rapidandroid.activity.chart.ChartBroker#setVariable(int)
519         */
520
521        public void setVariable(int id) {
522                // TODO Auto-generated method stub
523                if(id == 0) {
524                        this.fieldToPlot = null;
525                } else {
526                        this.fieldToPlot = mForm.getFields()[id-1];
527                }
528                this.mGraphData = null;
529                this.mGraphOptions = null;
530        }
531/* (non-Javadoc)
532         * @see org.rapidandroid.activity.chart.ChartBroker#finishGraph()
533         */
534       
535        public String getName() {
536                return "graph_form";
537        }
538}
Note: See TracBrowser for help on using the browser.