Implementing Check-in time chart in Orga App
Earlier in the Open event orga app there were no charts present to track the check-in time of the attendees. Hence it was quite cumbersome for the organiser to track the people and at what time they have checked-in. Using this feature of check-in time chart, the process has become quite easier. Whenever an attendee checks-in, the data point is added to the chart and a chart is plotted. The Y-axis shows the number of attendees and the X-axis shows the time at which they have checked-in. To implement this feature I have taken use of the MPAndroidCharts library which makes the job a lot easier. Following steps were followed to implement the charts: Adding the following Library dependency in the build.gradle file implementation "com.github.PhilJay:MPAndroidChart:v3.0.3" Now the following code is added to the ticket_analytics.xml file. This is done so that the UI of the charts can be created. The following XML file consists of the LineChart XML tag which shows the check-in time chart on screen. Also the labelling of the axis needs to be done, so the X-axis is explicitly named as “TIME”. <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/spacing_normal" android:layout_marginStart="@dimen/spacing_normal" android:layout_marginTop="@dimen/spacing_normal" android:text="@string/check_in_summary" android:textAllCaps="true" android:textSize="@dimen/text_size_small" /> <com.github.mikephil.charting.charts.LineChart android:id="@+id/chartCheckIn" android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginEnd="@dimen/spacing_normal" android:layout_marginLeft="@dimen/spacing_normal" android:layout_marginRight="@dimen/spacing_normal" android:layout_marginStart="@dimen/spacing_normal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:text="@string/check_in_time" android:textSize="10sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <FrameLayout android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/color_shadow" /> <FrameLayout android:layout_width="match_parent" android:layout_height="@dimen/spacing_small" android:background="@color/color_bottom_surface" /> </LinearLayout> </LinearLayout> Now the a method loadCheckIn( ) chart needs to added to the EventsDashboardPresenter. This is called from the EventsDashboardFragment. The loadDataCheckIn( ) is created in the ChartAnalyzer class. We pass getId( ) as the parameter. private void loadCheckInTimesChart() { chartAnalyser.showChart(getView().getCheckinTimeChartView()); chartAnalyser.loadDataCheckIn(getId()) .compose(disposeCompletable(getDisposable())) .subscribe(() -> { getView().showChartCheckIn(true); chartAnalyser.showChart(getView().getCheckinTimeChartView()); }, throwable -> getView().showChartCheckIn(false)); } Now we add the method loadDataCheckIn( ) in the ChartAnalyzer class. This method returns a Completable and takes eventId as the single parameter. public Completable loadDataCheckIn(long eventId) { clearData(); isCheckinChart = true; return getAttendeeSource(eventId).doOnNext(attendee -> { String checkInTime = attendee.getCheckinTimes(); int length = checkInTime.split(",").length; String latestCheckInTime = checkInTime.split(",")[length - 1]; error = checkInTime == null ? true : false; addDataPointForCheckIn(checkInTimeMap, latestCheckInTime); }) .toList() .doAfterSuccess(attendees -> this.attendees = attendees) .toCompletable() .doOnComplete(() -> { if (error) throw new IllegalAccessException("No checkin's found"); checkInDataSet = setDataForCheckIn(checkInTimeMap, "check-in time"); prepare(); }); } It calls the getAttendeeSource( ) which further gives a call to the method getAttendees( ) from the AttendeeRepository. All the inormation related to the attendees is returned from which the check-in times is extracted. The check-in times are returned in comma separated form and hence we need to extract the first element of the sequence. private Observable<Attendee> getAttendeeSource(long eventId) { if (attendees == null || attendees.isEmpty()) return attendeeRepository.getAttendees(eventId, false); else return Observable.fromIterable(attendees); } After the success of loading the attendees, the method addDataPointForCheckIn is called. We call it by inserting the parameters Map<Integer, Long> and the dateString which we had passed from the loadDataCheckIn( ). Following is the code for it. A map is created out of the data. The key in the map is the time and value…
