Android折线图的探讨

  概括

           最近做一个项目,有个需要折线图的需求,刚开始自己很犯懒,就想着随便从网上找个用就用,后来发现网上的介绍和案例,都是各有千秋,对我来说用他们都不是那么的完美,

比如一线介绍简单的画法,确实介绍的太简单了,如果改造他们的,太麻烦,真不如我自己重写,也有比较强大的三方库,比如HelloCharts和MPAndroidChart等,他们不但能满足画折线基本需要,而且还能实现了负责的动画功能,不过他们也有自己的短处,比如HelloCharts的y轴刻度不能自定义,MPAndroidChart折线显示数据的显示不好自定义,可能时间有限,我也没深入研究他们的源码,想来想去还是自己写个吧,毕竟他们体积还是有点大,我只是需要一个简单折线图,


 原理

         其实画折线图的原理很简单,就是在ondraw里利用画布Cavans根据你的需要,确定好X轴和Y轴,然后画出来,在这个过程中第一点就是要确认你的原点坐标,第二点就是你的布局总大小和你的X的长度和Y轴的高度,第三部就是X轴和Y轴分几等分,然后根据这几点画出你需要的折线,其中细节算法大家可以根据自己的项目需要来定义,好吧闲话少说咱们直接上代码吧。



代码:

  

canvas.drawLine(mXor, mYor, mXor, mYor - mHeight, mPaint == null ? mDefaultPaint : mPaint);//y//y轴上的刻度
List<Float> yLineValue = new ArrayList<>();
yLineValue.add(4f);
yLineValue.add(4 + mRato);
yLineValue.add(4 + mRato * 2);
yLineValue.add(4 + mRato * 3);
yLineValue.add(4 + mRato * 4);
yLineValue.add(4 + mRato * 5);
for (int i = 0; i < mLineNum + 1; i++) {
    //y轴刻度
    canvas.drawText("" + yLineValue.get(i), mXor - dp2px(15), mYor - mYSpace * i,
            mTextPaint == null ? mDefaultTextPaint : mTextPaint);
    if ((i != 0) && mIsYGridLine) {
        canvas.drawLine(mXor - 5, mYor - mYSpace * i, mXor + mWidth,
                mYor - mYSpace * i, mPaint == null ? mDefaultPaint : mPaint);//垂直Y轴的线非x    }
}
canvas.drawLine(mXor, mYor, mXor + mWidth, mYor, mPaint == null ? mDefaultPaint : mPaint);//x//x轴上的刻度线
for (int j = 1; j < 7; j++) {
    canvas.drawLine(mXor + mXSpace * j, mYor, mXor + mXSpace * j, mYor + 5, mPaint == null ? mDefaultPaint : mPaint);
    if (mIsXGridLine) {
        canvas.drawLine(mXor + mXSpace * j, mYor, mXor + mXSpace * j, mYor - mHeight, mPaint == null ? mDefaultPaint : mPaint);
        //垂直x轴的线,非Y    }
}
//x轴刻度线上的值
List<String> xLineValues = getDates();
for (int j = 0; j < xLineValues.size(); j++) {
    canvas.drawText(xLineValues.get(j), mXor + mXSpace * j - mTextSize * 1.5f, mYor + dp2px(15),
            mTextPaint == null ? mDefaultTextPaint : mTextPaint);
}

//画曲线
List<Float> xyLineValue = new ArrayList<>();
xyLineValue.add(4.53f);
xyLineValue.add(4.50f);
xyLineValue.add(4.55f);
xyLineValue.add(4.57f);
xyLineValue.add(4.53f);
xyLineValue.add(4.60f);
xyLineValue.add(4.62f);
if (mIsFill) {
    Path linePath = new Path();
    linePath.moveTo(mXor + 4, mYor - 2);
    for (int i = 0; i < xyLineValue.size(); i++) {
        linePath.lineTo(mXor + mXSpace * i, mYor - createLineValue(xyLineValue.get(i)));
    }
    linePath.lineTo(mXor + mWidth - 4, mYor - 2);

    canvas.drawPath(linePath, mFillPaint == null ? mDefaultFillPaint : mFillPaint);
    if (mValuePaint == null) {
        mDefaultValuePaint.setStrokeWidth(6);
    } else {
        mValuePaint.setStrokeWidth(6);
    }
}
Path linePath1 = new Path();
for (int i = 0; i < xyLineValue.size(); i++) {
    if (i == 0) {
        linePath1.moveTo(mXor, mYor - createLineValue(xyLineValue.get(i)));
    } else {
        linePath1.lineTo(mXor + mXSpace * i, mYor - createLineValue(xyLineValue.get(i)));
    }

}

canvas.drawPath(linePath1, mValuePaint == null ? mDefaultValuePaint : mValuePaint);
for (int i = 0; i < xyLineValue.size(); i++) {
    //画曲线上的点

    if (mIsShowValues) {
        canvas.drawText("" + xyLineValue.get(i), mXor + mXSpace * i - mTextSize * 1.5f,
                mYor - createLineValue(xyLineValue.get(i)) - dp2px(8),
                mTextPaint == null ? mDefaultTextPaint : mTextPaint);

        float xCenter = mXor + mXSpace * i;
        float yCenter = mYor - createLineValue(xyLineValue.get(i));
        RectF rectF1 = new RectF(xCenter - dp2px(2), yCenter - dp2px(2), xCenter + dp2px(2), yCenter + dp2px(2));
        switch (mPointType) {
            case HOLLOW_CIRCLE:
                canvas.drawArc(rectF1, 0, 360, false, mPointPaint == null ? mDefaultPointPaint : mPointPaint);
                break;
            case SLIDE_CIRCLE:
                mDefaultPointPaint.reset();
                mDefaultPointPaint.setColor(Color.RED);
                mDefaultPointPaint.setStrokeWidth(2f);
                mDefaultPointPaint.setStyle(Paint.Style.FILL);
                canvas.drawArc(rectF1, 0, 360, true, mPointPaint == null ? mDefaultPointPaint : mPointPaint);
                break;
            case HOLLOW_SQUARE:
                canvas.drawRect(rectF1, mPointPaint == null ? mDefaultPointPaint : mPointPaint);
                break;
            case SLIDE_SQUARE:
                mDefaultPointPaint.reset();
                mDefaultPointPaint.setColor(Color.RED);
                mDefaultPointPaint.setStrokeWidth(2f);
                mDefaultPointPaint.setStyle(Paint.Style.FILL);
                canvas.drawRect(rectF1, mPointPaint == null ? mDefaultPointPaint : mPointPaint);
                break;

            default:
                canvas.drawArc(rectF1, 0, 360, false, mPointPaint == null ? mDefaultPointPaint : mPointPaint);
                break;
        }

    }
}
上面是画折线的核心代码

源码已经上传到github:https://github.com/XinRan5312/QXSimpleLineChart

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值