MPAndroidChart的简单封装

框架地址:https://github.com/PhilJay/MPAndroidChart

因为需求中大部分图表的样式都差不多,只有里面的数据做了变化,而使用图表的时候又需要对图表进行各种各样的配置,所以对图表框架进一步封装是有必要的。
我这里将图表的配置写在一个类中,将常用的方法(数据,图表颜色,描述,等等)令写方法出来设置。。因为使用的是建造者模式,可以根据需求定义。这里封装了线性图、饼状图、柱状图、雷达图。

写了一个数据类ChartValue用来存放所需数据的XY值,然后将数据设置也封装到了,配置类中,图表构建完成后获得图表的View对象,填充到想要的布局中去。

具体实现

ChartView数据类:用来存放X,Y轴值。

package cn.xiaolongonly.mpchartsample.bean;

/**
 * @author xiaolong
 * @version v1.0
 * @function <描述功能>
 * @date 2016/9/22-17:32
 */
public class ChartValue<T> {
    public String xVal;
    public T yVal;

    public ChartValue() {
    }

    public ChartValue(String xVal, T yVal) {
        this.xVal = xVal;
        this.yVal = yVal;
    }
}

Item项:每个需要的图表构建一个item对象,存放固定配置和数据设置


package cn.xiaolongonly.mpchartsample.chart.item;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;

import java.util.ArrayList;
import java.util.List;

import cn.xiaolongonly.mpchartsample.R;
import cn.xiaolongonly.mpchartsample.bean.ChartValue;
import cn.xiaolongonly.mpchartsample.chart.markview.DataMarkView;
import cn.xiaolongonly.mpchartsample.chart.util.ColorTemplate;

public class LineChartItem extends BaseChartItem {
    private String xDesc;
    private String yDesc;
    private DataMarkView dataMarkView;

    public LineChartItem(ChartData cd, Context c, IAxisValueFormatter iAxisValueFormatter) {
        super(cd, c, iAxisValueFormatter);
    }

    public LineChartItem(ChartData cd, Context c, DataMarkView dataMarkView, IAxisValueFormatter iAxisValueFormatter) {
        super(cd, c, iAxisValueFormatter);
        this.dataMarkView = dataMarkView;
    }

    @Override
    public int getItemType() {
        return TYPE_LINECHART;
    }

    public View getView() {
        return getView(null);
    }

    public String getxDesc() {
        return xDesc;
    }

    public void setxDesc(String xDesc) {
        this.xDesc = xDesc;
    }

    public String getyDesc() {
        return yDesc;
    }

    public void setyDesc(String yDesc) {
        this.yDesc = yDesc;
    }

    @Override
    public View getView(View convertView) {

        ViewHolder holder = null;

        if (convertView == null) {

            holder = new ViewHolder();

            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.list_item_linechart, null);
            holder.chart = (LineChart) convertView.findViewById(R.id.chart);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        // apply styling

        LineChart lineChart = (LineChart) holder.chart;
        lineChart.setBackgroundColor(mContext.getResources().getColor(R.color.chart_bg));
        lineChart.getLegend().setPosition(Legend.LegendPosition.ABOVE_CHART_LEFT);
        lineChart.getLegend().setForm(Legend.LegendForm.CIRCLE);
        // 设置无数据文本提示
        lineChart.setDescription(null);
//        lineChart.setNoDataText(mContext.getResources().getString(R.string.chart_no_data));
//        lineChart.setXYDesc(xDesc, yDesc);
        if (!xDesc.equals("") || !yDesc.equals("")) {
            lineChart.setXYDesc(xDesc, yDesc, 10f, mContext.getResources().getColor(R.color.normal_black_color));
        }
        //设置单方向和双方向缩放 true x,y方向可以同时控制,false只能控制x方向的缩小放大或者Y方向的缩小放大
        lineChart.setPinchZoom(true);
        DataMarkView dataMarkView = new DataMarkView(mContext, 0, "");
        lineChart.setMarkerView(dataMarkView);
        lineChart.setDrawGridBackground(false);
        XAxis xAxis = lineChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //定制X轴是在图表上方还是下方。
        xAxis.setDrawGridLines(false);
        xAxis.setGranularity(1);//放大的时候X值不增多
        xAxis.setValueFormatter(mIAxisValueFormatter);
        if (dataMarkView != null) {
            lineChart.setMarkerView(dataMarkView);
        }
        YAxis yAxisRight = lineChart.getAxisRight();
        yAxisRight.setEnabled(false);
        YAxis yAxisLeft = lineChart.getAxisLeft();
        yAxisLeft.setAxisMinimum(0);
        // set data
        lineChart.setData((LineData) mChartData);

        // do not forget to refresh the chart
        // holder.chart.invalidate();
        lineChart.animateX(750);
        lineChart.animateY(750);

        return convertView;

    }

    public static class Builder {
        private int[] colors = ColorTemplate.PIE_COLORS;
        private String[] describles = new String[]{""};
        private String xDesc = "";
        private String yDesc = "";
        private List> charValueLists = new ArrayList<>();
        private Context context;
        private boolean isFillColor;
        private ArrayList labels = new ArrayList<>();

        public Builder(Context context) {
            this.context = context;
        }

        public Builder addChartValueList(List charValueLists) {
            this.charValueLists.add(charValueLists);
            return this;
        }

        public Builder setChartValueList(List> charValueLists) {
            this.charValueLists = charValueLists;
            return this;
        }

        public Builder setyDesc(String yDesc) {
            this.yDesc = yDesc;
            return this;
        }

        public Builder setxDesc(String xDesc) {
            this.xDesc = xDesc;
            return this;
        }

        public Builder setDescribles(String[] describles) {
            this.describles = describles;
            return this;
        }

        public Builder setColorReses(int[] colorReses) {
            this.colors = new int[colorReses.length];
            for (int i = 0; i < colors.length; i++) {
                colors[i] = context.getResources().getColor(colorReses[i]);
            }
            return this;
        }

        public Builder fillColorEnable(boolean isFillColor) {
            this.isFillColor = isFillColor;
            return this;
        }

        public LineChartItem build() {
            return build(null);
        }

        public LineChartItem build(DataMarkView dataMarkView) {
            List lineDataSets = new ArrayList<>();
            for (int listIndexOutside = 0; listIndexOutside < charValueLists.size(); listIndexOutside++) {
                ArrayList entries = new ArrayList();
                for (int listIndexInside = 0; listIndexInside < charValueLists.get(listIndexOutside).size(); listIndexInside++) {
                    entries.add(new Entry((float) listIndexInside, (float) charValueLists.get(listIndexOutside).get(listIndexInside).yVal));
                    if (listIndexOutside == 0) {
                        labels.add(charValueLists.get(listIndexOutside).get(listIndexInside).xVal);
                    }
                }
                lineDataSets.add(generateLineDataSet(entries, describles[listIndexOutside], colors[listIndexOutside % colors.length]));
            }
            IAxisValueFormatter iAxisValueFormatter = new IAxisValueFormatter() {
                @Override
                public String getFormattedValue(float value, AxisBase axis) {
                    return labels.get((int) value % labels.size());
                }
            };
            LineData cd = new LineData(lineDataSets);
            LineChartItem lineChartItem = null;
            if (dataMarkView != null) {
                lineChartItem = new LineChartItem(cd, context, dataMarkView, iAxisValueFormatter);
            } else {
                lineChartItem = new LineChartItem(cd, context, iAxisValueFormatter);
            }
            lineChartItem.setxDesc(xDesc);
            lineChartItem.setyDesc(yDesc);
            return lineChartItem;
        }

        private ILineDataSet generateLineDataSet(ArrayList entries, String describle, int color) {
            LineDataSet dataSet = new LineDataSet(entries, describle);
            dataSet.setLineWidth(2.0f);
            dataSet.setCircleRadius(3.5f);
            dataSet.setDrawCircleHole(true);//填充圆
            dataSet.setValueTextSize(9f);
            dataSet.setHighlightLineWidth(2.0f);
            dataSet.setDrawFilled(isFillColor);
            dataSet.setFillAlpha(51);
            dataSet.setFillColor(color); //填充色
            dataSet.setHighLightColor(color); //选中十字线色
            dataSet.setColor(color); //线条颜色
            dataSet.setCircleColor(color); //圆点颜色
            dataSet.setCircleColorHole(Color.WHITE);
            dataSet.setCircleHoleRadius(2.0f);
            dataSet.setDrawValues(false);
            return dataSet;
        }
    }

}

当然如果需求图表有其他样式的的话,我觉得也可以把配置信息抽取出来,通过不同的配置来设置不同的样式。

在Activity中的使用


package cn.xiaolongonly.mpchartsample.ui;

import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.List;

import cn.xiaolongonly.mpchartsample.R;
import cn.xiaolongonly.mpchartsample.base.BaseTitleActivity;
import cn.xiaolongonly.mpchartsample.bean.ChartValue;
import cn.xiaolongonly.mpchartsample.chart.item.LineChartItem;

/**
 * @author xiaolong
 * @version v1.0
 * @function <描述功能>
 * @date 2016/12/5-17:32
 */
public class LineChartActivity2 extends BaseTitleActivity {
    private RelativeLayout rlContent;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_chart;
    }

    @Override
    protected void initView() {
        rlContent = findView(R.id.rlContent);
        List chartValues = new ArrayList<>();
        chartValues.add(new ChartValue("11月", 110f));
        chartValues.add(new ChartValue("10月", 120f));
        chartValues.add(new ChartValue("9月", 100f));
        List chartValues2 = new ArrayList<>();
        chartValues2.add(new ChartValue("11月", 155f));
        chartValues2.add(new ChartValue("10月", 133f));
        chartValues2.add(new ChartValue("9月", 122f));
        LineChartItem lineChartItem = new LineChartItem.Builder(this).setxDesc("单位(月)")
                .setyDesc("单位(万)").setDescribles(new String[]{"项目支出金额"})
                .addChartValueList(chartValues).addChartValueList(chartValues2)
                .build();
        rlContent.addView(lineChartItem.getView());
    }

    @Override
    protected void setListener() {

    }

}

是不是就简单多了只要构建一个Item对象,然后将item对象的图表布局,add到View中去就可以了。

实现效果
MPAndroidChart的简单封装_第1张图片

项目github下载

总结

一直都没想到有一天我也能这么写代码,感觉代码写多了很多东西就懂了。

在最开始的时候老大让我对图表框架进行二次封装,我听的一脸懵逼,经过一段时间的思考,反复对照之前的项目,因为之前的项目的配置都写在继承的图表中,在xml布局中要将图表改成继承的图表,数据导入也写在了Activity类中,感觉代码特别多且杂,后来想到了一句话,多用组合少用继承,现在看来确实,组合的方式会比继承好很多。虽然参考了好多代码,封装的也不怎么样,但是我确实是做到了。

那时候跟同时说我把图表框架封装完的时候,同事说,不会啊封装的不错。对于我这种渣渣来讲就是莫大的安慰了。离自己的目标又近了一步。加油~~

你可能感兴趣的:(MPChart)