本来当时只想做两个练练手后就快速越过Canvas的,对这块我一向兴趣不大,不过最近在绘了两个图后忽然发现,以前那些很常见的图
表,仔细想一下,如果不太讲求通用性,不考虑一些特效外,光图表本身, 自己简单的画出来,好像也不难。这样尝试尝试,自娱自乐下也蛮不错的。
这不,我又画了个Area Chart,就用到drawLine和Path两个东东配合下透明度就实现了。
效果图如下:
至于怎么实现的,主要原理就是个Path加透明度的事,透明度自定了个公式计算出来,越到后面的越透明,
层次感就出来了。具体看看我的代码实现。
package com.xcl.canvas04; /** * Canvas练习 * 自已画面积图(Area Chart) * * author:xiongchuanliang * date:2014-4-8 */ import android.os.Bundle; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.util.DisplayMetrics; import android.view.Menu; import android.view.View; @SuppressLint("NewApi") public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); setContentView(new PanelAreaChart(this)); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } 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, }; //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); //解决4.1版本 以下canvas.drawTextOnPath()不显示问题 this.setLayerType(View.LAYER_TYPE_SOFTWARE,null); //屏幕信息 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].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]); } /////////////////////////////////////// } } }搞定。
附其它链接:
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168