【Android】アニメーション付き円グラフを作ってみる

<img src="http://oneworld2.sakura.ne.jp/blog/graph4.gif" width=200>
http://qiita.com/kitanoow/items/91c6031ab903523b8cd7
http://qiita.com/kitanoow/items/bfd963ed9bf6f8f708ed

この辺に引き続き。
ただし中切り抜きは出来ず(どうにか方法はありそうですが、いい方法が思い浮かばず)

半径は対象表示領域の約半分として調整
アニメーションといっても実質はタイマーで管理し、描画部分を
徐々に増やしているだけ。


```java:PieGraphView.java

public class PieGraphView extends View {
    private ArrayList<HashMap<String,String>> params;
    float _end_angle = -90;

    public PieGraphView(Context context, ArrayList<HashMap<String, String>> params) {
        super(context);
        this.params = params;

    }

    public void onDraw(Canvas c){
        int width  = c.getWidth();
        int length = params.size();
        float max = 0;
        for(int i=0;i<length;i++) {
            float val = Integer.parseInt(params.get(i).get("value"));
            max += val;
        }
        float radius = width/2 - 30;
        float start_angle = -90;
        float end_angle = 0;
        GraphPoint center = new GraphPoint(radius + 15, radius + 15 );
        for(int i=0;i<length;i++) {
            float val = Integer.parseInt(params.get(i).get("value"));
            end_angle = start_angle + 360 * (val / max);
            if(end_angle > _end_angle) {
                end_angle = _end_angle;
            }
            this.createPieSlice(c,Integer.parseInt(params.get(i).get("color")),start_angle,end_angle,center,radius);
            start_angle = end_angle;
        }
    }

    private void createPieSlice(Canvas c, int color,float start_angle,float end_angle,GraphPoint center,float r){
        Paint paint = new Paint();
        paint.setAntiAlias(false);
        paint.setColor(color);
        RectF oval1 = new RectF(center.getX()-r, center.getY()-r, center.getX() + r, center.getY() + r);
        c.drawArc(oval1, start_angle, end_angle - start_angle, true, paint);

        //外枠
        paint = new Paint();
        paint.setColor(Color.argb(255, 0, 0, 0));
        paint.setStyle(Paint.Style.STROKE);
        c.drawArc(oval1, start_angle, end_angle-start_angle, true, paint);

    }


    Timer timer;

    public void startAnimation(){
        _end_angle = -90;
        final Handler handler = new Handler();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                float angle = (float)(360 / 100.0);
                _end_angle += angle;
                if(_end_angle > 270) {
                    _end_angle = 270;
                    timer.cancel();
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        invalidate();
                    }
                });
            }
        };

        timer = new Timer();
        //アニメーションのスピード調整できるようにしたいところ
        timer.schedule(task,0,30);

    }
    public void changeParam(ArrayList<HashMap<String,String>> params)
    {
        this.params = params;
        this.invalidate();
    }

}

```

x,y管理用。いらんかったかも。


```java:GraphPoint.java

public class GraphPoint {
    private float x;
    private float y;
    public GraphPoint(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public void setX(float x) {
        this.x = x;
    }

    public void setY(float y) {
        this.y = y;
    }

}

```


利用イメージはこんな感じで。
1秒後にアニメーションを開始させている

```java:MainActivity.java


public class MainActivity extends ActionBarActivity {
    protected PieGraphView pieGraphView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //activity_main.xmlで用意した、ただのFrameLayout
        FrameLayout circle = (FrameLayout)findViewById(R.id.circleView);
        circle.setBackgroundColor(Color.argb(0, 0, 0, 0));

        ArrayList<HashMap<String,String>> params = new ArrayList<HashMap<String,String>>();
        ArrayList<Integer> color = new ArrayList<Integer>();
        color.add(Color.argb(255,255,0,0));
        color.add(Color.argb(255,0,255,0));
        color.add(Color.argb(255,0,0,255));
        color.add(Color.argb(255,255,255,0));

        Random rnd = new Random();
        for(int i=0;i<4;i++){
            HashMap<String,String> map = new HashMap<String,String>();
            int r = rnd.nextInt(100) + 1;
            map.put("color", String.valueOf(color.get(i)));
            map.put("value", String.valueOf(r));
            params.add(map);
        }
        pieGraphView = new PieGraphView(this,params);
        circle.addView(pieGraphView);


        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                pieGraphView.startAnimation();
            }
        },1000);
    }

}
```