Android simple Pie Chart
Once upon time I needed a simple pie chart for my Android application and I found some libraries and tutorials, but in the end I ended up doing it in what I think, simple way. I created a new view and the draw actual chart to canvas. In this example there are three different colors in pie chart and it also holds touch events for user to get more information about each slice of the pie.
Start by creating new project to your IDE , with blank activity.
We need to add place for our pie chart to existing
activity_main.xml
, and you can do that by adding new LinearLayout with id ofpieLayout
after the TextView helloworld. So fullactivity_main.xml
would look something like this.<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/pieLayout" android:paddingRight="40dp" android:paddingLeft="40dp" android:paddingBottom="40dp" android:paddingTop="40dp" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > </LinearLayout> </RelativeLayout>
We need add this new layout to our current
MainActivity
. Afterpublic class MainActivity
we addLinearLayout pieLayout;
and also add to onCreate method,pieLayout = (LinearLayout) findViewById(R.id.pieLayout);
. Later in step 5. you will find the wholeMainActivity.class
.Then we need a actual Pie Drawing class.
package examples.leinoset.org.pieexample; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; public class DrawPieChart extends View { Bitmap bitmap; float Cyan = 0; float Blue = 0; float Yellow = 0; public DrawPieChart(Context context) { super(context); this.setDrawingCacheEnabled(true); } public DrawPieChart(Context context, float blue,float cyan,float yellow) { super(context); // Here we create actual pie and get values for it. this.Cyan = cyan; this.Blue = blue; this.Yellow = yellow; this.setDrawingCacheEnabled(true); } @Override protected void onDraw(Canvas canvas) { // Here in this method we draw pie to canvas super.onDraw(canvas); RectF rectF; // Check orientation to get always symmetrical pie if (canvas.getHeight()>canvas.getWidth()) { rectF = new RectF(0, 0, canvas.getWidth(), canvas.getWidth()); } else { rectF = new RectF(0, 0, canvas.getHeight(), canvas.getHeight()); } // Then we need to count correct values what we draw: float total = Blue + Cyan + Yellow; float cyanPie = (float) Cyan/total; float yellowPie = (float) Yellow/total; float px = 90; float py = 360 * cyanPie; float fx = 90; float fy = -360 * yellowPie; // Draw Blue Paint blue = new Paint(); blue.setColor(Color.BLUE); blue.setStyle(Paint.Style.FILL); canvas.drawArc (rectF, 90, 360, true, blue); // Draw black stroke Paint black = new Paint(); black.setColor(Color.BLACK); black.setStyle(Paint.Style.STROKE); black.setStrokeWidth(1); canvas.drawArc (rectF, 90, 360, true, black); // Draw Cyan Paint cyan = new Paint(); cyan.setColor(Color.CYAN); cyan.setStyle(Paint.Style.FILL); canvas.drawArc (rectF, 90, py, true, cyan); // Draw Yellow Paint yellow = new Paint(); yellow.setColor(Color.YELLOW); yellow.setStyle(Paint.Style.FILL); canvas.drawArc (rectF, 90, fy, true, yellow); bitmap = this.getDrawingCache(true); } @Override public boolean onTouchEvent(MotionEvent event) { // On touch of each color let's make toast for user. int color = bitmap.getPixel((int) event.getX(), (int) event.getY()); Log.d(null, "touchevent color is "+color ); Log.d(null, "is matching"); if (color == Color.YELLOW) { Toast.makeText(getContext(), "You Touched Yellow", Toast.LENGTH_SHORT).show(); } if (color == Color.CYAN) { Toast.makeText(getContext(), "You Touched Cyan", Toast.LENGTH_SHORT).show(); } if (color == Color.BLUE) { Toast.makeText(getContext(), "You Touched Blue", Toast.LENGTH_SHORT).show(); } return super.onTouchEvent(event); }
}
Then we are ready to finalize our
MainActivity
by addingdrawPie
method. So the finalMainActivity.class
would look like this.package examples.leinoset.org.pieexample; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.LinearLayout; public class MainActivity extends ActionBarActivity { //Get PieChart DrawPieChart pie; // We need LinearLayout for pie LinearLayout pieLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pieLayout = (LinearLayout) findViewById(R.id.pieLayout); // And finally let's draw the pie :) drawPie(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public void drawPie() { // remove existing view's if any pieLayout.removeAllViews(); // pass values for method // DrawPieChart(Context context, float blue,float cyan,float yellow) // pie = new DrawPieChart(getApplicationContext(),33,33,33); // Then add our pie to layout pieLayout.addView(pie); } }
You are DONE! :) There you have it, you can now try it and it should look like this,