簡單的android折線圖繪製

上圖

wKiom1PcVQqDL2JhAADD3ng_Q1k567.jpg

說到android的折線圖,我就必須要說一下關於繪製view的幾個重要的工具,Canvas(畫布),Paint(畫筆),Path(路徑)。

     Canvas顧名思義就是用來作畫的板子或者說是布。沒有它就算有了畫筆也是無從下手。當然我們可以通過Canvas的各種屬性來設置Canvas,例如:

    

canvas.drawColor(Color.BLACK);//設置背景顏色爲黑色

其他設置就自己去查看api了,這裏不多講了。

     Paint畫筆,用來作畫的筆,不管我們在畫布上面繪製什麼,都離不開畫筆,只要用到canvas的地方請帶上畫筆。和畫布一樣,畫筆也可以設計他獨特的屬性,例如顏色呀,粗細呀虛實線呀什麼的,這裏也不多說了。

     Path路徑,就像是我們小學時候用的尺子一樣,如果要畫一條直線就得沿着尺子的邊緣話,這就是路徑的功能,不過這裏的路徑沒有那麼必須,簡單的線還是可以直接用paint畫出來的,畫折線圖用到path的地方主要是畫虛線,其實我也不是很明白爲何必須用path,不過如果直接用paint+PathEffect+座標來畫畫出來就永遠是直線了,大概因爲虛線是一節節的畫的吧。

    上面簡單的介紹了一下用到的工具,下面就講講我畫折線圖的一些思路吧。

    首先,一個座標圖必然要有原點座標,X,Y軸,繪製折線的基線表格,最後就是折線啦。

    原點可以自己定義繪製在任何地方,我這裏由於不知道手機屏幕的具體大小,怕繪製出來比較雞肋,於是做了個屏幕自適應:


       原點X座標=邊距(也就是距離邊界的寬度,android的像素點是從屏幕的左上角開始的)

       原點Y座標 = 屏幕的高度 - 邊距

       X軸的長度 = 屏幕寬度 - 2*邊距 

       Y軸的長度 = 屏幕高度 - 2*邊距

       X軸的單位長度 = (屏幕寬度 - 2 * 邊距) / (X軸所顯示的標線數 - 1);

       Y軸的單位長度 = (屏幕高度 - 2* 邊距 )/(Y軸所顯示的標線數 - 1)

   畫圖的時候各個點座標的計算方法是:

       Y軸座標 = (Y軸的單位長度 /(Y軸1點顯示的數字 - 原點Y軸顯示的數字))*(數據的Y軸數據-原點數字)

       X軸同理

這樣整個折線圖的畫法就很清晰啦。下面直接上代碼

       


	// 畫表格
	private void drawTable(Canvas canvas) {
		Paint paint = new Paint();
		paint.setStyle(Paint.Style.STROKE);
		paint.setColor(Color.GRAY);
		Path path = new Path();
		PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
		paint.setPathEffect(effects);
		// 縱向線
		for (int i = 1; i * Xscale <= (this.getWidth() - this.Margin); i++) {
			int startX = Xpoint + i * Xscale;
			int startY = Ypoint;
			int stopY = Ypoint - (this.Ylabel.length - 1) * Yscale;
			path.moveTo(startX, startY);
			path.lineTo(startX, stopY);
			canvas.drawPath(path, paint);
		}
		// 橫向線
		for (int i = 1; (Ypoint - i * Yscale) >= this.Margin; i++) {
			int startX = Xpoint;
			int startY = Ypoint - i * Yscale;
			int stopX = Xpoint + (this.Xlabel.length - 1) * Xscale;
			path.moveTo(startX, startY);
			path.lineTo(stopX, startY);
			paint.setColor(Color.DKGRAY);
			canvas.drawPath(path, paint);
			paint.setColor(Color.WHITE);
			paint.setTextSize(this.Margin / 2);
			canvas.drawText(this.Ylabel[i], this.Margin / 4, startY
					+ this.Margin / 4, paint);
		}
	}	
	// 畫橫縱軸
	private void drawXLine(Canvas canvas, Paint p) {
		canvas.drawLine(Xpoint, Ypoint, this.Margin, this.Margin, p);
		canvas.drawLine(Xpoint, this.Margin, Xpoint - Xpoint / 3, this.Margin
				+ this.Margin / 3, p);
		canvas.drawLine(Xpoint, this.Margin, Xpoint + Xpoint / 3, this.Margin
				+ this.Margin / 3, p);
	}

	private void drawYLine(Canvas canvas, Paint p) {
		canvas.drawLine(Xpoint, Ypoint, this.getWidth() - this.Margin, Ypoint,
				p);
		canvas.drawLine(this.getWidth() - this.Margin, Ypoint, this.getWidth()
				- this.Margin - this.Margin / 3, Ypoint - this.Margin / 3, p);
		canvas.drawLine(this.getWidth() - this.Margin, Ypoint, this.getWidth()
				- this.Margin - this.Margin / 3, Ypoint + this.Margin / 3, p);
	}
	// 畫數據
	private void drawData(Canvas canvas) {
		Paint p = new Paint();
		p.setAntiAlias(true);
		p.setColor(Color.WHITE);
		p.setTextSize(this.Margin / 2);
		// 縱向線
		for (int i = 1; i * Xscale <= (this.getWidth() - this.Margin); i++) {
			int startX = Xpoint + i * Xscale;
			canvas.drawText(this.Xlabel[i], startX - this.Margin / 4,
					this.getHeight() - this.Margin / 4, p);
			canvas.drawCircle(startX, calY(Data[i]), 4, p);
			canvas.drawLine(Xpoint+(i-1)*Xscale, calY(Data[i-1]), startX, calY(Data[i]), p);
		}
	}
	
	/**
	 * 
	 * @param y  
	 * @return
	 */
	private int calY(int y){ 
		int y0 = 0 ;
		int y1 = 0 ;
		try{
			y0 = Integer.parseInt(Ylabel[0]);
			y1 = Integer.parseInt(Ylabel[1]);
		}catch(Exception e){
			return 0;
		}
		try{
			return Ypoint-((y-y0)*Yscale/(y1-y0)) ;
		}catch(Exception e){
			return 0;
		}
	}

最後不要忘了

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
		Paint p1 = new Paint();
		p1.setStyle(Paint.Style.STROKE);
		p1.setAntiAlias(true);
		p1.setColor(Color.WHITE);
		p1.setStrokeWidth(2);
		init();
		this.drawXLine(canvas, p1);
		this.drawYLine(canvas, p1);
		this.drawTable(canvas);
		this.drawData(canvas);
	}

完整項目的代碼在下面,有興趣的可以自己下載來玩玩

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章