1. 程式人生 > >Android Canvas練習(2)自已繪餅圖(Pie Chart)

Android Canvas練習(2)自已繪餅圖(Pie Chart)

    上文弄了個繪製報表的,有了報表,當然想一併也繪個餅圖,柱形圖之類的玩玩,看看了API,覺得應當很簡單,餅圖實現了下,

實現程式碼確實也很簡單,Android的這些函式封裝的確實好用。

   效果圖如下:

       

      不過實現過程還是比較曲折的,首先碰到一個sdk的bug,drawTextOnPath()用法明明是對的,但老是不顯示沒效果,後面

才查到,這個是BUG,後來在http://blog.csdn.net/yanzi1225627/article/details/8583066 上查到解決方法是在view的建構函式裡設定this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);  才算能繼續下去。

 先附上完整的實現程式碼:       
package com.xcl.chart;

/**
 * Canvas練習 
 * 	  自已畫餅圖,實現出來後覺得也算實用.
 *   
 * author:xiongchuanliang
 * date:2014-4-6
 */

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.view.View;

@SuppressLint("NewApi")
public class PanelPieChart1 extends View {
	
	private int ScrHeight;
	private int ScrWidth;
					
	private Paint[] arrPaintArc;
	private Paint PaintText = null;
	/*
	final int[] colors = new int[]{			
			R.color.red,
			R.color.white,
			R.color.green,
			R.color.yellow,
			R.color.blue,				
		};*/
	
	//RGB顏色陣列
	private final int arrColorRgb[][] = { {77, 83, 97},  
							              {148, 159, 181},  
							              {253, 180, 90},
							              {52, 194, 188},
							              {39, 51, 72},
							              {255, 135, 195},
							              {215, 124, 124},
							              {180, 205, 230}} ;
	
	//演示用的比例,實際使用中,即為外部傳入的比例引數
	final float arrPer[] = new float[]{20f,30f,10f,40f};
	
	public PanelPieChart1(Context context){
		super(context);
		
		//解決4.1版本 以下canvas.drawTextOnPath()不顯示問題			
		this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
		
		//螢幕資訊
		DisplayMetrics dm = getResources().getDisplayMetrics();
		ScrHeight = dm.heightPixels;
		ScrWidth = dm.widthPixels;
					
		//設定邊緣特殊效果
	    BlurMaskFilter PaintBGBlur = new BlurMaskFilter(
	    						1, BlurMaskFilter.Blur.INNER);

		arrPaintArc = new Paint[5];	
		//Resources res = this.getResources();
		for(int i=0;i<5;i++)
		{
			arrPaintArc[i] = new Paint();			
			//arrPaintArc[i].setColor(res.getColor(colors[i] )); 
			arrPaintArc[i].setARGB(255, arrColorRgb[i][0], arrColorRgb[i][1], arrColorRgb[i][2]);
			arrPaintArc[i].setStyle(Paint.Style.FILL);
			arrPaintArc[i].setStrokeWidth(4);
			arrPaintArc[i].setMaskFilter(PaintBGBlur);
		}
			
		PaintText = new Paint();
		PaintText.setColor(Color.BLUE);
		PaintText.setTextSize(22);
		//PaintText.setTypeface(Typeface.DEFAULT_BOLD);
	}
	
	public void onDraw(Canvas canvas){
		//畫布背景
		canvas.drawColor(Color.WHITE);
		
		float cirX = ScrWidth / 2;
		float cirY = ScrHeight / 3 ;
		float radius = ScrHeight / 5 ;//150;
		//先畫個圓確定下顯示位置
		//canvas.drawCircle(cirX,cirY,radius,PaintArcRed);
								
		float arcLeft = cirX - radius;
		float arcTop  = cirY - radius ;
		float arcRight = cirX + radius ;
		float arcBottom = cirY + radius ;
		RectF arcRF0 = new RectF(arcLeft ,arcTop,arcRight,arcBottom);	
		
		Path pathArc=new Path();   		    			    
		// x,y,半徑 ,CW
		pathArc.addCircle(cirX,cirY,radius,Direction.CW); 
		    //繪出餅圖大輪廓
		canvas.drawPath(pathArc,arrPaintArc[0]);
	 
		float CurrPer = 0f; //偏移角度
		float Percentage =  0f; //當前所佔比例
								
		int scrOffsetW = ScrWidth - 200;
		int scrOffsetH = ScrHeight - 300;
		int scrOffsetT = 40;
							
		//Resources res = this.getResources();			
		int i= 0;
		for(i=0; i<3; i++) //注意迴圈次數噢
		{
			//將百分比轉換為餅圖顯示角度
			Percentage = 360 * (arrPer[i]/ 100);
			Percentage = (float)(Math.round(Percentage *100))/100;
			 
			//在餅圖中顯示所佔比例
			canvas.drawArc(arcRF0, CurrPer, Percentage, true, arrPaintArc[i+2]); 
			
			//當前顏色
			canvas.drawRect(scrOffsetW ,scrOffsetH + i * scrOffsetT,
					scrOffsetW + 60 ,scrOffsetH - 30 + i * scrOffsetT, arrPaintArc[i+2]);
			//當前比例	
			canvas.drawText(String.valueOf(arrPer[i]) +"%",
					scrOffsetW + 70,scrOffsetH + i * scrOffsetT, PaintText);
			//下次的起始角度
			CurrPer += Percentage;
		}
		
		//最末尾比例說明
		canvas.drawRect(scrOffsetW ,scrOffsetH + i * scrOffsetT,
				scrOffsetW + 60 ,scrOffsetH - 30 + i * scrOffsetT, arrPaintArc[0]);
			
		canvas.drawText(String.valueOf(arrPer[i]) +"%",
				scrOffsetW + 70,scrOffsetH + i * scrOffsetT, PaintText);

		//Demo的作者資訊
		canvas.drawText("author:xcl",
				70,scrOffsetH + i+1 * scrOffsetT, PaintText);
		canvas.drawText("date:2014-4-7",
				70,scrOffsetH + i * scrOffsetT, PaintText);			
		
	}		
}

 程式碼註釋算比較詳細,就不多說了,主要整理下我實現過程中瞭解到的一些使用方法.

      RectF  定義矩形,這個用得很多,定座標時,腦子中一定要有一個清楚的印象,示意圖如下:

           

            要是在實現時確定不了,可以用 canvas.drawRect(new RectF(left, top, right bottm), paint);  在螢幕上畫出來看看效果。

       Path: 官網Doc 

             這個在可以先用下面的程式碼看看效果:            

Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
Path p = new Path();
p.moveTo(20,20);
p.lineTo(100,200);
p.lineTo(200,100);
p.lineTo(240,155);
canvas.drawPath(p,paint);
     效果如下:

         

   path不斷可以畫線,還可以有特殊的用法:    


   其實現程式碼如下:           

float cirX = ScrWidth / 2;
			float cirY = ScrHeight / 3 ;
			float radius = ScrHeight / 5 ;
			
		    Path pathArc=new Path();   		    			    
			// x,y,半徑 ,CW為順時針繪製
			pathArc.addCircle(cirX,cirY,radius,Direction.CW); 

		    canvas.drawPath(pathArc,arrPaintArc[0]);
		    canvas.drawTextOnPath("環繞文字",pathArc,0,30,PaintText); //在路徑上繪製文字
     對path,如果不確實效果,可以用drawPath打印出來看看,如果打印出來是一片空白,則有可能是你輸入的位置引數不正確所致

drawTextOnPath 函式原型:

          drawTextOnPath (String text,Path ath,float hOffset,float vOffset,Pating paint)

        這個函式能讓文字跟著path跑,hOffset引數指定水平偏移 vOffset引數指定垂直偏移量是多少。

     drawArc()函式畫圓弧的,一個最典型的用法如下:

 canvas.drawArc(new RectF(0, 0, 128, 128), 0,120, true, new Paint(
		    		Paint.ANTI_ALIAS_FLAG));
           餅圖百分比的扇形圖主要就是用它來實現的。

還有一個Style屬性要說下,它決定了是空心,還是實心之類。
    Paint.Style.STROKE:Only draw the outline of the shapes
    Paint.Style.FILLE:Only fill the shapes
    Paint.Style.FILL_AND_STROKE:Fill and draw the outline of the shapes

大致就這些了。

MAIL: [email protected]

BLOG: http://blog.csdn.net/xcl168

相關推薦

Android Canvas練習(2)自已(Pie Chart)

    上文弄了個繪製報表的,有了報表,當然想一併也繪個餅圖,柱形圖之類的玩玩,看看了API,覺得應當很簡單,餅圖實現了下, 實現程式碼確實也很簡單,Android的這些函式封裝的確實好用。    效果圖如下:               不過實現過程還是比較曲折的,首

Android Canvas練習(9)自已分割突出效果的(Pie Chart)

   這裡畫了個餅圖的變種,具有分割突出效果的餅圖(Pie Chart),就是個切蛋糕效果的餅圖,畫這種圖,其技巧就在於圓心的偏移。 在圓心偏移,半徑不變的基礎上,效果就出來了。     上圖:               怎麼樣,效果還是有模有樣的吧。      程式碼很

Android Canvas練習(6)(Pie Chart)百分比標註位置計算技巧

     今天終於解決了困擾整整一週的,一個令人抓狂的HPUX程式碼問題。可以在這半夜神清氣爽的說下昨天晚上推匯出來的一個小技巧, 如何在一張餅圖(Pie Chart)上每個扇形的中心位置標記出百分比。 我之前寫了一篇怎麼自繪餅圖的文章,但百分比都是另外在一個 地方顯示的,

c#通過.net自帶的chart控制元件繪製pie chart

原文地址:http://www.veryhuo.com/a/view/52954.html 需要實現的目標是:   1.將資料繫結到pie的後臺資料中,自動生成餅圖。   2.生成的餅圖有詳細文字的說明。   具體的實現步驟:   >>前臺介面的設

Android Canvas練習(7)繪製歐冠八強防守&控制率資料對比

    在網易資料酷的<<足壇"斧頭幫"!瘋狂馬競打爆巴薩>>中看到一幅圖,非常有特色,因為最近用Canvas繪了不少圖表,就想用程式碼把這幅圖也繪出來。 基本也繪出來了,效果圖如下:           繪製這張圖,api用得到不多,但恰好把我前面

Android使用j4lChartAndroid外掛繪製3D

圖表是常見的直觀表示資料的途徑,目前在android手機上繪製圖表基本有兩種方法:一是利用java的canvas自己繪製,這種方法自己可操作性強,可以隨心所欲地繪製,但是缺點就是工作量大;二是利用第三方外掛。本文將給大家介紹一下利用第三方外掛j4lChartAndroid如

D3 v4.x 的echarts化(2-4)—— 擴充套件玫瑰

關於餅圖的拓展基本沒有什麼創新點。 設計思路:通過線性比例尺得到圓弧半徑和資料的關係,得到跟資料相關的圓環。有其他需求或需要一起探討的可以+我Q380205984。下面是實現該圖的程式碼和註釋。 <template> <div id =

ECharts圖表常用屬性參考 -- Pie

option = { color: ['#5697d0', '#56cfd0', '#56d078', '#a9d056', '#d0b856', '#d07b56', '#a656d0', '#d056a1', '#d05656', '#5673d0'],

Echarts圖表庫。 pie 圖表元件的使用。元件API使用規則--DOME

var myChart = echarts.init(document.getElementById('main')); var option = { baseOption:{ //調色盤顏色列表 //

R語言的(pie)學習

 剛開始學習R語言, 第一篇的筆記, 長久以來作為一個數據倉庫工程師,整天活在資料的礦坑中, 卻一直沒有涉足資料探勘,實屬慚愧。 為培養學習的興趣和寫學習筆記的良好愛好, 故選擇最最簡單的餅圖作為分析物件。 第一感覺, R最為統計分析, 資料探勘的工具, 具有強大的分析能力

Android canvas制柱形統計

ext.get hit 選擇 etc new 工廠模式 imp 設計模式 layout 如今非常多應用都須要一些統計圖。眼下第三方的統計圖也有非常多。可是在自己看來僅僅要不是特別耽誤時間還是選擇用canvas自己繪制比較合理。依賴於第三方的繪制在需求上也

Android 使用Canvas繪製

效果: 嗯,一個很簡單的餅圖繪製。 用法 可以在xml檔案中配置,也可以直接new一個例項出來。 <com.paoword.oa.view.SectorGraphView android:id="@+id/s

DWR(AJAX)+Highcharts制曲線圖,

logging 數據類型 hid 一個 ext js xml 通過 for 源代碼下載 基本需求: 1. 在前臺會用DWR框架(或者AJAX)調用Java後臺代碼獲取要在Hightcharts展示的數據 2. 了解JSON(JavaScript

aNDROID仿支付寶效果

餅圖 aid hao123 .com andro smart and lis oid sMaRT%E6%BC%82%E4%BA%AE%E6%97%B6%E9%92%9F%E2%80%94%E2%80%94%E6%BA%90%E4%BB%A3%E7%A0%81 http:/

簡單

-s 分布 plot blue params gre pyplot gree 比例 import matplotlib.pyplot as lt#顯示中文lt.rcParams[‘font.sans-serif‘]=[‘SimHei‘]lt.rcParams[‘axes.u

小程序使用Canvas

tar lin canvas style nload raw 代碼 程序 function 先上效果圖 -------------------------------------------------------------wxml代碼開始---------------

挑戰練習2.9 從按鈕到標按鈕

分享 image .com alt info 後退 初始 界面 對象 把前進和後退按鈕變成只顯示指示圖標,讓用戶界面更清爽。 1.把UI界面的Button控件換成ImageButton 2.初始化ImageButton控件對象 3.修改Button為Image

Android

第一步匯入library 詳細見MPchart使用詳解及詳細屬性(一) 1 第二步pieChart原始碼 import android.app.Activity; import android.graphics.Color; import android.gr

運用canvas折線和柱狀

對象 tel radi rec 註意 tco 一起 right scrip 一、繪制折線圖 1、首先,隨便定義一個數組對象代表坐標,然後繪出打底的網格線: <canvas width="600px" height="400px" ></c

android studio 3.2.1 截screenshot報:unexpected error while obtaining screenshot from device: EOF解決辦法

問題: 今天用android studio截圖android機地圖畫面,就報瞭如下的錯誤:unexpected error while obtaining screenshot from device: EOF,導致截圖失敗。 原因: 晚上搜了下原因,大概說是因為android機的