软件编程
位置:首页>> 软件编程>> Android编程>> Android LineChart绘制折线图的示例详解

Android LineChart绘制折线图的示例详解

作者:Bytezero!  发布时间:2022-10-15 22:43:37 

标签:Android,LineChart,折线图

1.首先在 build.gradle 里导入包

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

2.新建 启动Activity  

LineChartActivity 如下

**
* @Author: Bytezero_zhengLei
* @Time: 2023/3/24 10:12
* @Project_Name: LineChartActivity.java
* @Email: 420498246@qq.com
* @Description:
* @TODO: 折线图
*/

public class LineChartActivity extends AppCompatActivity {

private LineChart lineChart;
   List<IncomeBean> list = new ArrayList<>();

@Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_line_chart);

lineChart = (LineChart) findViewById(R.id.linechart);

lineChart = MPAndroidUtil.initChart(this, lineChart);

for (int i =0; i <10; i ++){
           IncomeBean incomeBean = new IncomeBean(36.5,"2020-01-01 00:00:00");
           list.add(incomeBean);

}

// 开始画折线图
       setLineChart(list, "BMI" + "kg/²", getResources().getColor(R.color.bule_title));
   }

//设置折线

public void setLineChart(List<IncomeBean> mLineChart, String string, int color) {
       lineChart = MPAndroidUtil.initChart(this, lineChart);
       lineChart.setData(MPAndroidUtil.showLineChart(mLineChart, string, color));
       //设置一页最大显示个数为6,超出部分就滑动
       float ratio = (float) mLineChart.size() / (float) 6;
       //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
       // lineChart.zoom(ratio, 1f, 0, 0);
       // 设置填充图
       Drawable drawable = getResources().getDrawable(R.drawable.fade_blue);
       MPAndroidUtil.setChartFillDrawable(drawable, lineChart);
       // 设置点击的弹窗
       MPAndroidUtil.setMarkerView1(lineChart);

/* lineChart.getLineData().addDataSet(MPAndroidUtil.addLine(list1, "地位条", getResources().getColor(R.color.text_orange)));
       lineChart.invalidate();*/

}
}

3.新建数据 IncomeBean

/**
* @Author: Bytezero_zhengLei
* @Time: 2023/3/24 10:24
* @Project_Name: IncomeBean.java
* @Email: 420498246@qq.com
* @Description:
* @TODO:
*/

public class IncomeBean implements Serializable {
   public String tradeDate;// 时间
   public double value;// 数值

public IncomeBean(double mValue, String mTradeDate) {
       tradeDate = mTradeDate;
       value = mValue;
   }

@Override
   public String toString() {
       return "IncomeBean{" +
               "tradeDate='" + tradeDate + '\'' +
               ", value=" + value +
               '}';
   }
}

4.制定折线图的属性  MPAndroidUtil

/**
* @Author: Bytezero_zhengLei
* @Time: 2023/3/24 10:20
* @Project_Name: MPAndroidUtil.java
* @Email: 420498246@qq.com
* @Description:
* @TODO:
*/

public class MPAndroidUtil {
   private static final String TAG = "MPAndroidUtil";
   private static XAxis xAxis = null;                //X轴
   private static YAxis leftYAxis;            //左侧Y轴
   private static YAxis rightYaxis;           //右侧Y轴
   private static Legend legend;              //图例

/**
    * 初始化图表 折线图
    */
   public static LineChart initChart(Context context, LineChart lineChart) {

/***图表设置***/
       //是否展示网格线
       lineChart.setDrawGridBackground(false);
       //是否显示边界
       lineChart.setDrawBorders(false);
       //是否可以拖动
       lineChart.setDragEnabled(false);
       //是否有触摸事件
       lineChart.setTouchEnabled(true);
       // 关闭双击放大功能
       lineChart.setDoubleTapToZoomEnabled(false);
       //设置XY轴动画效果
       lineChart.animateY(2500);
       lineChart.animateX(1500);

lineChart.setBackgroundColor(context.getResources().getColor(R.color.white));

/***XY轴的设置***/
       xAxis = null;
       xAxis = lineChart.getXAxis();
       leftYAxis = lineChart.getAxisLeft();
       rightYaxis = lineChart.getAxisRight();
       //X轴设置显示位置在底部
       xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
       xAxis.setAxisMinimum(0f);
       xAxis.setGranularity(1f);
       //保证Y轴从0开始,不然会上移一点
       leftYAxis.setAxisMinimum(0f);
       rightYaxis.setAxisMinimum(0f);

// 但还是显示了网格线,而且不是我们想要的 虚线 。其实那是 X Y轴自己的网格线,禁掉即可
       xAxis.setDrawGridLines(false);
       rightYaxis.setDrawGridLines(false);
       leftYAxis.setDrawGridLines(true);
       //设置X Y轴网格线为虚线(实体线长度、间隔距离、偏移量:通常使用 0)
       leftYAxis.enableGridDashedLine(10f, 10f, 0f);
       // 目标效果图没有右侧Y轴,所以去掉右侧Y轴
       rightYaxis.setEnabled(false);

/***折线图例 标签 设置***/
       legend = lineChart.getLegend();
       //legend.setEnabled(false);
       //设置显示类型,LINE CIRCLE SQUARE EMPTY 等等 多种方式,查看LegendForm 即可
       legend.setForm(Legend.LegendForm.LINE);
       legend.setTextSize(12f);
       //显示位置 左下方
       legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
       legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
       legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
       //是否绘制在图表里面
       legend.setDrawInside(false);
       // legend.setExtra(mLegendEntries);

//        lineChart.setNoDataText(context.getResources().getString(R.string.No_data));
       lineChart.setNoDataText("  ");
       // 设置右下角的提示
       Description description = new Description();
//        description.setText("需要展示的内容");
       description.setEnabled(false);
       lineChart.setDescription(description);

lineChart.setExtraBottomOffset(2 * 8f);

lineChart.setXAxisRenderer(new CustomXAxisRenderer(lineChart.getViewPortHandler(), lineChart.getXAxis(), lineChart.getTransformer(YAxis.AxisDependency.LEFT)));
       return lineChart;
   }

/**
    * 曲线初始化设置 一个LineDataSet 代表一条曲线
    *
    * @param lineDataSet 线条
    * @param color       线条颜色
    * @param mode
    */
   public static LineDataSet initLineDataSet(LineDataSet lineDataSet, int color, LineDataSet.Mode mode) {
       lineDataSet.setColor(color);
       lineDataSet.setCircleColor(color);
       lineDataSet.setLineWidth(1f);
       lineDataSet.setCircleRadius(2f);
       //设置曲线值的圆点是实心还是空心
       lineDataSet.setDrawCircleHole(true);
       lineDataSet.setValueTextSize(10f);
       //设置折线图填充
       lineDataSet.setDrawFilled(true);
       lineDataSet.setFormLineWidth(1f);
       lineDataSet.setFormSize(15.f);
       if (mode == null) {
           //设置曲线展示为圆滑曲线(如果不设置则默认折线)
           lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
       } else {
           lineDataSet.setMode(mode);
       }
       // 不显示值
       lineDataSet.setDrawValues(false);
       return lineDataSet;

}

public static LineData showLineChart(final List<IncomeBean> dataList, String name, int color) {
       List<Entry> entries = new ArrayList<>();
       for (int i = 0; i < dataList.size(); i++) {
           IncomeBean data = dataList.get(i);
           /**
            * 在此可查看 Entry构造方法,可发现 可传入数值 Entry(float x, float y)
            * 也可传入Drawable, Entry(float x, float y, Drawable icon) 可在XY轴交点 设置Drawable图像展示
            */
           Entry entry = new Entry(i, (float) data.value);
           entries.add(entry);
       }
       xAxis.setValueFormatter(new IndexAxisValueFormatter() {
           @Override
           public String getFormattedValue(float value) {
               String tradeDate;
               try {
                   tradeDate = dataList.get((int) value % dataList.size()).tradeDate;
               } catch (Exception mE) {
                   tradeDate = "2020-01-01 00:00:00";
               }

return StrToStr("yyyy-MM-dd HH:mm:ss", "MM-dd HH:mm", tradeDate);
           }
       });

xAxis.setLabelCount(6, false);

leftYAxis.setLabelCount(8);
       // 每一个LineDataSet代表一条线
       LineDataSet lineDataSet = new LineDataSet(entries, name);
       lineDataSet = initLineDataSet(lineDataSet, color, LineDataSet.Mode.CUBIC_BEZIER);
       LineData lineData = new LineData(lineDataSet);
       return lineData;

}

public static void setMarkerView1(LineChart lineChart) {
//        LineChartMarkView1 mv = new LineChartMarkView1(MApplication.getInstance(), xAxis.getValueFormatter());
       LineChartMarkView1 mv = new LineChartMarkView1(lineChart.getContext(), xAxis.getValueFormatter());
       mv.setChartView(lineChart);
       lineChart.setMarker(mv);
       lineChart.invalidate();
   }

/*
    * 设置线条填充背景颜色
    *
    * @param drawable
    */
   public static LineChart setChartFillDrawable(Drawable drawable, LineChart mLineChart) {
       if (mLineChart.getData() != null && mLineChart.getData().getDataSetCount() > 0) {
           LineDataSet lineDataSet = (LineDataSet) mLineChart.getData().getDataSetByIndex(0);
           //避免在 initLineDataSet()方法中 设置了 lineDataSet.setDrawFilled(false); 而无法实现效果
           lineDataSet.setDrawFilled(true);
           lineDataSet.setFillDrawable(drawable);

mLineChart.invalidate();

}
       return mLineChart;
   }

// 传入某种格式的时间格式,得到特定的时间格式
   public static String StrToStr(String SimpleDateFormat_in, String SimpleDateFormat_out, String str) {
       SimpleDateFormat format = new SimpleDateFormat(SimpleDateFormat_in);
       SimpleDateFormat format1 = new SimpleDateFormat(SimpleDateFormat_out);
       Date date = null;
       try {
           date = format.parse(str);
       } catch (ParseException e) {
           e.printStackTrace();
       }
       return format1.format(date.getTime());
   }

}

5.LineChartMarkView1

**
* @Author: Bytezero_zhengLei
* @Time: 2023/3/24 10:45
* @Project_Name: LineChartMarkView1.java
* @Email: 420498246@qq.com
* @Description:
* @TODO:
*/

public class LineChartMarkView1 extends MarkerView {

private TextView tvDate;
   private TextView tvValue;
   private IAxisValueFormatter xAxisValueFormatter;
   DecimalFormat df = new DecimalFormat(".00");

public LineChartMarkView1(Context context, IAxisValueFormatter xAxisValueFormatter) {
       super(context, R.layout.layout_markview1);
       this.xAxisValueFormatter = xAxisValueFormatter;

tvDate = findViewById(R.id.tv_date);
       tvValue = findViewById(R.id.tv_value);
   }

@SuppressLint("SetTextI18n")
   @Override
   public void refreshContent(Entry e, Highlight highlight) {
       Chart chart = getChartView();
       if (chart instanceof LineChart) {
           LineData lineData = ((LineChart) chart).getLineData();
           //获取到图表中的所有曲线
           List<ILineDataSet> dataSetList = lineData.getDataSets();
           for (int i = 0; i < dataSetList.size(); i++) {
               LineDataSet dataSet = (LineDataSet) dataSetList.get(i);
               //获取到曲线的所有在Y轴的数据集合,根据当前X轴的位置 来获取对应的Y轴值
               float y = dataSet.getValues().get((int) e.getX()).getY();
               if (i == 0) {
                   tvValue.setText(dataSet.getLabel() + ":" + e.getY());
               }
           }
           tvDate.setText(xAxisValueFormatter.getFormattedValue(e.getX(), null));
       }

super.refreshContent(e, highlight);
   }

@Override
   public MPPointF getOffset() {
       return new MPPointF(-(getWidth() / 2), -getHeight());

}
}

6.CustomXAxisRenderer

/**
* @Author: Bytezero_zhengLei
* @Time: 2023/3/24 10:23
* @Project_Name: CustomXAxisRenderer.java
* @Email: 420498246@qq.com
* @Description:
* @TODO:
*/

public class CustomXAxisRenderer extends XAxisRenderer {
   public CustomXAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) {
       super(viewPortHandler, xAxis, trans);
   }

@Override
   protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
//        super.drawLabel(c, formattedLabel, x, y, anchor, angleDegrees);//注释掉这个,否则坐标标签复写两次
       String[] lines = formattedLabel.split(" ");
       for (int i = 0; i < lines.length; i++) {
           float vOffset = i * mAxisLabelPaint.getTextSize();
           Utils.drawXAxisValue(c, lines[i], x, y + vOffset, mAxisLabelPaint, anchor, angleDegrees);
       }
   }
}

7.一些 小的  layout  

LineChartMarkView1的layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/shape_square"
   android:orientation="vertical">

<TextView
       android:id="@+id/tv_date"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textColor="@android:color/white" />

<TextView
       android:id="@+id/tv_value"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginTop="5dp"
       android:textColor="@android:color/white" />
</LinearLayout>

LineChartActivity中的 layout

<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=".LineChart.LineChartActivity">

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

</LinearLayout>

这样就ok了

Android LineChart绘制折线图的示例详解

来源:https://www.cnblogs.com/Bytezero/p/17250982.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com