Android 可视化图表绘制,你应该用这个库

2,111 阅读4分钟

随着进入大数据时代,数据越来越多,可视化能将数据以更加直观的方式展现出来,使数据更加客观、更具说服力,从而助用户理解和分析数据。所以今天我们来看看如何使用 Kotlin 来画一个折线图的可视化图表。

Screenshot_20220706_170135.jpg

技术选型

Android端比较有名的可视化图表是 MPAndroidChart,但今天我选型了F2Native,主要是因为其图表类型丰富,支持了7大类型的图表,跨iOS,Android平台,最后是其实现了图形语法理论,能通过面向对象的组合,组合出千变万化的图表,能快速应付业务变化。

开发实现

代码都托管在 GitHub上,如果不想看教程,可直接下载。

下载下来后记得修改 local.properties 中的 sdk.dir 和 ndk.dir 的路径。

1.创建工程

我们用 Android Studio 创建一个空的工程 image.png

点击 Next, 在接下来的界面中输入工程名字 LineChart-Swift, 并选择 Language 为 Kotlin,Minimum SDK 选择 API 18,最后点击 Finish.

image.png

2.引用F2Native

F2Native 已经上传到 jetpack 中,所以我们要在工程的build.gradle中增加

maven { url 'https://jitpack.io' }

然后去模块的 build.gradle 中增加依赖, 我们默认使用最新的版本

implementation 'com.github.antvis:F2Native:latest.release'

3.准备数据

由于引擎数据的入参格式是一个String的数组,我准备了如下的数据, 并保存为data.json文件。然后放到 assets 目录下面.

[{    "genre": "Sports",    "sold": 275}, {    "genre": "Strategy",    "sold": 115}, {    "genre": "Action",    "sold": 120}, {    "genre": "Shooter",    "sold": 350}, {    "genre": "Other",    "sold": 150}]

4.创建View

我们在 res/layout/activity_main.xml中增加 F2CanvasView 并设置宽和高, 这个View就是用来展示折线图的。

<com.antgroup.antv.f2.F2CanvasView
    android:id="@+id/canvasView"
    android:layout_width="match_parent"
    android:layout_height="220dp"/>

image.png

5.代码接入

数据和 xml 中的View准备好后,接下来就是写代码了,我们到 MainActivity.kt 中引入相关的包

import com.antgroup.antv.f2.*
import com.antgroup.antv.f2.F2Chart.*

编写相关代码逻辑,我把每一步的注释都写在代码中了

//需要继承F2CanvasView.Adapter在,其回调函数中绘制和销毁对象
class MainActivity : AppCompatActivity(), F2CanvasView.Adapter {
    //声明对象
    //F2CanvasView是展示折线图的View
    private var mCanvasView: F2CanvasView? = null
    //F2Chart 是负责图表绘制
    private var mChart: F2Chart? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //关联xml中的view
        mCanvasView = findViewById(R.id.canvasView) as? F2CanvasView;
        //初始化view
        mCanvasView!!.initCanvasContext();
        //设置adapter
        mCanvasView!!.setAdapter(this);
    }

    //adapter的绘制回调,图表绘制操作在这里
    override fun onCanvasDraw(canvasView: F2CanvasView) {
        //初始化chart, 因为需要canvasView的宽和高,在这里初始化确保能拿到canvasView的宽和高
        if (mChart == null) {
            mChart = create(
                canvasView.context,
                "LineChart-Kotlin",
                canvasView.width.toDouble(),
                canvasView.height.toDouble()
            )
        }
        //关联chart和canvasView,chart最后需要把图表显示在canvasView上
        mChart!!.setCanvas(canvasView)
        //设置chart的内边距
        mChart!!.padding(10.0, 10.0, 10.0, 10.0)
        //使用utils加载数据
        val source: String =
            Utils.loadAssetFile(canvasView.context, "data.json")
        //把数据设置到chart中
        mChart!!.source(source)
        //在chart上画一条折线,折线的x轴和y轴的数据映射分别是genre, sold字段
        mChart!!.line().position("genre*sold")
        //渲染 并显示在canvasView上
        mChart!!.render()
    }

    //adapter的销毁回调,用来销毁chart
    override fun onDestroy() {
        super.onDestroy()
        if (mChart != null) {
            mChart!!.destroy()
        }
    }
}

如果你看到这边,那么恭喜,以上就是绘制折线图需要的所有代码,效果如下: Screenshot_20220706_170135.jpg

刚才也提到了,F2Native 实现了图形语法,能通过组合的方式快速应付业务迭代的快速,假如突然需求变了,要画柱图了,那我们只要改变 mChart!!.line().position("genre*sold") 中的那行代码中的 line 为 interval 即可

mChart!!.interval().position("genre*sold")

柱图就出来了,是不是很方便

Screenshot_20220706_170223.jpg

写在最后

当然这还是最基本的图表显示,真实业务中应该还会有一些更复杂的设计,比如y轴上要附加单位,比如元,其次柱的颜色要有区分,最后是手势按上去最好会有一些 Tip 说明。这些我会在后面的文章在具体介绍,感谢大家的阅读,代码已提交到 GitHub 了,欢迎大家下载。

如果你对 iOS 版本的线柱图绘制也感兴趣,可参考我的另一篇文章 10行代码绘制线柱图 | iOS Swift





下面是在开发当中遇到的一些小问题,记录下来,以备参考

Android 12报错

Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined.

解决

在 AndroidManifest.xml 中设置 android:exported = "true"

image.png

NDK路径报错

NDK at /Users/weiqing.twq/Library/Android/sdk/ndk/21.4.7075529 did not have a source.properties file

设置ndk.dir即可

ndk.dir=/Users/weiqing.twq/Library/Android/sdk/ndk/16.1.4479499

image.png

Kotlin 版本不匹配报错

Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.

在工程的 build.gradle 设置提示的版本,我这提示的是1.6.0

ext.kotlin_version = "1.6.0"

image.png

最后的最后防水图一张

larm-rmah-R1Ku62Z7zqE-unsplash.jpg