Android Canvas练习(5)自已绘面积图(Area Chart)

      本来当时只想做两个练练手后就快速越过Canvas的,对这块我一向兴趣不大,不过最近在绘了两个图后忽然发现,以前那些很常见的图

表,仔细想一下,如果不太讲求通用性,不考虑一些特效外,光图表本身, 自己简单的画出来,好像也不难。这样尝试尝试,自娱自乐下也蛮不错的。

      这不,我又画了个Area Chart,就用到drawLine和Path两个东东配合下透明度就实现了。

  效果图如下:

     

  至于怎么实现的,主要原理就是个Path加透明度的事,透明度自定了个公式计算出来,越到后面的越透明,

层次感就出来了。具体看看我的代码实现。    

package com.xcl.chart;

/**
 * Canvas练习 
 * 	  自已画面积图(Area Chart)
 *   
 * author:xiongchuanliang
 * date:2014-4-8
 */


//import android.annotation.SuppressLint;
import android.content.Context;
//import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.util.DisplayMetrics;
import android.view.View;


public class PanelAreaChart extends View {
	
	private int ScrHeight;
	private int ScrWidth;
					
	private Paint[] arrPaint;
	private Paint PaintText = null;		
	/*
	final int[] colors = new int[]{					
			R.color.red,	
			R.color.blue,
			R.color.green,
			R.color.yellow,			
			R.color.red1,	
			R.color.green1,	
			R.color.dark1,				
			R.color.blue1,	
			R.color.blue2,	
			R.color.blue3,	
			R.color.white,
		};
	*/
	
	//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}} ;
		

	
	//Area chart图演示用的比例,实际使用中,即为外部传入的比例参数	
	private final int arrNumArea[][] = {{40,60,70,60,50,60},
										{30,40,50,40,40,50},
										{20,50,30,40,30,20}} ;
	
	
	public PanelAreaChart(Context context){
		super(context);

		//屏幕信息
		DisplayMetrics dm = getResources().getDisplayMetrics();
		ScrHeight = dm.heightPixels;
		ScrWidth = dm.widthPixels;

		arrPaint = new Paint[8];	
		//Resources res = this.getResources();
		for(int i=0;i<8;i++)
		{
			arrPaint[i] = new Paint();			
			//arrPaint[i].setColor(res.getColor(colors[i] )); 
			arrPaint[i].setARGB(255, arrColorRgb[i][0], arrColorRgb[i][1], arrColorRgb[i][2]);
			
			arrPaint[i].setStyle(Paint.Style.FILL);
			arrPaint[i].setStrokeWidth(4);	
		}
			
		PaintText = new Paint();
		PaintText.setColor(Color.BLUE);
		PaintText.setTextSize(22);	
	}
	
	public void onDraw(Canvas canvas){
		//画布背景
		canvas.drawColor(Color.WHITE);
				
		//饼图标题
		canvas.drawText("自绘面积图(Area Chart)", 100,50, PaintText);	
		
		arrPaint[0].setTextSize(25);
		arrPaint[3].setTextSize(25);			
		arrPaint[0].setStyle(Paint.Style.FILL_AND_STROKE);
		arrPaint[0].setAlpha(50);
		
		int i= 0;		
		
		int lnWidth = 10; //标识线宽度
		int lnSpace = 50; //标识间距
		
		int startx = 70;
		int endx = startx + 20;
		
		int starty =  ScrHeight/2  +150 ;
		int endy = ScrHeight /2 +150 ;
		
		int initX = startx;
		int initY = starty;			
	
		int HLength = ScrWidth - 10; //横线宽度
		
		/
	    //Area Chart
	    ///
		// Y 轴  标识线和值
		int yCount = 9;
		for(i=0; i<yCount; i++) 
		{				
			starty =  initY - (i+1) * lnSpace;
			endy = starty;				
			if(i == 0) continue;
			//画折线
			//canvas.drawLine( initX  ,starty + lnSpace ,startx + yCount * lnSpace ,starty + lnSpace, PaintText);
			canvas.drawLine( initX  ,starty + lnSpace ,HLength ,starty + lnSpace, PaintText);
			
			//Y轴标注
			canvas.drawText(Integer.toString(i * 10), initX - 35,endy + lnSpace, PaintText);							
		}				
		// 画出 Y 轴线
		canvas.drawLine( startx ,starty ,initX ,initY, PaintText);
		
		// X 轴轴标注			
		for(i =0; i< 6;i++)
		{
			startx=  initX + (i+1) * lnSpace;
			endx = startx;					
			//标识文字
			canvas.drawText(Integer.toString(i +1 )+"月", initX + (i+1) * lnSpace  - lnSpace/2 ,initY  + 20, PaintText);
		}
		// 画出 X 轴线
		canvas.drawLine( initX ,initY  ,HLength ,initY, PaintText);
		
		//绘制面积图
		 for(i=0 ; i < arrNumArea.length ; i++) { 
			//用于画折线	
			Path p = new Path();
			p.moveTo(initX,initY);				
							
			int ColorNum = 0;
			arrPaint[i].setStyle(Style.FILL);	
			
			//透明度。其取值范围是0---255,数值越小,越透明,颜色上表现越淡	
			//依公式算透明比例
			 int curAlpha = 255 - 200/arrNumArea.length*i;
			 arrPaint[i].setAlpha( curAlpha );							
			
            for(int j=0 ; j< arrNumArea[i].length ; j++) {  
   
                startx=  initX + (j+1) * lnSpace;
				endx = startx;
								
				//将传入值转为屏幕坐标位置, 其中值10只适应当前例子
				int yPos = initY -   lnSpace * (arrNumArea[i][j]/10);					
				p.lineTo(startx ,yPos ); 
				
				//收尾,将path连接一气
				if(j == arrNumArea[i].length - 1) 
				{
					p.lineTo(startx ,initY);	
				}						                
            } 
            canvas.drawPath(p,arrPaint[i]);		
        } 
		
	    ///
		 canvas.drawText("author:xiongchuanliang", 10, ScrHeight - 180, PaintText);
	}		
}

   搞定。

附其它链接:

     Android Canvas练习(1)画一张报表来玩   

   Android Canvas练习(2)自已绘饼图

   Android Canvas练习(3)自已绘柱形图

   Android Canvas练习(4)自已绘折线图


MAIL: xcl_168@aliyun.com

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值