Android图表绘制

由于最新项目需要用到图表显示数据,所以参考网上的资源,写了一个demo,主要是通过在Activity发送不同的数据到view里面刷新显示,每发送一次数据,就显示几个随机数到view显示。
显示效果如图:
这里写图片描述
代码注释比较详细,就不做太多说明了。
ZywChartView.java

@SuppressLint("DrawAllocation")
public class ZywChartView extends View {

    private String TAG = "ZywChartView";
    // 默认边距

    private float Margin = 40;

    //圆半径
    private int circleRadius = 8;

    // X,Y轴的单位长度
    private float Xscale = 20;
    private float Yscale = 20;

    //X轴第1个节点到最后1个节点的长度
    private float xLength;
    //Y轴第1个节点到最后1个节点的长度
    private float yLength;

    //X轴第1个节点的偏移量
    private float xFirstPointOffset;

    //y轴显示的节点间隔距离
    private int yScaleForData = 5;

    //画线颜色
    private int lineColor = this.getResources().getColor(R.color.saswell_yellow);

    // 原点坐标
    private float Xpoint;
    private float Ypoint;

    private String yUnit = "";
    private String xUnit = "";

    // X,Y轴上面的显示文字
    private String[] Xlabel = { "1", "2", "3", "4", "5", "6", "7"};
    private String[] Ylabel = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
            "9", "10" };

    private final static int Y_SCALE_FOR_DATA_DAY = 5; 
    private final static int Y_SCALE_FOR_DATA_WEEK = 2; 
    private final static int Y_SCALE_FOR_DATA_MOUNTH = 2; 

    // 曲线数据
    private int[] Data = {5, 5, 5, 5, 5, 5, 5};

    public ZywChartView(Context context, String[] xlabel, String[] ylabel, int[] data) {
        super(context);
        this.Xlabel = xlabel;
        this.Ylabel = ylabel;
        this.Data = data;
    }

    public ZywChartView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs, int defStyleAttr)");
    }

    public ZywChartView(Context context, AttributeSet attrs) {
        super(context, attrs);

        init();
        xFirstPointOffset = 2 * this.Margin;
        Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs)");
    }

    public ZywChartView(Context context) {
        super(context);
        Log.e(TAG,"ZywChartView(Context context)");
    }

    /**
     * 设置显示的数据
     * @param str要显示的数据字符串
     * @author zyw
     */
    public void setData(String str){
        String[] tempData;
        tempData = str.split(",");  
        int yDataLength = 0;
        Log.e(TAG, "str = " + str);
        Data = new int[tempData.length];
        Xlabel = new String[tempData.length];

        if(tempData.length >= 28){
            yScaleForData = Y_SCALE_FOR_DATA_MOUNTH;
            yDataLength = 25;
            xUnit = getResources().getString(R.string.x_unit_month);
            yUnit = getResources().getString(R.string.y_unit_month);
        }else if(tempData.length >= 12){
            yScaleForData = Y_SCALE_FOR_DATA_DAY;
            yDataLength = 61;
            xUnit = getResources().getString(R.string.x_unit_day);
            yUnit = getResources().getString(R.string.y_unit_day);
        }else{
            yScaleForData = Y_SCALE_FOR_DATA_WEEK;
            yDataLength = 25;
            xUnit = getResources().getString(R.string.x_unit_week);
            yUnit = getResources().getString(R.string.y_unit_week);
        }

        Ylabel = new String[yDataLength];
        for(int i = 0; i < yDataLength; i++){
            Ylabel[i] = Integer.toString(i);
            //Log.e(TAG,"Ylable[" + i +  "]" + Ylabel[i]);
        }

        for(int i = 0; i < tempData.length; i++){
            Data[i] = Integer.parseInt(tempData[i]);
            //Log.e(TAG,"Data[" + i +  "]" + Data[i]);
            Xlabel[i] = Integer.toString(i + 1);
            Log.e(TAG,"Xlable[" + i +  "]" + Xlabel[i]);
        }

        invalidate();
    }

    // 初始化数据
    public void init() {
        Xpoint = this.Margin;
        Log.e(TAG, "this.getHeight() == " + this.getHeight());
        Ypoint = this.getHeight() - this.Margin;
        Xscale = (this.getWidth() - 4 * this.Margin) / (this.Xlabel.length);
        Yscale = (this.getHeight() - 3 * this.Margin) / (this.Ylabel.length);

        xLength = this.getWidth() - (4 * this.Margin);
        yLength = this.getHeight() - (2 * this.Margin);

        xFirstPointOffset = Xscale;
    }

    public float getMargin() {
        return Margin;
    }

    public void setMargin(int margin) {
        Margin = margin;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        Log.e(TAG, "onDraw");
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        paint.setColor(lineColor);
        paint.setStrokeWidth(3);
        init();
        this.drawXLine(canvas, paint);
        this.drawYLine(canvas, paint);
        this.drawDashPath(canvas);
        this.drawData(canvas);
        this.drawXUnit(canvas);
        this.drawYUnit(canvas);
    }

    //画虚线
    private void drawDashPath(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(lineColor);
        paint.setStrokeWidth(3);
        Path path = new Path();
        //绘制长度为10的实线,再绘制长度为10的空白,再绘制长度为10的实线,再回执长度为10的空白,依次重复,1为偏移量
        PathEffect effects = new DashPathEffect(new float[] { 10, 10, 10, 10}, 1);
        paint.setPathEffect(effects);

        // 纵向线
        for (int i = 0; i * Xscale < xLength; i++) {
            float startX = Xpoint + i * Xscale + xFirstPointOffset;
            float startY = Ypoint;
            float stopY = calY(Data[i]);
            path.moveTo(startX, startY);
            path.lineTo(startX, stopY);
            canvas.drawPath(path, paint);
        }
    }

    private void drawXUnit(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(2);
        p.setTextSize(this.Margin / 2);
        canvas.drawText(xUnit, this.getWidth() - this.Margin * 2 + this.Margin / 4, Ypoint + this.Margin / 5, p);
    }

    private void drawYUnit(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(2);
        p.setTextSize(this.Margin / 2);
        canvas.drawText(yUnit, this.Margin / 2, this.Margin / 2, p);
    }

    // 画横纵轴
    private void drawXLine(Canvas canvas, Paint p) {
        canvas.drawLine(Xpoint, Ypoint, this.getWidth() - this.Margin * 2, Ypoint,
                p);
        canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
                - this.Margin * 2 - this.Margin / 3, Ypoint - this.Margin / 3, p);
        canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
                - this.Margin * 2 - this.Margin / 3, Ypoint + this.Margin / 3, p);
    }

    private void drawYLine(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 drawData(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(3);
        p.setTextSize(this.Margin / 2);
        //横向
        for (int i = 0; i * Xscale < xLength; i++) {
            float startX = Xpoint + i * Xscale + xFirstPointOffset;
            canvas.drawText(this.Xlabel[i], startX - this.Margin / 4,
                    this.getHeight() - this.Margin / 4, p);
            canvas.drawCircle(startX, calY(Data[i]), circleRadius, p);
            if(i != 0){
                canvas.drawLine(Xpoint + (i - 1) * Xscale + xFirstPointOffset, calY(Data[i-1]), startX, calY(Data[i]), p);
            }
        }

        //纵向
        for (int i = 0; (yLength - i * Yscale) >= this.Margin; i += yScaleForData) {
            float startY = Ypoint - i * Yscale;
            canvas.drawText(this.Ylabel[i], this.Margin / 4, startY
                    + this.Margin / 4, p);
        }
    }

    /**
     * 
     * @param y  
     * @return
     */
    private float calY(int y){ 
        int y0 = 0 ;
        int y1 = 0 ;
        //  Log.i("zzzz", "y:"+y);
        try{
            y0 = Integer.parseInt(Ylabel[0]);
            //      Log.i("zzzz", "y0"+y0);
            y1 = Integer.parseInt(Ylabel[1]);
            //      Log.i("zzzz","y1"+y1);
        }catch(Exception e){
            //      Log.i("zzzz", "string changed is err");
            return 0;
        }
        try{
            //      Log.i("zzzz", "返回数据"+(Ypoint-(y-y0)*Yscale/(y1-y0)) );
            return Ypoint - ((y-y0) * Yscale/(y1-y0));
        }catch(Exception e){
            //  Log.i("zzzz", "return is err");
            return 0;
        }
    }

}

EnergyConsumptionActivity.java

public class EnergyConsumptionActivity extends Activity{
    private int randomNum;
    private RadioGroup rgModeSelect;
    private RadioButton rbDayMode,rbWeekMode,rbMonthMode;
    private String TAG = "MainActivity";
    private Button btnSetData,btnTitle;
    private ZywChartView myView;
    private String strData;
    private int mode,randomDataLength = 10;
    private final static int DAY_MODE = 1;
    private final static int WEEK_MODE = 2;
    private final static int MONTH_MODE = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_energy_consumption);

        init();
    }

    private OnClickListener onClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btnSetData:
                Log.e("ZYW", "set Data.");
                sendData(mode);
                break;

            case R.id.title_back:
                Log.e(TAG,"finish.");
                finish();
                break;

            default:
                break;
            }

        }
    };

    private OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            try {
                switch(checkedId){
                case R.id.rbDayMode:
                    mode = DAY_MODE;
                    randomDataLength = 60;
                    break;
                case R.id.rbWeekMode:
                    mode = WEEK_MODE;
                    randomDataLength = 24;
                    break;
                case R.id.rbmonthMode:
                    mode = MONTH_MODE;
                    randomDataLength = 24;
                    break;
                }
                sendData(mode);
                Log.e(TAG, "mode = " + mode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 在0-randomDataLength中生成一个随机数
     * @return 随机生成的数字组合字符串: data1,data2,data3,...dataN
     */
    public String getRandomNum(int mode){
        String strRandomNum = "";
        int maxI = 7;
        //根据模式(天、周、月)确定要绘制的折线图
        switch (mode) {
        case DAY_MODE:
            maxI = 12;
            break;

        case WEEK_MODE:
            maxI = 7;
            break;

        case MONTH_MODE:
            maxI = 30;
            break;

        default:
            Log.e(TAG, "mode is error");
            break;
        }

        for(int i = 0; i < maxI; i++){
            //在0-randomDataLength中生成一个随机数
            randomNum = (int) (Math.random()*randomDataLength);
            //Log.e(TAG, "randomNum ==" + randomNum);
            if(i != (maxI - 1)){
                strRandomNum += randomNum + ",";
            }
            else{
                strRandomNum += randomNum;
            }
        }
        Log.e(TAG, "strRandomNum ==" + strRandomNum);
        return strRandomNum;
    }

    /**
     * 发送数据
     * @param mode
     */
    public void sendData(int mode){
        strData = getRandomNum(mode);
        myView.setData(strData);
    }

    public void init(){
        btnSetData = (Button) findViewById(R.id.btnSetData);
        btnTitle = (Button) findViewById(R.id.title_back);
        myView = (ZywChartView) findViewById(R.id.myView);
        rbDayMode = (RadioButton) findViewById(R.id.rbDayMode);
        rbWeekMode = (RadioButton) findViewById(R.id.rbWeekMode);
        rbMonthMode = (RadioButton) findViewById(R.id.rbmonthMode);
        rgModeSelect = (RadioGroup) findViewById(R.id.rgModeSelect);

        rgModeSelect.setOnCheckedChangeListener(checkedChangeListener);
        btnTitle.setOnClickListener(onClickListener);
        btnSetData.setOnClickListener(onClickListener);

        rbDayMode.setChecked(true);
    }
}

demo下载地址:http://download.csdn.net/detail/oqinyou/9492870

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值