利用canvas画rect画出条形统计图

功能:叠加显示两组数据,需要先将纵坐标值换算成到顶部的距离值,因此先计算出k和b。另外maxY和minY的更新可以让图表自适应数据的变化。

public class SimpleBarChartView extends View {

    private int maxY = 0;
    private int minY = 0;
    private double k = 0;
    private double b = 0;
    private int chartHeight = 500;
    private int blackHeight = 20;

    private int[] foregroudTraffic;
    private int[] backgroundTraffic;
    private int[] yLabels =
            new int[]{80000, 60000, 40000, 20000, 0};
    private String[] xTitles =
            new String[]{"1", "2", "3", "4", "5", "6", "7"};


    public SimpleBarChartView(Context context, int[] foregroudTraffic, int[] backgroundTraffic, String[] xTitles) {
        super(context);
        init(context, null);
        this.foregroudTraffic = foregroudTraffic;
        this.backgroundTraffic = backgroundTraffic;
        this.xTitles = xTitles;
        updateKandB();
        updateYLabels();
        this.postInvalidate();  //可以子线程 更新视图的方法调用。
    }


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

    //  坐标轴 轴线 画笔:
    private Paint axisLinePaint;
    //  坐标轴水平内部 虚线画笔
    private Paint hLinePaint;
    //  绘制文本的画笔
    private Paint titlePaint;
    //  矩形画笔 柱状图的样式信息
    private Paint recPaint;


    private void init(Context context, AttributeSet attrs) {

        axisLinePaint = new Paint();
        hLinePaint = new Paint();
        titlePaint = new Paint();
        recPaint = new Paint();
        axisLinePaint.setColor(Color.DKGRAY);
        hLinePaint.setColor(Color.LTGRAY);
        titlePaint.setColor(Color.BLACK);

    }


    private void updateMinYAndMaxY() {
        if (foregroudTraffic != null && foregroudTraffic.length > 0) {
            int thisCount = foregroudTraffic.length;
            for (int i = 0; i < thisCount; i++) {
                minY = foregroudTraffic[i]+backgroundTraffic[i] < minY ? foregroudTraffic[i]+backgroundTraffic[i] : minY;
                maxY = foregroudTraffic[i]+backgroundTraffic[i] > maxY ? foregroudTraffic[i]+backgroundTraffic[i] : maxY;
            }
        }

    }

    private void updateYLabels() {
        for (int i = 0; i < yLabels.length; i++) {
            yLabels[i] = (yLabels.length - 1 - i) * (maxY) / (yLabels.length - 1);
        }
    }

    private void updateKandB() {
        updateMinYAndMaxY();
        k = (chartHeight - blackHeight) / (double) (minY - maxY);
        b = blackHeight - k * maxY;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        canvas.drawLine(100, 10, 100, chartHeight, axisLinePaint);
        canvas.drawLine(100, chartHeight, width - 10, chartHeight, axisLinePaint);
        int leftHeight = chartHeight - 20;// 左侧外周的 需要划分的高度:
        int hPerHeight = leftHeight / 4;
        hLinePaint.setTextAlign(Align.CENTER);
        for (int i = 0; i < 4; i++) {
            canvas.drawLine(100, 20 + i * hPerHeight, width - 10, 20 + i * hPerHeight, hLinePaint);
        }

        FontMetrics metrics = titlePaint.getFontMetrics();
        int descent = (int) metrics.descent;
        titlePaint.setTextAlign(Align.RIGHT);
        for (int i = 0; i < yLabels.length; i++) {
            canvas.drawText("" + yLabels[i], chartHeight / 4, 20 + i * hPerHeight + descent, titlePaint);
        }
        int xAxisLength = width - 110;
        int columCount = xTitles.length + 1;
        int step = xAxisLength / columCount;
        for (int i = 0; i < columCount - 1; i++) {
            canvas.drawText(xTitles[i], 100 + step * (i + 1), chartHeight + 20, titlePaint);
        }

        if (foregroudTraffic != null && foregroudTraffic.length > 0) {
            int thisCount = foregroudTraffic.length;
            for (int i = 0; i < thisCount; i++) {
                int value = foregroudTraffic[i]+backgroundTraffic[i];
                int topValue = (int) (k * value + b);
                recPaint.setColor(0xFF1078CF);
                Rect rect = new Rect();
                rect.left = 100 + step * (i + 1) - 10;
                rect.right = 100 + step * (i + 1) + 10;
                rect.top = topValue;
                rect.bottom = chartHeight;
                canvas.drawRect(rect, recPaint);
            }
        }


        if (backgroundTraffic != null && backgroundTraffic.length > 0) {
            int thisCount = backgroundTraffic.length;


            for (int i = 0; i < thisCount; i++) {
                int value = backgroundTraffic[i];
                int topValue = (int) (k * value + b);
                recPaint.setColor(0xFFAA1122);
                Rect rect = new Rect();
                rect.left = 100 + step * (i + 1) - 10;
                rect.right = 100 + step * (i + 1) + 10;
                rect.top = topValue;
                rect.bottom = chartHeight;
                canvas.drawRect(rect, recPaint);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值