简单的柱形图实现

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.tiangui.R;
import com.tiangui.utils.DensityUtil;

/**
 * 文件描述:柱形图控件
 * 作者:Created by BiJingCun on 2018/5/15.
 */
public class HistogramView extends View {
    private Paint mPaint_X;//X坐标轴画笔
    private Paint mPaint_Y;//Y坐标轴画笔
    private Paint mPaint_InsideLine;//内部虚线P
    private Paint mPaint_Text;//字体画笔
    private Paint mPaint_Time;//字体画笔
    private Paint mPaint_Rec;//矩形画笔
    private Integer[] data;
    private float width;
    private float height;
    private String[] mText_Y;
    private String[] mText_X;//默认X轴坐标
    private int rec_color;
    private int mColor_text;
    private int mColor_line;
    private float mHeight_offset;
    private float mWeight_offset;
    private Paint mPaintY_text;
    private int maxLength;//最大值
    private Context context;
    private float mTimeHeight;
    private String timeStr="时长(min)";

    public HistogramView(Context context) {
        super(context);
        init(context, null);
    }

    public HistogramView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    /**
     * 更新XY轴坐标
     */
    public void upDateTextForX(String[] text_X) {
        this.mText_X = text_X;
        this.postInvalidate();  //更新视图
    }

    /**
     * 更新数据
     */
    public void upData(Integer[] data, String[] mText_Y ,int maxLength) {
        this.data = data;
        this.mText_Y=mText_Y;
        this.maxLength=maxLength;
    }

    /**
     * 初始化画笔
     */
    private void init(Context context, AttributeSet attrs) {
        this.context = context;
        mColor_line = context.getResources().getColor(R.color.color_e8e8e8);//所有轴线的颜色
        mColor_text = context.getResources().getColor(R.color.color_b8b8b8);//所有字体的颜色
        rec_color = context.getResources().getColor(R.color.color_79cff7);//柱形图的内部颜色

        mPaint_X = new Paint();//X
        mPaint_X.setColor(mColor_line);
        mPaint_X.setStrokeWidth(DensityUtil.dip2px(context, 1));

        mPaintY_text = new Paint();//纵坐标的字体
        mPaintY_text.setColor(mColor_text);
        mPaintY_text.setTextSize(DensityUtil.sp2px(context, 11));
        mPaintY_text.setTextAlign(Paint.Align.CENTER);

        mPaint_Y = new Paint();//Y
        mPaint_Y.setColor(mColor_line);
        mPaint_Y.setStrokeWidth(DensityUtil.dip2px(context, 1));

        mPaint_InsideLine = new Paint();//横向标线
        mPaint_InsideLine.setColor(mColor_line);
        mPaint_InsideLine.setStrokeWidth(DensityUtil.dip2px(context, 1));

        mPaint_Text = new Paint();//字体
        mPaint_Text.setColor(mColor_text);
        mPaint_Text.setTextSize(DensityUtil.sp2px(context, 11));
        mPaint_Text.setTextAlign(Paint.Align.CENTER);

        mPaint_Time = new Paint();//字体
        mPaint_Time.setColor(mColor_text);
        mPaint_Time.setTextSize(DensityUtil.sp2px(context, 11));
        mPaint_Time.setTextAlign(Paint.Align.LEFT);

        mPaint_InsideLine.setAntiAlias(true);
        mPaint_Text.setAntiAlias(true);
        mPaint_X.setAntiAlias(true);
        mPaint_Y.setAntiAlias(true);

        mPaint_Rec = new Paint();//柱形图
        mPaint_Rec.setColor(rec_color);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        width = getWidth();
        height = getHeight();
        if (mText_X != null && data != null && mText_Y != null) {
            Rect rectMax = new Rect();
            String strMax = String.valueOf(maxLength);
            mPaintY_text.getTextBounds(strMax,0,strMax.length(), rectMax);
            mWeight_offset = rectMax.width()+30;//Y轴的最大值的宽度;

            Rect rectX = new Rect();
            mPaint_Text.getTextBounds(mText_X[0],0,mText_X[0].length(), rectX);
            float heightX = rectX.height();
            mHeight_offset = heightX+30;//Y轴竖向偏移

            Rect rectTime = new Rect();
            mPaint_Time.getTextBounds(timeStr,0,timeStr.length(), rectTime);
            mTimeHeight = rectTime.height();//左上角提示单位的字体高度

            float weightPointX = mWeight_offset;//原点坐标 X
            float heightPointY = height - mHeight_offset;//原点坐标Y
            float heightZhu = height - mHeight_offset - mTimeHeight*2;//显示柱状图区域的高度;
            float leftHeight_Every = heightZhu / 2; //Y轴每个数据的间距
            float downWeight_Every = (width - mWeight_offset) / mText_X.length;//X轴每个数据的间距

            //画XY坐标轴
            canvas.drawLine(weightPointX, heightPointY, width, heightPointY, mPaint_X);
            canvas.drawLine(weightPointX, heightPointY, mWeight_offset, 0, mPaint_Y);

            //画内部灰线
            for (int i = 1; i < 3; i++) {
                canvas.drawLine(mWeight_offset, heightPointY - (i * leftHeight_Every), width, heightPointY - (i * leftHeight_Every), mPaint_InsideLine);
            }
            //画X轴坐标
            for (int i = 1; i < mText_X.length + 1; i++) {
                canvas.drawText(mText_X[i - 1], mWeight_offset / 3 + downWeight_Every * (i), height-10, mPaint_Text);
            }

            if (this.data != null && this.data.length > 0) {
                //画Y轴坐标
                canvas.drawText("0", mWeight_offset / 2, heightPointY, mPaintY_text);
                for (int i = 1; i < 3; i++) {
                    canvas.drawText(mText_Y[i - 1], mWeight_offset / 2, heightPointY - (i * leftHeight_Every) + 10, mPaintY_text);
                }
                //画矩形
                for (int i = 1; i < data.length + 1; i++) {
                    double data_Yx = (double) data[i - 1] / maxLength;//获取到的比例
                    RectF rect = new RectF();
                    rect.left = mWeight_offset / 3 + downWeight_Every * i - 20;
                    rect.right = mWeight_offset / 3 + downWeight_Every * i + 20;
                    rect.top = (heightPointY - (float) (data_Yx * heightZhu));
                    rect.bottom = heightPointY;
                    canvas.drawRect(rect, mPaint_Rec);
//                canvas.drawText(data[i - 1] + "步", 10 + downWeight_Every * i, (height - 50 - (int) (data_Yx * leftHeight_Every)) - 15, mPaint_Text);
                }
            }

            //画左上角的时长文字;
            canvas.drawText(timeStr, mWeight_offset + 30, mTimeHeight, mPaint_Time);
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_34979546/article/details/80408839