1. 程式人生 > >手工畫折線圖(不使用第三方jar)

手工畫折線圖(不使用第三方jar)

大神勿噴謝謝!

  很多剛學android的人很害怕畫折線圖,覺得折線圖呈現非常複雜,感覺自己能力不足無法勝任!而且也有很多也很好用的jar包,但是jar畢竟是別人的,雖說開

源,但是有幾個人能開啟裡面的程式碼從頭研究一遍,一般都是做完專案就扔到一邊,jar包功能有限,又怎麼去應付那些腦洞大開的UI設計師跟呆傻蠢萌的產品經理

提出的各種需求呢?

上有產品經理,下有測試小妹,好吧,苦逼的程式猿跟程式媛,只能自己動手豐衣足食了!

知道原理後,你就會發現折線圖非常簡單,開發中有2種解決折線圖簡單而直接的方法:

1.使用android提供的path類(下篇博文再說);

2.直接使用onDraw(Canvas canvas)方法的canvas去畫線就能解決(這篇博文就用它了);

廢話不多,上程式碼!!!

package com.anjie.view;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class ZXView extends View {

	private List<Integer> xlist;//x座標標籤
	private List<Integer> ylist;//y座標標籤
	private List<Integer> params;//引數集合
	
	private Paint paint;
	private Paint paintLines;
	private Paint paintArc;
	private Paint paintText;
	
	private float Xoffset=0;//X軸偏移或叫間隔
	private float Yoffset=0;//Y軸偏移或叫間隔
	public float XSpac=50;
	public float Xspac=50;
	public float YSpac=50;
	public float rightXspac=50;
	public float rightYspac=50;
	public int textsize=20;
	
	public float circleRadius=10;
	
	private float lastX=-1;
	private float lastY=-1;
	
	public ZXView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		initWidget();
	}
	
	public ZXView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		initWidget();
	}
	
	public ZXView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		initWidget();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		
		drawXY(canvas);
		drawLine(canvas);
		Log.i("111", getWidth()+"");
		super.onDraw(canvas);
	}

	public void initViewData(List<Integer> xlist,List<Integer> ylist,List<Integer> params){
		this.xlist=xlist;
		this.ylist=ylist;
		this.params=params;
	}
	
	public void updataUI(){
		invalidate();
	}
	
	/**
	 * 畫折圖
	 * @param canvas
	 */
	private void drawLine(Canvas canvas) {
		// TODO Auto-generated method stub
		Xoffset=((getWidth())-20)/(xlist.size());
		Yoffset=(getHeight())/(ylist.size());
Log.i("texts","X=" + Xoffset+"Y="+Yoffset);
		float rulerOffset=0;
		
		if(xlist.size()<2)
			throw new IllegalArgumentException("the params argument is <2");
		else
			rulerOffset=(xlist.get(1)-xlist.get(0));
		
		
		if(params==null&¶ms.size()<=0)
			throw new IllegalArgumentException("the params is null or 0");
		
		Paint p=new Paint();
		p.setAntiAlias(true);
		p.setTextSize(25);
		p.setColor(Color.WHITE);
		canvas.drawText("KW", 10+Xoffset, 20, p);
		
		for(int i=0;i<params.size();i++){
			int param=params.get(i);
			float histigramHight=param*(Yoffset/rulerOffset);
			
			float currentX=(Xoffset*i+Xspac+5);
			float currentY=(getHeight()-YSpac-histigramHight);
			
			canvas.drawCircle(currentX,currentY,circleRadius, paintArc);
			
			if(lastX!=-1){
				canvas.drawLine(lastX, lastY, currentX, currentY, paintLines);
			}
			lastX=currentX;
			lastY=currentY;
		}
		//重置lastX跟Y
		lastX=-1;
		lastY=-1;
		
	}
	/**
	 * 畫座標
	 * @param canvas
	 */
	private void drawXY(Canvas canvas){
		canvas.drawLine(XSpac,0,XSpac,getHeight()-5-XSpac, paint);//X
		canvas.drawLine(XSpac,getHeight()-XSpac,getWidth(),getHeight()-XSpac, paint);//Y
		canvas.drawLine(getWidth(), 0, getWidth()-1, getHeight()-YSpac, paint);//右邊Y
		float yOffset=getHeight()/ylist.size();
		float xOffset=(getWidth()-XSpac)/xlist.size();
		
		for(int i=0;i<ylist.size();i++){//畫字
			canvas.drawText(ylist.get(i)+"",0, getHeight()-yOffset*i-YSpac, paintText);
		}
		for(int i=0;i<xlist.size();i++){
			canvas.drawText(xlist.get(i)+"",XSpac+xOffset*i,getHeight()-YSpac+textsize, paintText);
		}
		
		for(int i=0;i<ylist.size();i++){
			for(int j=0;j<50;j++){
				canvas.drawLine(XSpac+j*30,yOffset*i-YSpac,XSpac+j*30+20,yOffset*i-YSpac,paint);
			}
		}
	}

	private void initWidget() {
		// TODO Auto-generated method stub
		paint=new Paint();
		paint.setColor(Color.parseColor("#999999"));
		paint.setTypeface(Typeface.DEFAULT);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(2);
		
		paintLines=new Paint();
		paintLines.setColor(Color.parseColor("#00B4EA"));
		paintLines.setTypeface(Typeface.DEFAULT);
		paintLines.setAntiAlias(true);
		paintLines.setStrokeWidth(3);
		
		paintArc=new Paint();
		paintArc.setColor(Color.parseColor("#EBEEEF"));
		paintArc.setTypeface(Typeface.DEFAULT);
		paintArc.setAntiAlias(true);
		paintArc.setStrokeWidth(2);
		
		paintText=new Paint();
		paintText.setColor(Color.parseColor("#ffffff"));
		paintText.setTypeface(Typeface.DEFAULT);
		paintText.setAntiAlias(true);
		paintText.setStrokeWidth(2);
		paintText.setTextSize(textsize);
	}

	

}

還有layout檔案:

<com.anjie.view.ZXView
            android:id="@+id/zx_view"
            android:layout_width="fill_parent"
            android:layout_height="150dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp" />


客官們可以自己拉下來執行看看或者我提供demo!!!

哈哈!這就完工了,,我拿去應付人(dai)見(sha)人(chun)愛(meng)的產品經理去了!你們呢?


最後宣告:大神勿噴!!!