Android?LineChart繪制折線圖的示例詳解
1.首先在 build.gradle 里導(dǎo)入包
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
2.新建 啟動(dòng)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);
}
// 開(kāi)始畫(huà)折線圖
setLineChart(list, "BMI" + "kg/2", getResources().getColor(R.color.bule_title));
}
//設(shè)置折線
public void setLineChart(List<IncomeBean> mLineChart, String string, int color) {
lineChart = MPAndroidUtil.initChart(this, lineChart);
lineChart.setData(MPAndroidUtil.showLineChart(mLineChart, string, color));
//設(shè)置一頁(yè)最大顯示個(gè)數(shù)為6,超出部分就滑動(dòng)
float ratio = (float) mLineChart.size() / (float) 6;
//顯示的時(shí)候是按照多大的比率縮放顯示,1f表示不放大縮小
// lineChart.zoom(ratio, 1f, 0, 0);
// 設(shè)置填充圖
Drawable drawable = getResources().getDrawable(R.drawable.fade_blue);
MPAndroidUtil.setChartFillDrawable(drawable, lineChart);
// 設(shè)置點(diǎn)擊的彈窗
MPAndroidUtil.setMarkerView1(lineChart);
/* lineChart.getLineData().addDataSet(MPAndroidUtil.addLine(list1, "地位條", getResources().getColor(R.color.text_orange)));
lineChart.invalidate();*/
}
}3.新建數(shù)據(jù) 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;// 時(shí)間
public double value;// 數(shù)值
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; //左側(cè)Y軸
private static YAxis rightYaxis; //右側(cè)Y軸
private static Legend legend; //圖例
/**
* 初始化圖表 折線圖
*/
public static LineChart initChart(Context context, LineChart lineChart) {
/***圖表設(shè)置***/
//是否展示網(wǎng)格線
lineChart.setDrawGridBackground(false);
//是否顯示邊界
lineChart.setDrawBorders(false);
//是否可以拖動(dòng)
lineChart.setDragEnabled(false);
//是否有觸摸事件
lineChart.setTouchEnabled(true);
// 關(guān)閉雙擊放大功能
lineChart.setDoubleTapToZoomEnabled(false);
//設(shè)置XY軸動(dòng)畫(huà)效果
lineChart.animateY(2500);
lineChart.animateX(1500);
lineChart.setBackgroundColor(context.getResources().getColor(R.color.white));
/***XY軸的設(shè)置***/
xAxis = null;
xAxis = lineChart.getXAxis();
leftYAxis = lineChart.getAxisLeft();
rightYaxis = lineChart.getAxisRight();
//X軸設(shè)置顯示位置在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setAxisMinimum(0f);
xAxis.setGranularity(1f);
//保證Y軸從0開(kāi)始,不然會(huì)上移一點(diǎn)
leftYAxis.setAxisMinimum(0f);
rightYaxis.setAxisMinimum(0f);
// 但還是顯示了網(wǎng)格線,而且不是我們想要的 虛線 。其實(shí)那是 X Y軸自己的網(wǎng)格線,禁掉即可
xAxis.setDrawGridLines(false);
rightYaxis.setDrawGridLines(false);
leftYAxis.setDrawGridLines(true);
//設(shè)置X Y軸網(wǎng)格線為虛線(實(shí)體線長(zhǎng)度、間隔距離、偏移量:通常使用 0)
leftYAxis.enableGridDashedLine(10f, 10f, 0f);
// 目標(biāo)效果圖沒(méi)有右側(cè)Y軸,所以去掉右側(cè)Y軸
rightYaxis.setEnabled(false);
/***折線圖例 標(biāo)簽 設(shè)置***/
legend = lineChart.getLegend();
//legend.setEnabled(false);
//設(shè)置顯示類(lèi)型,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(" ");
// 設(shè)置右下角的提示
Description description = new Description();
// description.setText("需要展示的內(nèi)容");
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;
}
/**
* 曲線初始化設(shè)置 一個(gè)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);
//設(shè)置曲線值的圓點(diǎn)是實(shí)心還是空心
lineDataSet.setDrawCircleHole(true);
lineDataSet.setValueTextSize(10f);
//設(shè)置折線圖填充
lineDataSet.setDrawFilled(true);
lineDataSet.setFormLineWidth(1f);
lineDataSet.setFormSize(15.f);
if (mode == null) {
//設(shè)置曲線展示為圓滑曲線(如果不設(shè)置則默認(rèn)折線)
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構(gòu)造方法,可發(fā)現(xiàn) 可傳入數(shù)值 Entry(float x, float y)
* 也可傳入Drawable, Entry(float x, float y, Drawable icon) 可在XY軸交點(diǎn) 設(shè)置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);
// 每一個(gè)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();
}
/*
* 設(shè)置線條填充背景顏色
*
* @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()方法中 設(shè)置了 lineDataSet.setDrawFilled(false); 而無(wú)法實(shí)現(xiàn)效果
lineDataSet.setDrawFilled(true);
lineDataSet.setFillDrawable(drawable);
mLineChart.invalidate();
}
return mLineChart;
}
// 傳入某種格式的時(shí)間格式,得到特定的時(shí)間格式
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軸的數(shù)據(jù)集合,根據(jù)當(dāng)前X軸的位置 來(lái)獲取對(duì)應(yīng)的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);//注釋掉這個(gè),否則坐標(biāo)標(biāo)簽復(fù)寫(xiě)兩次
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了

到此這篇關(guān)于Android LineChart繪制折線圖的示例詳解的文章就介紹到這了,更多相關(guān)Android LineChart折線圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解析ADT-20問(wèn)題 android support library
本篇文章是對(duì)ADT-20問(wèn)題 android support library進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
在Android項(xiàng)目中使用AspectJ的方法
這篇文章主要介紹了在Android項(xiàng)目中使用AspectJ的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
詳解Android?Flutter中SliverAppBar的使用教程
對(duì)于一個(gè)APP來(lái)說(shuō),肯定會(huì)有一個(gè)AppBar,這個(gè)AppBar一般包含了APP的導(dǎo)航信息等。在lutter已經(jīng)為我們提供了一個(gè)非常強(qiáng)大的AppBar組件,這個(gè)組件叫做SliverAppBar。本文就來(lái)聊聊它的具體使用吧2023-01-01
Android?Camera+SurfaceView自動(dòng)聚焦防止變形拉伸
這篇文章主要為大家介紹了Android自定義相機(jī)Camera+SurfaceView實(shí)現(xiàn)自動(dòng)聚焦防止變形拉伸詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
android中RecycleView添加下滑到底部的監(jiān)聽(tīng)示例
本篇文章主要介紹了android中RecycleView添加下滑到底部的監(jiān)聽(tīng)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
jenkins 遠(yuǎn)程構(gòu)建Android的過(guò)程詳解
這篇文章主要介紹了jenkins 遠(yuǎn)程構(gòu)建Android的過(guò)程詳解的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android消息通知欄的實(shí)現(xiàn)方法介紹
本篇文章是對(duì)Android消息通知欄的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android自定義動(dòng)畫(huà)根據(jù)控件Y軸旋轉(zhuǎn)動(dòng)畫(huà)(仿紅包)
這篇文章主要介紹了Android自定義動(dòng)畫(huà)根據(jù)控件Y軸旋轉(zhuǎn)動(dòng)畫(huà)(仿紅包),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
android studio 一直卡在Gradle:Build Running的幾種解決辦法
這篇文章主要介紹了android studio 一直卡在Gradle:Build Running的解決辦法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10

