MPAndroidchart实现自定义样式
先上效果:
ActivityChartLine.class:
package com.usung.mybletwo.activity;
import android.annotation.SuppressLint;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.widget.TextView;
import com.github.mikephil.charting.charts.LineChart;
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.usung.mybletwo.R;
import com.usung.mybletwo.base.BaseActivity;
import com.usung.mybletwo.base.BaseApplication;
import com.usung.mybletwo.bean.Tobacco;
import com.usung.mybletwo.util.LogUtils;
import com.usung.mybletwo.util.TimeUtil;
import com.usung.mybletwo.widget.MyXAxisValueFomatter;
import com.usung.mybletwo.widget.MyYAxisValueFomatter;
import org.litepal.LitePal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Descriptions: 折线图表(可左右滑动)
* Created by fenghui on 2019/3/12.
*/
public class ActivityChartLineextends BaseActivityimplements TabLayout.OnTabSelectedListener {
private LineChartmLineChart1, mLineChart2, mLineChart3;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chart_line);
getIntentValue();
// createSqlData();
initView();
}
void getIntentValue(){
// productName = getIntent().getStringExtra("productName");
}
@Override
public void initView() {
super.initView();
((TextView)findViewById(R.id.tv_title)).setText("统计曲线");
mLineChart1 = findViewById(R.id.lineChart1);
mLineChart2 = findViewById(R.id.lineChart2);
mLineChart3 = findViewById(R.id.lineChart3);
tableLayout();
getDataAndInitChart(0); // 参数为position,position默认为0(默认按周筛选数据)
}
void tableLayout(){
TabLayout mTabLayout = findViewById(R.id.tabLayout);
TabLayout.Tab tab1 = mTabLayout.newTab().setText("周");
TabLayout.Tab tab2 = mTabLayout.newTab().setText("月");
TabLayout.Tab tab3 = mTabLayout.newTab().setText("年");
mTabLayout.addTab(tab1);
mTabLayout.addTab(tab2);
mTabLayout.addTab(tab3);
mTabLayout.addOnTabSelectedListener(this);
}
void initChartLine(){
setChartProperties(mLineChart1, 1, list1);
setChartProperties(mLineChart2, 2, list2);
setChartProperties(mLineChart3, 3, list3);
}
/**
* 原文:https://blog.csdn.net/u013855006/article/details/78702867
*/
@SuppressLint("ResourceAsColor")
private void setChartProperties(LineChart mLineChart, int colorTag, ArrayList list) {
//设置描述文本不显示
mLineChart.getDescription().setEnabled(false);
// Description description = new Description();
// description.setText(productName);
// mLineChart.setDescription(description);
//设置是否显示表格背景
// mLineChart.setDrawGridBackground(true);
mLineChart.setBackgroundColor(getResources().getColor(R.color.chartLine_bg_color)); // 设置背景颜色
//设置是否可以触摸
mLineChart.setTouchEnabled(true);
mLineChart.setDragDecelerationFrictionCoef(0.9f);
mLineChart.setDragEnabled(true); // 设置是否可以拖拽
mLineChart.setScaleEnabled(false); // 设置是否可以缩放
mLineChart.setHighlightPerDragEnabled(false); // 设置选中点高亮显示
mLineChart.setPinchZoom(true);
// 隐藏右边 的坐标轴
mLineChart.getAxisRight().setEnabled(false);
mLineChart.getAxisLeft().setEnabled(true);
// X 轴坐标设置
XAxis xAxis = mLineChart.getXAxis();
// xAxis.setAxisMinimum(0);
xAxis.setTextColor(getResources().getColor(R.color.titleColor)); // 设置X坐标轴刻度坐标文字颜色
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); // 设置图标坐标这刻度在坐标轴下边
xAxis.setGranularity(1f); // 间隔尺寸
xAxis.setGridColor(getResources().getColor(R.color.transparent)); // 设置竖网格线颜色透明,则值显示横网格线
// xAxis.setAvoidFirstLastClipping(true);
xAxis.setGranularity(1f);
xAxis.setLabelCount(list.size(),true);
xAxis.setDrawLabels(true);
if (position ==0){
xAxis.setLabelCount(7);
xAxis.setValueFormatter(new MyXAxisValueFomatter(position, listDateLables));
}else if (position ==1){
xAxis.setLabelCount(6);
xAxis.setValueFormatter(new MyXAxisValueFomatter(position, listDateLables));
}else if (position ==2){
xAxis.setLabelCount(12);
xAxis.setValueFormatter(new MyXAxisValueFomatter(position, listMonthLables));
}
// Y 轴坐标设置
YAxis yAxis = mLineChart.getAxisLeft();
yAxis.setAxisMinimum(0);
yAxis.setTextColor(getResources().getColor(R.color.titleColor));
yAxis.enableGridDashedLine(10f, 5f, 0f); // 设置横网格线为虚线
yAxis.setAxisLineColor(getResources().getColor(R.color.transparent)); // 设置Y轴坐标轴颜色透明
// float ratio = (float) xValueList.size()/(float) 6; // 设置一页最大显示个数为6,超出部分就滑动
yAxis.setValueFormatter(new MyYAxisValueFomatter(colorTag));
float ratio =1;
mLineChart.zoom(ratio,1f,0,0); // 显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
mLineChart.animateX(1500); // 设置从X轴出来的动画时间
// mLineChart.animateXY(1000,1000, Easing.EasingOption.EaseInSine, Easing.EasingOption.EaseInSine); // 设置XY轴动画
setChartData(mLineChart, colorTag, list);
}
private void setChartData(LineChart mLineChart, int colorTag, ArrayList list){
LineDataSet set1;
set1 =new LineDataSet(list, null);
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
if (colorTag ==1){
set1.setColor(getResources().getColor(R.color.chart1_color));
set1.setCircleColor(getResources().getColor(R.color.chart1_color));
}else if (colorTag ==2){
set1.setColor(getResources().getColor(R.color.chart2_color));
set1.setCircleColor(getResources().getColor(R.color.chart2_color));
}else if (colorTag ==3){
set1.setColor(getResources().getColor(R.color.chart3_color));
set1.setCircleColor(getResources().getColor(R.color.chart3_color));
}
set1.setDrawValues(false); // 设置不显示点位的值,默认true
set1.setLineWidth(2f);
set1.setCircleRadius(3f);
set1.setFillAlpha(65);
LineData data =new LineData(set1);
mLineChart.setData(data);
}
@Override
public void getIntentValue(@org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
}
int position =0; // 默认选中周,默认按周查询
@Override
public void onTabSelected(TabLayout.Tab tab) {
LogUtils.Companion.log_I("--------- onTabSelected ---------- tab.getPosition() = " + tab.getPosition());
position = tab.getPosition();
getDataAndInitChart(position);
}
/**
* 获取数据库筛选开始时间
* @param position 0:周, 1:月, 2:年
* @return
*/
long getScreeningTime(int position){
long oneDaySeconds =24 *60 *60 *1000;
long stampMillSecond =0;
switch (position){
case 0:
stampMillSecond = TimeUtil.getLastWeek() + oneDaySeconds;
break;
case 1:
// stampMillSecond = TimeUtil.getLastMonth() + oneDaySeconds;
String time = TimeUtil.stampToDate(new Date().getTime() -29 * oneDaySeconds);
try {
stampMillSecond = TimeUtil.dateToStamp(time.substring(0, 10) +" 00:00:00");
}catch (ParseException e) {
e.printStackTrace();
}
break;
case 2:
String date = TimeUtil.stampToDate(TimeUtil.getLastYear()).substring(0, 10) +" 00:00:00";
try {
stampMillSecond = TimeUtil.dateToStamp(date)+oneDaySeconds;
}catch (ParseException e) {
e.printStackTrace();
}
break;
}
String time = TimeUtil.stampToDate(stampMillSecond);
long stampLastWeek =0;
try {
stampLastWeek = TimeUtil.dateToStamp(time.substring(0, 10) +" 00:00:00");
}catch (ParseException e) {
e.printStackTrace();
}
return stampLastWeek;
}
// list1、list2、list3分表表示周、月、年的抽烟支数的集合
ArrayListlist1 =null; // 第一个表的数据集合(抽烟支数的集合)
ArrayListlist2 =null; // 第二个表的数据集合(焦油量的集合)
ArrayListlist3 =null; // 第三个表的数据集合(一氧化碳的集合)
ListlistTobaccoFilter =null;
private void initList(){
if (list1 ==null){
list1 =new ArrayList<>();
}
if (list2 ==null){
list2 =new ArrayList<>();
}
if (list3 ==null){
list3 =new ArrayList<>();
}
if (listTobaccoFilter ==null){
listTobaccoFilter =new ArrayList<>();
}
list1.clear();
list2.clear();
list3.clear();
}
/**
* 按照周月年查询第一张表的数据(抽烟支数)
* @param position
* @return
*/
ArrayListlistDateLables =new ArrayList<>(); // 日期label
private void queryData(int position){
listTobaccoFilter.clear();
long screeningTimeStart = getScreeningTime(position);
LogUtils.Companion.log_I("------------ screeningTimeStart -------------- "+ screeningTimeStart);
int dataCount =7;
if (position ==0){
dataCount =7;
List tempListTobaccoFilter = LitePal.where("bleAddress = ? and smokeDate >= ? and smokeDate <= ?",
BaseApplication.Companion.getInstance().getOkbleDevice().getMacAddress(),
screeningTimeStart +"", new Date().getTime() +"").find(Tobacco.class);
listTobaccoFilter.addAll(tempListTobaccoFilter);
}else if (position ==1){
dataCount =30;
List tempListTobaccoFilter = LitePal.where("bleAddress = ? and smokeDate >= ? and smokeDate <= ?",
BaseApplication.Companion.getInstance().getOkbleDevice().getMacAddress(),
screeningTimeStart+"", new Date().getTime() +"").find(Tobacco.class);
listTobaccoFilter.addAll(tempListTobaccoFilter);
}else if (position ==2){
dataCount =12;
Cursor cursor = LitePal.findBySQL("SELECT DISTINCT t.month ,(SELECT sum(smokeTotalToday) FROM tobacco WHERE month = t.month AND bleAddress = t.bleAddress ) AS total FROM tobacco AS t WHERE month >= "+screeningTimeStart+" AND bleAddress = '"
+BaseApplication.Companion.getInstance().getOkbleDevice().getMacAddress()+"' ORDER BY month");
ArrayList tempList =new ArrayList<>();
while (cursor.moveToNext()){
long m =cursor.getLong(cursor.getColumnIndex("month")); // 查询到的数据所在月份,m 是在查询语句中定义的
int total = cursor.getInt(cursor.getColumnIndex("total")); // 每个月的总数,total 是在查询语句中定义的
tempList.add(new Entry(Integer.parseInt(TimeUtil.stampToDate(m).substring(5,7)), total));
}
// todo 单据写个方法获取12个月的数据
get12MonthesData(dataCount, tempList);
return ;
}
list1.clear();
if (listTobaccoFilter ==null ||listTobaccoFilter.isEmpty()){
for (int i =1; i <= dataCount; i++) {
list1.add(new Entry(i+1, 0));
}
}else{
listDateLables.clear();
long newData =0;
for (int i =0; i < dataCount; i++) {
newData = screeningTimeStart + i *3600 *24 *1000L;
listDateLables.add(TimeUtil.stampToDateMonthAndDay(newData));
for (int j =0; j
if (TimeUtil.isSameDate(newData, (long)listTobaccoFilter.get(j).getSmokeDate())) {
list1.add(new Entry(i+1, (float)listTobaccoFilter.get(j).getSmokeTotalToday()));
break;
}else{
if (j ==listTobaccoFilter.size()-1){
list1.add(new Entry(i+1, 0));
}
}
}
}
}
}
private void getList2OrList3(int chartType){
double tar = BaseApplication.Companion.getInstance().getListCigaretteDataChecked().get(0).getTar();
double carbonMonoxide = BaseApplication.Companion.getInstance().getListCigaretteDataChecked().get(0).getCarbonMonoxide();
if (chartType ==2){
list2.clear();
}else if (chartType ==3){
list3.clear();
}
for (int i =0; i
if (chartType ==2){
list2.add(new Entry(i +1, (float) (list1.get(i).getY() * tar)));
}else if (chartType ==3){
list3.add(new Entry(i+1, (float) (list1.get(i).getY() * carbonMonoxide)));
}
}
}
/**
* 获取三张表的数据(抽烟支数、焦油量、一氧化碳三个折线图的数据)
*/
private void getDataAndInitChart(int position){
initList();
queryData(position);
getList2OrList3(2); // chartType 1:抽烟支数折线图 2:焦油量折线图 3:一氧化碳折线图
getList2OrList3(3);
initChartLine();
}
/**
* 获取过去12个月的月份
* @return
*/
ArrayListlistMonthLables =new ArrayList<>(); // 月份label
ArrayListgetMonth(int currentMonth){
listMonthLables.clear();
ArrayList listMonth =new ArrayList<>();
for (int i =0; i <12; i++) {
if (1 + currentMonth + i >12){
listMonthLables.add(1 + currentMonth + i -12 +"");
listMonth.add(1 + currentMonth + i -12);
}else {
listMonthLables.add(1 + currentMonth + i+"");
listMonth.add(1 + currentMonth + i);
}
}
return listMonth;
}
/**
* 组装数据(年份数据) 12个月
* @param dataCount
* @param list
*/
private ArrayListget12MonthesData(int dataCount, ArrayList list){
int currentMonth = Integer.parseInt(TimeUtil.stampToDate(new Date().getTime()).substring(5, 7));
ArrayList listMonth = getMonth(currentMonth);
list1.clear();
for (int i =0; i < dataCount; i++) {
for (int m =0; m < list.size(); m++) {
if (listMonth.get(i) == (list.get(m).getX())){
list1.add(new Entry(i+1, list.get(m).getY()));
break;
}else{
if (m == list.size() -1){
list1.add(new Entry(i+1, 0));
}
}
}
}
return list1;
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
自定义X轴刻度:
package com.usung.mybletwo.widget;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.ArrayList;
/**
* Descriptions: 自定义 MPAndroidChart X轴坐标刻度值
* Created by fenghui on 2019/4/12.
*/
public class MyXAxisValueFomatterimplements IAxisValueFormatter {
int position =0;
ArrayListlistXLables =null;
/**
* @param position 此type参数同ActivityChartLine里面的position是一回事,默认为0
* position=0:按周筛选(筛选过去7天),position=1:按月筛选(筛选过去30天),position=2:按年筛选(筛选过去一年)
*/
public MyXAxisValueFomatter(int position, ArrayList listXLables) {
this.position = position;
this.listXLables = listXLables;
}
@Override
public StringgetFormattedValue(float value, AxisBase axis) {
try {// try catch 是因为有一个莫名其妙的错误
String tempValue ="";
if (value ==0) {
tempValue = (int) value +"";
}else {
switch (position) {
case 0:
if (value !=7) {
tempValue =listXLables.get((int) value -1);
}else {
tempValue =listXLables.get((int) value -1);
}
break;
case 1:
if (value !=30) {
tempValue =listXLables.get((int) value -1);
}else {
tempValue =listXLables.get((int) value -1);
}
break;
case 2:
if (value !=12) {
tempValue =listXLables.get((int) value -1);
}else {
tempValue =listXLables.get((int) value -1) +"(月)";
}
break;
}
}
return tempValue;
}catch (Exception e) {
return "";
}
}
}