本来当时只想做两个练练手后就快速越过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);
}
}
搞定。
附其它链接:
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168