Android开发之自绘制柱状图

 

使用Canvas绘制柱状统计图                                        

在看过http://blog.csdn.net/jia20003/article/details/7522716这篇文章后,简单修改了下该博主的程序,实现了统计数据库中某两个字段的统计图

 

package com.example.mytabhostdemo.record;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.mytabhostdemo.SplashActivity;
import com.example.mytabhostdemo.db.DbOpenHelper;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebSettings.TextSize;

public class BarChart extends View {

	private  Context  context;
	private  double  maxcount ;
	private  double  mincount ;
	private  DbOpenHelper dbhelper ;
	private  SQLiteDatabase  database;
	private  List<Map<String,Object>> list  = new ArrayList<Map<String ,Object >>( );

	public  BarChart(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		this.context= context;
	}

	public BarChart(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public BarChart(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}
	

	
	@Override 
	public void onDraw(Canvas  canvas )
	{
		
		
      canvas.drawColor(Color.WHITE);//设置背景颜色
    
	  getDataSource();
	 /*获取屏幕的宽度*/	
	 // DisplayMetrics   ds = getResources().getDisplayMetrics();
     //getWindowManager().getDefaultDisplay().getMetrics(ds);
     //int width= ds.widthPixels;
      
	//在Activity中可以直接使用getWindowManager()获取屏幕的大小	,但在Activity外的类中不能使用getWindowManager()这个方法。
	 WindowManager wm = (WindowManager)this.getContext().getSystemService( Context.WINDOW_SERVICE);
	 
	 Display  display  = wm.getDefaultDisplay();
	 
	 int width = display.getWidth();
	 int height = display.getHeight()-80;//留下标题的空间
  
	 Paint  mypaint = new Paint ();
	 
	 mypaint.setAntiAlias(true);//设置反锯齿效果,使得图像看起来更平滑
	 
	 //绘制工作区
	 mypaint.setColor( Color.YELLOW);//勾勒边沿
	 mypaint.setStrokeWidth( 2 );
	 canvas.drawRect(0, 0,width, height, mypaint);
	 mypaint.setColor( Color.WHITE);//设置背景为白色
	 mypaint.setStrokeWidth( 0);
	 canvas.drawRect(2,2, width-2,height-2,mypaint);
	 
	 //绘制x,y轴
     int xoffset  = (int)(width*0.1);//设置偏移量,按x,y轴等比例缩放
	 int yoffset = (int)(height*0.1);	
	 
	 mypaint.setColor(Color.GREEN);
	 mypaint.setStyle( Style.FILL);
	 
	 //这里面将y轴坐标,画到了80,避免标题显示时,与统计表重合
	 canvas.drawLine( 2+xoffset ,height-2-yoffset, 2+xoffset,80,mypaint );//画y轴 ,此时的y轴
	 canvas.drawLine( 2+xoffset, height-2-yoffset,width-2,height-2-yoffset,mypaint);//画x轴
	  
	 //显示标题
	 mypaint.setTextSize(20);//设置画笔的颜色
	 mypaint.setColor(Color.GREEN);
     canvas.drawText("电控查询统计图",(width-2)/3,30 ,mypaint);
	
     int xUnit_value = ( width-2-xoffset)/(list.size( )+1);//将x轴均等份
     //绘制y轴,将y轴分成12等份
     int yUnit = 12;
     int yUnit_value= (height-2-yoffset-80)/yUnit;//减去顶部,为标题预留的80个单元
     
     //绘制虚线
     mypaint.setColor( Color.LTGRAY);
     mypaint.setStyle( Style.STROKE);
     mypaint.setStrokeWidth( 1 );
     //PathEffect 是指路径的方式,DashPathEffect是PathEffect的一个子类,
     // 其中的float数组,必须为偶数,且>=2,指定了多少长度的实线,之后再画多少长度的虚线。
     //程序中,是先绘制长度为1的实线,再绘制长度为3的空白,1是偏移量。
     mypaint.setPathEffect( new DashPathEffect( new float[]{ 1,3},1 ) );
      
     for( int j = 0 ; j < 12; j++)//这个虚线的边界解决
     {
         canvas.drawLine(2+xoffset, height-2-yoffset-(yUnit_value*(j+1)), width-2,height-2-yoffset-(yUnit_value*(j+1)) ,mypaint);
	 }
     
     //在y轴方向上,刻度赋值
     double ymarkers = ( (maxcount-mincount) *5/4)/yUnit;// 为了避免查询的最大值,显示到屏幕的顶端,这样的图像显示的比例为4/5
     
     NumberFormat nf = NumberFormat.getInstance();//数据格式化
     nf.setMaximumFractionDigits(1);//保留一位小数
     nf.setMinimumFractionDigits(1);
     
     mypaint.setColor(Color.CYAN);
     mypaint.setStyle(Style.STROKE);
     mypaint.setPathEffect(null);
     mypaint.setStrokeWidth(0);
     mypaint.setTextSize(10);
   
     for( int j = 0 ; j <= 12; j++)
     {    
    	 double markers = ymarkers*j;
         canvas.drawText( nf.format(markers), xoffset-20,height-2-yoffset-(yUnit_value*(j)), mypaint);//xoffset-2避免字体显示的位置太靠近
	 }
     
     //绘制柱状图
     mypaint.setStyle(Style.FILL);
     mypaint.setStrokeWidth( 2);

     for( int j = 0; j<list.size();j++ )
     {
    	 
    	 int barWidth = ( int )( xUnit_value/5);//定义统计图中,柱体的宽度。这个可以根据个人喜好自定义,在每一个区间内,只用1/5来显示柱状图
    	 int startPos = xoffset +2 +xUnit_value*(j+1);//j+1,使得x轴的每一个区间从坐标原点,向后平移一个区间。
    	
    	 int interval = barWidth/2 ;
    	 
    	 Map<String,Object>map = list.get(j);
		 int temp =  Integer.parseInt( map.get("count").toString( ));
    	
         int barHeight = temp*( yUnit_value/ymarkers);//这儿存在问题,如果使用的是(temp/ymarkers)*yUnit_value,则每次计算的基数有问题。所以改为temp*( yUnit_value/ymarkers)
    	 
    	 //绘制柱状图
    	 mypaint.setColor(Color.MAGENTA);
    	 canvas.drawRect(startPos, height-2-yoffset-barHeight,
    			   startPos+barWidth,height-2-yoffset,mypaint);
    	 
    	 //绘制数据值
    	 mypaint.setColor(Color.BLUE);
    	 canvas.drawText( String.valueOf(temp),  startPos,height-2-yoffset-barHeight-4  ,mypaint);
    	 
    	 //绘制x轴上面的横坐标
    	 mypaint.setColor(Color.CYAN);
    	 String  str = map.get("eControl").toString();  
		 canvas.drawText(str, startPos-interval, height-2-yoffset+10, mypaint);//x-interval是为了,让x轴上显示的字,居中显示
    	 
     }
     

     //绘制一个统计表的小方块
     mypaint.setColor(Color.MAGENTA);
     canvas.drawRect( 2+xoffset, height-2-yoffset/2, 16+xoffset,height-2-yoffset/2-16   ,mypaint);
     
     mypaint.setColor(Color.BLACK);
     canvas.drawText( "查询记录count", 25+xoffset,height-2-yoffset/2,mypaint);
 
	}
	

	/*遍历数据库*/
	public void   ViewDatabase(  )
	{
		
		SplashActivity  activity = new SplashActivity();
        String  outFileName = activity.getDataFilePath( )+"databases/jackdata.db";
		 
        dbhelper = new DbOpenHelper ( context );
        
        try{
        	
        	database = dbhelper.openDatabase(outFileName);
        	
        	Cursor record_cursor = database.rawQuery("select eControl ,count from tb_eController group by eControl order by count desc", null);
        	
        	int column = record_cursor.getColumnCount();
        	
        	while( record_cursor.moveToNext() )
        	{
        		Map<String ,Object > map = new HashMap<String ,Object >();
        		
        		for( int i = 0; i < column; i++ )
        		{
        			
        			String cols_name = record_cursor.getColumnName(i);
        			String cols_value = record_cursor.getString(record_cursor.getColumnIndex(cols_name));
        			if( cols_value == null )
        			{
        				cols_value="";
        			}
        			else 
        			{
        				map.put( cols_name,cols_value );
        			}
        		}
        		list.add( map );
        	}
        	record_cursor.close();
        	dbhelper.close();
        	
        }catch( NullPointerException e )
        {
        	
        	e.printStackTrace();
        }finally{
        	 if(database!=null)
             {
             	database.close();
             }
        }
        
	}
	
	/* 获得需要的数据*/
	public  void   getDataSource ( )
	{
		  
	      maxcount = 0;
	      mincount = 0;
	      
	      ViewDatabase( );//遍历数据库得到count字段,eControl字段,数据存到list中
	      
	     //得出list中count的最大,最小值。
	     for( Map<String,Object > map:list )
			{
				 int temp =  Integer.parseInt( map.get("count").toString());
				 if( maxcount < temp )
				 {
					 maxcount = temp;
				 }
				 if( mincount > temp )
				 {
					 mincount = temp;
				 }
		
			}
	}
	

}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值