สร้างกราฟ Pie Chart บน Android ด้วย AChartEngine

สร้างกราฟ Pie Chart บน Android ด้วย AChartEngine Cover Image

บทความสอนเขียนแอพ Android วันนี้ขอนำเสนอเรื่อง การเขียนกราฟด้วย AChartEngine สำหรับบทความนี้จะเป็นการแสดง Pie Chart แบบง่ายๆให้ดูนะครับ เริ่มต้น ก็สร้างโปรเจ็คแบบปกติ ไฟล์ที่ต้องใช้มีแค่ 2 ไฟล์ครับ คือ ไฟล์ Activity กับ ไฟล์เลเอาท์ xml (หรือว่าจะใช้คลาสเก่าจากโปรเจ็คที่แล้วก็ได้)

สำหรับใครที่ยังไม่รู้จัก AchartEngine แนะนำให้อ่านบทความแรกที่ผมเขียน ได้ที่นี่ครับ สร้างกราฟ Line Chart บน Android ด้วย AChartEngine

Getting Started with AChartEngine

ก่อนที่จะไปสร้าง Pie Chart ด้วย AChartEngine เรามาดูภาพรวม แล้วก็แต่ละคลาสที่ใช้กันก่อนครับ

  • CategorySeries : ตัวนี้คือข้อมูลของกราฟ Pie ของเรา โดยจะแบ่งเป็นแต่ละชิ้นตามจำนวนข้อมูลของเรา
  • SimpleSeriesRenderer : ตัวนี้เอาไว้ render Pie แต่ละชิ้นของเราครับ เช่นพวก ปรับสีต่างๆ
  • DefaultRenderer : ตัวนี้สำหรับ render ทั้งกราฟ (คล้ายๆกับ XYMultipleSeriesRenderer)
  • GraphicalView : ตัวนี้คือ View ชนิดหนึ่ง ที่เอาไว้แสดง graph ครับ

รายละเอียดคร่าวๆ ก็เป็นดังนี้ หากใครงง (แน่นอนว่าต้องงง ถ้าเพิ่งเคยทำ ต้องลองดูตัวอย่าง แล้วจะเข้าใจมากขึ้นครับ) คิดว่า Pie Chart เขียนง่ายกว่า Line Chart แน่นอนครับ หากเข้าใจ Line Chart จากบทความก่อนหน้า บทความนี้ต้องบอกว่าง่ายมากๆครับ

เริ่มสร้างกราฟ

เป้าหมายคือ ต้องการแสดงกราฟ Pie Chart โดยดึงข้อมูลเวอร์ชันของ Android จากเว็บนี้ Android Dashboard

Android Dashboard

ทำการสร้างคลาสแอคติวิตี้ขึ้นมาใหม่ ตั้งชื่อว่า PieChartActivity.java ขึ้นมา โค๊ดเริ่มต้นผมเป็นแบบนี้

package com.devahoy.sample.achartengine;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {}

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }

}

fragment_main จะใช้อันเดียวกันกับโปรเจ็คที่แล้วนะครับ เนื่องจากมันไม่มีอะไรเลย มีแค่ RelativeLayout อันเดียวเอง

ใครใช้ fragment ไม่เป็น แนะนำให้อ่าน Android Fragment คือ? จริงๆควรจะใช้ fragment ในทุกๆโปรเจ็คนะครับ

ก่อนสร้างกราฟ เราต้องมีข้อมูลก่อน ฉะนั้น สร้างข้อมูลขึ้นมาโดยอ้างอิงข้อมูลจากเว็บ โดยสร้างเมธอดใหม่ ชื่อ initData() แบบนี้


private void initData() {
    String[] codename = {
            "KitKat", "Jelly Bean", "Ice Cream Sandwich",
            "Gingerbread", "Froyo"
    };

    double[] values = {13.6, 58.4, 12.3, 14.9, 0.8 };
    String[] colors = {
            "#ff4444", "#99cc00", "#aa66cc", "#33b5e5", "#ffbb33"
    };
}

จากโค๊ดด้านบน codename คือชื่อเวอร์ชันของแอนดรอยส์ ส่วน values คือข้อมูลที่เรามี และ colors หมายถึงสีแต่ละชิ้นของ Pie ว่าจะให้สีอะไรบ้าง ต่อมาเมื่อมีข้อมูลแล้ว ก็เริ่มทำการสร้างกราฟได้เลย

Pie Chart จะใช้ CategorySeries ในการเก็บข้อมูล ฉะนั้นก็สร้างแบบนี้เลย (ยังอยู่ในเมธอด initData() นะ)

CategorySeries series = new CategorySeries("Android Platform Version");
int length = codename.length;
for (int i = 0; i < length; i++) {
    series.add(codename[i], values[i]);
}

ต่อมาใช้ DefaultRenderer และ SimpleSeriesRenderer เพื่อไว้ render กราฟ โดย SimpleSeriesRenderer คือการ render Pie แต่ละชิ้น ในขณะที่ DefaultRenderer ใช้ render Pie ทั้งก้อน

DefaultRenderer renderer = new DefaultRenderer();
for (int i = 0; i < length; i++) {
    SimpleSeriesRenderer seriesRenderer = new SimpleSeriesRenderer();
    seriesRenderer.setColor(Color.parseColor(colors[i]));

    renderer.addSeriesRenderer(seriesRenderer);
}

ด้านบนเป็นการกำหนด ให้แสดง Pie แต่ละชิ้น โดยใช้สีที่กำหนดไว้

ปรับแต่งหน้าตา Chart ซักเล็กน้อย เพราะตัวหนังสือเล็กไปหน่อย

renderer.setChartTitleTextSize(60);
renderer.setChartTitle("Android Platform Version");
renderer.setLabelsTextSize(30);
renderer.setLabelsColor(Color.GRAY);
renderer.setLegendTextSize(30);

สุดท้ายเพิ่มอีกหนึ่งบรรทัด เป็นอันจบเมธอด initData()

drawChart(series, renderer);

ปล่อยให้ error ไว้ก่อนครับ เนื่องจากเรายังไม่ได้ทำการสร้าง เมธอด drawChart() ให้ไปสร้างเลเอาท์ xml ก่อน

สร้างไฟล์ XML

จริงๆ ใช้ xml จากบทความก่อนก็ได้ครับ แต่ว่ารอบนี้ผมกะให้มันมี padding ด้วยเนื่องจากมันจะดูสวยกว่าครับ จะได้ดังนี้

<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:padding="12dp"
    tools:context="com.devahoy.sample.achartengine.MainActivity$PlaceholderFragment" >

    <RelativeLayout
        android:id="@+id/graph_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</RelativeLayout>

ต่อมาที่คลาส PlachHolderFragment ภายในคลาส MainActivity ก็เพ่ิมนี้ลงไป

private View mView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    mView = rootView;
    initData();
    return rootView;
}

เพื่อจะเอา View ที่สร้างจาก onCreateView() ไปใช้ในการสร้าง graph ครับ เลยต้องประกาศเป็นตัวแปร global ไว้

ต่อมาได้เวลาเพิ่มเมธอด drawChart() ซักที ภายในเมธอดก็มีโค๊ดแบบนี้

private void drawChart(CategorySeries series,
                               DefaultRenderer renderer) {
    GraphicalView graphView =
            ChartFactory.getLineChartView(getActivity(), series, renderer);

    RelativeLayout container =
            (RelativeLayout) mView.findViewById(R.id.graph_container);

    container.addView(graphView);
}

เราใช้ GraphicalView ซึ่งมันก็คือ View นั่นแหละ เหมือนๆกับ TextView, EditText, Button ทั่วๆไป จากนั้น ก็ใช้ RelativeLayout ที่เราได้สร้างไว้ใน fragment_main.xml ที่ชื่อว่า graph_container ทำการ addView() ซะ เป็นอันจบ

เมื่อเปิดโปรแกรมขึ้นมา จะได้ดังภาพ

AChart Engine

สรุป

ตัวอย่างนี้ก็เป็นตัวอย่างการใช้ AChartEngine โดยการวาด Pie Chart แบบง่ายๆนั้นเอง หวังว่าผู้อ่านทุกท่าน สามารถนำไปประยุกต์ ปรับแต่ง ใช้งานให้เข้ากับแอพของท่านได้นะครับ

สุดท้าย โค๊ดตัวอย่าง อัพลง gist เรียบร้อยแล้ว ไปดูได้ที่นี่ครับ

Source Code

Chai

Chai Phonbopit : Developer แห่งหนึ่ง • ผู้ชายธรรมดาๆ ที่ชื่นชอบ Node.js, JavaScript และ Open Source มีงานอดิเรกเป็น Acoustic Guitar และ Football

บทความล่าสุด