精华内容
下载资源
问答
  • Android图表

    2017-05-21 21:25:40
    app是对MPAndroidChart的整理,mychart是自己修改的(柱状图和饼图)
  • 1.介绍 MPAndroidChart GitHub地址  MPAndroidChart的强大之处就不在多说了,目前最新的版本是3.0.1,在新版本中很多方法都被弃用了,这个要注意一下,在网上查到的大多数资料都是关于旧版本的,今天来实现一下...
  • android 图表

    2013-05-17 20:02:55
    android柱状图 android曲线图 android饼状图 android统计图表
  • 作者Idtk,源码SmallChart,SmallChart是一个开源的Android图表库,拥有5种不同的图表类型来展示数据。可以通过输入的数据以及可设置的颜色、画笔大小等属性方便的创建图表。
  • 主要为大家详细介绍了一个酷炫的Android图表制作框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • android图表

    2019-02-19 14:08:41
    由于Google提供的AChartEngine的功能强大但使用起来较为复杂,MPAndroidChart同样能够实现一些效果较好的直方图,折线图,饼图等绘制,使用也较为简单轻便; 介绍MPAndroidChart
  • Android图表小Demo

    2016-08-05 11:46:40
    hellochart使用简单Demo
  • android图表控件

    2014-10-09 14:20:19
    android中的柱柱图、线形图、网状图
  • MPAndroidChart 是一个强大的 Android 图表库,它提供了漂亮而全面的图表和图形。 它功能强大且易于使用,支持创建条形图、折线图、饼图、气泡图、散点图、雷达图和烛台图,以及缩放、拖动和动画。 图表呈现干净且...
  • Android图表框架库

    2018-10-30 16:26:58
    Android App开发使用的图表框架,可以在App中轻松实现多种图表。 如:K线图,折线图,柱状图,环形图等等,近20多种
  • 通过 ViewPager 与 Fragment 实现 水平页面滑动分别显示 饼状图、折线图、柱形图
  • Android图表年度最强总结,一篇文章从入门到精通!

    万次阅读 多人点赞 2020-03-13 14:35:28
    说到Android图表,不得不说一说MPAndroidChart这个强大的开源图表库,什么折线图、柱状图、饼图、气泡图、蜡烛图、混合图那是应有尽有!

    说到Android图表,不得不说一说MPAndroidChart这个强大的开源图表库,至于有多强大,先给你看看实现的效果图!如果效果图成功地引起了你的注意,那么,嘿嘿嘿,当然是把这篇文章看完,最后再点个赞!


    悄咪咪告诉你,这只是可实现效果的冰山一角(还有很多效果图我放在文章的最后面了)
    在这里插入图片描述
    MPAndroidChart是GitHub一个名叫Philipp的大神所写,可又绘制各种图表的一个库。在现在大数据即将来临的时代,用图表来展示数据,更直观易懂。并且很多行业(比如股票、医疗等等…)都需要图表来支撑。所以,画图对我们程序员来说也是一门必要的技术。其中图表的类型有这些:**LineChart(折线图)BarChart(柱状图),HorizontalBarChart(横向柱状图)CandleStickChart(蜡烛图)BubbleChart(气泡图)PieChart(饼状图)RadarChart(雷达图)ScatterChart(散点图)CombinedChart(组合图)。**

    添加依赖

    只需要简单地添加上依赖就可以愉快的使用这个强大的图标库了!
    具体操作请跳转至我的原创博客:MPAndroidChart的详细使用——添加依赖

    创建视图以及简单实现

    实现一个简单的图很简单,首先需要在你的XML文件中添加上一个视图(View),然后后台代码中创建一个List<Entry>,再把X轴和Y轴数据传入List中,接着创建DataSet对象和Data对象传入相应的参数,最后控件调用setData()方法传入你的Data对象,一个折线图就生成了!大致代码就是这样子:

    //其中两个参数对应的分别是   X轴   Y轴
    list.add(new Entry(0,7));     
    list.add(new Entry(1,10));
    list.add(new Entry(2,12));
    list.add(new Entry(3,6));
    list.add(new Entry(4,3));
    //list是你这条线的数据  "语文" 是你对这条线的描述
    LineDataSet lineDataSet=new LineDataSet(list,"语文");   
    LineData lineData=new LineData(lineDataSet);
    //有多条数据则使用adddataset()方法 参数是你的DataSet
    //lineData.addDataSet(lineDataSet);
    

    具体代码以及实现请跳转至我的原创博客:MPAndroidChart的详细使用——创建视图以及简单实现

    图表的交互

    图表的交互,指的是你对图表的一些操作,比如:缩放手势、点击、长按、拖拉等等,这些事件都可以通过设置来进行启用(或禁用)以及事件的监听回调。如下是监听回调的部分方法:

    public interface OnChartGestureListener {
        //长按监听事件回调
        public void onChartLongPressed(MotionEvent me);
        //双击监听事件回调
        public void onChartDoubleTapped(MotionEvent me);
       //单击监听事件回调
        public void onChartSingleTapped(MotionEvent me);
    }
    

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——图表的交互

    高亮

    在这里插入图片描述
    如上图,高亮指的是当你点击图表中某个数据时,那个数据会突出显示(当然你可以禁用),高亮显示可以启用(或禁用),也可以对高亮进行样式的设置、甚至可以通过重写高亮类然后使用setHighlighter(ChartHighlighter highlighter)方法传入你自定义的高亮类进行自定义样式(比如定义成一个图片的样子…),并且高亮也有事件的监听回调:

    public interface OnChartValueSelectedListener {
        //选中一处高亮时的回调
        public void onValueSelected(Entry e, Highlight h);
        //没有选中时的回调
        public void onNothingSelected();
    }
    

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——高亮

    坐标轴

    坐标轴作为图表最重要的元素之一,对其进行一番美化是非常有必要的!比如你可以通过setEnabled(boolean enabled)方法设置是否绘制坐标轴,也可以通过setAxisMaximum(float max)方法设置坐标轴上的最大值、最小值。根据需要,你甚至可以通过setInverted(boolean enabled)把坐标轴反转过来!当然,坐标轴有一个非常重要的属性是经常需要设置的,那就是坐标轴上的标签,可能你需要显示的X轴是星期的形式,而默认的则是阿拉伯数字,这里直接通过.setValueFormatter();方法重新格式化一下即可!部分X轴的实现方法如下:

    XAxis xAxis = chart.getXAxis();//实例化X轴对象进行使用
    //设置X轴位置 有以下几种   TOP   BOTTOM   BOTH_SIDED   TOP_INSIDE    BOTTOM_INSIDE
    xAxis.setPosition(XAxisPosition.BOTTOM);
    //设置X轴标签数据绘制的角度   也就是X轴上数据标签的旋转角度
    xAxis.setLabelRotationAngle(90)
    xAxis.setTextColor(Color.RED);//设置标签字体颜色
    // 自定义X轴上的数据格式
    xAxis.setValueFormatter(new MyCustomFormatter());
    

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——坐标轴(X轴、Y轴、零线)

    添加数据

    添加数据其实很简单,只需要写一个List,然后向里面添加你的数据,但是由于绘制不同图表所需要填入的参数不同,List<>尖括号里面所包含的类型也需要转变,比如折线图(LineChart)是List,比如条形图(BarChart)是List,而饼图(PieChart)则是List等等,每种图都有不同的Entry,所以你添加数据时参数也会有所差异,下面列举了几个例子:

    //折线图(LineChart)添加数据
    List<Entry>list=new ArrayList<>();   
    //其中两个参数对应的分别是   X轴   Y轴
    list.add(new Entry(1,10));
    list.add(new Entry(2,12));
    
    //条形图(BarChart)添加数据
    List<BarEntry>list=new ArrayList<>();
    //其中两个数字对应的分别是   X轴   Y轴
    list.add(new BarEntry(1,7));     
    list.add(new BarEntry(2,10));
    
    //饼图(PieChart)添加数据
    List<PieEntry> list= new ArrayList<>();
    //第一个参数是当前所占区域的大小数据,第二个参数是当前扇形的描述
    list.add(new PieEntry(20, "软件设计"));
    list.add(new PieEntry(30, "英语"));
    

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——设置数据

    ValueFormatter接口

    如下图,其中折线上数据的单位、X轴标签的自定义都是通过ValueFormatter接口来实现的,ValueFormatter接口可以对图表数据、X轴、Y轴进行数据的格式化(自定义),在实际开发中是一个非常常用的接口,也是学习图表必学的技能点之一!
    在这里插入图片描述
    在这里插入图片描述
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——ValueFormatter接口

    图表样式设置

    在这里插入图片描述
    说到图表的一些样式设置,如上图是简单地设置了一下图表的背景颜色,想要作出一个漂亮的图表,图表的整块视图的样式设置就显得极为重要了,比如你需要调整一下整个图表的背景颜色只需要调用setBackgroundColor(int color)方法,比如你想设置整个图表的边框以及边框线的宽度只需要调用setBorderColor(int color)setBorderWidth(float width)方法即可,等等的方法还有很多…
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——图表的设置and图表样式设置

    图例

    图例同样作为图表最重要的元素之一,其样式的美化也是学习图表必不可少的一门功课,如下图,图例的样式以及位置那是千变万化,只需要小小几行代码,你就可以拥有一个精美的小图例,你可以调用setEnabled(boolean enabled)方法来禁用(或启用)图例,你也可以调用setPosition(LegendPosition pos)方法来设置图例在图表中的位置,你甚至可以setCustom(int[] colors, String[] labels)自定义图例的颜色以及标签文本的内容!
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——Legend图例的详细设置

    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    图表的描述(右下角的英文)

    在这里插入图片描述
    刚学习图表的同学可能会注意到,无论画的是什么类型的图表,右下角总是会有一串很小的英文字母,也不知道干啥的,总是和狗皮膏药一样跟着你的每一个图表,当然英语比较好的同学就能看懂单词的意思,那就是图表的描述,实际开发中我们用到图表的描述的时候并不多,你要说给图表加描述,你大可以在图表的上方加上一个TextView,可以实现更多的标题样式,而这个描述你要让它显示在你的图表正上方,然后去定义一些字体大小、字体颜色完全不如去写一个TextView简单,说归说,用法还是要会的,嘿嘿嘿
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——图表描述的设置(右下角的那串英文)

    图表动态数据

    在这里插入图片描述
    如上图,动态数据也是实际开发中经常需要用到的属性,这里演示的添加数据和删除数据,当然如果你是要做一个实时更新数据图表也是同理,只需要对你的数据重新进行设置,然后调用.notifyDataSetChanged().invalidate()方法对图表的数据以及显示进行更新,你就会看到一个拥有全新数据的图表出现在你面前!
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——图表动态实时数据

    修改视窗显示

    修改视窗显示,实际上是对View的显示进行一些设置,比如利用setVisibleXRangeMaximum(float maxXRange)方法,对一次最大显示的X轴大小进行定义,或者利用setExtraOffsets(float left, float top, float right, float bottom)设置额外的偏移量(围绕图表视图),再或者可以调用centerViewTo(float xValue, float yValue, AxisDependency axis)将当前视图的中心移动到指定的x值和y值,以及利用代码对视图进行缩放等等…
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——修改视窗显示

    动画

    在这里插入图片描述
    作为一名效果派,一个图表没有个像样的动画哪里行?木呆木呆那都不是我的风格,这里只是演示了动画中最简单的Y轴动画,注意这是最简单的,可以说是最Low的效果,有多少种你就数数下面多少种吧(20+),效果之多我都想用图表做个动画片了~

    public enum EasingOption {//由于效果太多,中间用逗号隔开了
    Linear,EaseInQuad,EaseOutQuad,EaseInOutQuad,EaseInCubic,EaseOutCubic,EaseInOutCubic,EaseInQuart,
    EaseOutQuart,EaseInOutQuart,EaseInSine,EaseOutSine,EaseInOutSine,EaseInExpo,EaseOutExpo,EaseInOutExpo,
    EaseInCirc,EaseOutCirc,EaseInOutCirc,EaseInElastic,EaseOutElastic,EaseInOutElastic,EaseInBack,EaseOutBack,
    EaseInOutBack,EaseInBounce,EaseOutBounce,EaseInOutBounce
    }
    

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——动画

    MarkerView

    iMarker接口可以实现自定义高亮显示标记的视图,只需要写一个类去继承MarkerView,然后实例化Marker以后,调用图表的.setMarker()方法即可。
    这里是两个预设的IMarker

    MarkerView允许加载一个layout去展示对应的标注,继承这个类并重写refreshContent(…)方法来使用标注数据
    MarkerImage允许加载一张图片在标注上显示对应的图片,继承这个类并重写refreshContent(…)方法来使用标注数据

    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——MarkerView

    ChartData类以及ChartData子类

    ChartData类是所有数据类(子类)的基类,类似于LineData, BarData、…诸若此类。它用于为Chart通过setData(…)图表的方法。其实很多时候用ChartData的子类的方法就能够满足功能需求,这里是为了让你更好的熟悉和了解图表的数据模型。先写一个类继承ChartData,然后重写一些方法等等,这里不多BB。
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——ChartData类以及ChartData子类

    DataSet类以及DataSet子类

    DataSet类是所有数据集类(子类)的基类,类似于LineDataSet, BarDataSet、…诸若此类。其方法基本和ChartData一样,所以也不多BB。
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——DataSet类以及DataSet子类

    ViewPortHandler(视图控制器)

    ViewPortHandler类负责处理图表的视图端口。这意味着它负责图表视图中可见的内容,它在平移和缩放级别、图表的大小以及绘图区域和当前偏移量方面都是当前状态。这个ViewPortHandler允许直接访问上述所有属性并修改它们。建议:这方面的设置最好是有一定水平且熟悉API的人来进行操作,否则可能会出现很多意外错误。
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——ViewPortHandler(视图控制器)

    FillFormat接口

    FillFormatter接口允许自定义LineDataSet的数据应在何处不进行绘制(也就是跳过)。只需要创建一个类并实现FillFormatter接口来使用。很简单,写一个类实现FillFormat接口,然后DataSet对象调用.setFillFormatter()方法传入参数即可实现。
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——FillFormat接口

    很有用的杂项设置

    这部分是官方归类为杂项的一些方法,比如:清除图表数据、以及一些获取图表的信息的方法、还有把图表保存成图片存放在手机的图库等等…!有一些都是实际开发经常需要使用的方法,所以也很重要!比如clear()清除图表中所有的数据,比如isEmpty()判断图表数据对象是否为空,再比如saveToGallery(String title)将当前图表作为图像保存到图库(需权限)。
    具体代码以及更多实现请跳转至我的原创博客:MPAndroidChart的详细使用——杂类(很有用)

    最后献上一大波效果图

    折线图的
    在这里插入图片描述
    条形图的
    在这里插入图片描述
    饼图的
    在这里插入图片描述
    雷达图、气泡图、散点图、、蜡烛图、组合图的
    在这里插入图片描述
    第一篇破万字的博客,如果屏幕前的你觉得写得还不是太烂。。。点个赞鼓励一下下呗~| 点个赞再走!!!

    展开全文
  • android图表demo

    2015-12-16 15:33:23
    这个demo非常好,5分值得的,这是花了心血整理的
  • 本文是关于Android开源图表控件的整理,塞选条件基于以下三个...使用简单,但功能强大,而且支持Realm,兼容Android 2.2及以上版本,一直保持Android图表开源控件里面的一哥地位。有意思的是,MPAndroidChart还有一个.

     Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3.0)_xhuww的博客-CSDN博客

     Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)_xhuww的博客-CSDN博客_android linechart

     Android图表控件MPAndroidChart之线形图表介绍(LineChart)_盒Beauty的博客-CSDN博客_android linechart

    AndroidMPChart学习之LineChart详细总结_AlexMoonStriver的博客-CSDN博客_android chart 

    Android图表控件MPAndroidChart——BarChart实现多列柱状图以及堆积柱状图_xhuww的博客-CSDN博客_android柱状图控件 

    本文是关于Android开源图表控件的整理,塞选条件基于以下三个:

    • Github上的start、watch、fork数其中有两项超过100;
    • 同时还需要作者最近半年仍在维护更新;
    • 使用文档基本齐全;

    MPAndroidChart

    https://github.com/PhilJay/MPAndroidChart

    使用简单,但功能强大,而且支持Realm,兼容Android 2.2及以上版本,一直保持Android图表开源控件里面的一哥地位。有意思的是,MPAndroidChart还有一个iOS平台的版本(https://github.com/danielgindi/Charts)。

    HelloCharts

    https://github.com/lecho/hellocharts-android

    最低兼容Android 2.2,开启已经硬件加速后效果会更好,作者更推荐在Android 4.0以上的平台使用。

    WilliamChart

    https://github.com/diogobernardino/WilliamChart

    最低兼容Android 4.0,作者不仅仅是想实现一个图表功能的控件,他更希望能够优雅直观的效果来为用户展示可视化数据。

    总结

    Github上能找到的,口碑和维护还不错的控件就这么多,其他符合要求的欢迎补充。

    展开全文
  • Android图表控件

    2015-05-19 11:24:48
    相当漂亮的图表控件。包含动画自定义,复合图表,有很强的扩展性。
  • android:text="线形图表" android:textColor="@color/btn_white" android:textSize="20sp"/> android:id="@+id/chart_v_LineChart" android:layout_width="match_parent" android:layout_height="300dp"/> ...
    效果:

    在这里插入图片描述

    一,添加依赖:

    1 . 在project的build.gradle中添加依赖:

        repositories {
            //......//
            maven { url "https://jitpack.io"}//chart需求
        }
    

    2 . 在app的build.gradle中添加依赖:

    dependencies {
        //......//
        implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
    }
    
    二,布局文件:
    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <!-- 线形图表 -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingTop="20dp"
                android:paddingBottom="20dp"
                android:divider="@drawable/spacer_medium8"
                android:showDividers="middle"
                android:background="#ffd2d2">
                <TextView
                    android:id="@+id/chart_btn_LineChart"
                    android:layout_width="160dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center|left"
                    android:background="@color/btn_gray"
                    android:padding="8dp"
                    android:text="线形图表"
                    android:textColor="@color/btn_white"
                    android:textSize="20sp"/>
                <com.github.mikephil.charting.charts.LineChart
                    android:id="@+id/chart_v_LineChart"
                    android:layout_width="match_parent"
                    android:layout_height="300dp"/>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:divider="@drawable/spacer_medium8"
                    android:showDividers="middle"
                    android:padding="5dp">
                    <TextView
                        android:id="@+id/chart_btn_lc_changeTheVerValue"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="是否显示顶点值"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                    <TextView
                        android:id="@+id/chart_btn_lc_changeFilled"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="是否填充"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                    <TextView
                        android:id="@+id/chart_btn_lc_changeTheVerCircle"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="是否显示圆点"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:divider="@drawable/spacer_medium8"
                    android:showDividers="middle"
                    android:padding="5dp">
                    <TextView
                        android:id="@+id/chart_btn_lc_changeMode"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="切换立方"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                    <TextView
                        android:id="@+id/chart_btn_lc_animationX"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="x轴动画"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                    <TextView
                        android:id="@+id/chart_btn_lc_animationY"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="y轴动画"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:divider="@drawable/spacer_medium8"
                    android:showDividers="middle"
                    android:padding="5dp">
                    <TextView
                        android:id="@+id/chart_btn_lc_animationXY"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="xy轴动画"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                    <TextView
                        android:id="@+id/chart_btn_lc_refresh"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:background="@color/btn_gray"
                        android:text="刷新数据"
                        android:textSize="15sp"
                        android:textColor="@color/btn_black"/>
                </LinearLayout>
            </LinearLayout>     
        </LinearLayout>
    </ScrollView>
    
    三,封装类(可以直接用,也可修改成自己需求的):
    import android.graphics.Color;
    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 com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
    import com.github.mikephil.charting.listener.OnChartGestureListener;
    import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
    import com.github.mikephil.charting.utils.Utils;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 线形图表
     */
    public class MPLineChartManager {
        //线形表
        private LineChart mLineChart;
        private List<LineDataSet> setList;
        public MPLineChartManager(LineChart lineChart){
            this.mLineChart = lineChart;
            setList = new ArrayList<>();
        }
        /**
         * 设置X轴
         * @param isEnable 设置轴启用或禁用 如果禁用以下的设置全部不生效
         * @param isgdl x轴上每个点对应的线 true=显示/false=禁用
         * @param gdl 设置竖线的显示样式 若isgdl=true时显示: 0=实线/!0=虚线
         * @param xColor x轴字体颜色
         * @param xPosition x轴的显示位置
         * @param xAngle x轴标签的旋转角度
         * */
        public void setXAxis(boolean isEnable, boolean isgdl, float gdl, int xColor, XAxis.XAxisPosition xPosition, float xAngle){
            XAxis xAxis = mLineChart.getXAxis();
            xAxis.setEnabled(isEnable);//设置轴启用或禁用 如果禁用以下的设置全部不生效
            xAxis.setDrawGridLines(isgdl);//设置x轴上每个点对应的线
            //设置竖线的显示样式为虚线:lineLength控制虚线段的长度,spaceLength控制线之间的空间
            xAxis.enableGridDashedLine(gdl, gdl, 0f);
            xAxis.setDrawLabels(true);//绘制标签  指x轴上的对应数值
            xAxis.setPosition(xPosition);//设置x轴的显示位置
            xAxis.setTextColor(xColor);//设置字体颜色
    
            xAxis.setAvoidFirstLastClipping(true);//图表将避免第一个和最后一个标签条目被减掉在图表或屏幕的边缘
            xAxis.setLabelRotationAngle(xAngle);//设置x轴标签的旋转角度
        }
        /**
         * 设置Y轴
         * @param lineList 限制线列表
         * @param gdl 虚线设置
         * */
        public void setYLeftAndLimit(List<LimitLine> lineList, float gdl) {
            mLineChart.getAxisRight().setEnabled(false);//禁用右边的轴线
            YAxis leftAxis = mLineChart.getAxisLeft();
            //重置所有限制线,以避免重叠线
            leftAxis.removeAllLimitLines();
            //设置限制线
            if (lineList != null){
                for (LimitLine item : lineList) {
                    leftAxis.addLimitLine(item);
                }
            }
            leftAxis.enableGridDashedLine(gdl, gdl, 0f);
            leftAxis.setDrawLimitLinesBehindData(true);//是否绘制0所在的网格线
        }
        public void setYRightAndLimit(List<LimitLine> lineList, float gdl) {
            mLineChart.getAxisLeft().setEnabled(false);
            YAxis rightAxis = mLineChart.getAxisRight();
            //重置所有限制线,以避免重叠线
            rightAxis.removeAllLimitLines();
            //设置限制线
            for (LimitLine item : lineList){
                rightAxis.addLimitLine(item);
            }
            rightAxis.enableGridDashedLine(gdl, gdl, 0f);
            rightAxis.setDrawLimitLinesBehindData(true);
        }
        /**
         * 设置与图表交互
         * @param isTE 设置是否可以触摸  为fase时后面无效
         * @param isDE 是否可以拖拽
         * @param isDX 是否可以缩放 仅x轴
         * @param isDY 是否可以缩放 仅y轴
         * @param isDXY 设置x轴和y轴能否同时缩放。默认是false
         * @param isDoubleMax 设置是否可以通过双击屏幕放大图表。默认是true
         * @param isHPDE 能否拖拽高亮线(数据点与坐标的提示线),默认是true
         * @param isDDLE 拖拽滚动时,手放开是否会持续滚动,默认是true(false是拖到哪是哪,true拖拽之后还会有缓冲)
         * */
        public void setInteraction(boolean isTE, boolean isDE, boolean isDX, boolean isDY, boolean isDXY,
                                   boolean isDoubleMax, boolean isHPDE, boolean isDDLE){
            mLineChart.setTouchEnabled(isTE); // 设置是否可以触摸
            mLineChart.setDragEnabled(isDE);// 是否可以拖拽
            mLineChart.setScaleEnabled(false);// 是否可以缩放 x和y轴, 默认是true
            mLineChart.setScaleXEnabled(isDX); //是否可以缩放 仅x轴
            mLineChart.setScaleYEnabled(isDY); //是否可以缩放 仅y轴
            mLineChart.setPinchZoom(isDXY);  //设置x轴和y轴能否同时缩放。默认是否
            mLineChart.setDoubleTapToZoomEnabled(isDoubleMax);//设置是否可以通过双击屏幕放大图表。默认是true
            mLineChart.setHighlightPerDragEnabled(isHPDE);//能否拖拽高亮线(数据点与坐标的提示线),默认是true
            mLineChart.setDragDecelerationEnabled(isDDLE);//拖拽滚动时,手放开是否会持续滚动,默认是true(false是拖到哪是哪,true拖拽之后还会有缓冲)
            mLineChart.setDragDecelerationFrictionCoef(0.99f);//与上面那个属性配合,持续滚动时的速度快慢,[0,1) 0代表立即停止。
        }
        /**
         * 设置图例
         * @param position 设置图例的位置 Legend.LegendPosition.枚举
         * @param txtSize 设置文字大小
         * @param type 正方形,圆形或线 Legend.LegendForm.枚举
         *
         * */
        public void setLegend(Legend.LegendPosition position, float txtSize, int txtColor, Legend.LegendForm type){
            Legend legend = mLineChart.getLegend();//图例
            legend.setPosition(position);//设置图例的位置
            legend.setTextSize(txtSize);//设置文字大小
            legend.setTextColor(txtColor);
            legend.setForm(type);//正方形,圆形或线
            legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
            legend.setFormSize(8f); // 设置Form的大小
            legend.setWordWrapEnabled(true);//是否支持自动换行 目前只支持BelowChartLeft, BelowChartRight, BelowChartCenter
            legend.setFormLineWidth(0f);//设置Form的宽度
        }
        //x轴动画
        public void animationX(int duration){
            mLineChart.animateX(duration);
        }
        public void animationX(int duration, Easing.EasingOption eo){
            mLineChart.animateX(duration, eo);
        }
        //y轴动画
        public void animationY(int duration){
            mLineChart.animateY(duration);
        }
        public void animationY(int duration, Easing.EasingOption eo){
            mLineChart.animateY(duration, eo);
        }
        //xy轴动画
        public void animationXY(int x, int y) {
            mLineChart.animateXY(x, y);
        }
        public void animationXY(int x, int y, Easing.EasingOption eox, Easing.EasingOption eoy) {
            mLineChart.animateXY(x, y, eox, eoy);
        }
        /**
         * 创建
         * @param values 数据值
         * @param title 标题
         * @param dl 线各种长度
         * @param color 颜色
         * @param txtSize 字体大小
         * @param isDHL 是否禁用点击高亮线
         * @param dHL 线
         * @param colorDHL 线颜色
         * @param isFill 是否充填
         * @param colorFill 充填颜色
         * */
        public void addData(ArrayList<Entry> values, String title, float dl, int color, float txtSize,
                            boolean isDHL, float dHL, int colorDHL,
                            boolean isFill, int colorFill) {
            // 创建一个数据集,并给它一个类型
            LineDataSet set = new LineDataSet(values, title);
            // 在这里设置线
            set.enableDashedLine(dl, dl, 0f);
            set.setColor(color);
            set.setCircleColor(color);
            set.setLineWidth(1f);
            set.setCircleRadius(2f);
            set.setValueTextSize(txtSize);
            //是否禁用点击高亮线
            set.setHighlightEnabled(isDHL);
            set.enableDashedHighlightLine(dHL, dHL, 0f);//点击后的高亮线的显示样式
            set.setHighlightLineWidth(2f);//设置点击交点后显示高亮线宽
            set.setHighLightColor(colorDHL);//设置点击交点后显示交高亮线的颜色
            //填充
            set.setDrawFilled(isFill);
            if (Utils.getSDKInt() >= 18) {// 填充背景只支持18以上
                //Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
                //set.setFillDrawable(drawable);
                set.setFillColor(colorFill);
            } else {
                set.setFillColor(Color.BLACK);
            }
            setList.add(set);
    
            //ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            添加数据集
            //dataSets.add(set);
            创建一个数据集的数据对象
            //LineData data = new LineData(dataSets);
            谁知数据
            //mLineChart.setData(data);
        }
    
        public void setData(){
            ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            //添加数据集
            for (LineDataSet item : setList){
                dataSets.add(item);
            }
            //创建一个数据集的数据对象
            LineData data = new LineData(dataSets);
            //谁知数据
            mLineChart.setData(data);
        }
        /**
         * 刷新数据
         * @param lists 数据列表
         * */
        public void refreshData(List<ArrayList<Entry>> lists) {
            for (int i=0; i < setList.size(); i++) {
                setList.set(i, (LineDataSet) mLineChart.getData().getDataSetByIndex(i));
                setList.get(i).setValues(lists.get(i));
            }
            mLineChart.getData().notifyDataChanged();
            mLineChart.notifyDataSetChanged();
        }
    
        // 刷新
        public void invalidate(){
            this.mLineChart.invalidate();
        }
        
        //是否显示顶点值
        public void changeTheVerValue(boolean b){
            //获取到当前值
            List<ILineDataSet> sets = mLineChart.getData().getDataSets();
            for (ILineDataSet iSet : sets) {
                LineDataSet set = (LineDataSet) iSet;
                //切换显示/隐藏
                set.setDrawValues(b);
            }
            //刷新
            invalidate();
        }
        //是否填充
        public void changeFilled(boolean b){
            List<ILineDataSet> setsFilled = mLineChart.getData().getDataSets();
            for (ILineDataSet iSet : setsFilled) {
                LineDataSet set = (LineDataSet) iSet;
                set.setDrawFilled(b);
            }
            invalidate();
        }
        //是否显示圆点
        public void changeTheVerCircle(boolean b){
            List<ILineDataSet> setsCircles = mLineChart.getData().getDataSets();
            for (ILineDataSet iSet : setsCircles) {
                LineDataSet set = (LineDataSet) iSet;
                set.setDrawCircles(b);
            }
            invalidate();
        }
        //切换立方
        public void changeMode(LineDataSet.Mode mode){
            List<ILineDataSet> setsCubic = mLineChart.getData().getDataSets();
            for (ILineDataSet iSet : setsCubic) {
                LineDataSet set = (LineDataSet) iSet;
                set.setMode(mode);
            }
            invalidate();
        }
        //设置监听事件
        public void setListener(OnChartGestureListener onChartGestureListener, OnChartValueSelectedListener onChartValueSelectedListener){
            //设置手势滑动事件
            mLineChart.setOnChartGestureListener(onChartGestureListener);
            //设置数值选择监听
            mLineChart.setOnChartValueSelectedListener(onChartValueSelectedListener);
        }
    }
    
    
    四,调用(例子):

    在Activity中调用例子,可根据自己的需求修改。
    1 . 定义,初始化相关组件及添加事件:

        private MPLineChartManager mpLineChartManager;
        private View chart_btn_LineChart;
        private LineChart chart_v_LineChart;
        private View chart_btn_lc_changeTheVerValue;
        private boolean is_changeTheVerValue = true;
        private View chart_btn_lc_changeFilled;
        private boolean is_changeFilled = true;
        private View chart_btn_lc_changeTheVerCircle;
        private boolean is_changeTheVerCircle = true;
        private View chart_btn_lc_changeMode;
        private int state_changeMode = 1;
        private TextView chart_btn_lc_animationX;
        private TextView chart_btn_lc_animationY;
        private int state_animationY = 1;
        private View chart_btn_lc_animationXY;
        private View chart_btn_lc_refresh;
    
        private void initLineChart(){
            chart_btn_LineChart = findViewById(R.id.chart_btn_LineChart);
            chart_v_LineChart = (LineChart) findViewById(R.id.chart_v_LineChart);
            chart_btn_lc_changeTheVerValue  = findViewById(R.id.chart_btn_lc_changeTheVerValue);
            chart_btn_lc_changeFilled = findViewById(R.id.chart_btn_lc_changeFilled);
            chart_btn_lc_changeTheVerCircle = findViewById(R.id.chart_btn_lc_changeTheVerCircle);
            chart_btn_lc_changeMode = findViewById(R.id.chart_btn_lc_changeMode);
            chart_btn_lc_animationX = (TextView) findViewById(R.id.chart_btn_lc_animationX);
            chart_btn_lc_animationY = (TextView) findViewById(R.id.chart_btn_lc_animationY);
            chart_btn_lc_animationXY = (TextView) findViewById(R.id.chart_btn_lc_animationXY);
            chart_btn_lc_refresh = findViewById(R.id.chart_btn_lc_refresh);
    
            chart_btn_lc_refresh.setOnClickListener(clickListener);
            chart_btn_lc_animationXY.setOnClickListener(clickListener);
            chart_btn_LineChart.setOnClickListener(clickListener);
            chart_btn_lc_changeTheVerValue.setOnClickListener(clickListener);
            chart_btn_lc_changeFilled.setOnClickListener(clickListener);
            chart_btn_lc_changeTheVerCircle.setOnClickListener(clickListener);
            chart_btn_lc_changeMode.setOnClickListener(clickListener);
            chart_btn_lc_animationX.setOnClickListener(clickListener);
            chart_btn_lc_animationY.setOnClickListener(clickListener);
        }
            
        private View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()){
                    //  start --------------- 线形图 ------------------
                    case R.id.chart_btn_lc_refresh: // 刷新
                    {
                        click_lc_Refresh();
                        break;
                    }
                    case R.id.chart_btn_lc_animationXY:// x,y轴动画
                    {
                        mpLineChartManager.animationXY(3000, 3000);
                        break;
                    }
                    case R.id.chart_btn_lc_animationY:// y轴动画
                    {
                        click_lc_AnimationY();
                        break;
                    }
                    case R.id.chart_btn_lc_animationX:// x轴动画
                    {
                        Random rand = new Random();
                        int duration = (rand.nextInt(20) + 1) * 1000;
                        mpLineChartManager.animationX(duration);
                        chart_btn_lc_animationX.setText("x轴动画 " + String.valueOf(duration));
                        break;
                    }
                    case R.id.chart_btn_lc_changeMode://切换立方
                    {
                        click_lc_changeMode();
                        break;
                    }
                    case R.id.chart_btn_lc_changeTheVerCircle://是否显示顶点
                    {
                        click_lc_changeTheVerCircle();
                        break;
                    }
                    case R.id.chart_btn_lc_changeFilled://是否填充
                    {
                        click_lc_changeFilled();
                        break;
                    }
                    case R.id.chart_btn_lc_changeTheVerValue://是否显示顶点值
                    {
                        click_lc_changeTheVerValue();
                        break;
                    }
                    case R.id.chart_btn_LineChart: //创建线形图表
                    {
                        clickLineChart();
                        break;
                    }
                    //  end --------------- 线形图 ------------------
                }
            }
        };
    
    

    2 . 创建图表:

        private void clickLineChart() {
            mpLineChartManager = new MPLineChartManager(chart_v_LineChart);
            mpLineChartManager.setXAxis(true, true, 10f, Color.BLUE, XAxis.XAxisPosition.BOTTOM, 10f);
            // 假数据 限制线列表(可以不添加)
            LimitLine limit1 = new LimitLine(180f, "优秀");
            limit1.setLineWidth(1f);
            limit1.enableDashedLine(10f, 10f, 0f);
            limit1.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
            limit1.setTextSize(10f);
            LimitLine limit2 = new LimitLine(120f, "不及格");
            limit2.setLineWidth(1f);
            limit2.enableDashedLine(10f, 10f, 0f);
            limit2.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
            limit2.setTextSize(10f);
            // 添加限制线值
            List<LimitLine> lineList = new ArrayList<>();
            lineList.add(limit1);
            lineList.add(limit2);
            mpLineChartManager.setYLeftAndLimit(lineList, 10f);
    
            //假数据 折线1111
            ArrayList<Entry> values1 = new ArrayList<Entry>();
            values1.add(new Entry(100, 120));
            values1.add(new Entry(120, 150));
            values1.add(new Entry(130, 120));
            values1.add(new Entry(140, 130));
            values1.add(new Entry(150, 110));
            mpLineChartManager.addData(values1, "小兵一号", 0f, Color.BLUE,8f,
                    false, 5f, Color.GREEN,
                    true, Color.YELLOW);
    
            //假数据 折线2222
            ArrayList<Entry> values2 = new ArrayList<Entry>();
            values2.add(new Entry(100, 30));
            values2.add(new Entry(120, 60));
            values2.add(new Entry(130, 100));
            values2.add(new Entry(140, 180));
            values2.add(new Entry(150, 20));
            mpLineChartManager.addData(values2, "小兵二号", 5f, Color.BLACK,8f,
                    false, 5f, Color.GREEN,
                    true, Color.RED);
    
            mpLineChartManager.setData();
            mpLineChartManager.setInteraction(true,true, true, true, false,
                    false, false, false);
            mpLineChartManager.setLegend(Legend.LegendPosition.ABOVE_CHART_LEFT, 10f, Color.BLACK, Legend.LegendForm.CIRCLE);
            mpLineChartManager.invalidate();
        }
    

    3 . 刷新数据:

        private void click_lc_Refresh(){
            //假数据  临时测试值,根据实情处理
            Random random = new Random();
            int n1 = random.nextInt(200);
            int n2 = random.nextInt(200);
            int n3 = random.nextInt(200);
            int n4 = random.nextInt(200);
            int n5 = random.nextInt(200);
            // 假数据 折线1111
            ArrayList<Entry> values1 = new ArrayList<Entry>();
            values1.add(new Entry(100, n1));
            values1.add(new Entry(120, n2));
            values1.add(new Entry(130, n3));
            values1.add(new Entry(140, n4));
            values1.add(new Entry(150, n5));
            // 假数据 折线2222
            ArrayList<Entry> values2 = new ArrayList<Entry>();
            values2.add(new Entry(100, n5));
            values2.add(new Entry(120, n4));
            values2.add(new Entry(130, n3));
            values2.add(new Entry(140, n2));
            values2.add(new Entry(150, n1));
            // 执行
            List<ArrayList<Entry>> list = new ArrayList<>();
            list.add(values1);
            list.add(values2);
            mpLineChartManager.refreshData(list);
            mpLineChartManager.invalidate();
        }
    

    4 . 是否显示顶点值:

        private void click_lc_changeTheVerValue(){
            if (is_changeTheVerValue){
                is_changeTheVerValue = false;
            }else {
                is_changeTheVerValue = true;
            }
            mpLineChartManager.changeTheVerValue(is_changeTheVerValue);
        }
    

    5 . 是否填充:

        private void click_lc_changeFilled(){
            if (is_changeFilled){
                is_changeFilled = false;
            }else {
                is_changeFilled = true;
            }
            mpLineChartManager.changeFilled(is_changeFilled);
        }
    

    6 . 是否显示顶点:

        private void click_lc_changeTheVerCircle(){
            if (is_changeTheVerCircle){
                is_changeTheVerCircle = false;
            }else {
                is_changeTheVerCircle = true;
            }
            mpLineChartManager.changeTheVerCircle(is_changeTheVerCircle);
        }
    

    7 . 切换立方(线的形状):

        private void click_lc_changeMode(){
            if (state_changeMode == 1) {
                state_changeMode = 2;
                mpLineChartManager.changeMode(LineDataSet.Mode.CUBIC_BEZIER);
            } else if (state_changeMode == 2) {
                state_changeMode = 3;
                mpLineChartManager.changeMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
            } else if (state_changeMode == 3) {
                state_changeMode = 4;
                mpLineChartManager.changeMode(LineDataSet.Mode.STEPPED);
            } else if (state_changeMode == 4) {
                state_changeMode = 1;
                mpLineChartManager.changeMode(LineDataSet.Mode.LINEAR);
            }
        }
    

    8 . y轴动画(有很多形式,自己找合适的吧!):

        private void click_lc_AnimationY(){
            if (state_animationY == 1){
                state_animationY = 2;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInBack);
                chart_btn_lc_animationY.setText("y轴动画 EaseInBack");
            }else if (state_animationY == 2){
                state_animationY = 3;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInBounce);
                chart_btn_lc_animationY.setText("y轴动画 EaseInBounce");
            } else if (state_animationY == 3){
                state_animationY = 4;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInCirc);
                chart_btn_lc_animationY.setText("y轴动画 EaseInCirc");
            } else if (state_animationY == 4){
                state_animationY = 5;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInCubic);
                chart_btn_lc_animationY.setText("y轴动画 EaseInCubic");
            } else if (state_animationY == 5){
                state_animationY = 6;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInElastic);
                chart_btn_lc_animationY.setText("y轴动画 EaseInElastic");
            } else if (state_animationY == 6){
                state_animationY = 7;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInExpo);
                chart_btn_lc_animationY.setText("y轴动画 EaseInExpo");
            } else if (state_animationY == 7){
                state_animationY = 1;
                mpLineChartManager.animationY(4000, Easing.EasingOption.EaseInOutCubic);
                chart_btn_lc_animationY.setText("y轴动画 EaseInOutCubic");
            }
    

    9 . 备注:
    以上是我的简单总结!

    展开全文
  • Android 图表生成类库

    2021-05-17 15:43:40
    AChartEngine是一个针对Android程序开发的开源图表生成类库。支持以下几种图表类型: 折线图 区域图 散点图 time chart 柱状图 饼状图 bubble chart doughnut chart
  • MPAndroidChart是一个功能强大的Android图表控件库,它实现了许多常见的图表效果。关于MPAndroidChart的使用文章已经很多了,这里不再详细介绍它的使用。当数据量过多时,一部手机小小的屏幕是无法显示完全的。因此...
    前言

    MPAndroidChart是一个功能强大的Android图表控件库,它实现了许多常见的图表效果。关于MPAndroidChart的使用文章已经很多了,这里不再详细介绍它的使用。当数据量过多时,一部手机小小的屏幕是无法显示完全的。因此需要让图表能够放大显示,并提供左右滑动功能。

    实现

    原理:获取图表的Matrix,通过Matrix来实现图表的放大,平移操作。
    关键代码如下:

    // 获取图标Matrix参数
    mMatrix = mMainChart.getViewPortHandler().getMatrixTouch();
    // 设置平移距离(这里是平移到图标的最右边)
    float distance = mMainChart.getContentRect().width() * (scaleX - 1);
    mMatrix.setTranslate(-distance, 0);
    //两个参数分别是x,y轴的缩放比例。
    mMatrix.preScale(scaleX, 1f);
    // 刷新
    mMatrix = mMainChart.getViewPortHandler().refresh(mMatrix, mMainChart, true);
    
    效果如下
    • 可以拖动滑块控制图表的滑动
    • 当图标滑动或缩放时,滑块也会做出相应的改变
    源码解读

    源码地址:
    https://gitee.com/yvxiang/ChartDemo
    https://github.com/TangLiangs/ChartDemo

    DataModel: 数据模型,在使用图表时,需要转换为Entry。

    public class DataModel {
    
        public int x;
    
        public int y;
    
        public DataModel(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    

    MainChartConfig: 图表的基础设置,以及对联动视图的管理。

    public class MainChartConfig {
    
        // 图表
        private LineChart mMainChart;
        // 图表控制滑块
        private ScrollBlockView mSubScroll;
        // 表格默认缩放比例
        private float scaleX = 6;
    
        private Context mContext;
        private Matrix mMatrix;
    
        private List<Entry> entryList = new ArrayList<>();
        private List<Integer> colorList = new ArrayList<>();
    
    
        public MainChartConfig(LineChart mainChart, ScrollBlockView scrollView, Context context) {
            mMainChart = mainChart;
            mSubScroll = scrollView;
            mContext = context;
            mMatrix = mMainChart.getViewPortHandler().getMatrixTouch();
            initData();
        }
    
        /**
         * 初始化数据
         */
        private void initData() {
            setMainChart();
            setMainXConfig();
            setMainYConfig();
            setScrollConfig();
            setScrollViewRate();
        }
    
        /**
         * 图表绘制
         */
        public void setData(List<DataModel> dataModels) {
            parseEntry(dataModels);
            setMainLineData();
            refresh();
        }
    
        /**
         * 刷新表格
         */
        private void refresh() {
            // 设置自动缩放
            float distance = mMainChart.getContentRect().width() * (scaleX - 1);
            mMatrix.setTranslate(-distance, 0);
            //两个参数分别是x,y轴的缩放比例。
            mMatrix.preScale(scaleX, 1f);
            mMatrix = mMainChart.getViewPortHandler().refresh(mMatrix, mMainChart, true);
            mMainChart.notifyDataSetChanged();
            mMainChart.invalidate();
            mSubScroll.setScrollRate(1.0f, scaleX);
        }
    
        /**
         * 解析数据
         */
        private void parseEntry(List<DataModel> models) {
            // 清除旧的数据
            entryList.clear();
            colorList.clear();
    
            if (models != null && models.size() > 0) {
                // 取最值,适应高度
                float max = 0;
                float min = 0;
                for (int i = 0; i < models.size(); i++) {
                    // 设置Y轴数据
                    DataModel model = models.get(i);
                    Entry entry = new Entry(model.x, model.y);
                    entryList.add(entry);
    
                    // 根据y值,设置点的颜色
                    if (model.y <= 4) {
                        colorList.add(mContext.getResources().getColor(R.color.orange));
                    } else if (model.y <= 10) {
                        colorList.add(mContext.getResources().getColor(R.color.blue));
                    } else {
                        colorList.add(mContext.getResources().getColor(R.color.red));
                    }
    
                    if (max < model.y) {
                        max = model.y;
                    }
    
                    if (min > model.y) {
                        min = model.y;
                    }
                }
                updateY(max, min);
            } else {
                // 设置一个超出范围的值,保证列表不空,可以解决空数据下,不触发绘制的问题
                entryList.add(new Entry(1000, 1000));
            }
        }
    
        /**
         * 根据图表中的最值进行自适应Y轴的高度
         */
        private void updateY(float max, float min) {
            if (max <= 10) {
                // 最大值不低于15
                max = 15;
            } else {
                max = max + 5;
            }
    
            if (min > 2) {
                // 最小值不大于0,为了能让4.0的限制线显示完全
                min = 2;
            } else {
                min = min - 2;
            }
    
            mMainChart.getAxisLeft().setAxisMaximum(max);
            mMainChart.getAxisLeft().setAxisMinimum(min);
        }
    
        /**
         * 图表设置
         */
        private void setMainChart() {
            Description description = new Description();
            // 不需要右下角的描述文字
            description.setEnabled(false);
            mMainChart.setDescription(description);
            // 不需要背景
            mMainChart.setBackground(null);
            // 可以拖动,而不影响缩放比例
            mMainChart.setDragEnabled(true);
            // 设置没有数据时候的字体样式
            mMainChart.setNoDataText("");
            mMainChart.setNoDataTextColor(mContext.getResources().getColor(R.color.gray));
            // 不需要网格背景
            mMainChart.setDrawGridBackground(false);
            // 不需要边界
            mMainChart.setDrawBorders(false);
            // X轴可以缩放,Y轴不能缩放
            mMainChart.setScaleXEnabled(true);
            mMainChart.setScaleYEnabled(false);
            // 左右两边预留点空白部分
            mMainChart.setExtraOffsets(20, 0, 20, 0);
            // 不需要展示图例
            mMainChart.getLegend().setEnabled(false);
        }
    
    
        /**
         * 图表曲线设置
         */
        private void setMainLineData() {
    
            LineDataSet lineDataSet = new LineDataSet(entryList, null);
            // 使用贝塞尔曲线
            lineDataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
            // 画过的区域不填充
            lineDataSet.setDrawFilled(false);
            // 不需要展示数据的值
            lineDataSet.setDrawValues(false);
            // 使用圆形标记
            lineDataSet.setDrawCircles(true);
            lineDataSet.setCircleRadius(5);
            lineDataSet.setCircleHoleRadius(3);
            // 使用空心圆标记
            lineDataSet.setDrawCircleHole(true);
            // 设置每个圆形标记的颜色
            lineDataSet.setCircleColors(colorList);
            // 设置曲线的颜色
            lineDataSet.setColor(mContext.getResources().getColor(R.color.white));
            // 设置线宽
            lineDataSet.setLineWidth(3f);
            // 需要高亮的指示器
            lineDataSet.setDrawHighlightIndicators(true);
            lineDataSet.setHighlightLineWidth(1);
            lineDataSet.setHighLightColor(mContext.getResources().getColor(R.color.white));
            lineDataSet.setDrawHorizontalHighlightIndicator(false);
            lineDataSet.enableDashedHighlightLine(8, 8, 0f);
            LineData lineData = new LineData(lineDataSet);
            mMainChart.setData(lineData);
        }
    
        /**
         * 图表X坐标轴设置
         */
        private void setMainXConfig() {
    
            XAxis xAxis = mMainChart.getXAxis();
            //X轴设置显示位置在底部
            xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
            // 设置最大值,最小值
            xAxis.setAxisMaximum(24f);
            xAxis.setAxisMinimum(0f);
            //设置标签的数量
            xAxis.setLabelCount(5, false);
            xAxis.setDrawGridLines(false);
            // 设置X轴字体
            xAxis.setTextSize(11);
            xAxis.setTextColor(mContext.getResources().getColor(R.color.black));
            // 不要轴线
            xAxis.setDrawAxisLine(false);
            // 不要网格线
            xAxis.setDrawGridLines(false);
            xAxis.setGranularity(1);
        }
    
    
        /**
         * 图表Y坐标轴设置
         */
        private void setMainYConfig() {
            YAxis yAxis = mMainChart.getAxisLeft();
            // 不需要右边Y轴
            mMainChart.getAxisRight().setEnabled(false);
            // 添加最高和最低两条限制线
            yAxis.addLimitLine(getLimitLine(10, "10", mContext.getResources().getColor(R.color.white)));
            yAxis.addLimitLine(getLimitLine(4, "4.0", mContext.getResources().getColor(R.color.white)));
            // 设置Y轴最小值
            yAxis.setAxisMinimum(0);
            // 设置Y轴最大值
            yAxis.setAxisMaximum(15);
            // 不要网格背景
            yAxis.setDrawGridLines(false);
            yAxis.setGranularityEnabled(false);
            yAxis.setDrawAxisLine(false);
            // 不要标签
            yAxis.setDrawLabels(false);
            // 限制线在数据下方
            yAxis.setDrawLimitLinesBehindData(true);
        }
    
        /**
         * 获取限制线,限制线设置
         */
        private LimitLine getLimitLine(float limit, String label, int color) {
            // 设置限制值,和标签文字,限制值是血糖中的限制值,标签就是限制值
            LimitLine highLimit = new LimitLine(limit, label);
            // 限制线颜色为白色
            highLimit.setLineColor(color);
            // 线宽度为1
            highLimit.setLineWidth(1);
            // 标签位置在左边
            highLimit.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
            // 标签字体
            highLimit.setTextSize(10);
            // 标签颜色
            highLimit.setTextColor(color);
            // 使用虚线,设置每个短线的长度,和间隔长度
            highLimit.enableDashedLine(15, 15, 0);
            return highLimit;
        }
    
        /**
         * 滑块滑动时,图表改变相应的位置
         */
        private void setScrollConfig() {
            mSubScroll.setOnScrollListener(new ScrollBlockView.OnScrollListener() {
                @Override
                public void onScroll(float scrollRate) {
                    float distance = mMainChart.getContentRect().width() * (scaleX - 1) * scrollRate;
                    mMatrix.setTranslate(-distance, 0);
                    mMatrix.preScale(scaleX, 1);
                    mMainChart.getViewPortHandler().refresh(mMatrix, mMainChart, true);
                }
            });
        }
    
        /**
         * 图表拖动或缩放的时候,改变滑块的位置和大小
         */
        private void setScrollViewRate() {
            mMainChart.setOnChartGestureListener(new SimpleChartGestureListener() {
                float start = mMainChart.getViewPortHandler().getTransX();
    
                @Override
                public void onChartTranslate(MotionEvent me, float dX, float dY) {
                    updateMoveView(start);
                    start = mMainChart.getViewPortHandler().getTransX();
                }
    
                @Override
                public void onChartScale(MotionEvent me, float sX, float sY) {
                    scaleX = mMainChart.getViewPortHandler().getScaleX();
                    updateMoveView(start);
                    start = mMainChart.getViewPortHandler().getTransX();
                }
            });
        }
    
        /**
         * 更新滑块的位置
         */
        private void updateMoveView(float start) {
            float distance = mMainChart.getViewPortHandler().getTransX();
            // 两次滑动间隔小于10,不触发滑块的滑动
            if (distance - start < scaleX && distance - start > -scaleX && scaleX > 1.1) {
                return;
            }
    
            // 基本不缩放的时候直接充满
            if (scaleX < 1.01) {
                scaleX = 1;
            }
    
            float scrollRate = 1;
            float total = mMainChart.getContentRect().width() * (scaleX - 1);
            if (total != 0) {
                scrollRate = -distance / total;
            }
    
            mSubScroll.setScrollRate(scrollRate, scaleX);
        }
    }
    

    ScrollBlockView: 图表下方的联动滑块,标识图表当前显示的数据位置。

    public class ScrollBlockView extends View {
        // 背景颜色
        private int mBgColor;
        private Paint mBgPaint;
        // 滑块画笔
        private Paint mBlockPaint;
        // 滑块颜色
        private int mBlockColor;
        // 滑块的宽度
        private int mBlockWidth;
        // 滑块区域
        private RectF rectF;
        private Region mRegion;
        // View的宽度
        private int mWidth;
        // 当前滑动的位置[0, 1]
        private float scrollRate = 1f;
        // 缩放比例
        private float scale = 6f;
    
        // 滑动监听
        private OnScrollListener listener;
    
        public ScrollBlockView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initAttrs(context, attrs);
            initPaint();
            initData();
        }
    
    
        private void initAttrs(Context context, AttributeSet attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScrollBlockView);
            mBgColor = typedArray.getColor(R.styleable.ScrollBlockView_bgColor, Color.parseColor("#ECFBFF"));
            mBlockColor = typedArray.getColor(R.styleable.ScrollBlockView_blockColor, Color.parseColor("#D6F6FF"));
            typedArray.recycle();
        }
    
        private void initPaint() {
            mBlockPaint = new Paint();
            mBlockPaint.setColor(mBlockColor);
            mBlockPaint.setStyle(Paint.Style.FILL);
    
            mBgPaint = new Paint();
            mBgPaint.setColor(mBgColor);
            mBgPaint.setStyle(Paint.Style.FILL);
        }
    
        private void initData() {
            rectF = new RectF();
            mRegion = new Region();
            setBackgroundColor(mBgColor);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            mWidth = getMeasuredWidth();
            mBlockWidth = (int) (mWidth / scale);
            rectF.left = (mWidth - mBlockWidth) * scrollRate;
            rectF.top = 0;
            rectF.right = (mWidth - mBlockWidth) * scrollRate + mBlockWidth;
            rectF.bottom = getHeight();
            mRegion.set((int)rectF.left, (int) rectF.top, (int)rectF.right, (int)rectF.bottom);
            canvas.drawRect(rectF, mBlockPaint);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            float x = event.getX();
            float y = event.getY();
    
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                return mRegion.contains((int) x, (int) y);
            }
    
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                if (x < mBlockWidth / 2f || x > getWidth() - mBlockWidth / 2f) {
                    return false;
                }
    
                // scrollRate是以滑块的left位置为基准计算出来的,范围[0, 1]
                float scrollRate = (x - mBlockWidth / 2f) / (mWidth - mBlockWidth);
                // 滑块位置已经改变,不需要重新绘制了
                setScrollRate(scrollRate, scale);
    
                if (listener != null) {
                    listener.onScroll(scrollRate);
                }
                return true;
            }
            return false;
        }
    
        /**
         * 设置滑块移动的比例
         */
        public void setScrollRate(float scrollRate, float scale) {
            // 当值重复时,不再重绘
            if (this.scrollRate == scrollRate && this.scale == scale) {
                return;
            }
            if (scale < 1) {
                this.scale = 1;
            } else {
                this.scale = scale;
            }
    
            if (this.scrollRate > 1) {
                this.scrollRate = 1;
            } else if (this.scrollRate < 0) {
                this.scrollRate = 0;
            } else {
                this.scrollRate = scrollRate;
            }
            invalidate();
        }
    
        public void setOnScrollListener(OnScrollListener listener) {
            this.listener = listener;
        }
    
        public interface OnScrollListener {
            void onScroll(float scrollRate);
        }
    }
    
    展开全文
  • Android 图表开发开源库MPAndroidChart

    万次阅读 2018-02-23 10:09:47
    上面是APP中实现的效果图(点击可以放大查看)MpAndroidChart 的下载地址图1的效果不是用这个实现的,如果感兴趣可以参考我这篇文章 Android渐变圆环总体来说,MPAndroidChart可能是目前Android 开发最好用的一个...
  • Android 图表框架

    千次阅读 2018-10-26 17:54:19
    Android 收集好用的库与UI效果demo索引 1.MPAndroidChart是一款图表框架 折线图、柱形图、饼形图等图标样样都有 github https://github.com/PhilJay/MPAndroidChart MPAndroidChart 直线图重写,一个很好看的图,...
  • Android 图表生成类库.rar
  • Android图表插件

    千次阅读 2018-06-13 22:03:16
    Android图表插件 图表简介 图表使用的原因是为了将一堆杂乱无章或者是有序的数字转换为可视化、形象的图像展示,能够以简洁、简便方式展示所要表达的内容,android图表使用主要目的是进行数据分析,并将分析结果...
  • 基本上如想在android上实现动态效果的android图表,可以是用该demo,能够很方便好看的实现想要的图表效果 图表源码 hellocharts android图表
  • Android 图表开源框架之MPAndroidChart LineChart折线图,v3.0.1版本,MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,...
  • Android 图表源码

    2017-01-15 22:03:18
    集成饼图、直方图、曲线图、折线图等各种2D、3D图形图表开发源程序,包含全部继承类及调用APP源代码,可以根据需要随意修改,极具参考价值。
  • 转载一篇Android图表控件MPAndroidChart的博客。 相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3.0) Android图表控件MPAndroidChart——曲线图LineChart的使用(多条曲线) Android图表控件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,157
精华内容 10,862
关键字:

android图表