实现一个简单的柱状图表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16247851/article/details/86165564

效果图如下:

自定义控件代码:



import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.content.ContextCompat;
import android.view.View;
import com.mmjrxy.school.R;

import java.util.List;

public class CustomBarChart extends View {

    // 坐标单位
    private String[] xLabel;
    // 数据
    private float[] dataList;
    private List<Integer> colorList;
    // 默认边距
    private int margin = 45;
    // 距离左边偏移量
    private int marginX = 10;
    // 原点坐标
    private int xPoint;
    private int yPoint;
    // X,Y轴的单位长度
    private int xScale;
    private int yScale;

    private float percent;
    // 画笔
    private Paint paintAxes;
    private Paint paintCoordinate;
    private Paint paintRectF;
    private Paint paintValue;

    private int currentIndex = -1;
    private float currentPaint = 0;

    public CustomBarChart(Context context, String[] xLabel,
                          float[] dataList, List<Integer> colorList) {
        super(context);
        this.xLabel = xLabel;
        this.dataList = dataList;
        this.colorList = colorList;
    }

    public CustomBarChart(Context context) {
        super(context);
    }

    /**
     * 初始化数据值和画笔
     */
    public void init() {

        //柱状图显示比例
        float max = 0;
        for (int i = 0; i < dataList.length; i++) {
            if (dataList[i] > max) {
                max = dataList[i];
            }
        }
        percent = max / 5.0f;

        xPoint = margin + marginX;
        yPoint = this.getHeight() - margin;
        xScale = (this.getWidth() - 2 * margin - marginX) / (xLabel.length - 1);
        yScale = (this.getHeight() - 2 * margin - marginX) / 6;

        //x轴画笔
        paintAxes = new Paint();
        paintAxes.setStyle(Paint.Style.STROKE);
        paintAxes.setAntiAlias(true);
        paintAxes.setDither(true);
        paintAxes.setColor(ContextCompat.getColor(getContext(), R.color.gray));
        paintAxes.setStrokeWidth(4);
        //x轴刻度画笔
        paintCoordinate = new Paint();
        paintCoordinate.setStyle(Paint.Style.STROKE);
        paintCoordinate.setDither(true);
        paintCoordinate.setAntiAlias(true);
        paintCoordinate.setColor(ContextCompat.getColor(getContext(), R.color.colorBody));
        paintCoordinate.setTextSize(40);
        //柱形图画笔
        paintRectF = new Paint();
        paintRectF.setStyle(Paint.Style.FILL);
        paintRectF.setDither(true);
        paintRectF.setAntiAlias(true);
        paintRectF.setStrokeWidth(20);
        //柱形图上面的数字画笔
        paintValue = new Paint();
        paintValue.setStyle(Paint.Style.STROKE);
        paintValue.setAntiAlias(true);
        paintValue.setDither(true);
        paintValue.setTextAlign(Paint.Align.CENTER);
        paintValue.setTextSize(40);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(ContextCompat.getColor(getContext(), R.color.white));
        init();
        drawAxesLine(canvas, paintAxes);
        drawCoordinate(canvas, paintCoordinate);
        drawData(canvas, paintRectF, dataList, colorList);


    }

    /**
     * 绘制坐标轴
     */
    private void drawAxesLine(Canvas canvas, Paint paint) {
        canvas.drawLine(xPoint - 40, yPoint, this.getWidth() - margin / xLabel.length-1, yPoint, paint);
    }

    /**
     * 绘制刻度
     */
    private void drawCoordinate(Canvas canvas, Paint paint) {
        // X轴坐标
        for (int i = 0; i <= (xLabel.length - 1); i++) {
            paint.setTextAlign(Paint.Align.CENTER);
            int startX = xPoint + i * xScale;
            canvas.drawText(xLabel[i], startX, this.getHeight() - margin / xLabel.length-1, paint);
        }
    }

    /**
     * 绘制单柱形
     */
    private void drawData(Canvas canvas, Paint paint, float data[], List<Integer> colorList) {

        if (currentIndex != -1) {
            for (int i = 0; i < currentIndex; i++) {
                int startX = xPoint + i * xScale;
                //柱状图
                RectF rect = new RectF(startX - 20, toY(data[i]), startX + 20, this.getHeight() - margin);
                paint.setColor(colorList.get(i));
                canvas.drawRect(rect, paint);
                //绘制单数值
                paintValue.setColor(colorList.get(i));
                canvas.drawText(data[i] + "", xPoint + i * xScale, toY(data[i]) - 5, paintValue);
            }
            int startX = xPoint + currentIndex * xScale;
            currentPaint -= 5;//速度
            RectF rect = new RectF(startX - 20, currentPaint, startX + 20, this.getHeight() - margin);//绘制柱状图的
            paint.setColor(colorList.get(currentIndex));
            canvas.drawRect(rect, paint);
            paintValue.setColor(colorList.get(currentIndex));
            canvas.drawText(data[currentIndex] + "", xPoint + currentIndex * xScale, currentPaint - 5, paintValue);
            if (currentPaint > toY(data[currentIndex])) {
                invalidate();
            } else {
                if (currentIndex < data.length - 1) {
                    currentIndex++;
                    currentPaint = 0;
                    currentPaint = this.getHeight() - margin;
                    invalidate();
                }
            }
        } else {
            currentIndex = 0;
            currentPaint = this.getHeight() - margin;
            invalidate();
        }
    }

    /**
     * 数据按比例转坐标
     */
    private float toY(float num) {
        float y;
        try {
            float a = num / percent;
            y = yPoint - a * yScale;
        } catch (Exception e) {
            return 0;
        }
        return y;
    }

}

使用:

 String[] xLabel = {"听课", "打卡", "分享", "评论", "创圈", "入圈", "其他"};
        float[] data = {23, 45, 32, 28, 65, 78, 99};
        List<Integer> colors = new ArrayList<>(mColors.length);
        for (int s : mColors) {
            colors.add(s);
        }
curveChart.addView(new CustomBarChart(this, xLabel, data, colors));

其中curveChart是线性布局或者相对布局都可以。

猜你喜欢

转载自blog.csdn.net/qq_16247851/article/details/86165564