Android開發學習之路--圖表實現(achartengine/MPAndroidChart)之初體驗
??已經有一段時間沒有更新部落格了,在上周離開工作了4年的公司,從此不再安安穩穩地工作了,更多的是接受挑戰和實現自身價值的提高。離開了嵌入式linux,從此擁抱移動互連網,也許有點為時已晚,但是相信通過努力,什麼時候都不會太晚。關於轉行,關於這次的轉型會不會成功,都是未知數,誰知道呢。以後就好好學習互連網相關的知識,偶爾業餘玩玩樹莓派,玩玩機器人之類的。
??時間過得很快,已經在新公司待了一周了,簡單熟悉了環境,熟悉了產品,也學了些第三份架構的使用,什麼data binding, retrofit, picasso,rxjava/rxandroid等。雖然學得不快,也算是瞭解了部分了,這些後面再慢慢地總結。
?? 嘮叨了一大堆,還是記錄記錄android下的圖表的簡單實現吧。關於android的圖表,這裡就換作chart吧,如果要自己實現的話,那工作量可是很大的,好在有好幾個開源的架構可以拿來使用,首先是achartengine了:achartengine github源碼連結。其次是MPAndroidChart:MPAndroidChart github源碼連結。關於更詳細的介紹可以參考上面的連結,這裡主要是簡單講下使用。因為沒找到android studio的dependencies,所以就網上下載了相應的jar包了,具體已經在百度雲上了,可以參考下面的連結。
連結: http://pan.baidu.com/s/1i4N2glB 密碼: 2fe2
運行效果如下
?? 這裡依次是atchartengine的折線圖,MPAndroidChart的折線圖和餅圖。
achartengine
??至於怎麼包含jar包,怎麼建工程這就不多講了,既然都要學習第三方的架構了,這些基礎肯定有的了。首先是怎麼把chart安在介面上,achartengine可以直接使用LinearLayout,然後把需要的chart繪畫在這個LinearLayout上。具體xml如下所示:
??具體代碼實現如下,基本上都加了注釋了,理解起來還是很方便的了,具體看ChartActivity代碼中:
??當然atchartengine還有其他更加強大的功能,這裡只是簡單用了下折線圖。
MPAndroidChart折線圖配置
??MPAndroidChart的實現需要用到自訂的空間com.github.mikephil.charting.charts.LineChart來實現折線圖:
餅圖配置
??MPAndroidChart的實現需要用到自訂的空間com.github.mikephil.charting.charts.PieChart來實現折線圖:
act_chart xml實現
ChartActivity java代碼實現:
??代碼的主要介紹在注釋裡面:
package com.jared.emdatabindingstudy.ui;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.os.Bundle;import android.support.annotation.Nullable;import android.util.DisplayMetrics;import android.view.View;import android.widget.Button;import android.widget.LinearLayout;import com.github.mikephil.charting.charts.LineChart;import com.github.mikephil.charting.charts.PieChart;import com.github.mikephil.charting.components.Legend;import com.github.mikephil.charting.components.XAxis;import com.github.mikephil.charting.components.YAxis;import com.github.mikephil.charting.data.Entry;import com.github.mikephil.charting.data.LineData;import com.github.mikephil.charting.data.LineDataSet;import com.github.mikephil.charting.data.PieData;import com.github.mikephil.charting.data.PieDataSet;import com.jared.emdatabindingstudy.R;import org.achartengine.ChartFactory;import org.achartengine.GraphicalView;import org.achartengine.chart.PointStyle;import org.achartengine.model.CategorySeries;import org.achartengine.model.XYMultipleSeriesDataset;import org.achartengine.renderer.XYMultipleSeriesRenderer;import org.achartengine.renderer.XYSeriesRenderer;import java.util.ArrayList;import java.util.List;/** * Created by jared on 16/4/1. */public class ChartActivity extends BaseActivity { private final static String TAG = ChartActivity.class.getSimpleName(); private LinearLayout chartLyt; private LineChart mLineChart; private PieChart mPieChart; Typeface mTf; // 自訂顯示字型 private Button getDataBtn; private List lists = new ArrayList(); private void setLists() { lists.clear(); for (int i = 1; i < 20; i++) { int value = ((int) (Math.random() * 100)); lists.add(value); } } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_chart); getDataBtn = (Button) findViewById(R.id.getData); getDataBtn.setOnClickListener(this); chartLyt = (LinearLayout) findViewById(R.id.chart); mTf = Typeface.createFromAsset(getAssets(), "OpenSans-Bold.ttf"); drawTheChart(); drawTheChartByMPAndroid(); drawPieChart(); } private void drawPieChart() { mPieChart = (PieChart) findViewById(R.id.spread_pie_chart); PieData mPieData = getPieData(4, 100); showPieChart(mPieChart, mPieData); } private void showPieChart(PieChart pieChart, PieData pieData) { pieChart.setHoleColorTransparent(true); pieChart.setHoleRadius(40f); //半徑 pieChart.setTransparentCircleRadius(50f); //半透明圈 pieChart.setDescription(""); pieChart.setDrawHoleEnabled(true); pieChart.setRotationAngle(90); //初始角度 pieChart.setRotationEnabled(true); //可以手動旋轉 pieChart.setUsePercentValues(true); //顯示百分比 pieChart.setDrawCenterText(true); //餅狀圖中間可以添加文字 pieChart.setCenterText("人員分布"); pieChart.setCenterTextColor(Color.GRAY); pieChart.setCenterTextTypeface(mTf); pieChart.setData(pieData); Legend mLegend = pieChart.getLegend(); //設定比例圖 mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART); //坐右邊顯示 mLegend.setXEntrySpace(10f); mLegend.setYEntrySpace(5f); mLegend.setTypeface(mTf); mLegend.setTextColor(Color.GRAY); pieChart.animateXY(1000, 1000); } private PieData getPieData(int count, float range) { ArrayList xValues = new ArrayList(); //用來表示每個餅塊上的內容 String[] content = new String[] {"<10", "10~20", "21~40", ">40"}; for (int i = 0; i < count; i++) { xValues.add("年齡("+content[i]+")"); } ArrayList yValue = new ArrayList(); //用來表示封裝每個餅塊的實際資料 List qs = new ArrayList(); qs.add(14f); qs.add(14f);qs.add(34f);qs.add(38f); for (int i = 0; i < qs.size(); i++) { yValue.add(new Entry(qs.get(i), i)); } PieDataSet pieDataSet = new PieDataSet(yValue, "2015瀏覽量統計"); pieDataSet.setSliceSpace(0f); ArrayList colors = new ArrayList(); //餅圖顏色 colors.add(Color.rgb(205, 205, 205)); colors.add(Color.rgb(114, 188, 223)); colors.add(Color.rgb(255, 123, 124)); colors.add(Color.rgb(57, 135, 200)); pieDataSet.setColors(colors); //設定顏色 pieDataSet.setValueTextSize(8f); pieDataSet.setValueTextColor(Color.WHITE); pieDataSet.setValueTypeface(mTf); //設定字型樣式 DisplayMetrics metrics = getResources().getDisplayMetrics(); float px = 5 * (metrics.densityDpi / 160f); pieDataSet.setSelectionShift(px); //選中態多出的長度 PieData pieData = new PieData(xValues, pieDataSet); return pieData; } private void drawTheChartByMPAndroid() { mLineChart = (LineChart) findViewById(R.id.spread_line_chart); LineData lineData = getLineData(36, 1000); showChart(mLineChart, lineData, Color.rgb(137, 230, 81)); } private void showChart(LineChart lineChart, LineData lineData, int color) { lineChart.setDrawBorders(false); //在折線圖上添加邊框 lineChart.setDescription(""); //資料描述 lineChart.setNoDataTextDescription("You need to provide data for the chart."); lineChart.setDrawGridBackground(false); //表格顏色 lineChart.setGridBackgroundColor(Color.WHITE & 0x70FFFFFF); //表格的顏色,設定一個透明度 lineChart.setTouchEnabled(true); //可點擊 lineChart.setDragEnabled(true); //可拖拽 lineChart.setScaleEnabled(true); //可縮放 lineChart.setPinchZoom(false); lineChart.setBackgroundColor(color); //設定背景顏色 lineChart.setData(lineData); //填充資料 Legend mLegend = lineChart.getLegend(); //設定標示,就是那個一組y的value的 mLegend.setForm(Legend.LegendForm.CIRCLE); //樣式 mLegend.setFormSize(6f); //字型 mLegend.setTextColor(Color.WHITE); //顏色 lineChart.setVisibleXRange(1, 7); //x軸可顯示的座標範圍 XAxis xAxis = lineChart.getXAxis(); //x軸的標示 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //x軸位置 xAxis.setTextColor(Color.WHITE); //字型的顏色 xAxis.setTextSize(10f); //字型大小 xAxis.setGridColor(Color.WHITE);//網格線顏色 xAxis.setDrawGridLines(false); //不顯示網格線 xAxis.setTypeface(mTf); YAxis axisLeft = lineChart.getAxisLeft(); //y軸左邊標示 YAxis axisRight = lineChart.getAxisRight(); //y軸右邊標示 axisLeft.setTextColor(Color.WHITE); //字型顏色 axisLeft.setTextSize(10f); //字型大小 axisLeft.setAxisMaxValue(1000f); //最大值 axisLeft.setLabelCount(6, true); //顯示格數 axisLeft.setGridColor(Color.WHITE); //網格線顏色 axisLeft.setTypeface(mTf); axisRight.setDrawAxisLine(false); axisRight.setDrawGridLines(false); axisRight.setDrawLabels(false); lineChart.animateX(2500); //立即執行動畫 } private LineData getLineData(int count, float range) { ArrayList xValues = new ArrayList(); for (int i = 0; i < count; i++) { // x軸顯示的資料,這裡預設使用數字下標顯示 xValues.add("" + (i+1)); } // y軸的資料 ArrayList yValues = new ArrayList(); for (int i = 0; i < count; i++) { float value = (int) (Math.random() * range); yValues.add(new Entry(value, i)); } // create a dataset and give it a type // y軸的資料集合 LineDataSet lineDataSet = new LineDataSet(yValues, "訪問量統計"); // mLineDataSet.setFillAlpha(110); // mLineDataSet.setFillColor(Color.RED); //用y軸的集合來設定參數 lineDataSet.setLineWidth(1.75f); // 線寬 lineDataSet.setCircleSize(3f);// 顯示的圓形大小 lineDataSet.setColor(Color.WHITE);// 顯示顏色 lineDataSet.setCircleColor(Color.WHITE);// 圓形的顏色 lineDataSet.setHighLightColor(Color.WHITE); // 高亮的線的顏色 lineDataSet.setHighlightEnabled(true); lineDataSet.setValueTextColor(Color.WHITE); //數值顯示的顏色 lineDataSet.setValueTextSize(8f); //數值顯示的大小 lineDataSet.setValueTypeface(mTf); ArrayList lineDataSets = new ArrayList(); lineDataSets.add(lineDataSet); // 添加資料集合 //建立lineData LineData lineData = new LineData(xValues, lineDataSets); return lineData; } public void drawTheChart() { XYMultipleSeriesRenderer mRenderer = getXYMulSeriesRenderer(); XYSeriesRenderer renderer = getXYSeriesRenderer(); mRenderer.addSeriesRenderer(renderer); setLists(); XYMultipleSeriesDataset dataset = getDataSet(); GraphicalView chartView = ChartFactory.getLineChartView(this, dataset, mRenderer); chartLyt.addView(chartView, 0); //chartLyt.invalidate(); } public XYSeriesRenderer getXYSeriesRenderer() { XYSeriesRenderer renderer = new XYSeriesRenderer(); //設定折線寬度 renderer.setLineWidth(2); //設定折線顏色 renderer.setColor(Color.GRAY); renderer.setDisplayBoundingPoints(true); //點的樣式 renderer.setPointStyle(PointStyle.CIRCLE); //設定點的大小 renderer.setPointStrokeWidth(3); //設定數值顯示的字型大小 renderer.setChartValuesTextSize(30); //顯示數值 renderer.setDisplayChartValues(true); return renderer; } public XYMultipleSeriesDataset getDataSet() { XYMultipleSeriesDataset barDataset = new XYMultipleSeriesDataset(); CategorySeries barSeries = new CategorySeries("2016年"); for (int i = 0; i < lists.size(); i++) { barSeries.add(lists.get(i)); } barDataset.addSeries(barSeries.toXYSeries()); return barDataset; } public XYMultipleSeriesRenderer getXYMulSeriesRenderer() { XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(); renderer.setMarginsColor(Color.argb(0x00, 0xF3, 0xF3, 0xF3)); // 設定背景顏色 renderer.setApplyBackgroundColor(true); renderer.setBackgroundColor(Color.WHITE); //設定Title的內容和大小 renderer.setChartTitle("訪問量統計"); renderer.setChartTitleTextSize(50); //圖表與四周的邊距 renderer.setMargins(new int[]{80, 80, 50, 50}); //設定X,Y軸title的內容和大小 renderer.setXTitle("日期"); renderer.setYTitle("訪問數"); renderer.setAxisTitleTextSize(30); //renderer.setAxesColor(Color.WHITE); renderer.setLabelsColor(Color.BLACK); //圖例文字的大小 renderer.setLegendTextSize(20); // x、y軸上刻度顏色和大小 renderer.setXLabelsColor(Color.BLACK); renderer.setYLabelsColor(0, Color.BLACK); renderer.setLabelsTextSize(20); renderer.setYLabelsPadding(30); // 設定X軸的最小數字和最大數字,由於我們的資料是從1開始,所以設定為0.5就可以在1之前讓出一部分 // 有興趣的童鞋可以刪除下面兩行代碼看一下效果 renderer.setPanEnabled(false, false); //顯示網格 renderer.setShowGrid(true); //X,Y軸上的數字數量 renderer.setXLabels(10); renderer.setYLabels(10); // 設定X軸的最小數字和最大數字 renderer.setXAxisMin(1); renderer.setXAxisMax(20); // 設定Y軸的最小數字和最大數字 renderer.setYAxisMin(0); renderer.setYAxisMax(100); // 設定渲染器顯示縮放按鈕 renderer.setZoomButtonsVisible(true); // 設定渲染器允許放大縮小 renderer.setZoomEnabled(true); // 消除鋸齒 renderer.setAntialiasing(true); // 刻度標記與X軸座標文字左側對齊 renderer.setXLabelsAlign(Paint.Align.LEFT); // Y軸與Y軸座標文字靠左對齊 renderer.setYLabelsAlign(Paint.Align.LEFT); // 允許左右拖動,但不允許上下拖動. renderer.setPanEnabled(true, false); return renderer; } @Override public void onClick(View view) { super.onClick(view); switch (view.getId()) { case R.id.getData: drawTheChart(); drawTheChartByMPAndroid(); drawPieChart(); break; default: break; } }}
這裡主要是介紹了chart的簡單使用,具體得看需求再進行修改了,個人還是比較喜歡MPAndroidChart,不管是顯示的效果還是使用的方便。