导读
F2Native,为移动端而生的可视化图表引擎。从 1.0 全新版本发布以来,我们一直朝着提供高性能,跨端,开箱即用的生动图表的方向努力,同时面对移动端多样的环境,多端适配也一直是我们在努力追求的目标。这次 2.0 的升级,我们不仅在性能和稳定性上取得了较大提升,同时也适配了多端,让 F2Native 运行到了更多的系统和平台上。
功能亮点
多端支持
F2Native 1.0 发布的时已经支持 iOS 和 Android 端,经过一年的发展,2.0 新增 Mac OS 端和 Webassembly 的支持,得益于底层的图形语法和渲染都使用 C++ 实现,我们在不同端上都有一致的表现。在 iOS 和 Android的开发语言除了 Objective-C 和 Java ,我们还支持了 Swift 和 Kotlin。在不同端,不同语言上,我们的开发API 描述都基本保持一致。
Android
fun onCanvasDraw(canvasView: F2CanvasView) {
if (mChart == null) {
mChart = F2Chart.create(canvasView.context,"SingleIntervalChart_2",canvasView.width.toDouble(),canvasView.height.toDouble())
}
mChart!!.setCanvas(canvasView)
mChart!!.padding(20.0, 10.0, 10.0, 10.0)
mChart!!.source(loadAssetFile(canvasView.context, "mockData_singleIntervalChart_2.json"))
mChart!!.interval().position("genre*sold").color("genre")
mChart!!.setScale("sold", ScaleConfigBuilder().min(0.0))
mChart!!.setScale("genre", ScaleConfigBuilder().range(doubleArrayOf(0.1, 0.9)))
mChart!!.render()
}
iOS
func chartRender() {
let jsonPath = Bundle.main.path(forResource: "Res/mockData_baseInterval2", ofType: "json")
guard let jsonString = try? String.init(contentsOfFile: jsonPath!) else {
return
}
let jsonData = F2Utils.toJsonArray(jsonString)
self.chart!.canvas()(self.canvasView!)
self.chart!.padding()(10, 20, 10, 0)
self.chart!.source()(jsonData)
self.chart!.interval()().position()("genre*sold").color()("genre", [])
self.chart!.scale()("sold", ["min":0])
self.chart!.scale()("genre", ["range": [0.1, 0.9]])
self.chart!.render()();
}
Mac OS
- (void)chartRender {
self.chart.canvas(self.canvasView).
self.chart.padding(10, 20, 10, 0.f).
self.chart.source(data);
self.chart.interval().position(@"genre*sold").color(@"genre", @[]);
self.chart.scale(@"sold", @{@"min": @(0)});
self.chart.scale(@"genre", @{@"range": @[@(0.1), @(0.9)]});
self.chart.render();
}
Webassembly
Module.onRuntimeInitialized = function () {
const vec = new Module.StringVector();
var chart = new Module.F2Chart("baseinterval", 600, 400, scale);
chart.canvas("canvas").margin(0, 0, 0, 0).padding(10, 10, 20, 20).source(data);
chart.scale("sold", "{\"min\":0}");
chart.scale("genre", "{\"range\":[0.1,0.9]}");
chart.interval().position("genre*sold").color("genre", vec);
chart.render();
vec.delete();
chart.delete();
}
性能提升
我们自研了底层的 Canvas,分别使用了 iOS 端内置的图形库 CoreGraphics ,Android 端的 Android Canvas 来封装对齐W3C标准的 Canvas ,完成后在渲染性能得到了较大的提升,相比 1.0版本,在 Android端渲染性能提升5倍,内存消耗双端各降低2-3倍。由于使用系统的渲染库来分装 Canvas ,在Android 端我们抛弃了 TextureView , 使用最基本的View来显示图表,当View 嵌入到 Android 的系统组件中,如 RecycleView , ListView 中,相比 TextureView 会有更好的兼容性和用户体验。
减小包体积
得益于我们研发了更合适可视化场景的 Canvas ,我们去除了最大的外部依赖 GCanvas 及其它一些依赖,在2.0上的依赖只有一个 json 库,iOS 和 Android 端打包后占App的真实大小分别为 500KB , 250KB 左右。
稳定性提升
在 iOS 和 Android 端分别建立了基于 XCTest 和 AndroidTest 的单测框架,且目前单测覆盖率已经达到 50% 左右,后面我们也会继续提升。同时经过了大量业务的验证,各种细节的bug也暴露出来并得到了修复,可用率已经达到99.9999%。
更简单的构建
我们把 F2Native 在iOS 端发布到了 CocoaPods ,Android 端发布到了 jitpack 。通过包管理,可以简化工程引用,减少开发者工程配置的问题,现可分别通过如下方式来引用。
通过 CocoaPods 引用
pod 'F2'
通过 jitpack 引用
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.antvis:F2Native:latest.release'
}
因为 F2Native 需要使 NDK 编译 C++ 代码,别忘记在 local.properties 中设置 ndk.dir
Roadmap
未来的规划主要是基于目前引擎已存在的问题和将来可视化将面对的挑战进行规划的,我们将会在以下几个方面继续投入开发和完善。
增强Webassembly
通过把 C++ 代码编译成 Webassembly 能让 F2Native 运行在浏览器中和 Wasm 容器中,最终让同一套图形语法描述能运行在更多的端和技术栈上面,解决多端差异性问题。目前我们初步打通了链路,但是在开发者体验,文档,Demo 示例仍然有很多事情需要做。
持续性能优化
对于 F2Native 引擎,高性能一直是我们努力的方向,所以我们依旧会投入时间在引擎核心的 C++ 库,各端的 Bridge 上进行性能优化,以期待提供更好的用户体验。
完善图表类型
我们会支持更多的新图表类型,丰富现有的图表类型。同时也会增加图表的动画和交互的表现力。
关于我们
如果想了解更多细节欢迎 star 我们的 GitHub 和 官网,更多F2、F6的信息详见:
- F2 GitHub: github.com/antvis/F2
- F2 官网:f2.antv.vision
- F6 GitHub: github.com/antvis/F6
- F6 官网:f6.antv.vision