Day 25 - Eaze Graph
สวัสดีครับ บทความนี้เป็นบทความที่ 25 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ Learn 30 Android Libraries in 30 days
สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ
- Day 1 : AndroidStaggered Grid
- Day 2 : Paralloid
- Day 3 : Retrofit
- Day 4 : SwipeRefreshLayout
- Day 5 : Android GraphView
- Day 6 : Holo Color Picker
- Day 7 : Android Async Http
- Day 8 : Crashlytics
- Day 9 : Butter Knife
- Day 10 : Android Annotations
- Day 11 : DateTimePicker
- Day 12 : Circular Progress Button
- Day 13 : ViewPager
- Day 14 : ViewPagerIndicator
- Day 15 : FadingActionBar
- Day 16 : AutofitTextView
- Day 17 : SwipeListView
- Day 18 : ShowcaseView
- Day 19 : GreenDAO
- Day 20 : AndroidViewAnimation
- Day 21 : ActiveAndroid
- Day 22 : Twitter4J
- Day 23 : ListViewAnimations
- Day 24 : AndEngine
- Day 25 : EazeGraph
- Day 26 : Cardslib
- Day 27 : AdapterKit
- Day 28 : WeatherLib
- Day 29 : FlatUI
- Day 30 : Android Firebase
สำหรับวันนี้ขอนำเสนอเรื่อง EazeGraph ตัวนี้เป็น Library ที่เอาไว้แสดง Graph บน Android ะครับ คล้ายๆกับ AChartEngine และ Android GraphView แต่จุดเด่นของ Library นี้คือเน้นความสวยงามครับ สำหรับ Graph แต่ละชนิดที่ใช้ได้ใน Library ก็ได้แก่
- LineChart
- BarChart
- Stacked Bar Chart
- PieChart
Installation
ขั้นตอนการติดตั้ง เปิดไฟล์ build.gradle
ขึ้นมา แล้วเพิ่ม dependencies ลงไปดังนี้
dependencies {
compile 'com.github.blackfizz:eazegraph:1.1.3-SNAPSHOT@aar'
}
กด Sync Gradle เป็นอันเรียบร้อย
Usage
การใช้งาน EazeGraph ในบทความนี้ ผมขอทำตัวอย่าง แค่ 3 ตัวอย่างนะครับ คือ PieChart, BarChart และ LineChart ส่วน Stacked Bar Chart มันก็คล้ายๆกับ BarChart ก็เลยไม่ทำ ไปอ่านเพิ่มเติมใน Docs ของมันเลยครับ
Pie Chart
การสร้าง PieChart จำเป็นต้องมีคลาส ดังนีครับ
PieChart
: เป็น Container เอาไว้เก็บข้อมูลสำหรับแสดง ChartPieModel
: เป็นก้อน Slice ของ Pie 1 PieModel คือ Pie 1 ชิ้น สร้างได้โดยnew PieChart("name", value, color)
parameter คือชื่อ ค่าที่ต้องการ และสี (เป็น int เช่น0xffff0000
หรือ `Color.parseColor("#ff0000"))
ตัวอย่างเลเอาท์ XML ของ Pie Chart
<org.eazegraph.lib.charts.PieChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/piechart"
android:layout_width="match_parent"
android:layout_height="300dp"
android:padding="8dp"
app:egLegendTextSize="18sp"
app:egUsePieRotation="true"
app:egValueTextSize="36sp"/>
วิธีการเรียกใช้งานจากคลาส Java
PieChart pieChart = (PieChart) findViewById(R.id.piechart);
pieChart.addPieSlice(new PieModel("Name", 100, Color.parseColor("#ff0000")));
Bar Chart
การสร้าง BarChart จำเป็นต้องมีคลาสดังนี้
BarChart
: เป็น Container เอาไว้เก็บข้อมูลและแสดงผลแบบ Bar ChartBarModel
: เป็นชนิดข้อมูลแบบ Bar 1 BarModel คือข้อมูล 1 แท่ง สร้างได้โดยnew BarModel("name", value, color)
parameter เหมือนกับการสร้าง PieModel
ตัวอย่างเลเอาท์ XML ของ Bar Chart คือ
<org.eazegraph.lib.charts.BarChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/barchart"
android:layout_width="match_parent"
android:layout_height="256dp"
android:padding="10dp"
app:egFixedBarWidth="true"
app:egBarWidth="20dp"
app:egLegendHeight="40dp"/>
วิธีการเรียกใช้งานจากคลาส Java คือ
BarChart barChart = (BarChart) findViewById(R.id.barchart);
barChart.addBar(new BarModel("MyBarChart1", 10.5f, 0xff444444));
Line Chart
การสร้าง LineChart ต้องใช้คลาสดังนี้
ValueLineChart
: เป็น Container เอาไว้เก็บข้อมูล และแสดง Line ChartValueLineSeries
: เป็นเหมือนกลุ่มข้อมูล คล้ายๆกับ Array ของข้อมูลValueLinePoint
: เป็นข้อมูลแต่ละจุด เช่น แกน x = 1, x = 2, x = 3 มีค่า 2, 3, 4 ตามลำดับ วิธีการสร้างก็คือnew ValueLinePoint(name, value)
parameter คือ ชื่อ และ ค่าที่ต้องการ
ตัวอย่างไฟล์เลเอาท์ XML ของ LineChart คือ
<org.eazegraph.lib.charts.ValueLineChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cubiclinechart"
android:layout_width="match_parent"
android:layout_height="200dp"
app:egUseCubic="true"
app:egUseOverlapFill="true"
app:egCurveSmoothness="0.4"
app:egIndicatorColor="#FE6DA8"
app:egLegendHeight="40dp"
app:egShowStandardValue="true"/>
วิธีการเรียกใช้งานจากคลาส Java คือ
ValueLineChart lineChart = (ValueLineChart) findViewById(R.id.linechart);
ValueLineSeries series = new ValueLineSeries();
series.setColor(0xffff0000);
series.addPoint(new ValueLinePoint("Red", 24.4f));
series.addPoint(new ValueLinePoint("Green", 11.3f));
series.addPoint(new ValueLinePoint("Blue", 18.6f));
lineChart.addSeries(series);
เมื่อพอรู้รายละเอียดการใช้งานคร่าวๆแล้ว มาลองสร้างโปรเจ็คกันดูเลยครับ (หากใครต้องการรายละเอียดของ Chart เพิ่มเติม อ่าน Docs ประกอบนะครับ)
Create Project
ตัวโปรเจ็คนี้ ผมจะทำการสร้างโดยใช้ ViewPager จากนั้นก็แสดง Fragment แต่ละอย่าง แบ่งเป็น PieChartFragment, BarChartFragment และ LineChartFragment นะครับ สำหรับใครที่ไม่รู้วิธีการสร้าง ViewPager อ่านได้จากบทความนี้ประกอบครับ สอนการใช้งาน ViewPager
เริ่มแรกผมทำการสร้าง เลเอาท์หลักขึ้นมาก่อน ผมตั้งชื่อว่า activity_eazegraph.xml
ภายในมีแค่ ViewPager อันเดียว ดังนี้
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
จากนั้นสร้างคลาส Activity หลักขึ้นมา ชื่อว่า EazeGraphActivity.java
ทำการ binding ViewPager จากไฟล์ xml
public class EazeGraphActivity extends ActionBarActivity {
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eazegraph);
mViewPager = (ViewPager) findViewById(R.id.pager);
}
}
ต่อมาสร้าง Adapter ขึ้นมาโดย extends FragmentStatePagerAdapter
เพื่อใช้เปลี่ยน Fragment เวลาเราเลื่อน ViewPager ตั้งชื่อคลาสว่า MyPagerAdapter
อยู่ภายในคลาส EazeGraphActivity
ดังนี้
package com.devahoy.learn30androidlibraries.day25;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import com.devahoy.learn30androidlibraries.R;
public class EazeGraphActivity extends ActionBarActivity {
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eazegraph);
mViewPager = (ViewPager) findViewById(R.id.pager);
PagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(adapter);
}
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private final int NUM_OF_PAGE = 3;
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment;
switch (i) {
case 0:
fragment = new PieChartFragment();
break;
case 1:
fragment = new BarChartFragment();
break;
case 2:
fragment = new LineChartFragment();
break;
default:
fragment = new PieChartFragment();
}
return fragment;
}
@Override
public int getCount() {
return NUM_OF_PAGE;
}
}
}
จากด้านบนผมทำการสร้าง ViewPager ทั้งหมด 3 หน้า เมื่ออยู่ที่หน้าแรก จะทำการโหลด PieChartFragment
มาแสดง หากเลื่อนไปหน้าสอง ก็จะโชว์ BarChartFragment
และเลื่อนไปหน้าสุดท้าย ก็จะโชว์ LineChartFragment
ส่วนในเมธอด onCreate()
ก็ทำการสร้างออปเจ็ค MyPagerAdapter
ขึ้นมา แล้วให้ ViewPager ทำการ setAdapter()
ซะ เมื่อถึงตอนนี้ โค๊ดด้านบน error แน่นอน เพราะว่ายังไม่ได้สร้าง Fragment ซักอัน :D
ต่อมาสร้าง Fragment แต่ละอันเลย เริ่มจาก
PieChartFragment
ไฟล์เลเอาท์ xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.eazegraph.lib.charts.PieChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/piechart"
android:layout_width="match_parent"
android:layout_height="400dp"
android:padding="8dp"
app:egLegendTextSize="18sp"
app:egUsePieRotation="true"
app:egValueTextSize="36sp"/>
</LinearLayout>
ตัวคลาส Java
package com.devahoy.learn30androidlibraries.day25;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.devahoy.learn30androidlibraries.R;
import org.eazegraph.lib.charts.PieChart;
import org.eazegraph.lib.communication.IOnItemFocusChangedListener;
import org.eazegraph.lib.models.PieModel;
public class PieChartFragment extends Fragment {
private PieChart mPieChart;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.day25_fragment_pie_chart, container, false);
mPieChart = (PieChart) view.findViewById(R.id.piechart);
initData();
return view;
}
@Override
public void onResume() {
super.onResume();
mPieChart.startAnimation();
}
private void initData() {
mPieChart.addPieSlice(new PieModel("KitKat", 17.9f,
Color.parseColor("#df5346")));
mPieChart.addPieSlice(new PieModel("Jelly Bean", 56.5f,
Color.parseColor("#6dd621")));
mPieChart.addPieSlice(new PieModel("Ice Cream Sandwich", 11.4f,
Color.parseColor("#1f3b83")));
mPieChart.addPieSlice(new PieModel("Gingerbread", 13.5f,
Color.parseColor("#34a394")));
mPieChart.addPieSlice(new PieModel("Froyo", 0.7f,
Color.parseColor("#22a7d0")));
mPieChart.setOnItemFocusChangedListener(new IOnItemFocusChangedListener() {
@Override
public void onItemFocusChanged(int position) {
// TODO: To do what you want.
}
});
}
}
ด้านบนเป็นการสร้าง Pie Chart โดยใช้ข้อมูล Android Dashboard มาแสดง
BarChart
ไฟล์เลเอาท์ xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.eazegraph.lib.charts.BarChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/barchart"
android:layout_width="match_parent"
android:layout_height="400dp"
android:padding="10dp"
app:egFixedBarWidth="true"
app:egBarWidth="20dp"
app:egLegendHeight="40dp"/>
</LinearLayout>
ไฟล์ BarChartFragment.java
package com.devahoy.learn30androidlibraries.day25;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.devahoy.learn30androidlibraries.R;
import org.eazegraph.lib.charts.BarChart;
import org.eazegraph.lib.models.BarModel;
public class BarChartFragment extends Fragment {
private BarChart mBarChart;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.day25_fragment_bar_chart, container, false);
mBarChart = (BarChart) view.findViewById(R.id.barchart);
initData();
return view;
}
@Override
public void onResume() {
super.onResume();
mBarChart.startAnimation();
}
private void initData() {
mBarChart.addBar(new BarModel("2010", 89.4f, 0xff663397));
mBarChart.addBar(new BarModel("2011", 53.0f, 0xff4183d7));
mBarChart.addBar(new BarModel("2012", 100, 0xff19b5fe));
mBarChart.addBar(new BarModel("2013", 42.9f, 0xff1e8bc3));
mBarChart.addBar(new BarModel("2014", 113.8f, 0xff36d7b7));
}
}
LineChart
ไฟล์เลเอาท์ xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.eazegraph.lib.charts.ValueLineChart
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/linechart"
android:layout_width="match_parent"
android:layout_height="160dp"
app:egUseCubic="true"
app:egUseOverlapFill="true"
app:egCurveSmoothness="0.4"
app:egIndicatorColor="#ff1aa8fe"
app:egLegendHeight="40dp"
app:egShowStandardValue="true"/>
</LinearLayout>
ไฟล์ LineChart.java
package com.devahoy.learn30androidlibraries.day25;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.devahoy.learn30androidlibraries.R;
import org.eazegraph.lib.charts.ValueLineChart;
import org.eazegraph.lib.models.ValueLinePoint;
import org.eazegraph.lib.models.ValueLineSeries;
public class LineChartFragment extends Fragment {
private ValueLineChart mLineChart;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.day25_fragment_line_chart, container, false);
mLineChart = (ValueLineChart) view.findViewById(R.id.linechart);
initData();
return view;
}
@Override
public void onResume() {
super.onResume();
mLineChart.startAnimation();
}
private void initData() {
ValueLineSeries series = new ValueLineSeries();
series.setColor(Color.parseColor("#f62459"));
series.addPoint(new ValueLinePoint("Sun", 12.4f));
series.addPoint(new ValueLinePoint("Mon", 23.4f));
series.addPoint(new ValueLinePoint("Tue", 51.2f));
series.addPoint(new ValueLinePoint("Wed", 26.6f));
series.addPoint(new ValueLinePoint("Thu", 34.2f));
series.addPoint(new ValueLinePoint("Fri", 13.5f));
series.addPoint(new ValueLinePoint("Sat", 61.9f));
mLineChart.addSeries(series);
}
}
เมื่อลองรันโปรแกรม จะได้หน้าตาแบบนี้
สรุป
จริงๆ หากใครเคยเขียน Graph/Chart ด้วย Library ตัวอื่น จะรู้สึกว่ามันคล้ายๆกันมาก วิธีการเขียน ชนิดของกราฟ แตกต่างกันบ้างเล็กน้อย หลังจากลองใช้ตัวนี้ก็รู้สึกว่า หน้าตามันสวยดี แถมมี Animation ด้วย จริงๆ AChartEngine ก็ทำได้นะ แต่ต้องปรับแต่งนานสมควร สำหรับใครที่อยากให้กราฟมันหน้าตาสวยงาม ก็ลอง EazeGraph ดูได้ครับ
สุดท้าย Source Code เหมือนเดิม จริงๆ ก็ก็อปมาแปะในบทความเกือบครบละนะ
Happy Coding :D
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit