先直接上图把。
x轴,底部为1440点,对应一天的1440分钟。
数据可能不是连续的,所以如果连续超过10分钟(10个点)都没有点的时候。就把前面加过的数据作为数据集,加入到datasets数组内。
最后形成的结果就是,数据集和折线的数量是不确定的。会根据数据源的变化而变化,形成这样比较好看,而且时间也比较精准的折线图。
核心代码:
/**
* Demo class representing data.
*/
public class Data {
final String xAxisValue;
final float yValue;
final float xValue;
final long Timestamp;
Data(float xValue, float yValue, String xAxisValue,long mTimestamp) {
this.xAxisValue = xAxisValue;
this.yValue = yValue;
this.xValue = xValue;
this.Timestamp = mTimestamp;
}
}
private void SetXYData(String dataday){
//初始化数据源
data = new ArrayList<>();
this.setDataDay(dataday);
String mData = DataDay;
float x;
float y;
long mTimesTamp;
//查7-28号的数据,将时间戳和Rate拿出来。
TemHeartRate_TableList = (List<HeartRate_Table>)mHeart_LitePad.CheckDateByTimestamp("2C:4D:79:C1:85:4E",mData,1);
long mStart_Timestamp = ( mHeart_LitePad.dateToLong(mData)) /1000l; //转化过来是毫秒级的,所以/1000
long mEnd_Timestamp = mStart_Timestamp+60*60*24;//-->86400
float point = (int) (mEnd_Timestamp - mStart_Timestamp) /60;
for( HeartRate_Table d : TemHeartRate_TableList){
//将数据中的时间戳与今天开始时间对比,则知道该放到哪个点
x = mHeart_LitePad.SeparatedMinute(mStart_Timestamp*1000, d.getDate());//对比是毫秒级的
Data_xValue.add(x);
y = d.getHeart_rate();
Data_yValue.add(y);
mTimesTamp = d.getDate();
Data_Timestamp.add(mTimesTamp);
}
int StablePointCount = 0;
for(float i = 0;i<=point;i++){
boolean StablePoint = (( (int) i%360) == 0);
//是否包含这个点,是的话瞄点用数列,否则瞄0
if( Data_xValue.contains(i) ){
int indexof = Data_xValue.lastIndexOf(i);//同一个分钟(点),去设置最大的那个值
if( StablePoint )
{
if(i ==0){
MothDay = mHeart_LitePad.getTime_ymd(mStart_Timestamp*1000);
data.add(new Data(i, Data_yValue.get(indexof), MothDay, Data_Timestamp.get(indexof) ));
}else{
StablePointCount++;
HourMinute = mHeart_LitePad.getTime_hm( (mStart_Timestamp)*1000 +StablePointCount*1000*60*60*6);
data.add(new Data(i, Data_yValue.get(indexof), HourMinute,Data_Timestamp.get(indexof)));
}
}else{
data.add(new Data(i, Data_yValue.get(indexof), "",Data_Timestamp.get(indexof) ));
}
}else{
if( StablePoint )
{
if(i ==0){
MothDay = mHeart_LitePad.getTime_ymd(mStart_Timestamp*1000);
data.add(new Data(i, 0, MothDay, (long)( (mStart_Timestamp)*1000+60*i) ));
}else{
StablePointCount++;
HourMinute = mHeart_LitePad.getTime_hm( (mStart_Timestamp)*1000 +StablePointCount*1000*60*60*6);
data.add(new Data(i, 0, HourMinute,(long)( (mStart_Timestamp)*1000+60*i)));
}
}else{
data.add(new Data(i, 0, "",(long)( ((mStart_Timestamp)*1000)+(60*i*1000)) ));
}
}
}
//设置之前先清除数据
chart.clear();
//设定表中的数据
//SetChartDataxx();
DrawChartPoint_dynamic();
// draw points over time,绘制点的动画时间
chart.animateX(2000);
}
//有点则瞄点,无则不瞄点
private void DrawChartPoint_dynamic(){
ArrayList<Entry> values = new ArrayList<>();
//连续几分钟的计时
int continue_count=0;
List<LineDataSet> SetList = new ArrayList<>();
//DataSets列表-->数据集
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
LineDataSet set1;
int count=data.size();
for (int i = 0; i < count; i++) {
float val = (float) data.get(i).yValue;
if(data.get(i).yValue == 0 ){
//values.add(new Entry(data.get(i).xValue, 0));
continue_count++;
}else {
//Log.d(TAG, "SetChartDataxx: xxx");
//有加则清零
continue_count = 0;
values.add(new Entry(data.get(i).xValue, val));
}
//是不是连续十次了
if(continue_count >= 10){
//说明没有存到过valus所以不用管,有的话就生成一个set1往列表里面加
if(values.isEmpty()){
}else{
//初始化LineDataSet以代表该数据集
Log.d(TAG, "values.size: "+values.size());
Log.d(TAG, "SetChartData_dynamic: xxxxxxxx"+values.get(0));
if (chart.getData() != null &&
chart.getData().getDataSetCount() > 0) {
Log.d(TAG, "SetChartData_dynamic: yyyyy");
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
set1.setValues(values);
set1.notifyDataSetChanged();
chart.getData().notifyDataChanged();
} else{
set1 = new LineDataSet(values,"abc"+values.get(0).getX());
//set1.setDrawIcons(false);
//线条的颜色
set1.setColor(R.drawable.fade_red);
//表中数据圆点的颜色
set1.setCircleColor(Color.BLACK);
//表中数据线条的宽度
set1.setLineWidth(1f);
//表中数据的圆点,如果数据多则不瞄点,少则瞄点
if(values.size()>10){
set1.setDrawCircles(false);
set1.setCircleColor(Color.RED);
}
set1.setCircleColor(Color.RED);
set1.setCircleRadius(3f);
//数据显示的字大小
//set1.setValueTextSize(9f);
set1.setDrawValues(false);
// set the filled area
set1.setDrawFilled(true);
set1.setFillFormatter(new IFillFormatter() {
@Override
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
return chart.getAxisLeft().getAxisMinimum();
}
});
// set color of filled area
if (Utils.getSDKInt() >= 18) {
// drawables only supported on api level 18 and above
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.fade_red);
set1.setFillDrawable(drawable);
} else {
set1.setFillColor(Color.BLACK);
}
SetList.add(set1);
dataSets.add(set1);
//重新创建一个对象
values = new ArrayList<>();
Log.d(TAG, "values.size: "+values.size());
}
}
}
}
Log.d(TAG, "SetListEntryCount "+SetList.get(0).getEntryCount());
Log.d(TAG, "SetListEntryCount "+SetList.get(0).getLabel());
Log.d(TAG, "dataSets.size "+dataSets.size());
// create a data object with the data sets
LineData data = new LineData(dataSets);
// set data
chart.setData(data);
chart.notifyDataSetChanged();
chart.invalidate(); // refresh chart
}
数据源思路----->一分钟对应一个点,如果数据库里面有这个点,则在1440的这个数组加入y不为0的unit.
---->如果没有这个点,则填入y=0。
则在描绘点的时候,如果y=0,则不描绘。
---->且如果连续10个点都为0(即无数据)则看values是否为空,如果为空则不增加dataSets单元。如果不为空则创建一个LineDataSet加入进去,最后描绘线的时候就可以描绘出来了。