仿余额宝折线图

仿余额宝折线图

完整代码

github 地址https://github.com/lpy19930103/AndroidLineChart

效果图

/**
 * Created with Android Studio.
 * User: lipy
 * 折线图
 */
public class CommonLineChartView extends View implements View.OnTouchListener {

    private Surface surface;
    private String[] XLabels;
    private String[] YLabels;
    private BigDecimal perlabelBig;
    private BigDecimal ylabelBig1;
    private float[] data;
    private String title;
    private String content;
    private static Bitmap mBitmapBg;
    private Bitmap mCreatBitmap;
    private Drawable mDrawableTip;
    private Drawable mDrawableDot;
    private Boolean isHasDto = true;


    public CommonLineChartView(Context context) {
        this(context, null);
    }

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

    private void init() {
        surface = new Surface();
        mDrawableDot = getResources().getDrawable(圆点图);
        mDrawableTip = getResources().getDrawable(背景图 渐变色);
        if (mBitmapBg == null) {
            mBitmapBg = BitmapFactory.decodeResource(getResources(), R.drawable.transverse_lined_diagram);
        }
        surface.density = getResources().getDisplayMetrics().density;
        setBackgroundColor(surface.bgColor);
        setOnTouchListener(this);

    }

    public CommonLineChartView(Context context, AttributeSet attrs, int defStyle) {
        this(context, null);
    }

    private int YCoord(float y0) {
        if (y0 < 0)
            return -1;
        float y;
        y = y0;
        try {
            if (perlabelBig.floatValue() == 0 || y == 0) {
//                return surface.YPoint - surface.YScale;//最小值
                return surface.YPoint;//底边
            }
            if (y < ylabelBig1.floatValue()) {//小于最小值的情况
                return surface.YPoint - new BigDecimal(y).divide(ylabelBig1, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(yScaleBig).intValue();
            }
            return surface.YPoint - surface.YScale - new BigDecimal(y).subtract(ylabelBig1).divide(perlabelBig, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(yScaleBig).intValue();
        } catch (Exception e) {

        }
        return (int) y;
    }

    private int getXTextSpace(int i) {
        if (i == 0) return -10;
        if (i >= data.length - 1)
            return -10;
        if (data[i] > data[i - 1] && data[i] > data[i + 1]) return -10;
        if (data[i] < data[i - 1] && data[i] < data[i + 1]) return -10;
        if (data[i] > data[i - 1] && data[i] < data[i + 1]) return 0;
        if (data[i] < data[i - 1] && data[i] > data[i + 1]) return 0;
        return -10;
    }

    private int getYTextSpace(int i) {
        if (i == 0) return -10;
        if (i >= data.length - 1)
            return -10;
        if (data[i] > data[i - 1] && data[i] > data[i + 1]) return -10;
        if (data[i] < data[i - 1] && data[i] < data[i + 1]) return 20;
        if (data[i] > data[i - 1] && data[i] < data[i + 1]) return 20;
        if (data[i] < data[i - 1] && data[i] > data[i + 1]) return -10;
        return -10;
    }

    private BigDecimal yScaleBig;

    @Override
    protected void onDraw(Canvas canvas) {
        if (XLabels == null || YLabels == null) {
            if (!StringUtil.isEmpty(title) && !StringUtil.isEmpty(content) ) {
                canvas.drawText(title, surface.XPoint - DensityUtil.dp2px(getContext(), 20), surface.marginTop + DensityUtil.dp2px(getContext(), 6), surface.titlePaint);
                canvas.drawText(content, surface.XPoint - DensityUtil.dp2px(getContext(), 18), surface.marginTop + DensityUtil.dp2px(getContext(), 22), surface.titlePaint);
                super.onDraw(canvas);
            }
            return;
        }
        surface.XScale = (surface.XLength / (XLabels.length)) + DensityUtil.dp2px(getContext(), 10);
        surface.YScale = surface.YLength / (YLabels.length);
        yScaleBig = new BigDecimal(surface.YScale);
        int startX = surface.XPoint - DensityUtil.dp2px(getContext(), 20);
        float xTop = surface.xyTextPaint.measureText("0") + DensityUtil.dp2px(getContext(), 10);
        Rect rectF1 = new Rect(startX, surface.YPoint - YLabels.length * surface.YScale, surface.XPoint + surface.XLength, surface.YLength);
        for (int i = 0; i < YLabels.length && i * surface.YScale < surface.YLength; i++) {
            canvas.drawLine(startX, surface.YPoint - i * surface.YScale, surface.XPoint + surface.XLength + DensityUtil.dp2px(getContext(), 5), surface.YPoint - i * surface.YScale, surface.gridPaint);
            try {
                //值格式化
                String yLabel = YLabels[i];
                if (formatData != null && !"".equals(yLabel))
                    yLabel = formatData.format(yLabel);
                //y刻度值
                canvas.drawText(yLabel, startX + 5,
                        surface.YPoint - i * surface.YScale - 5, surface.xyTextPaint);
            } catch (Exception e) {
            }
        }

        for (int i = 0; i < XLabels.length && i * surface.XScale < surface.width; i++) {
            if (i == 0) {
                canvas.drawLine(startX, surface.YPoint, startX, surface.YPoint - surface.YLength, surface.gridPaint);

            } else {
                //x刻度线
                canvas.drawLine(startX + i * surface.XScale, surface.YPoint, startX + i * surface.XScale, surface.YPoint - surface.YLength, surface.gridPaint);
            }
            try {
                //x刻度
                canvas.drawText(XLabels[i], startX + i * surface.XScale - DensityUtil.dp2px(getContext(), 5), surface.YPoint + xTop, surface.xyTextPaint);
                int yCoord = YCoord(data[i]);
                if (i > 0 && YCoord(data[i - 1]) != -1 && yCoord != -1) {//0数据连线
                    canvas.drawLine(startX + (i - 1) * surface.XScale,
                            YCoord(data[i - 1]), startX + i * surface.XScale, yCoord, surface.linePaint);

                }

                if (data[i] != -1) {
                    isHasDto = true;
                    Path path = new Path();
                    path.moveTo(startX + (i - 1) * surface.XScale, surface.YPoint);
                    path.lineTo(startX + (i) * surface.XScale, surface.YPoint - 10);
                    path.lineTo(startX + (i) * surface.XScale, YCoord(data[i]));
                    path.lineTo(startX + (i - 1) * surface.XScale, YCoord(data[i - 1]));
                    path.close();
                    ShapeDrawable shapeDrawable = new ShapeDrawable(new PathShape(path, surface.XLength, DensityUtil.dp2px(getContext(), 260)));
                    if (mCreatBitmap == null) {
                        mCreatBitmap = Bitmap.createBitmap(mBitmapBg, startX, surface.YPoint - YLabels.length * surface.YScale, surface.XLength, DensityUtil.dp2px(getContext(), 260));
                    }
                    BitmapShader bitmapShader = new BitmapShader(mCreatBitmap,
                            Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
                    shapeDrawable.getPaint().setShader(bitmapShader);
                    shapeDrawable.setBounds(rectF1);
                    canvas.drawPath(path, shapeDrawable.getPaint());
                    canvas.drawCircle(startX + i * surface.XScale, yCoord, 0, surface.pointPaint);
                    if (i == (XLabels.length - 1)) {
                        String popText_ = data[i] + "";
                        float perCharX = surface.textPaint.measureText(popText_.charAt(0) + "");
                        float textX = perCharX * (popText_).length() / 2.0f;
                        canvas.drawBitmap(drawableToBitamp(mDrawableTip, DensityUtil.dip2px(getContext(), 35), DensityUtil.dip2px(getContext(), 24)), startX + i * surface.XScale - textX - DensityUtil.dp2px(getContext(), 15), yCoord - perCharX - 2 * surface.marginPopContent - DensityUtil.dp2px(getContext(), 15), surface.pointPaint);
                        if (formatData != null) {
                            popText_ = formatData.format(popText_);
                        }
                        //值显示
                        canvas.drawText(popText_, startX + i * surface.XScale - textX - DensityUtil.dp2px(getContext(), 10), yCoord - DensityUtil.dp2px(getContext(), 5) - (data[i] == 0 ? (surface.marginPopContent + 4) : surface.marginPopContent) - DensityUtil.dp2px(getContext(), 7), surface.textPaint);
                        canvas.drawBitmap(drawableToBitamp(mDrawableDot, DensityUtil.dp2px(getContext(), 15), DensityUtil.dp2px(getContext(), 15)), startX + i * surface.XScale - DensityUtil.dp2px(getContext(), 8), yCoord - DensityUtil.dp2px(getContext(), 8), surface.pointPaint);
                    }

                } else {
                    if (i == (XLabels.length - (XLabels.length - i))) {
                        if (isHasDto) {
                            int yCoord_ = YCoord(data[i - 1]);
                            String popText_ = data[i - 1] + "";
                            float perCharX = surface.textPaint.measureText(popText_.charAt(0) + "");
                            float textX = perCharX * (popText_).length() / 2.0f;
                            canvas.drawBitmap(drawableToBitamp(mDrawableTip, DensityUtil.dip2px(getContext(), 35), DensityUtil.dip2px(getContext(), 24)),
                                    startX + (i - 1) * surface.XScale - textX - DensityUtil.dp2px(getContext(), 17), yCoord_ - perCharX - 2 * surface.marginPopContent - DensityUtil.dp2px(getContext(), 15), surface.pointPaint);
                            if (formatData != null) {
                                popText_ = formatData.format(popText_);
                            }
                            canvas.drawText(popText_, startX + (i - 1) * surface.XScale - textX - DensityUtil.dp2px(getContext(), 12), yCoord_ - DensityUtil.dp2px(getContext(), 5) - (data[i] == 0 ? (surface.marginPopContent + 4) : surface.marginPopContent) - DensityUtil.dp2px(getContext(), 8), surface.textPaint);
                            canvas.drawBitmap(drawableToBitamp(mDrawableDot, DensityUtil.dp2px(getContext(), 15), DensityUtil.dp2px(getContext(), 15)), startX + (i - 1) * surface.XScale - DensityUtil.dp2px(getContext(), 10), yCoord_ - DensityUtil.dp2px(getContext(), 8), surface.pointPaint);
                            isHasDto = false;
                        }
                    }
                }
            } catch (Exception e) {
            }
        }

        canvas.drawText(title, surface.XPoint - DensityUtil.dp2px(getContext(), 20), surface.marginTop + DensityUtil.dp2px(getContext(), 6), surface.titlePaint);
        super.onDraw(canvas);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (changed) {
            surface.init();
        }
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        surface.height = getMeasuredHeight();
        surface.width = getMeasuredWidth();
    }

    public void setData(String[] XLabels, String[] YLabels, float[] data, String title) {
        this.XLabels = XLabels;
        this.YLabels = YLabels;
        this.data = data;
        this.title = title;
        this.ylabelBig1 = new BigDecimal(this.YLabels[1]);
        this.perlabelBig = new BigDecimal(this.YLabels[2]).subtract(ylabelBig1);
        invalidate();
    }

    public void setData(String title, String content) {
        this.title = title;
        this.content = content;
        invalidate();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }

    private class Surface {
        public float density;
        public int width;
        public int height;
        public int XPoint = DensityUtil.dp2px(getContext(), 35);
        public int YPoint;
        public int XScale = DensityUtil.dp2px(getContext(), 27);
        public int YScale = DensityUtil.dp2px(getContext(), 30);
        public int XLength;
        public int YLength;
        public int marginBottom = DensityUtil.dp2px(getContext(), 25);
        public int marginTop = DensityUtil.dp2px(getContext(), 17);
        public int marginPopContent = DensityUtil.dp2px(getContext(), 5);


        public int bgColor = getResources().getColor(R.color.white);
        public int titleColor = getResources().getColor(R.color.common_text_gray);
        public int lineColor = getResources().getColor(R.color.common_top_bg);
        public int textColor = Color.WHITE;
        public int pointColor = lineColor;
        public int axisXColor = getResources().getColor(R.color.common_line_chartview_scal);
        public int axisYColor = getResources().getColor(R.color.common_top_bg);
        //   public int gridColor = Color.GRAY;
        public int gridColor = getResources().getColor(R.color.common_point_line);

        public Paint titlePaint;
        public Paint textPaint;
        public Paint xyTextPaint;
        public Paint linePaint;
        public Paint pointPaint;
        public Paint axisXPaint;
        public Paint axisYPaint;
        public Paint axisYDataPaint;
        public Paint gridPaint;

        public void init() {
            YPoint = height - marginBottom;
            XLength = width - XPoint - DensityUtil.dp2px(getContext(), 20);

            titlePaint = new Paint();
            titlePaint.setColor(titleColor);
            titlePaint.setAntiAlias(true); //去掉锯齿
            titlePaint.setTextSize(DensityUtil.sp2px(getContext(), 14));
            YLength = YPoint - (int) titlePaint.getTextSize() - marginTop;
//            titlePaint.setTypeface(Typeface.DEFAULT_BOLD);

            textPaint = new Paint();
            textPaint.setColor(textColor);
            textPaint.setAntiAlias(true);
            textPaint.setTextSize(DensityUtil.sp2px(getContext(), 13));

            xyTextPaint = new Paint();
            xyTextPaint.setColor(axisXColor);
            xyTextPaint.setAntiAlias(true);
            xyTextPaint.setTextSize(DensityUtil.sp2px(getContext(), 10));
            xyTextPaint.setTypeface(Typeface.DEFAULT_BOLD);

            linePaint = new Paint();
            linePaint.setColor(lineColor);
            linePaint.setStyle(Paint.Style.STROKE);
            linePaint.setAntiAlias(true);
            linePaint.setStrokeWidth(5);

            pointPaint = new Paint();
            pointPaint.setColor(pointColor);
            pointPaint.setStyle(Paint.Style.STROKE);
            pointPaint.setAntiAlias(true);
            pointPaint.setStrokeWidth(10);

            axisXPaint = new Paint();
            axisXPaint.setColor(axisXColor);
            axisXPaint.setStyle(Paint.Style.STROKE);
            axisXPaint.setAntiAlias(true);
            axisXPaint.setStrokeWidth(4);

            axisYPaint = new Paint();
            axisYPaint.setColor(gridColor);
            axisYPaint.setStyle(Paint.Style.STROKE);
            axisYPaint.setAntiAlias(true);
            axisYPaint.setStrokeWidth(4);

            axisYDataPaint = new Paint();
            axisYDataPaint.setColor(pointColor);
            axisYDataPaint.setStyle(Paint.Style.FILL);
            axisYDataPaint.setAntiAlias(true);
            axisYDataPaint.setStrokeWidth(4);

            gridPaint = new Paint();
            gridPaint.setColor(gridColor);
            gridPaint.setStyle(Paint.Style.STROKE);
            gridPaint.setAntiAlias(true);
            gridPaint.setStrokeWidth(2);

        }

    }

    private FormatData formatData;

    public FormatData getFormatData() {
        return formatData;
    }

    public void setFormatData(FormatData formatData) {
        this.formatData = formatData;
    }

    public interface FormatData {
        public String format(String data);
    }

    private Bitmap bitmap;

    private Bitmap drawableToBitamp(Drawable drawable, int w, int h) {
//        int w = drawable.getIntrinsicWidth();
//        int h = drawable.getIntrinsicHeight();
        Bitmap.Config config =
                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                        : Bitmap.Config.RGB_565;
        bitmap = Bitmap.createBitmap(w, h, config);
        //注意,下面三行代码要用到,否在在View或者surfaceview里的canvas.drawBitmap会看不到图
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * 格式化数据
     */
    public String[] getWeekYdata(String maxValue, String minValue) {
        String[] temp = new String[]{"", "2", "3", "4", "5", "6"};
        if (maxValue != null && minValue != null) {
            BigDecimal max = new BigDecimal(maxValue).multiply(new BigDecimal(100));
            BigDecimal min = new BigDecimal(minValue).multiply(new BigDecimal(100)).setScale(3, BigDecimal.ROUND_DOWN);
            BigDecimal per = max.subtract(min).divide(new BigDecimal(4), 3, BigDecimal.ROUND_FLOOR);
            for (int i = 0; i < 5; i++) {
                temp[i + 1] = min.add(per.multiply(new BigDecimal(i + "")), new MathContext(3, RoundingMode.HALF_EVEN)).toString();
            }
            temp[5] = max.setScale(2, BigDecimal.ROUND_UP).toString();
        }
        return temp;
    }
}

初始化

private void initLineChartView() {
        commonLineChartView = (CommonLineChartView) refreshListViewInflate.findViewById(R.id.finance_chart_line);
        commonLineChartView.setFormatData(new CommonLineChartView.FormatData() {
            @Override
            public String format(String data) {
                if (data == null || "".equals(data)) {
                    return data;
                }
                DecimalFormat df = new DecimalFormat("###.00");
                String seres = df.format(Float.parseFloat(data));
                if (seres.startsWith(".")) {
                    seres = "0" + seres;
                }
                return seres;
            }
        });
    }

数据

 private void lineChartViewDataLeft() {
        String[] xdate = new String[]{"", "", "", "", "", "", ""};
        String[] ydata = commonLineChartView.getWeekYdata(param_.getMaxValue(), param_.getMinValue());
//        float[] data1 = new float[]{5.00f, 5.00f, 5.00f, 5.00f, 5.00f, 5.00f, -1f};
        commonLineChartView.setData(xdate, ydata, data, getString(R.string.finance_xjg_linechar_default_title));
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值