Android 图表开源框架之MPAndroidChart LineChart折线图(一)
Android 图表开源框架之MPAndroidChart LineChart折线图(二)
Android 图表开源框架之MPAndroidChart LineChart折线图(三)
Android 图表开源框架之MPAndroidChart LineChart折线图(四)动态添加数据
Android 图表开源框架之MPAndroidChart LineChart折线图(五)
Android 图表开源框架之MPAndroidChart PieChart扇形图(一)
Android 图表开源框架之MPAndroidChart PieChart扇形图(二)
Android 图表开源框架之MPAndroidChart LineChart之常用自定义设置功能
一.快速实现:(当前mpandroidchartlibrary版本是2.1.6版本)
1.主函数代码:
实现单、双曲线折线图,设置折线颜色,实现刷新数据、折线翻页(上一页、下一页操作逻辑),实现折线滑动、缩放效果、设置限制线、临界线、Legend图例等
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.bin.david.form.core.SmartTable;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
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.ArrayList;
import java.util.List;
import me.samlss.utils.LineChartManager2;
/**
*
* https://blog.csdn.net/shenggaofei/article/details/106450732
*
*/
public class MpAndroidChartActivity extends AppCompatActivity {
//参考网址 https://github.com/msandroid/androidChartDemo
private LineChart lineChart1, lineChart2;
private LineData lineData;
private LineChart lineChartSgf;
private List lists = new ArrayList<>();
private List mylists = new ArrayList<>();
private List plists = new ArrayList<>();
private int num = 0;
private int nums = 0;
private int total = 0;
private int init = 10;
private boolean isBottom =false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mp_chart);
// setDataViewTen();
setData();
initChart2();
initChart();
Button btRefresh = (Button) findViewById(R.id.bt_refresh);
Button btPrevious = (Button) findViewById(R.id.bt_previous);
Button btNext = (Button) findViewById(R.id.bt_next);
btPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
isBottom =false;
if(num<=1){
Toast.makeText(MpAndroidChartActivity.this,"到顶了",Toast.LENGTH_SHORT).show();
init = 20;
nums = 10;
// num = 0;
return;
}else {
}
// mylists.clear();
//屏幕显示的取值范围:1-10,11-20等,每一屏显示10条数据
// for (int i = 0; i < lists.size(); i++) {
// if(i%5==0){
// mylists.add(lists.get(i));
// Log.e("SGF",mylists.size()+"");
// }
// }
// lists.clear();
// lists.addAll(mylists);
// initChart();
// // 像ListView那样的通知数据更新
// lineChartSgf.notifyDataSetChanged();
// lineChartSgf.invalidate();
int myCycelTotal = total / 10;
float myCycelTotalFloat = (float) (total / 10.0);
if(myCycelTotalFloat>myCycelTotal){
myCycelTotal = myCycelTotal+1;
}
if(myCycelTotal=10){
// init-=10;
// }else {
// init = 10;
// }
// if(nums>0){
// nums-=10;
// }
plists = getPageByList(lists, num, 10);
if(num>0) {
num--;
}
if(init>=10){
init-=10;
}else {
init = 10;
}
if(nums>0){
nums-=10;
}
//循环添加数据
// int myCycelTotal = total / 10;
int cycelTotal = total / init;
if (total % init != 0) {
// cycelTotal += 1;
if (total < init) {
init = lists.size();
}
}
List list2 = new ArrayList();
// for (int i = 0; i < cycelTotal; i++) {//循环页数
for (int j = nums; j < init; j++) {
if(lists!=null){
if (lists.get(j) == null) {
break;
}
list2.add(lists.get(j));
}
}
System.out.println("保存1000条数据到数据库....");
System.out.println(list2);//每次循环保存的数据输出
lists.clear();
int av = lists.size();
lists.addAll(list2);
// lists.addAll(plists);
initChart();
// 像ListView那样的通知数据更新
lineChartSgf.notifyDataSetChanged();
lineChartSgf.invalidate();
//接下来写保存数据库方法
//.............
// lists.removeAll(list2);//移出已经保存过的数据
// list2.clear();//移出当前保存的数据
// }
if(num>0){
// num--;
// if(init>10){
// init-=10;
// }
// if(nums>0){
// nums-=10;
// }
}
// if(num>0){
// init-=10;
// nums-=10;
// }
int a = num;
int b = nums;
int c = init;
int cc = init;
}
});
btNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//屏幕显示的取值范围:1-10,11-20等,每一屏显示10条数据
setData();//重新获取总数据来计算
// if(lists.size()>=10){
// if(lists.size() % 10 >=1){
//
// }
// }
//list中有一批数据,每次取10笔出来处理
// int init = 10;
// int total = lists.size();
int myCycelTotal = total / 10;
float myCycelTotalFloat = (float) (total / 10.0);
if(myCycelTotalFloat>myCycelTotal){
myCycelTotal = myCycelTotal+1;
}
if(isBottom&&num>=myCycelTotal){
Toast.makeText(MpAndroidChartActivity.this,"到底了",Toast.LENGTH_SHORT).show();
num =myCycelTotal;
if(nums>20){
nums-=10;
}
if(init>=10){
init-=10;
}
return;
}
int cycelTotal = total / init;
if (total % init != 0) {
cycelTotal += 1;
if (total < init) {
init = lists.size();
}
}
// if(num>=myCycelTotal){
List list2 = new ArrayList();
// for (int i = 0; i < cycelTotal; i++) {//循环页数
for (int j = nums; j < init; j++) {
if(lists!=null){
if (lists.get(j) == null) {
break;
}
list2.add(lists.get(j));
}
}
System.out.println("保存1000条数据到数据库....");
System.out.println(list2);//每次循环保存的数据输出
lists.clear();
lists.addAll(list2);
initChart();
// 像ListView那样的通知数据更新
lineChartSgf.notifyDataSetChanged();
lineChartSgf.invalidate();
//接下来写保存数据库方法
//.............
// lists.removeAll(list2);//移出已经保存过的数据
// list2.clear();//移出当前保存的数据
// }
// if(num=myCycelTotal){
Toast.makeText(MpAndroidChartActivity.this,"到底了",Toast.LENGTH_SHORT).show();
isBottom = true;
num =myCycelTotal;
if(nums>20){
nums-=10;
}
if(init>=10){
init-=10;
}
}else {
// nums+=10;
// init+=10;
}
int a = num;
int b = nums;
int c = init;
int cc = init;
}
});
btRefresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 生成随机测试数
// float f = (float) ((Math.random()) * 20 + 50);
//
// lists.add(f);
setDataNew();
initChart();
// 像ListView那样的通知数据更新
lineChartSgf.notifyDataSetChanged();
lineChartSgf.invalidate();
//
//设置x轴的数据
// int numX = 5;
// //设置y轴的数据
// float[] datas1 = {536, 123, 769, 94, 85};//数据
// float[] datas2 = {736, 123, 126, 494, 85};//数据
// //设置折线的名称
// LineChartManager2.setLineName("当月值");
// //设置第二条折线y轴的数据
// LineChartManager2.setLineName1("上月值");
// //创建两条折线的图表
// lineData = LineChartManager2.initDoubleLineChart(MpAndroidChartActivity.this, lineChart1, numX, datas1, datas2);
// LineChartManager2.initDataStyle(lineChart2, lineData, MpAndroidChartActivity.this);
}
});
}
private void setData(){
//设置y轴的数据
lists.clear();
lists.add(166f);
lists.add(122f);
lists.add(145f);
lists.add(178f);
lists.add(155f);
lists.add(121f);
lists.add(111f);
lists.add(190f);
lists.add(180f);
lists.add(166f);
lists.add(266f);
lists.add(222f);
lists.add(245f);
lists.add(278f);
lists.add(255f);
lists.add(221f);
lists.add(211f);
lists.add(290f);
lists.add(280f);
lists.add(266f);
lists.add(366f);
lists.add(322f);
lists.add(345f);
lists.add(378f);
lists.add(355f);
lists.add(366f);
lists.add(355f);
lists.add(369f);
lists.add(332f);
lists.add(376f);
lists.add(466f);
lists.add(422f);
lists.add(445f);
lists.add(478f);
lists.add(455f);
lists.add(466f);
lists.add(455f);
lists.add(409f);
lists.add(432f);
lists.add(476f);
lists.add(566f);
lists.add(522f);
lists.add(545f);
lists.add(578f);
lists.add(555f);
lists.add(566f);
lists.add(555f);
// lists.add(509f);
// lists.add(532f);
// lists.add(576f);
total = lists.size();
// mylists.add(900f);
// mylists.add(200f);
// mylists.add(300f);
// mylists.add(900f);
// lists.addAll(mylists);
// plists = getPageByList(lists, 3, 10);
// lists.clear();
lists.addAll(plists);
// for (int i = 0; i < plists.size(); i++) {
// lists.add(plists.get(i));
// }
// int oo = lists.size();
}
/**
* 初始化取前十条值
*/
private void setDataViewTen(){
setData();//重新获取总数据来计算
int myCycelTotal = total / 10;
if (total % init != 0) {
if (total < init) {
init = lists.size();
}
}
if(num>=myCycelTotal){
Toast.makeText(MpAndroidChartActivity.this,"到底了",Toast.LENGTH_SHORT).show();
return;
}
List list2 = new ArrayList();
for (int j = nums; j < init; j++) {
if(lists!=null){
if (lists.get(j) == null) {
break;
}
list2.add(lists.get(j));
}
}
System.out.println("保存1000条数据到数据库....");
System.out.println(list2);//每次循环保存的数据输出
lists.clear();
lists.addAll(list2);
initChart();
// 像ListView那样的通知数据更新
lineChartSgf.notifyDataSetChanged();
lineChartSgf.invalidate();
if(num xValues = new ArrayList();
for (int i = 0; i < numX; i++) {
// x轴显示的数据,这里默认使用数字下标显示
// xValues.add("第" + (i+1) + "人");
xValues.add((i+100)+"");
}
// y轴的数据
ArrayList yValues = new ArrayList();
for (int i = 0; i < numX; i++) {
yValues.add(new Entry(lists.get(i), i));
}
//设置折线的样式
LineDataSet dataSet = new LineDataSet(yValues, "当月值");
// 改变折线样式,用曲线。
// mLineDataSet.setDrawCubic(true);
// 默认是直线
// 曲线的平滑度,值越大越平滑。
// mLineDataSet.setCubicIntensity(0.2f);
// 填充曲线下方的区域,红色,半透明。
dataSet.setDrawFilled(true);
dataSet.setFillAlpha(50);
dataSet.setFillColor(Color.RED);
// dataSet.setFillColor(R.drawable.gradient_chart_bg2);
int[] colors = { getResources().getColor(R.color.colorAccent),
getResources().getColor(android.R.color.white) };
// dataSet.setFillColor(getResources().getColor(R.drawable.gradient_chart_bg2));
//设置曲线下方渐变的阴影
// lineDataSet.setDrawFilled(true);
// lineDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_gradient_bg_shape));
//用y轴的集合来设置参数
dataSet.setLineWidth(1.75f); // 线宽
dataSet.setCircleSize(2f);// 显示的圆形大小
dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色
dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色
dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色
dataSet.setHighlightEnabled(true);
dataSet.setValueTextColor(Color.rgb(89, 194, 230)); //数值显示的颜色
dataSet.setValueTextSize(8f); //数值显示的大小
ArrayList dataSets = new ArrayList<>();
dataSets.add(dataSet);
//构建一个LineData 将dataSets放入
LineData lineData = new LineData(xValues, dataSets);
lineChartSgf.setData(lineData);
lineChartSgf.setDrawBorders(false); //在折线图上添加边框
//lineChart.setDescription("时间/数据"); //数据描述
lineChartSgf.setDrawGridBackground(false); //表格颜色
lineChartSgf.setGridBackgroundColor(Color.GRAY & 0x70FFFFFF); //表格的颜色,设置一个透明度
lineChartSgf.setTouchEnabled(true); //可点击
lineChartSgf.setScaleEnabled(false); //可缩放
lineChartSgf.setPinchZoom(false);
lineChartSgf.setBackgroundColor(Color.WHITE); //设置背景颜色
lineChartSgf.setData(lineData);
// 设置限制临界线
setLimitLineData(200,"sv",lineChartSgf,1);
// lineChart.setVisibleXRange(0, 6);//x轴可显示的坐标范围
//设置在曲线图中显示的最大数量
// lineChart.setVisibleXRangeMaximum(10);
setLimitLineData(290,"sd",lineChartSgf,1);
setLimitLineData(350,"2sd",lineChartSgf,1);
setLimitLineData(170,"sd-",lineChartSgf,1);
setLimitLineData(99,"2sd",lineChartSgf,1);
setLimitLineData(500,"test",lineChartSgf,1);
setLimitLineData2(400,"tt",lineChartSgf,1);
Legend mLegend = lineChartSgf.getLegend(); //设置标示,就是那个一组y的value的
mLegend.setForm(Legend.LegendForm.SQUARE); //样式
mLegend.setFormSize(6f); //字体
mLegend.setTextColor(Color.GRAY); //颜色
XAxis xAxis = lineChartSgf.getXAxis(); //x轴的标示
// xAxis.setSpaceBetweenLabels(5);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //x轴位置
xAxis.setTextColor(Color.GRAY); //字体的颜色
xAxis.setTextSize(10f); //字体大小
xAxis.setGridColor(Color.GRAY);//网格线颜色
xAxis.setDrawGridLines(false); //不显示网格线
YAxis axisLeft = lineChartSgf.getAxisLeft(); //y轴左边标示
YAxis axisRight = lineChartSgf.getAxisRight(); //y轴右边标示
axisLeft.setTextColor(Color.GRAY); //字体颜色
axisLeft.setTextSize(10f); //字体大小
// axisLeft.setAxisMaxValue(800f+10); //最大值
// axisLeft.setLabelCount(5, true); //显示格数
axisLeft.setGridColor(Color.GRAY); //网格线颜色
axisLeft.setDrawGridLines(false);//设置不显示y坐标的线
axisRight.setDrawAxisLine(false);
axisRight.setDrawGridLines(false);
axisRight.setDrawLabels(false);
if(lists.size()>=5){
// lineChartSgf.setScaleMinima(2.0f,1.0f);
// lineChartSgf.setDragEnabled(true); //可拖拽
// lineChartSgf.setVisibleXRange(0, 5); //x轴可显示的坐标范围
}else {
// lineChartSgf.setDragEnabled(false); //可拖拽
// lineChartSgf.setVisibleXRangeMaximum(lists.size());
lineChartSgf.setVisibleXRange(0, lists.size()); //x轴可显示的坐标范围
// lineChartSgf.setScaleMinima(1.5f,1.0f);
}
//设置动画效果
lineChartSgf.animateY(2000, Easing.EasingOption.Linear);
lineChartSgf.animateX(2000, Easing.EasingOption.Linear);
lineChartSgf.invalidate();
}
private void initChart2() {
lineChart2 = (LineChart) findViewById(R.id.line_chart);
//设置图表的描述
lineChart2.setDescription("双曲线");
//设置x轴的数据
int numX = 24;
//设置y轴的数据
float[] datas1 = {536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85};//数据
float[] datas2 = {736, 123, 369, 132, 82, 126, 94, 85, 136, 123, 369, 632, 102, 126, 94, 85, 136, 123, 269, 432, 102, 26, 494, 85};//数据
//设置折线的名称
LineChartManager2.setLineName("当月值");
//设置第二条折线y轴的数据
LineChartManager2.setLineName1("上月值");
//创建两条折线的图表
lineData = LineChartManager2.initDoubleLineChart(this, lineChart1, numX, datas1, datas2);
LineChartManager2.initDataStyle(lineChart2, lineData, this);
}
/**
* 设置临界点 虚线、实、线
* @param limitNum
* @param label
* @param lineChart
*/
private void setLimitLineData(int limitNum,String label,LineChart lineChart,int type) {
LimitLine limitLine = new LimitLine(limitNum, label);// 临界点
limitLine.setLineColor(Color.RED);
if(type == 1){//设置虚线,默认实线
limitLine.enableDashedLine(5.0f, 3.0f, 3.0f);
}
limitLine.setLineWidth(1.5f);
limitLine.setTextSize(10);
limitLine.setTextColor(Color.RED);
limitLine.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
lineChart.getAxisLeft().removeLimitLine(limitLine);
lineChart.getAxisLeft().addLimitLine(limitLine);
}
private void setLimitLineData2(int limitNum,String label,LineChart lineChart,int type) {
//设置虚线的临界点
LimitLine avgLine2 = new LimitLine((float) limitNum);
avgLine2.setLabel(label);
if(type == 1){
avgLine2.enableDashedLine(5.0f, 3.0f, 3.0f);
}
avgLine2.setLineColor(Color.parseColor("#33CC33"));
avgLine2.setTextSize(10);
avgLine2.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
lineChartSgf.getAxisLeft().addLimitLine(avgLine2);
}
@Override
protected void onDestroy() {
super.onDestroy();
// moveViewToAnimated 移动到某个点,有内存泄漏,暂未修复,希望网友可以指着
lineChartSgf.clearAllJobs();
lineChartSgf.clearAnimation();
lineChartSgf.clearFocus();
lineChartSgf.clearValues();//执行后再次执行clear(),空指针
lineChartSgf.cancelLongPress();
lineChartSgf.clear();
lineChartSgf.removeAllViewsInLayout();
lineChartSgf.removeAllViews();
}
/**
* 集合分页
*
* @param resourceList 要分页的集合
* @param pageIndex 页码
* @param pageSize 每页条数
* @return 分页后的集合
*/
public List getPageByList(List resourceList, int pageIndex, int pageSize) {
List pageList = new ArrayList<>();
if (pageIndex < 1) {
pageIndex = 1;
}
int size = resourceList.size();
int pageCount = size / pageSize;
int fromIndex = (pageIndex - 1) * pageSize;
int toIndex = fromIndex + pageSize;
if (toIndex >= size) {
toIndex = size;
}
if (pageIndex > pageCount + 1) {
fromIndex = 0;
toIndex = 0;
}
pageList = resourceList.subList( fromIndex, toIndex );
return pageList;
}
}
2.布局: