Android中LineChart设置曲线缩放比例

前人栽树后人乘凉!!!

问题:由于个人需求中曲线数据量较大(最多有10万个点),所有点数据在曲线中全部描绘出来,如果点上画圆圈,则无法正常拖动、缩放等;若只点与点连线不会有卡顿情况。并且数据量过大画图也会很耗时,所以拿到数据后可分段画,利用Handler的定时器一段一段的画,同时需要调moveViewToX方法每次画完之后移动到最后位置,有一个正在加载数据的假象。

题外话:

有人会问既然数据量那么大为什么不用Socket实时获取,我的回答是我的想法就是用Socket但不被采纳!!个人认为用Socket画大量数据的图效果会比较好,而且折线图加载显示的效果会比较流畅,用定时器的这种方法相当于仿了一个Socket但效果不流畅

解决方案:通过对曲线缩放比例的监听动态修改点上圆圈是否需要显示出来

新需求:曲线数据会有中断,两点之间时间间隔超过10分钟视为中断,则两点不进行相连;意思就是如果数据有中断,则需要将曲线显示成多个部分。

解决方案:前端使用的是echarts直接把Y轴值置为空即可中断,但Android端用的是Linechart画点需要传Y轴值(Y轴类型为float,默认为0)所以不能直接置空。我的做法是有中断则画多条曲线addEntry3方法是将曲线进行拼接,如果不拼接则后序的曲线会从0点开始画就会出现叠加的现象;如果需要显示曲线的图例(右下角显示的曲线名称),当前画多条曲线就会有多个图例(这个是没办法解决的,除非不显示图例),当进行曲线切的时候会出现图例没有更新的现象(查看A曲线显示图例A1、图例A1;当切换B曲线则显示图例B1、图例A1),这时就要用到lineChart_quxian.getLineData().removeDataSet(index);切换曲线的时候不光要清空曲线数据还要清空曲线对应的LineDataSet,每次动态创建添加曲线即可(addLine()方法),同时还需要清空lineChart_quxian.setMarker(null);lineChart_quxian.invalidate();曲线上标记点的设置,因为是通过画多条曲线实现的中断,切换曲线的时候如果不清空会报错,重新获取到数据之后重新设置Marker即可。

注意:使用MPAndroidChart-v3.0.1.jar这版jar包就可以(不清楚从哪版改进的),判断两点时间超过10分钟则在两点之间加两个无效值即可Float.NaN,网址:MPAndroidChart实现断线中间不绘制及其如何思考类似的问题_Rex叶然的博客-CSDN博客_mpandroidchart 折线断开

利用的是修改jar包源码,在3.0.1版jar包已经包含进去了这种情况,增加无效值的点就会直接断开;经过多款手机测试发现有的手机无法正常显示折线图,说明这种方法并无法适配所有机型,因此还是建议分段画折线

 ***后续修改:addEntry3方法中xCount的取值有问题,xCount的值应该为index之前前所有曲线的点的总和。然后再在其后边添加新的点

直接上代码

package com.test.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;

//参考网址:https://blog.csdn.net/u014769864/article/details/72723180?locationNum=7&fps=1
/**
 * 自定义LineChart并设置手势滑动事件监听缩放比例(OnChartGestureListener)
 */
public class MyLineChart extends LineChart implements OnChartGestureListener {

    private Context context;
    public MyLineChart(Context context) {
        super(context);
        this.context = context;
    }

    public MyLineChart(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    @Override
    protected void init() {
        super.init();
        setOnChartGestureListener(this);
    }
    @Override
    public void clear() {
        super.clear();
        //恢复初始缩放比例
        scale = 1;scaleTemp = 1;
    }
    private ScaleGestureDetector mScaleGestureDetector;
    private float scale = 1f;
    private float scaleTemp = 1;

    //手势开始
    @Override
    public void onChartGestureStart(MotionEvent motionEvent, ChartTouchListener.ChartGesture chartGesture) {
        System.out.println("MyLineChart:::手势开始");
    }
    //手势结束
    @Override
    public void onChartGestureEnd(MotionEvent motionEvent, ChartTouchListener.ChartGesture chartGesture) {
        scaleTemp = scale;
        System.out.println("MyLineChart:::手势结束");
    }
    //手势长按
    @Override
    public void onChartLongPressed(MotionEvent motionEvent) {
        System.out.println("MyLineChart:::手势长按");
    }
    //手势双击
    @Override
    public void onChartDoubleTapped(MotionEvent motionEvent) {
        System.out.println("MyLineChart:::手势双击");
    }
    //手势单点
    @Override
    public void onChartSingleTapped(MotionEvent motionEvent) {
        System.out.println("MyLineChart:::手势单点");
    }
    //手势滚动
    @Override
    public void onChartFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        System.out.println("MyLineChart:::手势滚动");
    }
    //手势比例(获取当前缩放比例)
    @Override
    public void onChartScale(MotionEvent motionEvent, float v, float v1) {
        scale = scaleTemp * v;
        if (scale<=1.0){
            scale = 1;
        }
        listener.onScale(scale);
        System.out.println("MyLineChart:::onChartScale:"+scale);
    }
    //手势边界
    @Override
    public void onChartTranslate(MotionEvent motionEvent, float v, float v1) {
        System.out.println("MyLineChart:::手势边界:");
    }

	NowScaleListener listener;
    public void setNowScaleList
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值