Android自动缩放上下限折线图示例

目录
  • 正文
  • AutoLineChart完整代码

正文

一条折线,根据最大最小值自动缩放上下限。

  • 继承View
  • 数据使用FloatBuffer存储
  • 可改变显示窗口的大小
  • 可指定坐标轴,折线和字体颜色

AutoLineChart完整代码

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import java.nio.FloatBuffer;
public class AutoLineChart extends View {
    private static final String TAG = "rustApp" + AutoLineChart.class.getSimpleName();
    private float yMax = 1.6f;
    private float yMin = -1.0f;
    float yAxisZoomLimitMax = 1.6f;
    float yAxisZoomLimitMin = -1.0f; // 缩小y轴的极限值
    // Y轴自动缩放时的增减距离
    float axisYPerStep = 0.1f;
    // 图表线条在view顶部留出的间距
    float viewYStart = 2;
    float axisTextSize = 10;
    private int onShowPointsCount = 500;  // 当前显示的数据个数
    int onShowMinPoints = 100;            // 至少要显示的数据个数
    private int maxPoint = 9000;          // 数据存储最大个数
    // 坐标轴线条宽度
    float axisLineWid = 1f;
    int dataLineWid = 4;
    // 数据线颜色
    private int dataColor = Color.parseColor("#eaffe9");
    // 图表中的背景线条颜色
    private int mainBgLineColor = Color.parseColor("#535353");
    // 坐标轴颜色
    private int axisColor = Color.WHITE;
    // 坐标值字体颜色
    private int axisTextColor = Color.WHITE;
    // 背景色
    private int viewBgColor = Color.parseColor("#222222");
    Rect rectText = new Rect();
    private float xStep = 1.0f;
    private float viewWidth;
    private float viewHeight;
    private float botLeftXOnView = 0; // 图表左下点在view中的x坐标
    private float botLeftYOnView = 0;
    private float originYToBottom = 20; // 图表原点距离view底部的距离
    private FloatBuffer dataBuffer;
    private Paint bgPaint;
    private Paint linePaint;
    public AutoLineChart(Context context) {
        this(context, null);
    }
    public AutoLineChart(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public AutoLineChart(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    public int getMaxPoint() {
        return maxPoint;
    }
    public void setOnShowPointsCount(int onShowPointsCount) {
        this.onShowPointsCount = onShowPointsCount;
    }
    public int getOnShowPointsCount() {
        return onShowPointsCount;
    }
    public int getOnShowMinPoints() {
        return onShowMinPoints;
    }
    public void addData(float data) {
        dataBuffer.put(data);
        if (dataBuffer.position() > (dataBuffer.capacity() * 2 / 3)) {
            float[] bufferArr = dataBuffer.array();
            System.arraycopy(bufferArr, dataBuffer.position() - maxPoint, bufferArr, 0, maxPoint);
            dataBuffer.position(maxPoint);
//            Log.d(TAG, "把当前数据移动到buffer起始位置 " + dataBuffer);
        }
        invalidate();
    }
    private void init(Context context) {
        dataBuffer = FloatBuffer.allocate(3 * maxPoint); // 分配3倍的空间
        bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bgPaint.setStrokeWidth(axisLineWid);
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setColor(mainBgLineColor);
        linePaint.setStrokeWidth(dataLineWid);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(dataColor);
        botLeftXOnView = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, context.getResources().getDisplayMetrics());
        originYToBottom = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());
        viewYStart = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());
        axisLineWid = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics());
        axisTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, context.getResources().getDisplayMetrics());
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = getWidth();
        viewHeight = getHeight();
        botLeftYOnView = viewHeight - originYToBottom;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(viewBgColor);
        xStep = (viewWidth - botLeftXOnView) / (onShowPointsCount - 1);
        float maxData = 0.1f;
        float minData = 0;
        int dataStartIndexInBuffer = 0; // 数据在buffer中的起始下标
        if (dataBuffer.position() > onShowPointsCount) {
            dataStartIndexInBuffer = dataBuffer.position() - onShowPointsCount;
        }
        float[] bufferArr = dataBuffer.array();
        for (int i = dataStartIndexInBuffer; i < dataBuffer.position(); i++) {
            if (bufferArr[i] < minData) {
                minData = bufferArr[i];
            } else if (bufferArr[i] > maxData) {
                maxData = bufferArr[i];
            }
        }
        zoomYAxis(maxData, minData);
        drawBgLines(canvas);
        drawWave(canvas, dataStartIndexInBuffer);
    }
    // 缩放Y轴
    private void zoomYAxis(float maxData, float minData) {
        if (maxData < yAxisZoomLimitMax) {
            yMax = yAxisZoomLimitMax;
        } else if (maxData < yMax) {
            while (maxData < yMax) {
                yMax -= axisYPerStep;
            }
            yMax += axisYPerStep;
        } else if (maxData > yMax) {
            while (maxData > yMax) {
                yMax += axisYPerStep;
            }
        }
        if (minData > yAxisZoomLimitMin) {
            yMin = yAxisZoomLimitMin;
        } else if (minData > yMin) {
            while (minData > yMin) {
                yMin += axisYPerStep;
            }
            yMin -= axisYPerStep;
        } else if (minData < yMin) {
            yMin -= axisYPerStep;
        }
    }
    private void drawBgLines(Canvas canvas) {
        // 画坐标轴
        bgPaint.setStyle(Paint.Style.FILL);
        bgPaint.setStrokeWidth(axisLineWid);
        bgPaint.setTextSize(axisTextSize);
        bgPaint.setTextAlign(Paint.Align.RIGHT);
        for (float y = 0; y <= yMax; y += 0.5) {
            drawYAxis(canvas, y);
        }
        for (float y = 0; y >= yMin; y -= 0.5) {
            drawYAxis(canvas, y);
        }
        bgPaint.setColor(axisColor);
        canvas.drawLine(botLeftXOnView, viewYStart / 2, botLeftXOnView, botLeftYOnView + viewYStart / 2, bgPaint);
//        canvas.drawLine(botLeftXOnView, botLeftYOnView, viewWidth, botLeftYOnView, bgPaint); // x轴
    }
    private void drawYAxis(Canvas canvas, float axisYValue) {
        final float yDataRange = yMax - yMin;
        final float yAxisRangeOnView = botLeftYOnView - viewYStart;
        float aY = botLeftYOnView - (axisYValue - yMin) / yDataRange * yAxisRangeOnView;
        bgPaint.setColor(axisColor);
        canvas.drawLine(botLeftXOnView - 20, aY, botLeftXOnView, aY, bgPaint);
        String axisText = String.valueOf(axisYValue);
        bgPaint.getTextBounds(axisText, 0, axisText.length(), rectText); // 获取文本的宽高
        canvas.drawText(axisText, botLeftXOnView - rectText.width() / 2, aY + rectText.height() / 2, bgPaint);
        bgPaint.setColor(mainBgLineColor);
        canvas.drawLine(botLeftXOnView, aY, viewWidth, aY, bgPaint);
    }
    private void drawWave(Canvas canvas, int dataStartIndexInBuffer) {
        final float yDataRange = yMax - yMin;
        final float yAxisRangeOnView = botLeftYOnView - viewYStart;
        final float yDataStep = yAxisRangeOnView / yDataRange;
        float[] dataArr = dataBuffer.array();
        for (int i = dataStartIndexInBuffer; i < dataBuffer.position() - 1; i++) {
            canvas.drawLine(botLeftXOnView + (i - dataStartIndexInBuffer) * xStep, getYL(dataArr[i], yDataStep),
                    botLeftXOnView + (i - dataStartIndexInBuffer + 1) * xStep, getYL(dataArr[i + 1], yDataStep),
                    linePaint);
        }
    }
    private float getYL(final float yData, float yDataStep) {
        return botLeftYOnView - (yData - yMin) * yDataStep;
    }
}

以上就是Android 自动缩放上下限的折线图的详细内容,更多关于Android 自动缩放上下限的折线图的资料请关注我们其它相关文章!

(0)

相关推荐

  • 学习使用Material Design控件(四)Android实现标题栏自动缩放、放大效果

    本文要实现内容移动时,标题栏自动缩放/放大的效果,效果如下: 控件介绍 这次需要用到得新控件比较多,主要有以下几个: CoordinatorLayout 组织它的子views之间协作的一个Layout,它可以给子View切换提供动画效果. AppBarLayout 可以让包含在其中的控件响应被标记了ScrollingViewBehavior的View的滚动事件 CollapsingToolbarLayout 可以控制包含在CollapsingToolbarLayout其中的控件,在响应colla

  • Android开发自定义控件之折线图实现方法详解

    本文实例讲述了Android开发自定义控件之折线图实现方法.分享给大家供大家参考,具体如下: 前言 折线图是Android开发中经常会碰到的效果,但由于涉及自定义View的知识,对许多刚入门的小白来说会觉得很高深.其实不然,接下来我就以尽量通俗的语言来说明下图折线图效果的实现过程. 效果图 实现过程 首先,选择自定义控件的方式. 自定义控件的实现有四种方式: 1.继承View,重写onDraw.onMeasure等方法. 2.继承已有的View(比如TextView). 3.继承ViewGrou

  • Android实现绘制折线图APP代码

    目录 一.总体设计 二.具体模块实现 三.效果展示 四.功能展望 总结 一.总体设计 1.寻找规律,公式化的生成坐标系. 2.将生成坐标系的关键参数设置为可自定义,从而可变的可以生成自己想要的坐标系. 3.将需要绘制的点绘制在坐标系中并生成折现图. 二.具体模块实现 1.坐标系的生成: public void chart(){ imageView=(ImageView)findViewById(R.id.image); newb = Bitmap.createBitmap(w, h, Bitma

  • Android图表库HelloChart绘制多折线图

    本文实例为大家分享了Android图表库HelloChart绘制多折线图的具体代码,供大家参考,具体内容如下 一.效果图 二.实现步骤 1.添加依赖库 compile 'com.github.lecho:hellocharts-android:v1.5.8' 2.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.a

  • Android绘制动态折线图

    所谓动态折线图,就是折线图能随着手指的滑动进行动态绘制,这里很定会产生动画效果.基于这个效果,这里使用SurfaceView进行制图. 实现步奏如下: (1): 这里新建一个绘图ChartView,继承SurfaceView并实现SurfaceHolder.Callback , Runnable接口,主要绘图工作在子线程中完成. (2):现实 SurfaceHolder.Callback接口的三个方法,并在 surfaceCreated中开启子线程进行绘图. (3):重写onTouchEvent

  • Android自定义可左右滑动和点击的折线图

    前言 前几天有小盆友让我写一个折线图,可以点击,可以左右滑动.对于折线肯定有很多项目都使用过,所以网上肯定也有很多demo,像AndroidChart.HelloChart之类的,功能相当丰富,效果也很赞,但是太重了,其他的小demo又不符合要求,当然了,我写的自定义折线图的思想也有来自这些小demo,对他们表示感谢. 效果图 废话不多说,先上效果图: 效果是不是很赞,如果上图满足你的需求,那就继续往下看. 自定义折线图的步骤: 1.自定义view所需要的属性 确定所需要的自定义view的属性,

  • Android绘制双折线图的方法

    本文实例为大家分享了Android绘制双折线图的具体代码,供大家参考,具体内容如下 自定义View实现双折线图,可点击,点击后带标签描述,暂未实现拖动的功能,实现效果如下: 代码如下: 首先,自定义布局属性: <declare-styleable name="LineChart">     <!--type2.LineChart(双折线图)-->     <attr name="maxYValue" format="integ

  • Android自动缩放上下限折线图示例

    目录 正文 AutoLineChart完整代码 正文 一条折线,根据最大最小值自动缩放上下限. 继承View 数据使用FloatBuffer存储 可改变显示窗口的大小 可指定坐标轴,折线和字体颜色 AutoLineChart完整代码 import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import

  • Android画图实现MPAndroidchart折线图示例详解

    目录 效果图 依赖 activity.xml MainActivity MyMarkerView 自定义class maekertextview .xml 常用属性 效果图 用的是3.1.0的依赖 依赖 allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } } //依赖 dependencies{ implementation 'com.github.PhilJay:MPAndroidCh

  • python数据可视化matplotlib绘制折线图示例

    目录 plt.plot()函数各参数解析 各参数具体含义为: x,y color linestyle linewidth marker 关于marker的参数 plt.plot()函数各参数解析 plt.plot()函数的作用是绘制折线图,它的参数有很多,常用的函数参数如下: plt.plot(x,y,color,linestyle,linewidth,marker,markersize,markerfacecolor,markeredgewidth,markeredgecolor) 各参数具体

  • Android自定义View实现折线图效果

    下面就是结果图(每种状态用一个表情图片表示): 一.主页面的布局文件如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height=&quo

  • Android开发RecyclerView实现折线图效果

    本文实例为大家分享了Android开发RecyclerView实现折线图效果的具体代码,供大家参考,具体内容如下 效果图如下: 实现的关键是自定义的控件: package com.example.recyclelinechart.test; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; imp

  • Android自定义View简易折线图控件(二)

    继续练习自定义View,这次带来的是简易折线图,支持坐标点点击监听,效果如下: 画坐标轴.画刻度.画点.连线..x.y轴的数据范围是写死的 1 <= x <= 7 ,1 <= y <= 70 ..写活的话涉及到坐标轴刻度的动态计算.坐标点的坐标修改,想想就头大,这里只练习自定义View. 1.在res/values文件夹下新建attrs.xml文件,编写自定义属性: <?xml version="1.0" encoding="utf-8"

  • java和matlab画多边形闭合折线图示例讲解

    1.使用matlab作闭合多边形图 没有找到直接画多边形的函数,只能是将各个点的坐标保存在数组中,将一个点与其相邻的点相连,并将最后一个点与第一个点连接.下面是一个示例的.m文件: 复制代码 代码如下: clear;clc;a=[0 2 4 6 8 10 12 14;0 2 1 4 6 6 5 7];  %要连接的点坐标 x;y[n,m]=size(a);for i=1:m-1;    line([a(1,i),a(1,i+1)],[a(2,i),a(2,i+1)]);  %连接节点line([

  • java 自动生成略缩图示例代码

    当你要做一个图库的项目时,对图片大小.像素的控制是首先需要解决的难题.一.单图生成略缩图单图经过重新绘制,生成新的图片.新图可以按一定比例由旧图缩小,也可以规定其固定尺寸.详细代码如下: 复制代码 代码如下: <SPAN style="FONT-SIZE: 14px">import com.sun.image.codec.jpeg.JPEGImageEncoder;import com.sun.image.codec.jpeg.JPEGCodec;import com.su

  • Python可视化神器pyecharts绘制折线图详情

    目录 折线图介绍 折线图模板系列 双折线图(气温最高最低温度趋势显示) 面积折线图(紧贴Y轴) 简单折线图(无动态和数据标签) 连接空白数据折线图 对数轴折线图示例 折线图堆叠(适合多个折线图展示) 二维曲线折线图(两个数据) 多维度折线图(颜色对比) 阶梯折线图 js高渲染折线图 折线图介绍 折线图和柱状图一样是我们日常可视化最多的一个图例,当然它的优势和适用场景相信大家肯定不陌生,要想快速的得出趋势,抓住趋势二字,就会很快的想到要用折线图来表示了.折线图是通过直线将这些点按照某种顺序连接起来

随机推荐