基于MPAndroidChart的自定义LineChart(一)----节点绘制叉号+分段绘制背景

基于MPAndroidChart的自定义LineChart(一)----节点绘制叉号+分段绘制背景_第1张图片

MPAndroidChart是Android平台上一款强大易用的图表库,支持线状图、柱状图、散点图等八种图表类型和缩放、拖动(平移)、选择等手势,还支持动画和高亮等功能。但是别人给好的功能毕竟只能满足一般功能,一个程序员最基本的能力就应该是根据需求做出自定义的功能了,这里我对MPAndroidChart进行一些改造,MPAndroidChart只能在节点绘制圆形,现在要给它加上绘制叉号的功能。另外,本来MPAndroidChart的背景只能设置整个一大块背景,现在我加上了按行设置背景色的功能。

效果如图:

基于MPAndroidChart的自定义LineChart(一)----节点绘制叉号+分段绘制背景_第2张图片

节点的细节部分:

基于MPAndroidChart的自定义LineChart(一)----节点绘制叉号+分段绘制背景_第3张图片

功能实现

继承LineChart

自定义LineChart的第一步是要继承LineChart,实现其构造方法。然后重写onDraw方法,在onDraw方法中,再绘制背景,绘制叉号,绘制图表。这里要注意绘制的顺序,从下到上,一层层叠加。

    /**
     * 重写onDraw方法,注意绘制顺序,先绘制背景色,再绘制叉号,最后绘制图表
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        drawBgColor(canvas);
        drawCross(canvas);
        super.onDraw(canvas);
        Log.i(TAG, "onDraw");
    }

画背景

为了让代码看起来更直观,我先创建了一个类BgColor,其中包含start,stop和color三个属性。

/**
 * Created by xiaoniu on 2017/4/10.
 * BgColor是设置背景的单位,创建时需要传入起点和终点的值,还有要设置的颜色
 * 如要把纵坐标20-40的背景设为红色,就新建一个BgColor
 * new BgColor(20,40,Color.RED)
 */

public class BgColor {

    /**
     * @param start 起始点
     * @param stop 结束点
     * @param color 颜色
     */
    public BgColor( float start, float stop,int color) {
        this.start = stop;
        this.stop = start;
        this.color = color;
    }

    private float start;
    private float stop;
    private int color;

    public float getStart() {
        return start;
    }

    public void setStart(float start) {
        this.start = start;
    }

    public float getStop() {
        return stop;
    }

    public void setStop(float stop) {
        this.stop = stop;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }
}

三个属性分别对应起始点,结束点和颜色。然后将自己需要设置的背景都放到一个List中。

    /**
     * 分段背景设置
     * @return 每条背景的组合
     */
    private ArrayList getBg() {
        ArrayList bgList = new ArrayList<>();

        bgList.add(new BgColor(10, 20, Color.YELLOW));//参数信息:纵坐标从0到20设置颜色为黄色
        bgList.add(new BgColor(20, 40, 0xFF00FF00));//支持16进制颜色
        bgList.add(new BgColor(40, 70, Color.BLUE));
        bgList.add(new BgColor(70, 80, Color.RED));
        return bgList;
    }

别忘了给图表设置绘制背景的属性,之后再把数据传给图表。

//给表格背景添加颜色
mChart.setDrawBgColor(true);
//设置背景颜色的属性
mChart.setBgColor(getBg());

而在自定义LineChart的drawBgColor方法中,就是从List中取出每个BgColor,获得其start和stop,再根据MPAndroidChart提供的能够将图表上的值转换为像素坐标点的方法getPixelForValues,得到需要绘制背景的左下角和右上角的坐标,用canvas画矩形就可以了。

private void drawBgColor(Canvas canvas) {
        if (enableDrawBgColor) {
            if (!bgList.isEmpty()) {
                Paint paint = new Paint();
                for (BgColor r : bgList
                        ) {
                    MPPointD pStart = this.getPixelForValues(this.getXChartMin(), r.getStart(), YAxis.AxisDependency.LEFT);//左下角
                    MPPointD pStop = this.getPixelForValues(this.getXChartMax(), r.getStop(), YAxis.AxisDependency.LEFT);//右上角
                    paint.setColor(r.getColor());
                    canvas.drawRect(new RectF((float) pStart.x, (float) pStart.y, (float) pStop.x, (float) pStop.y), paint);
                }
            }else {
                Log.i(TAG, "No BgColor to Draw");
            }
        }
    }

画叉号

画叉号之前要得到节点的数据,同样是利用getPixelForValues将图表上的值转化为像素坐标点

private void drawCross(Canvas canvas) {

        if (enableDrawCross) {
            if (this.getData() != null) {
                LineDataSet set = (LineDataSet) this.getData().getDataSetByIndex(0);
                list = set.getValues();
                set.setDrawCircles(false);
                LineData data = new LineData(set);
                this.setData(data);
                for (Entry e : list
                        ) {
                    MPPointD p = this.getPixelForValues(e.getX(), e.getY(), YAxis.AxisDependency.LEFT);
                    drawNode(canvas, (float) p.x, (float) p.y);
                }
            }else{
                Log.i(TAG, "No Data to Draw");
            }
        }
    }

画叉号就是绘制两个互相垂直的直线,有了像素坐标点和canvas也就很简单了。

    private void drawNode(Canvas canvas, float x, float y) {
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(crossWidth);
        canvas.drawLine(x - crossLength / 2, y - crossLength / 2, x + crossLength / 2, y + crossLength / 2, paint);
        canvas.drawLine(x - crossLength / 2, y + crossLength / 2, x + crossLength / 2, y - crossLength / 2, paint);
    }

END

细节比较粗糙,以后再完善,欢迎评论交流。

最后附上github代码:https://github.com/xiaoniu/CrossNodeLineChart

你可能感兴趣的:(基于MPAndroidChart的自定义LineChart(一)----节点绘制叉号+分段绘制背景)