1. 程式人生 > >Android Canvas練習(7)繪製歐冠八強防守&控制率資料對比圖

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

    在網易資料酷的<<足壇"斧頭幫"!瘋狂馬競打爆巴薩>>中看到一幅圖,非常有特色,因為最近用Canvas繪了不少圖表,就想用程式碼把這幅圖也繪出來。

基本也繪出來了,效果圖如下:

    

     繪製這張圖,api用得到不多,但恰好把我前面繪製那些圖的一些技巧都用上了。

附主程式如下:   

package com.xcl.chart;


/**
 * Canvas練習 
 * 	  自已畫環形圖(Dount Chart)
 *     仿網易資料酷中的環形圖
 * author:xiongchuanliang
 * date:2014-4-12
 */


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

@SuppressLint("NewApi") public class PanelDountChart extends View{

	private int ScrWidth,ScrHeight;	
	
	//總環數
	private final int DuCount = 5;

	public PanelDountChart(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		
		//解決4.1版本 以下canvas.drawTextOnPath()不顯示問題			
		this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
		
		//螢幕資訊
		DisplayMetrics dm = getResources().getDisplayMetrics();
		ScrHeight = dm.heightPixels;
		ScrWidth = dm.widthPixels;
	}
	
	
	public void onDraw(Canvas canvas){
		//畫布背景
		canvas.drawColor(Color.WHITE);

		
		float cirX = ScrWidth / 2;
		float cirY = ScrHeight / 3 ;
		float radius = ScrHeight / 4 ;
		//先畫個圓確定下顯示位置
		//canvas.drawCircle(cirX,cirY,radius,PaintGree);
								
		float arcLeft = cirX - radius;
		float arcTop  = cirY - radius ;
		float arcRight = cirX + radius ;
		float arcBottom = cirY + radius ;
		RectF arcRF0 = new RectF(arcLeft ,arcTop,arcRight,arcBottom);			

		////////////////////////////////////////////////////////////			
		//位置計算類  
        XChartCalc xcalc = new XChartCalc();					
        
        //實際用於計算的半徑
        float calcRadius = radius/2;
		////////////////////////////////////////////////////////////

    	//初始化各環顏色
	 	Paint[] arrPaint = new Paint[6];
	 
	 	arrPaint[0] = new Paint();			
		arrPaint[0].setColor(Color.CYAN);
							
		arrPaint[1] = new Paint();			
		arrPaint[1].setColor(Color.argb(255,1, 73, 157));
		
		arrPaint[2] = new Paint();			
		arrPaint[2].setColor(Color.argb(255,0, 94, 196));
		
		arrPaint[3] = new Paint();			
		arrPaint[3].setColor(Color.argb(255,73, 172, 222));
		
		arrPaint[4] = new Paint();			
		arrPaint[4].setColor(Color.argb(255,145, 218, 255));
					
		arrPaint[5] = new Paint();			
		arrPaint[5].setColor(Color.argb(255,204, 238, 255));
		
		arrPaint[1].setAntiAlias(true);
		arrPaint[2].setAntiAlias(true);
		arrPaint[3].setAntiAlias(true);
		arrPaint[4].setAntiAlias(true);
		arrPaint[5].setAntiAlias(true);
		
		//最外環紅色填充
		Paint PaintDcred = new Paint();
		PaintDcred.setStyle(Style.FILL);
		PaintDcred.setARGB(255,221,19,223);
		PaintDcred.setAntiAlias(true);
		//分割線
		Paint PaintDcLine = new Paint();
		PaintDcLine.setStyle(Style.FILL);
		PaintDcLine.setARGB(255,36, 169, 199);			
		PaintDcLine.setTypeface(Typeface.DEFAULT_BOLD);
		//標註用畫筆
		Paint PaintDcLabel = new Paint();
		PaintDcLabel.setStyle(Style.FILL);
		PaintDcLabel.setColor(Color.BLACK);
		PaintDcLabel.setTextSize(22);
		PaintDcLabel.setTypeface(Typeface.DEFAULT_BOLD);

		//附註
		canvas.drawText("仿網易資料酷",60,ScrHeight - 270, PaintDcLabel);	
		canvas.drawText("author:xiongchuanliang",60,ScrHeight - 250, PaintDcLabel);	

		
		//扇形角度 				
		float pAngle = 72f; 
		//偏移角度
		float pAngleOffset = 18f + 36f; 
		
		//分成五個環
		float avgRadius = radius / DuCount;
		
				
		for(int i=DuCount;i>=0;i--)
		{
			float curRadius = avgRadius * i;
			canvas.drawCircle(cirX,cirY,curRadius,arrPaint[i]);
			if(i == 5)
			{  
				//最外環扇區	
				canvas.drawArc(arcRF0, pAngleOffset + pAngle * (DuCount -1) ,pAngle, true,PaintDcred); 
			}			
		}		
		
		//外圍標註
        String arrLabel[] = new String[]{"控球率","搶斷","黃牌","犯規","失球數"};		
		for(int i=0;i<DuCount;i++)
		{
			Path PathLabel = new Path();
			PathLabel.addArc(arcRF0, pAngle*i+18, pAngle);
			canvas.drawTextOnPath(arrLabel[i],PathLabel,0,0,PaintDcLabel);
		}

		//各項資料陣列
		//String[] arrSort3S = new String[]{"No.1","No.2","No.3","No.3","No.5"};
		String[] arrSort3N = new String[]{"馬競","切爾西","巴薩","拜仁","曼聯"};
		String[] arrSort3V = new String[]{"5","7","8","8","9"};
		
		String[] arrSort4N = new String[]{"拜仁","巴薩","巴黎","皇馬","馬競"};
		String[] arrSort4V = new String[]{"69.2%","68%","61.8%","56%","43.1%"};
		
		String[] arrSort1N = new String[]{"馬競","切爾西","巴薩","多特","巴黎"};
		String[] arrSort1V = new String[]{"23","21","19","19","19"};
		
		String[] arrSort2N = new String[]{"馬競","多特","切爾西","曼聯","巴黎"};
		String[] arrSort2V = new String[]{"155","153","153","131","116"};
		
		String[] arrSort5N = new String[]{"馬競","多特","巴薩","切爾西","皇馬"};
		String[] arrSort5V = new String[]{"268","245","200","197","195"};
		
		//圓心紅色扇區
		arcLeft = cirX - avgRadius;
		arcTop  = cirY - avgRadius ;
		arcRight = cirX + avgRadius ;
		arcBottom = cirY + avgRadius ;
		RectF arcRF1 = new RectF(arcLeft ,arcTop,arcRight ,arcBottom );	
				
		PaintDcLabel.setTextSize(12);
		for(int j=0;j<DuCount;j++)
		{
			
		    if(j < DuCount -1) //最靠右外環填充為紅色
		    {			  
			  canvas.drawArc(arcRF1, pAngleOffset ,pAngle, true,PaintDcred); 
		    }
			
			xcalc.CalcArcEndPointXY(cirX, cirY, radius, pAngleOffset); 	
			 //扇形分割線
		    canvas.drawLine(cirX, cirY,  xcalc.getPosX(), xcalc.getPosY(), PaintDcLine);
		    		    
		    //標註俱樂部名字及各項資料
		   for(int i=0;i<DuCount;i++)
		   {			  		    	 
		    	 xcalc.CalcArcEndPointXY(cirX, cirY, avgRadius * (DuCount-i), pAngleOffset); 
		    	 
		    	 int curNm = DuCount-1-i;
		   		    	  	
		    	 if(j == 0){ //System.getProperty("line.separator")
		    		 canvas.drawText(arrSort5N[curNm]+"("+arrSort5V[curNm]+")", xcalc.getPosX(),xcalc.getPosY(), PaintDcLabel);  
		    	 }else if(j == 1){
		    		 canvas.drawText(arrSort1N[curNm]+"("+arrSort1V[curNm]+")", xcalc.getPosX(),xcalc.getPosY(), PaintDcLabel);  
		    	 }else if(j == 2){
		    		 canvas.drawText(arrSort2N[curNm]+"("+arrSort2V[curNm]+")", xcalc.getPosX(),xcalc.getPosY(), PaintDcLabel);  
		    	 }else if(j == 3){		    	     
		    	     canvas.drawText(arrSort3N[curNm]+"("+arrSort3V[curNm]+")", xcalc.getPosX(),xcalc.getPosY(), PaintDcLabel);  
		    	 }else if(j == 4){
		    		 canvas.drawText(arrSort4N[curNm]+"("+arrSort4V[curNm]+")", xcalc.getPosX(),xcalc.getPosY(), PaintDcLabel);  
		    	 }
		    	 
		    }		    
			pAngleOffset += pAngle;
		}
		///////////////////////////////////
	}
	

}
   像這種有特色的圖,可能在現成的圖表庫中是找不到類似的模板可以套用的,而手工用程式碼繪製的好處就來了,可以靈活的通過api繪製出來,當然,如果

你是用繪圖工具繪製,那當我沒說。

    Android Canvas練習(5)自已繪面積圖(Area Chart)

MAIL: [email protected]

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

相關推薦

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

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

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

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

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

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

初學Android,OpenGL ES之繪製平面多邊形(十)

在Android中使用OpenGL ES需三步1.建立GLSurfaceView元件,使用Activity顯示GLSurfaceView元件2.為GLSurfaceView建立GLSurfaceView.Renderer例項,實現Renderer類時需要實現接口裡的三個方法 

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

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

android canvas 繪製 Cirle 以外的區域為指定顏色

今天的內容主要是android.graphics.PorterDuff.Mode 有個需求類似: canvas上繪製圓以外的區域為alpha透明度的黑色,圓內區域為透明: 實現原理很簡單,就是把整個canvas畫成alpha透明度的黑色, canvas.drawARGB(alp

Android開發 ImageView上繪製旋轉圓環(透明度不同的旋轉圓環,利用canvas drawArc實現)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

#前端學習之canvascanvas練習(1)離奇事件:在正方形的畫布裡面繪製圓形顯示的是橢圓形

根據Html5的canvas的例子如下由於如此,於是我寫出一下的程式碼經過檢視才知道,canvas畫布的尺寸的大小和顯示的大小是有很大的區別的。在canvas裡面設定的是才是canvas本身的大小。前端渣渣一枚,看了很多大神的部落格,參考文章,可能自己半懂不懂的,可是隻要你反

Python練習7:turtle六邊形繪製

程式碼實現: import turtle turtle.setup(800, 800, 200, 200) turtle.pencolor("black") turtle.pensize(4) turtle.penup() turtle.fd(-150) turtle.pe

遞歸--練習7--noi1750全排列

時間 iostream 而且 sin content sort ble ret param 遞歸--練習7--noi1750全排列 一、心得 二、題目 1750:全排列 總時間限制: 1000ms 內存限制: 65536kB描述 給定一個由不同的小寫字母組成的字符串

Android canvas繪制柱形統計

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

Android的DatePicker和TimePicker-android學習之旅(三十

cursor ini lis drawable textview @+ type pin view DatePicker和TimePicker簡單介紹 DatePicker和TimePicker是從FrameLayout繼承而來。他們都是比較簡單的組件

Python-練習7

python 練習1.顯示文件的所有行,但忽略以#開頭的行;hello.txt文件第一行有一個#號執行程序:2. 逐頁顯示文本文件的程序,用戶輸入一個文件名,每次默認顯示行數為10行,給用戶一個選項,"是否繼續?(Y|N)"方法1:方法2:Python-練習7

Android項目實戰(三十):2017最新 將AndroidLibrary提交到JCenter倉庫(圖文教程)

success hub rdf fault 用戶 builds style config ocl 我們經常使用github上的開源項目,使用步驟也很簡單 比如: compile ‘acffo.xqx.xwaveviewlib:maven:1.0.0‘ 這裏就學習一下如何

java 練習7 打印當前時間

normal java 練習 代碼 cond second 學習 ava min style 打印當前時間。學習使用Date類和Calendar類。(教材P194頁) 代碼 package javawork; import java.util.Calendar; publ

決賽前瞻:皇馬vs利物浦

賽事資訊 足球預測 競彩足彩預測 隨著歐冠半決賽的落幕,球迷們都逐漸的吧焦點集中在這次歐冠決賽上,當然更值得關註的還是殺入決賽的球隊。皇馬和利物浦,在半決賽中,雙方打的都是驚心動魄,還好都是有驚無險,成功進入了總決賽。前面的浴血奮戰都是為了最後的勝利而做鋪墊,然而越到最後求穩往往是最值得考虐的因素

Android Studio安裝部署系列】十Android studio更換APP應用

tail map 安全區 大小 next detail 有時 ash blog 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 概述 Android Studio新建項目後會有一個默認圖標,那麽如何更換圖標呢? 替換圖標 這個方案不建議直接在已有項目上更換

SPFA算法的SLF優化 ——loj#10081. 「一本通 3.2 練習 7」道路和航線

。。 loj dijkstra 分享 spa 思想 text 超時 我見 今天做到一道最短路的題,原題https://loj.ac/problem/10081 題目大意為給一張有n個頂點的圖,點與點之間有m1條道路,m2條航線,道路是雙向的,且權值非負,而航線是單向的,權值

練習7.8、7.10

stream 標準 引用 類型 沒有 int 由於 寫到 istream 7.8:為什麽read函數將其Sales_data參數定義成普通引用,而print將其參數定義成常量引用? Ans:因為read函數的功能是讀取數據,並且從標準輸入流中讀取數據然後寫到對象中,修改了對

練習7.20

私有 nbsp 類的成員 函數 友元函數 破壞 成員函數 封裝 bsp 7.20:友元函數在什麽時候有用?請分別說明友元函數的利與弊。 Ans:當一個不是類的成員函數想要訪問類內的私有成員時,可以將其設為友元函數,這樣該函數就能訪問類內的所有成員。 利:提供了非成員函數想要