Plot a Horizontal Bar Graph using MPAndroidChart Library in SUSI.AI Android App

Graphs and charts provide a visual representation of the data. They provide a clearer and quicker understanding of the impact of certain statistics. Thus, SUSI.AI Android app makes use of bar charts to display statistics related to user ratings for SUSI skills. This blog guides through the steps to create a Horizontal Bar Chart, using MPAndroidChart library, that has been used in the SUSI.AI Android app skill details page to display the five star skill rating by the users. On vertical axis : Labels of the rating shown On horizontal axis : Percentage of total number of users who rated the skill with the corresponding number of stars on the vertical axis Step - 1 : Add the required dependencies to your build.gradle. (a) Project level build.gradle allprojects { repositories { maven { url 'https://jitpack.io' } } } (b) App level build.gradle dependencies { implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3' }   Step - 2 : Create an XML layout. <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Add a Horizontal Bar Chart using MPAndroidChart library --> <com.github.mikephil.charting.charts.HorizontalBarChart android:id="@+id/skill_rating_chart" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>   Step - 3 : Create an Activity and initialize the Horizontal Bar Chart. class MainActivity : Activity { lateinit var skillRatingChart : HorizontalBarChart override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.chart) setSkillGraph( ) } }   Step - 4 : Create a method in your MainActivity to set up the basic properties and the axes. /** * Set up the axes along with other necessary details for the horizontal bar chart. */ fun setSkillGraph(){ skillRatingChart = skill_rating_chart //skill_rating_chart is the id of the XML layout skillRatingChart.setDrawBarShadow(false) val description = Description() description.text = "" skillRatingChart.description = description skillRatingChart.legend.setEnabled(false) skillRatingChart.setPinchZoom(false) skillRatingChart.setDrawValueAboveBar(false) //Display the axis on the left (contains the labels 1*, 2* and so on) val xAxis = skillRatingChart.getXAxis() xAxis.setDrawGridLines(false) xAxis.setPosition(XAxis.XAxisPosition.BOTTOM) xAxis.setEnabled(true) xAxis.setDrawAxisLine(false) val yLeft = skillRatingChart.axisLeft //Set the minimum and maximum bar lengths as per the values that they represent yLeft.axisMaximum = 100f yLeft.axisMinimum = 0f yLeft.isEnabled = false //Set label count to 5 as we are displaying 5 star rating xAxis.setLabelCount(5) //Now add the labels to be added on the vertical axis val values = arrayOf("1 *", "2 *", "3 *", "4 *", "5 *") xAxis.valueFormatter = XAxisValueFormatter(values) val yRight = skillRatingChart.axisRight yRight.setDrawAxisLine(true) yRight.setDrawGridLines(false) yRight.isEnabled = false //Set bar entries and add necessary formatting setGraphData() //Add animation to the graph skillRatingChart.animateY(2000) } Here is the XAxisValueFormatter class that is used to add the custom labels to the vertical axis : public class XAxisValueFormatter implements IAxisValueFormatter { private String[] values; public XAxisValueFormatter(String[] values) { this.values = values; } @Override public String getFormattedValue(float value, AxisBase axis) { // "value" represents the position of the label on the axis (x or y) return this.values[(int) value]; } }   Step - 5 : Set the bar entries. /** * Set the bar entries i.e. the percentage of users who rated the skill with * a certain number of stars. * * Set the colors for different bars and the bar width of the bars. */ private fun…

Continue ReadingPlot a Horizontal Bar Graph using MPAndroidChart Library in SUSI.AI Android App

Comparing Different Graph View Libraries and Integrating Them in PSLab Android Application

There is a significant role of graphs in PSLab, they're used for the following purpose: To plot voltage signals from analog inputs in Oscilloscope Activity. To plot digital signals in Logical Analyzer Activity. To plot data points from various sensors. For this, we need to implement real time graphs that stimulate real time data from the PSLab device efficiently. It is necessary to analyze each and every Graph View Library, compare them and integrate the best one in PSLab Android app. Available Graph Libraries The available Graph View libraries of Android are: MPAndroidChart Graph-View SciChart Which one is the best with respect to the PSLab project? MPAndroidChart Line Graph plotted using MPAndroidChart (image source) It is an open source graph view library by Philipp Jahoda. The following are the features of MPAndroidChart There are 8 different chart types Scaling on both axes. Scaling can be done using pinch zoom gesture. Dual Axes, we can have 2 Y-axis. Real time support Customizable axis ie we can define different labels to the axis Save chart to SD-Card Predefined color templates Legends which are used to define which line depicts what. Animations Fully customizable, from background color to color of the lines and grids. On trying MPAndroidChart, I found it to be a slightly difficult to implement. Graph-View Line Graph plotted using GraphView Library (image source) It is also an open source graph view library by Jonas Gehring. The following are features of the Graph-View Supports Line Chart, Bar Chart and Points. Scrolling vertical and horizontal Scaling on both axes. Realtime Graph support Draw multiple series of data. Let the diagram show more that one series in a graph. You can set a color and a description for every series. Legends (as discussed in MPAndroidChart) Custom labels Manual Y axis limits can be set. SciChart It is rich APIs for Axis Ranging, Label Formatting, Chart Modifiers (interaction) and Renderable Series. It is packed with features but unfortunately, it is not open sourced. The Verdict Both MPAndroidChart and Graph-View are good libraries, packed with a lot of features. GraphView is easier to implement as compared to MPAndroidChat (not that difficult either). Both of them have the features like pinch zoom. MPAndroidChart had the feature of scale adjustment even when the graph is being plotted. The rate of plotting was comparable in both but it was slightly faster in MPAndroidChart. So, finally GraphView is easier to implement but MPAndroidChart has slightly better performance. So, we integrated MPAndroidChart in PSLab Android application. Integrating MPAndroidChart in PSLab Android App In order to integrate MPAndroidChart in the Android project add the following code in the build.gradle of your project.   compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' Creating Oscilloscope like graph If we observe an Oscilloscope, it has a black/blue screen with grid lines. An oscilloscope is a voltage vs time graph hence the x axis represents the time elapsed and y axis the voltage of the signal at the instant of time. There are left and right y axis for different channels.…

Continue ReadingComparing Different Graph View Libraries and Integrating Them in PSLab Android Application

Generating Real-Time Graphs in PSLab Android App

In PSLab Android App, we need to log data from the sensors and correspondingly generate real-time graphs. Real-time graphs mean a data streaming chart that automatically updates itself after every n second. This was different from what we did in Oscilloscope’s graph, here we need to determine the relative time at which the data is recorded from the sensor by the PSLab. Another thing we need to take care of was the range of x axis. Since the data to be streamed is ever growing, setting a large range of the x axis will only make reading sensor data tedious for the user. For this, the solution was to make real time rolling window graph. It’s like when the graph exceeds the maximum range of x axis, the graph doesn’t show the initial plots. For example, if I set that graph should show the data only for the 10-second window when the 11th-second data would be plot, the 1st-second data won’t be shown by the graph and maintains the difference between the maximum and the minimum range of the graph. The graph library we are going to use is MPAndroidChart. Let’s break-down the implementation step by step. First, we create a long variable, startTime which records the time at which the entire process starts. This would be the reference time. Flags make sure when to reset this time. if (flag == 0) { startTime = System.currentTimeMillis(); flag = 1; }   We used Async Tasks approach in which the data is from the sensors is acquired in the background thread and the graph is updated in the UI thread. Here we consider an example of the HMC5883L sensor, which is actually Magnetometer. We are calculating time elapsed by subtracting current time with the sartTime and the result is taken as the x coordinate. private class SensorDataFetch extends AsyncTask<Void, Void, Void> { ArrayList<Double> dataHMC5883L = new ArrayList<Double>(); long timeElapsed; @Override protected Void doInBackground(Void... params) { timeElapsed = (System.currentTimeMillis() - startTime) / 1000; entriesbx.add(new Entry((float) timeElapsed, dataHMC5883L.get(0).floatValue())); entriesby.add(new Entry((float) timeElapsed, dataHMC5883L.get(1).floatValue())); entriesbz.add(new Entry((float) timeElapsed, dataHMC5883L.get(2).floatValue())); return null; }   As we need to create a rolling window graph we require to add few lines of code with the standard implementation of the graph using MPAndroidChart. This entire code is placed under onPostExecute method of AsyncTasks. The following code sets data set for the Line Chart and tells the Line Chart that a new data is acquired. It’s very important to call notifyDataSetChanged, without this the things won’t work. mChart.setData(data); mChart.notifyDataSetChanged();   Now, we will set the visible range of x axis. This means that the graph window of the graph won’t change until and unless the range set by this method is not achieved. Here we are setting it to be 10 as we need a 10-second window. mChart.setVisibleXRangeMaximum(10); Then we will call moveViewToX method to move the view to the latest entry of the graph. Here, we have passed data.getEntryCount method which returns the no. of data points in the data…

Continue ReadingGenerating Real-Time Graphs in PSLab Android App

Integrating Stock Sensors with PSLab Android App

A sensor is a digital device (almost all the time an integrated circuit) which can receive data from outer environment and produce an electric signal proportional to that. This signal will be then processed by a microcontroller or a processor to provide useful functionalities. A mobile device running Android operating system usually has a few sensors built into it. The main purpose of these sensors is to provide user with better experience such as rotating the screen as he moves the device or turn off the screen when he is making a call to prevent unwanted screen touch events. PSLab Android application is capable of processing inputs received by different sensors plugged into it using the PSLab device and produce useful results. Developers are currently planning on integrating the stock sensors with the PSLab device so that the application can be used without the PSLab device. This blog is about how to initiate a stock sensor available in the Android device and get readings from it. Sensor API provided by Google developers is really helpful in achieving this task. The process is consist of several steps. It is also important to note the fact that there are devices that support only a few sensors while some devices will support a lot of sensors. There are few basic sensors that are available in every device such as “Accelerometer” - Measures acceleration along X, Y and Z axis “Gyroscope” - Measures device rotation along X, Y and Z axis “Light Sensor” - Measures illumination in Lux “Proximity Sensor” - Measures distance to an obstacle from sensor The implementing steps are as follows; Check availability of sensors First step is to invoke the SensorManager from Android system services. This class has a method to list all the available sensors in the device. SensorManager sensorManager; sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL); Once the list is populated, we can iterate through this to find out if the required sensors are available and obstruct displaying activities related to sensors that are not supported by the device. for (Sensor sensor : sensors) { switch (sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: break; case Sensor.TYPE_GYROSCOPE: break; ... } } Read data from sensors To read data sent from the sensor, one should implement the SensorEventListener interface. Under this interface, there are two method needs to be overridden. public class StockSensors extends AppCompatActivity implements SensorEventListener { @Override public void onSensorChanged(SensorEvent sensorEvent) { } @Override public void onAccuracyChanged(Sensor sensor, int i) { } } Out of these two methods, onSensorChanged() method should be addressed. This method provides a parameter SensorEvent which supports a method call getType() which returns an integer value representing the type of sensor produced the event. @Override public void onSensorChanged(SensorEvent sensorEvent) { switch (sensorEvent.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: break; case Sensor.TYPE_GYROSCOPE: break; ... } } Each available sensor should be registered under the SensorEventListener to make them available in onSensorChanged() method. The following code block illustrates how to modify the previous code to register each sensor easily with the…

Continue ReadingIntegrating Stock Sensors with PSLab Android App