Android MP PhilJay Group Bar Chart using Retrofit
This Tutorial describes how to create MP PhilJay group bar chart in android using retrofit. In contrast, Most of published tutorials describe group bar chart with a defined number of data sets.
Therefore, This tutorial solves the problem of fixed group space and bar width. In contrast, when the user click on button it shows the sales per product per month. Accordingly, we have three data sets.
More over, If the user made another click on the button the chart will display the sales per twelve months. So, we have twelve data sets.
Thus, we can not declare a fixed group space and bar width. Accordingly, This tutorial works on how to create a flexible bar chart using MP Philjay Library.
Additionally, You will learn how to work with Retrofit and multiple responses with single request. i.e. when you have API response with json array with children json array.
Moreover, Android mp philjay charts library is jitpack library which is maven repositories. Thus, It requires jitpack.io dependency. Lets start.
MP Philjay Bar Chart Dependencies
Start a new android studio and open project level gradle file. Next add the jitpack maven dependency.


maven { url "https://jitpack.io" }
Then, open module level gradle file and add the following dependencies. And click sync.

dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' implementation 'com.android.support:design:29.0.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' //add the following dependencies implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3' implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.squareup.retrofit2:retrofit:2.7.1' implementation 'com.squareup.retrofit2:converter-gson:2.7.1' }
Next, Open Android Manifest file and add the internet permissions and make the following changes.
<uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Then, Add the following colors in Colors.xml fie.
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#6200EE</color> <color name="colorPrimaryDark">#3700B3</color> <color name="colorAccent">#03DAC5</color> <color name="bar1">#F44336</color> <color name="bar2">#9C27B0</color> <color name="bar3">#2196F3</color> <color name="bar4">#E91E63</color> <color name="bar5">#FFEB3B</color> <color name="bar6">#009688</color> <color name="bar7">#8BC34A</color> <color name="bar8">#FF9800</color> <color name="bar9">#01579B</color> <color name="bar10">#827717</color> <color name="bar11">#006064</color> <color name="bar12">#B71C1C</color> </resources>
The next step, Open main_activity.xml file and add android mp philjay bar chart, Button and ProgressBar.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Show Sales/Product" android:background="@android:color/holo_green_dark" android:textAllCaps="false" android:textSize="18sp" android:id="@+id/switchChart" android:textStyle="bold" android:textColor="@android:color/white"/> <ProgressBar android:layout_width="40dp" android:layout_height="40dp" android:id="@+id/progress_circular" android:visibility="gone" android:layout_gravity="center"/> <com.github.mikephil.charting.charts.BarChart android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/bar_chart"/> </LinearLayout>
Create a new java class for Retrofit API Client as the following code.
public class ApiClient { private static final String BASE_URL = "http://10.0.2.2/barchart/"; public static Retrofit retrofit = null; public static Retrofit getRetrofit(){ if (retrofit == null){ retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build(); } return retrofit; } }
Create Interface class to add Retrofit Call method as the following code.
public interface ApiInterface { @GET("chart.php") Call<ChartResponse> getChartAnalysis(); }
Next, create and java class for SalesModel.
public class Sales { @SerializedName("product") private String product; @SerializedName("month") private String month; @SerializedName("sales") private int sales; public String getProduct() { return product; } public String getMonth() { return month; } public int getSales() { return sales; } }
Now, We need to create a new java class for Retrofit Response of the chart data.
public class ChartResponse { @SerializedName("sales") private Object getSalesResponse = null; @SerializedName("months") private Object getMonthsResponse = null; @SerializedName("products") private Object getProductsResponse = null; public Object getGetSalesResponse() { return getSalesResponse; } public Object getGetMonthsResponse() { return getMonthsResponse; } public Object getGetProductsResponse() { return getProductsResponse; } }
Group Bar Chart Back end Settings
We need to install local server. Download Wamp server from the following link and install it. After installation open it and wait till it`s tray icon become green color.

Click on the green icon and open WWW directory. Inside this directory create a new folder and name it barchart . Open the folder and and the following PHP Scripts.
By creating new text note and copy paste the following code and save the file with php extension.
Create conn.php file
<?php $db_name = "chartdatabas";
$username = "root";
$password = "";
$servername = "127.0.0.1";
$conn = mysqli_connect($servername,$username,$password ,$db_name); ?>
Create chart.php file.
<?php require "conn.php"; if($conn){ $sqlSelectDistinctMonths = "SELECT DISTINCTmonth
FROMproduct_sales
"; $monthsQuery = mysqli_query($conn,$sqlSelectDistinctMonths); $months = array(); while($row = mysqli_fetch_array($monthsQuery)){ array_push($months ,$row[0]);} $sqlSelectDistinctProducts = "SELECT DISTINCTproduct
FROMproduct_sales
"; $productsQuery = mysqli_query($conn,$sqlSelectDistinctProducts ); $products = array(); while($row = mysqli_fetch_array($productsQuery)){ array_push( $products ,$row[0]);} $sqlSelectSales = "SELECT * FROMproduct_sales
"; $salesQuery = mysqli_query($conn,$sqlSelectSales ); $sles = array(); while($row = mysqli_fetch_array($salesQuery)){ array_push($sles ,array('product'=>$row[1],'month'=>$row[2],'sales'=>$row[3])); } echo json_encode(array('sales'=>$sles ,'months'=>$months ,'products'=>$products) ); } else{ echo json_encode(array('sales'=>"Connection Error",'months'=>"Connection Error" ,'products'=>"Connection Error" )); }?>
Now, Open your browser and type “localhost/phpmyadmin”. In user name field type “root” and leave password empty and click Go button. You will enter the phpmyadmin as the following image.

In Databases tap type the database name “chartdatabase” and click create.
Next, download the products table from the above button and go to php myadmin and click import tab and select the excel file to import it. Similarly, You can follow steps of tutorial video on youtube. Finally, After importing table open main activity java file and put the following code
public class MainActivity extends AppCompatActivity { private static final String TAG = "TAG"; float barSpace = 0.02f; float groupSpace = 0.3f; List<Sales> salesList = new ArrayList<>(); List<String> products = new ArrayList<>(); List<String> monthsList = new ArrayList<>(); BarChart barChart; ProgressBar progressBar; Button switchChart; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); barChart = findViewById(R.id.bar_chart); progressBar = findViewById(R.id.progress_circular); switchChart = findViewById(R.id.switchChart); switchChart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getChartAnalysis(switchChart.getText().toString()); } }); } private void setBarChart(List<String> dataSets,List<String> groupList,String type){ int[] MyColors = { getResources().getColor( R.color.bar1), getResources().getColor( R.color.bar2), getResources().getColor( R.color.bar3), getResources().getColor( R.color.bar4), getResources().getColor( R.color.bar5), getResources().getColor( R.color.bar6), getResources().getColor( R.color.bar7), getResources().getColor( R.color.bar8), getResources().getColor( R.color.bar9), getResources().getColor( R.color.bar10), getResources().getColor( R.color.bar11), getResources().getColor( R.color.bar12), }; ArrayList<BarDataSet> arrayList = new ArrayList<>(); for (int i = 0; i < dataSets.size();i ++){ BarDataSet barDataSet = new BarDataSet(barEntries(dataSets.get(i),groupList,type),dataSets.get(i)); barDataSet.setColor(MyColors[i]); barDataSet.setValueTextSize(4f); arrayList.add(barDataSet); } BarData barData = new BarData(); for (int i = 0 ; i < arrayList.size();i ++){ barData.addDataSet(arrayList.get(i)); } barData.setValueTextSize(7f); barChart.setData(barData); barChart.setPinchZoom(false); barChart.setDrawGridBackground(false); XAxis xAxis = barChart.getXAxis(); xAxis.setValueFormatter(new IndexAxisValueFormatter(groupList)); xAxis.setPosition(XAxis.XAxisPosition.TOP); xAxis.setGranularity(1); xAxis.setGranularityEnabled(true); xAxis.setDrawGridLines(true); barData. setBarWidth(.02f); Legend legend = barChart.getLegend(); legend.setTextSize(10); legend.setWordWrapEnabled(true); barChart.setVisibleXRangeMaximum(2); barChart.getXAxis().setAxisMinimum(0); float defaultBarWidth; int groupCount = groupList.size(); defaultBarWidth = (1 - groupSpace)/arrayList.size() - barSpace; if(defaultBarWidth >=0) { barData.setBarWidth(defaultBarWidth); } barChart.getXAxis().setAxisMinimum(0); barChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupList.size()); barChart.getXAxis().setCenterAxisLabels(true); if (barData.getDataSetCount() > 1){ barChart.groupBars(0,groupSpace,barSpace); } barChart.invalidate(); } private ArrayList<BarEntry> barEntries(String month,List<String > groupList,String type){ ArrayList<BarEntry> arrayList =new ArrayList<>(); int i = 0; while (i < groupList.size()){ for (Sales s: salesList){ if(type.equals("month")) { if (s.getMonth().equals(month)) { BarEntry barEntry = new BarEntry(i, s.getSales()); arrayList.add(barEntry); } }else if(type.equals("product")){ if (s.getProduct().equals(month)) { BarEntry barEntry = new BarEntry(i, s.getSales()); arrayList.add(barEntry); } } i++; } } return arrayList; } private void getChartAnalysis(final String type){ progressBar.setVisibility(View.VISIBLE); ApiInterface apiInterface = ApiClient.getRetrofit().create(ApiInterface.class); Call<ChartResponse> call = apiInterface.getChartAnalysis(); call.enqueue(new Callback<ChartResponse>() { @Override public void onResponse(Call<ChartResponse> call, Response<ChartResponse> response) { progressBar.setVisibility(View.GONE); Gson gson = new GsonBuilder().create(); TypeToken<List<Sales>> typeTokenSales = new TypeToken<List<Sales>>() { }; TypeToken<List<String>> typeTokenProducts = new TypeToken<List<String>>() { }; TypeToken<List<String>> typeTokenMonths = new TypeToken<List<String>>() { }; salesList.clear(); salesList.addAll(gson.fromJson(gson.toJson(response.body().getGetSalesResponse()),typeTokenSales.getType())); products = gson.fromJson(gson.toJson(response.body().getGetProductsResponse()),typeTokenProducts.getType()); monthsList = gson.fromJson(gson.toJson(response.body().getGetMonthsResponse()),typeTokenMonths.getType()); Log.d(TAG, "onResponse: "+gson.toJson(monthsList)); if (type.equals("Show Sales/Product")){ setBarChart(products,monthsList,"product"); switchChart.setText("Show Sales/Month"); }else if(type.equals("Show Sales/Month")){ setBarChart(monthsList,products,"month"); switchChart.setText("Show Sales/Product"); } } @Override public void onFailure(Call<ChartResponse> call, Throwable t) { Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } }); } }
Thank You
Tutorial you may interested
I tryed this code using 000webhost but it is not working…getting the error in retrofit class
in manifest file enable clear text traffic in application layer. and add network security xml file a copy the following code
finally in application layer of manifest file add this
android:networkSecurityConfig=”@xml/network_security_config” considering the name of the xml file and changing the host url.