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 setGraphData() {

   //Add a list of bar entries
   val entries = ArrayList<BarEntry>()
   entries.add(BarEntry(0f, 27f))
   entries.add(BarEntry(1f, 45f))
   entries.add(BarEntry(2f, 65f))
   entries.add(BarEntry(3f, 77f))
   entries.add(BarEntry(4f, 93f))

  //Note : These entries can be replaced by real-time data, say, from an API

  ......

}

 

Step – 6 : Now create a BarDataSet.

To display the data in a bar chart, you need to initialize a
BarDataSet instance. BarDataSet is the Subclass of DataSet class. Now, initialize the BarDataSet and pass the argument as an ArrayList of BarEntry object.

val barDataSet = BarDataSet(entries, "Bar Data Set")

 

Step – 7 : Assign different colors to the bars (as required).

private fun setGraphData() {
    .....

   //Set the colors for bars with first color for 1*, second for 2* and so on
      barDataSet.setColors(
              ContextCompat.getColor(skillRatingChart.context, R.color.md_red_500),
              ContextCompat.getColor(skillRatingChart.context, R.color.md_deep_orange_400),
              ContextCompat.getColor(skillRatingChart.context, R.color.md_yellow_A700),
              ContextCompat.getColor(skillRatingChart.context, R.color.md_green_700),
              ContextCompat.getColor(skillRatingChart.context, R.color.md_indigo_700)

   .....
)


Step – 8 : Populate data into Bar Chart.

To load the data into Bar Chart, you need to initialize a
BarData object  with bardataset. This BarData object is then passed into setData() method to load Bar Chart with data.

//Set bar shadows
   skillRatingChart.setDrawBarShadow(true)
   barDataSet.barShadowColor = Color.argb(40, 150, 150, 150)
   val data = BarData(barDataSet)

   //Set the bar width
   //Note : To increase the spacing between the bars set the value of barWidth to < 1f
   data.barWidth = 0.9f

   //Finally set the data and refresh the graph
   skillRatingChart.data = data
   skillRatingChart.invalidate()
}


Your Horizontal Bar Chart is now ready.
Note: You can format the labels as per your need and requirement with the help of XAxisValueFormatter.

References

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.