目录

一、常用方法及相关属性 

 折线图中的属性所在位置:

常用方法:

二、动态曲线例子:

基本概念: 

1、添加依赖

2、LineChartUtil :

3、MainActivity:

4、CustomMarkerView:

5、activity_main:

6、markview:

7、效果图:

三、多条折线图

 1、MainActivity:

 2、LineChartHelper:

 3、activity_main:

 4、CustomMarkerView:(同上)

 5、效果图:

一、常用方法及相关属性 

        MPAndroidChart是一个非常流行的开源库,可以帮助你实现折线图、柱状图、饼图等多种图形。

 折线图中的属性所在位置:

动态折线图python 动态折线图开源_Line

常用方法:

  1. setTouchEnabled(boolean enabled) :设置图表是否可以触摸。
  2. setDragEnabled(boolean enabled):设置图表是否可以拖动。
  3. setScaleEnabled(boolean enabled):设置图表是否可以缩放。
  4. setDrawGridBackground(boolean enabled):设置是否在图表中绘制背景网格。
  5. setPinchZoom(boolean enabled):设置图表是否可以通过两个手指捏合进行缩放。
  6. getDescription():获取图表的描述对象。
  7. setDescription(String desc):设置图表的描述文本。
  8. setDescriptionEnabled(boolean enabled):设置图表描述是否可见。
  9. getXAxis():获取X轴对象。
  10. getAxisRight():获取右侧Y轴对象。
  11. getAxisLeft():获取左侧Y轴对象。
  12. setData(LineData data):设置图表的数据。
  13. getData():获取图表的数据。
  14. invalidate():使图表视图失效。
  15. setVisibleXRangeMaximum(float maxXRange):设置图表在X轴上可见的范围的最大值。
  16. moveViewToX(float xValue):将图表视图移动到指定的X轴数值。
  17. setMarker(IMarker marker):设置图表上用于标记选中项的Marker对象。
  18. setHighlightPerTapEnabled(boolean enabled):设置是否显示单击选中项的高亮。
  19. setHighlightPerDragEnabled(boolean enabled):设置是否显示拖动选中项的高亮。
  20. setOnChartValueSelectedListener(OnChartValueSelectedListener listener):设置当值被选中时调用的监听器。
  21. animateX(int durationMillis):在指定的时间内动画显示图表的X轴。
  22. animateY(int durationMillis):在指定的时间内动画显示图表的Y轴。
  23. animateXY(int xDurationMillis, int yDurationMillis):在指定的时间内动画显示图表的X轴和Y轴。
  24. setNoDataText(String text):设置没有数据时显示的文本。

二、例子:

基本概念: 

LineChart   // 折线表,存线集合,与xml中的控件绑定实力化
LineData    // 线集合,所有折线以数组的形式存到此集合中
LineDataSet // 点集合,即一条折线
Entry       // 某条折线上的一个点
XAxis       // X轴
YAxis       // Y轴,Y轴分左右,通过lineChart的getAxisLeft()、getAxisRight()得到
Legend      // 图例,即标识哪一条曲线,如用红色标识电流折线,蓝色标识电压折线
LimitLine   // 限制线
Description // 描述

1、添加依赖

implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

2、LineChartUtil :

package com.example.linechart;

import android.graphics.Color;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;

public class LineChartUtil {
    private LineChart mLineChart;
    // 设置最多显示20个点
    int maxVisibleCount = 20;
    private float lastX = 0;
    public LineChartUtil(LineChart lineChart){
        mLineChart = lineChart;
    }
    /**
     * 初始化X轴
     */
    public void initXAxis() {
        XAxis xAxis = mLineChart.getXAxis();
        //  2.设置X轴的位置(默认在上方):
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//值:BOTTOM,BOTH_SIDED,BOTTOM_INSIDE,TOP,TOP_INSIDE
        //  3.设置X轴坐标之间的最小间隔(因为此图有缩放功能,X轴,Y轴可设置可缩放)
        xAxis.setGranularity(1f);
        //  4.设置X轴的刻度数量
        xAxis.setLabelCount(40, false);
        // 5.设置X轴的值(最小值、最大值、然后会根据设置的刻度数量自动分配刻度显示)
        xAxis.setAxisMinimum(0f);
        xAxis.setAxisMaximum(20f);
        // 6.设置当前图表中最多在x轴坐标线上显示刻度线的总量
        mLineChart.setVisibleXRangeMaximum(5);// 设置当前图表中最多在x轴坐标线上显示的刻度线总量为6
    }
    /**
     * 初始化折线图数据集合
     */
    public void initLineChartData() {
        // 创建一个空数据集合并将其设置到图表中
        LineDataSet dataSet = new LineDataSet(null, "动态折线图");
        dataSet.setLineWidth(2.0f);
        // 设置折线的颜色
        dataSet.setColor(Color.RED);
        // 设置曲线为圆滑曲线
        dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
        // 设置折线图填充
        dataSet.setDrawFilled(true);
        // 设置每个点是否以圆圈来显示
        dataSet.setDrawCircles(true);
        // 是否显示每个点的y值
        dataSet.setDrawValues(true);
        // 创建LineData对象并设置其为图表的数据
        LineData data = new LineData(dataSet);
        mLineChart.setData(data);
    }
    /**
     * 初始化折线图
     */
    public void initLineChart() {
        // 折线图是否可以触摸
        mLineChart.setTouchEnabled(true);
        // 折线图是否可以拖动
        mLineChart.setDragEnabled(true);
        // 折线图是否可以放大
        mLineChart.setScaleEnabled(true);
        // 折线图是否显示网格
        mLineChart.setDrawGridBackground(true);
        // 如果设置为true, x和y轴可以用2个手指同时缩放,如果设置为false, x和y轴可以分别缩放。默认值:假
        mLineChart.setPinchZoom(true);
        // 返回图表的Description对象,该对象负责保存与显示在图表右下角的描述文本相关的所有信息(默认情况下)
        mLineChart.getDescription().setEnabled(false);
        mLineChart.animateX(1500);
        // 设置x轴的属性
        initXAxis();
        // 设置y轴的属性
        initYAxis();
        initLegend();
    }
    /**
     * 初始化折线图的图标
     */
    public void initLegend() {
        Legend legend = mLineChart.getLegend();
        // 设置图例位置为底部居中
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        // 显示图例文本
        legend.setEnabled(true);

        // 设置图例文本颜色
        legend.setTextColor(Color.BLACK);

        // 设置图例样式为水平
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        // 设置描述内容
        Description description = new Description();
        description.setText("时间/min");
        description.setTextColor(Color.RED);
        mLineChart.setDescription(description);
    }
    /**
     * 初始化折线图的y轴
     */
    public void initYAxis() {
        //  1.得到Y轴
        YAxis leftYAxis = mLineChart.getAxisLeft();
        YAxis rightYAxis = mLineChart.getAxisRight();
        // 2.设置某一个Y轴是否显示
        rightYAxis.setEnabled(false); //右侧Y轴不显示
        //3.限制线LimitLine(如上右图)
        LimitLine limitLine = new LimitLine(50,"警戒线"); //得到限制线
        limitLine.setLineWidth(2f); //宽度
        limitLine.setTextSize(10f);
        limitLine.setTextColor(Color.BLACK);  //颜色
        limitLine.setLineColor(Color.GREEN);
        leftYAxis.addLimitLine(limitLine); //Y轴添加限制线

        //4.X轴和Y轴类似,都具有相同的属性方法

        rightYAxis.setAxisMinimum(0f);
        rightYAxis.setAxisMaximum(100f);
        rightYAxis.setGranularity(1f);
//        rightYAxis.setLabelCount(11,false);
        rightYAxis.setTextColor(Color.BLUE); //文字颜色
        rightYAxis.setGridColor(Color.RED); //网格线颜色
        rightYAxis.setAxisLineColor(Color.GREEN); //Y轴颜色
    }

    public boolean addEntry() {
        LineData data = mLineChart.getData();
        if (data != null) {
            LineDataSet set = (LineDataSet) data.getDataSetByIndex(0);
            if (set == null) {
                set = createSet();
                data.addDataSet(set);
            }

            // 添加新点到数据集中
            data.addEntry(new Entry(lastX++, (float) (Math.random() * 80) + 10f), 0);

            // 更新数据
            data.notifyDataChanged();
            mLineChart.notifyDataSetChanged();

            // 平移x轴,确保新添加的点显示在最右侧

            float maxX = data.getXMax();
            if (maxX > maxVisibleCount) {
//                mLineChart.getXAxis().setAxisMinimum(data.getXMin() + 1);
//                mLineChart.getXAxis().setAxisMaximum(data.getXMax() + maxVisibleCount);
//                maxVisibleCount+=20;
                return false;
            }

            // 将图表滚动到最新的点处
            mLineChart.moveViewToX(data.getEntryCount()-4);
        }
        return true;
    }
    /**
     * 创建数据集
     */
    public LineDataSet createSet() {
        LineDataSet set = new LineDataSet(null, "动态折线图");
        set.setLineWidth(2.5f);
        set.setColor(Color.RED);
        set.setDrawCircles(false);
        set.setDrawValues(false);
        return set;
    }
}

3、MainActivity:

package com.example.linechart;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.graphics.Color;
import android.view.View;
import android.widget.Button;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private LineChart mLineChart;
    private Timer timer;
    boolean isStart = false;
    private Button pauseBtn,startBtn;
    private LineChartUtil mLineChartUtil;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pauseBtn = findViewById(R.id.pause);
        startBtn = findViewById(R.id.start);
        startBtn.setOnClickListener(this);
        pauseBtn.setOnClickListener(this);
        // 获取LineChart视图
        mLineChart = findViewById(R.id.chart);
        mLineChartUtil = new LineChartUtil(mLineChart);
        // 设置LineChart的属性
        mLineChartUtil.initLineChart();
        // 初始化折线图的数据
        mLineChartUtil.initLineChartData();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 定义并启动定时器
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // 在数据集中添加新点
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (isStart){
                            isStart = mLineChartUtil.addEntry();
                        }
                    }
                });
            }
        }, 0, 500);
    }
    @Override
    public void onPause() {
        super.onPause();
        timer.cancel();
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.pause:
                isStart = false;
                break;
            case R.id.start:
                isStart = true;
                break;
        }
    }
}

4、CustomMarkerView:

package com.example.linechart;

import android.content.Context;
import android.widget.TextView;

import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;

import java.util.Locale;

public class CustomMarkerView extends MarkerView {

    private TextView mValueTextView;

    public CustomMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);
        // 实例化 TextView 控件
        mValueTextView = findViewById(R.id.tv_value);
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        // 格式化数值并设置到 TextView 中
        String valueText = String.format(Locale.getDefault(), "%.2f °C", e.getY());
        mValueTextView.setText(valueText);

        super.refreshContent(e, highlight);
    }

    /**
     * 设置 MarkerView 的偏移量,使其显示在当前点的上方
     */
    @Override
    public MPPointF getOffset() {
        return new MPPointF(-(getWidth() / 2f), -getHeight());
    }
}

5、activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/chart"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始"/>

    <Button
        android:id="@+id/pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="暂停"/>
</LinearLayout>

6、markview:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tv_value"
        android:background="#DA2B7C"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white"
        android:textSize="12sp"/>

</LinearLayout>

效果图:

动态折线图python 动态折线图开源_折线图_02

三、多条折线图

 1、MainActivity:

package com.example.linedemo3;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;

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

public class MainActivity extends AppCompatActivity {
    LineChartHelper mLineChartHelper;
    LineChart mLineChart;
    List<Entry> entries1,entries2,entries3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLineChart = findViewById(R.id.lineChart);
        mLineChartHelper = new LineChartHelper(mLineChart,MainActivity.this);
        initData();
        mLineChartHelper.setChartData(entries1,entries2,entries3);
    }

    private void initData() {
        // 创建三条折线的数据集合
        entries1 = new ArrayList<>();
        entries2 = new ArrayList<>();
        entries3 = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            entries1.add(new Entry(i, (float) Math.random()+10));
            entries2.add(new Entry(i, (float) Math.random()+10));
            entries3.add(new Entry(i, (float) Math.random()+10));
        }




    }
}

 2、LineChartHelper:

package com.example.linedemo3;

import android.content.Context;
import android.graphics.Color;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
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.interfaces.datasets.ILineDataSet;

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

public class LineChartHelper {

    private LineChart mLineChart;
    private Context mContext;
    public LineChartHelper(LineChart lineChart,Context context) {
        mLineChart = lineChart;
        mContext = context;
        initLineChart();
    }

    /**
     * 初始化折线图
     */
    public void initLineChart() {
        // 创建 CustomMarkerView 对象,并设置 MarkerView
        CustomMarkerView markerView = new CustomMarkerView(mContext, R.layout.markview);
        mLineChart.setMarker(markerView);
        // 折线图是否可以触摸
        mLineChart.setTouchEnabled(true);
        // 折线图是否可以拖动
        mLineChart.setDragEnabled(true);
        // 折线图是否可以放大
        mLineChart.setScaleEnabled(true);
        // 折线图是否显示网格
        mLineChart.setDrawGridBackground(true);
        // 如果设置为true, x和y轴可以用2个手指同时缩放,如果设置为false, x和y轴可以分别缩放。默认值:假
        mLineChart.setPinchZoom(true);
        // 返回图表的Description对象,该对象负责保存与显示在图表右下角的描述文本相关的所有信息(默认情况下)
        mLineChart.getDescription().setEnabled(false);
        mLineChart.animateX(1500);
        // 设置x轴的属性
        initXAxis();
        // 设置y轴的属性
        initYAxis();
        initLegend();
    }
    /**
     * 初始化X轴
     */
    public void initXAxis() {
        XAxis xAxis = mLineChart.getXAxis();
        //  2.设置X轴的位置(默认在上方):
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//值:BOTTOM,BOTH_SIDED,BOTTOM_INSIDE,TOP,TOP_INSIDE
        //  3.设置X轴坐标之间的最小间隔(因为此图有缩放功能,X轴,Y轴可设置可缩放)
        xAxis.setGranularity(1f);
        //  4.设置X轴的刻度数量
        xAxis.setLabelCount(40, false);
        // 5.设置X轴的值(最小值、最大值、然后会根据设置的刻度数量自动分配刻度显示)
        xAxis.setAxisMinimum(0f);
        xAxis.setAxisMaximum(20f);
        // 6.设置当前图表中最多在x轴坐标线上显示刻度线的总量
        mLineChart.setVisibleXRangeMaximum(5);// 设置当前图表中最多在x轴坐标线上显示的刻度线总量为6
    }
    /**
     * 初始化折线图的图标
     */
    public void initLegend() {
        Legend legend = mLineChart.getLegend();
        // 设置图例位置为底部居中
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        // 显示图例文本
        legend.setEnabled(true);

        // 设置图例文本颜色
        legend.setTextColor(Color.BLACK);

        // 设置图例样式为水平
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        // 设置描述内容
        Description description = new Description();
        description.setText("时间/min");
        description.setTextColor(Color.RED);
        mLineChart.setDescription(description);
    }
    /**
     * 初始化折线图的y轴
     */
    public void initYAxis() {
        //  1.得到Y轴
        YAxis leftYAxis = mLineChart.getAxisLeft();
        YAxis rightYAxis = mLineChart.getAxisRight();
        // 2.设置某一个Y轴是否显示
        rightYAxis.setEnabled(false); //右侧Y轴不显示
        //3.限制线LimitLine(如上右图)
        LimitLine limitLine = new LimitLine(50,"警戒线"); //得到限制线
        limitLine.setLineWidth(2f); //宽度
        limitLine.setTextSize(10f);
        limitLine.setTextColor(Color.BLACK);  //颜色
        limitLine.setLineColor(Color.GREEN);
        leftYAxis.addLimitLine(limitLine); //Y轴添加限制线

        //4.X轴和Y轴类似,都具有相同的属性方法

        rightYAxis.setAxisMinimum(0f);
        rightYAxis.setAxisMaximum(100f);
        rightYAxis.setGranularity(1f);
//        rightYAxis.setLabelCount(11,false);
        rightYAxis.setTextColor(Color.BLUE); //文字颜色
        rightYAxis.setGridColor(Color.RED); //网格线颜色
        rightYAxis.setAxisLineColor(Color.GREEN); //Y轴颜色
    }
    public void setChartData(List<Entry> entries1, List<Entry> entries2, List<Entry> entries3) {
        // 将数据集合封装成 LineDataSet 对象,并设置各种绘制属性
        LineDataSet dataSet1 = new LineDataSet(entries1, "室温/°C");
        dataSet1.setColor(Color.RED);
        dataSet1.setValueTextColor(Color.RED);
        dataSet1.setLineWidth(2f);

        LineDataSet dataSet2 = new LineDataSet(entries2, "箱内温度/°C");
        dataSet2.setColor(Color.GREEN);
        dataSet2.setValueTextColor(Color.GREEN);
        dataSet2.setLineWidth(2f);
        LineDataSet dataSet3 = new LineDataSet(entries3, "外面温度/°C");
        dataSet3.setColor(Color.BLUE);
        dataSet3.setValueTextColor(Color.BLUE);
        dataSet3.setLineWidth(2f);

        // 将三条折线的 LineDataSet 对象放入 LineData 中
        List<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(dataSet1);
        dataSets.add(dataSet2);
        dataSets.add(dataSet3);
        LineData lineData = new LineData(dataSets);
        // 设置绘制样式以及其他属性
        mLineChart.setData(lineData);
        mLineChart.animateXY(1000, 1000);
    }

}

 3、activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/lineChart"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        />

</LinearLayout>

 4、CustomMarkerView:(同上)

 5、效果图:

动态折线图python 动态折线图开源_Line_03