Leinoset.org Web development and Mobile development, Front - and Backend, Android applications & games, design

Front- and Backend development, Web and Graphical design, Mobile application development
Front- and Backend development, Web and Graphical design, Mobile application development

Android simple Pie Chart

01 July 2015

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.

  1. Start by creating new project to your IDE , with blank activity.

  2. 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 of pieLayout after the TextView helloworld. So full activity_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>
    
  3. We need add this new layout to our current MainActivity. After public class MainActivity we add LinearLayout pieLayout; and also add to onCreate method, pieLayout = (LinearLayout) findViewById(R.id.pieLayout); . Later in step 5. you will find the whole MainActivity.class.

  4. 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);
    }
    

    }

  5. Then we are ready to finalize our MainActivity by adding drawPie method. So the final MainActivity.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);
        }
    }
    
  6. You are DONE! :) There you have it, you can now try it and it should look like this,