MPAndroidChart_折线图的那些事

MPAndroidChart攻略第一步——LineChart的点点滴滴。

带你入门折线图的基本使用,各种属性的设置,自定义轴上的标签,及去除边框线与轴线,和MarkView提示的使用。

目录

1. 从简易折线图开始

2. LineDataSet折线的设置

3. Lengend图例

4. 限制线的用法

5. 网格线的用法

-1. 先来看看x轴网格线

-2. y轴的用法

6. 去掉边框线以及轴线

7. 多条折线的设置

8. 自定义x轴显示的标签

9. MarkView提示

-1. 创建一个类继承自MarkerView

-2. 创建布局

-3. 使用

10. 动画等属性的使用

11. 可以优化改进的地方



从简易折线图开始

话不多说,代码走起,我们先写一个最简易的折线图,代码如下:

 <com.github.mikephil.charting.charts.LineChart
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:id="@+id/chart"/>
public class MainActivity extends AppCompatActivity {
    private LineChart lineChart;
    private LineDataSet set;
    private ArrayList<Entry> list = new ArrayList<>();  //数据集合

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lineChart = findViewById(R.id.chart);
        for (int i = 0; i < 10; i++) {
            list.add(new Entry(i, (float) (Math.random() * 80)));
        }
        setData(list);
    }
    private void setData(ArrayList<Entry> list) {
            set = new LineDataSet(list, "Label");
            LineData data = new LineData(set);
            //设置数据
            lineChart.setData(data);
    }

看效果还挺不错吧,但是我们实际开发时,往往需求没这么简单,下面,我们来对折线图各种方法进行一个总结。


LineDataSet折线的设置

具体方法注释都在代码里写着。

  private void setLine(LineDataSet set) {
        //设置线条的颜色
        set.setColor(Color.RED);
        //虚线模式下绘制直线
        set.enableDashedLine(20f, 5f, 0f);
        //点击后高亮线的显示颜色
        set.enableDashedHighlightLine(50f, 15f, 0f);

        //设置数据小圆点的颜色
        set.setCircleColor(Color.GREEN);
        //设置圆点是否有空心
        set.setDrawCircles(true);
        //设置线条的宽度,最大10f,最小0.2f
        set.setLineWidth(1f);
        //设置小圆点的半径,最小1f,默认4f
        set.setCircleRadius(5f);
        //设置是否显示小圆点
        set.setDrawCircles(true);
        //设置字体颜色
        set.setValueTextColor(Color.BLUE);
        //设置字体大小
        set.setValueTextSize(20f);
        //设置是否填充
        set.setDrawFilled(true);
    }

效果如下


 

Lengend图例

下面设置一下Lengend图例,也就是左下角那个小方框

 private void setLenged(){
        Legend legend=lineChart.getLegend();
        legend.setTextColor(Color.RED);
        legend.setTextSize(20f);
        //设置图例垂直对齐
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        //设置图例居中
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        //设置图例方向
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        //设置图例是在图内还是图外绘制
        legend.setDrawInside(false);
        //图例条目之间距离
        legend.setXEntrySpace(4f);
        //设置图例可否换行
        legend.setWordWrapEnabled(true);
        //设置图例现状为线.默认为方形
	    // legend.setForm(Legend.LegendForm.LINE);
        //是否隐藏图例/true_否,false_是
        legend.setEnabled(true);
    }

效果如下


 

限制线的用法

 private void maxLine(){
        //设置限制线
        LimitLine l1=new LimitLine(60f,"限制线");
        l1.setLineWidth(4f);
        l1.setTextSize(20f);
        l1.setLineColor(Color.RED);
        //允许在虚线模式下绘制(线段长度,分隔长度,偏移量)
        l1.enableDashedLine(10f,10f,0f);
        //设置限制线标签的位置
        l1.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
        l1.setTextSize(10f);
        //添加限制线
        lineChart.getAxisLeft().addLimitLine(l1);
        //是否隐藏限制线/true_否,false_是
        l1.setEnabled(true);
    }

 

 

 网格线的用法

先来看看x轴网格线

 private void XwangGe(){
        //设置x轴网格线
        XAxis xAxis=lineChart.getXAxis();
        //以虚线模式画网格线
        xAxis.enableGridDashedLine(10f,10f,0f);
        //设置x轴最大值
        xAxis.setAxisMaximum(200f);
        //设置x轴最小值
        xAxis.setAxisMinimum(0f);

        //撤销设置的最大值,让轴自动计算
        xAxis.resetAxisMaximum();
        //撤销设置的最小值,让轴自动计算
        xAxis.resetAxisMinimum();
//        //设置x轴标签数,默认为6个
        xAxis.setLabelCount(10);
//        //设置x轴标签数,若强制启用true,可能导致轴上的数字不均匀
//        xAxis.setLabelCount(10,true);
        
        //设置x轴之间的最小间隔。用于在图表放大后标签不至于重合
        xAxis.setGranularity(1f);
      //设置x轴轴线的宽度
        xAxis.setAxisLineWidth(1f);
       //设置轴线的颜色
        xAxis.setAxisLineColor(Color.BLUE);
      //设置x轴显示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    }

 

y轴的用法

//绘制Y轴网格线,有些方法上面也有,这里就不多加了
     private void YwangGe(){
        //y轴默认显示两个轴线,左右
        
        //获取图表左边y轴
        YAxis left=lineChart.getAxisLeft();
        //是否绘制0所在的网格线/默认false绘制
        left.setDrawZeroLine(true);
        //将网格线设置为虚线模式
        left.enableGridDashedLine(10f,10f,0f);
        //获取图表右边y轴
        YAxis right=lineChart.getAxisRight();
        //禁用图表右边y轴
        right.setEnabled(false);
    }


 

去掉边框线以及轴线

有些时候我们的需求需要去掉边框线,这时候可以用以下办法

private void yingcang() {
        //关闭边框矩形
        lineChart.setDrawBorders(false);
        //不绘制y轴左边的线
        lineChart.getAxisLeft().setDrawAxisLine(false);
       //不绘制y轴右边的线
//        lineChart.getAxisRight().setDrawAxisLine(false);
        //禁用图表右边y轴
        lineChart.getAxisRight().setEnabled(false);
        //禁用x轴
        lineChart.getXAxis().setEnabled(false);
        //隐藏图表左边y轴标签
        lineChart.getAxisLeft().setDrawLabels(false);
        //关闭x轴网格线./即竖线
//        lineChart.getXAxis().setDrawGridLines(false);

        //隐藏图表右下角显示内容
        Description description = new Description();
        description.setEnabled(false);
        lineChart.setDescription(description);
    }


多条折线的设置

方法也很简单,就是两个LineDataSet而已,我们修改上面的setData方法

private void setData(String name1,String name2) {
        //这里随机数了两个集合
        ArrayList <Entry> list=new ArrayList<>();
        ArrayList <Entry> list2=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Entry(i, (float) (Math.random() * 80)));
        }
        for (int i = 0; i < 10; i++) {
            list2.add(new Entry(i, (float) (Math.random() * 80)));
        }
        //这里两条线
        LineDataSet set1 = new LineDataSet(list, name1);
        LineDataSet set2 = new LineDataSet(list2, name2);
        setLine(set1);
        setLine(set2);
        //避免看不清,将折线2的颜色更改
        set2.setColor(Color.BLACK);
        //创建一个数据集
        ArrayList<ILineDataSet> dataSets=new ArrayList<>();
        dataSets.add(set1);
        dataSets.add(set2);
        LineData data = new LineData(dataSets);
        //设置数据
        lineChart.setData(data);
    }


 自定义x轴显示的标签

现在我们自定义一下x轴上显示的文字,y轴同理

private void Dif(){
        //为了演示更清楚,我们将x轴标签位于底部
        final String[] data={"周一","周二","周三","周四","周五","周六","周日"};
        XAxis xAxis=lineChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //格式化标签
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return data[(int) value];
            }
        });
    }

 现在看起来好像没什么问题,我们运行一下,结果提示数组越界。

为什么会这样呢?

原因是我们当初在随机数的时候,里面是10个数,而这里的自定义标签数组却只有7个,所以才产生数组越界。
也就是说,我们在自定义标签的时候,数组的下标一定要与你set数据的下标对应。我们现在修改一下setData()方法

   for (int i = 0; i < 7; i++) {
            list.add(new Entry(i, (float) (Math.random() * 80)));
        }
        for (int i = 0; i < 7; i++) {
            list2.add(new Entry(i, (float) (Math.random() * 80)));
        }

 运行一下,好了,所以细节问题要注意,还有一个问题就是,有时候如果产生下标个数不正确的情况,用下面这个方法
        //也就是强制平分x轴,但可能会造成数据位置偏差
         xAxis.setLabelCount(7,true);

MarkView提示

有些时候,我们可能需要点一下数据圆点,让放大显示,这个应该怎样做呢?
设置MarkView提示,如下操作

创建一个类继承自MarkerView

public class MyMarkerView extends MarkerView {
    /**
     * Constructor. Sets up the MarkerView with a custom layout resource.
     *
     * @param context
     * @param layoutResource the layout resource to use for the MarkerView
     */
    private TextView textView;
    private IAxisValueFormatter IAxisValueFormatter;
    private DecimalFormat format;
    public MyMarkerView(Context context) {
        super(context, R.layout.xk);	//第二个参数为布局
        textView=findViewById(R.id.textview);
        format=new DecimalFormat("##0");
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        textView.setText(format.format(e.getY()));
        super.refreshContent(e, highlight);
    }
    public MPPointF getOffset(){
        return  new MPPointF(-(getWidth()/2),-getHeight());
    }
}

创建布局

 布局里面也很简单,就一个textview 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="40dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textColor="#000"
        android:layout_centerHorizontal="true"
        android:textSize="24sp"
        android:layout_marginTop="7dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:id="@+id/textview"/>
</RelativeLayout>

 

使用

然后在onCreate方法里使用

 MyMarkerView myMarkerView = new MyMarkerView(this);
 myMarkerView.setChartView(lineChart);
 lineChart.setMarker(myMarkerView);

 动画等属性的使用

 //设置绘制折线的动画时间
        lineChart.animateX(2500);
        lineChart.animateY(2500);
//设置折线为圆滑折线(加在上面的setLine方法里)
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);
 		//设置数值选择监听
        lineChart.setOnChartValueSelectedListener(this);
        //后台绘制
        lineChart.setDrawGridBackground(false);
        //设置支持触控手势
        lineChart.setTouchEnabled(false);
        //设置缩放
        lineChart.setDragEnabled(false);
        //设置推动
        lineChart.setScaleEnabled(false);
        //如果禁用,扩展可以在x轴和y轴分别完成
        lineChart.setPinchZoom(true);


可以优化改进的地方

 在setData方法里面增加判断,避免多次重新加载 

给setData方法中添加如下代码

 		//判断表中原来是否有数据
if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {
 			//获取数据
            set = (LineDataSet) lineChart.getData().getDataSetByIndex(0);
            set.setValues(list);
             //刷新数据
            lineChart.getData().notifyDataChanged();
            lineChart.notifyDataSetChanged();
        }else{
            ....
       }

关于折线图的画法及常用的方法以上差不多了,下一次,我会将柱状图的画法及需要注意的地方进行一个总结,当然,柱状图与折线图使用差距并不是很大,如果有帮到你的地方,不胜荣幸。

猜你喜欢

转载自blog.csdn.net/petterp/article/details/85540746