Graphic:基于图形语法的Flutter可视化库
本⽂介绍了⼀个基于图形语法(Grammar of Graphics)的 Flutter 可视化库:
背景
数据可视化是应⽤开发中很常见但很重要的需求,⼀个好的可视化库能让数据可视化的开发事半功倍。可惜的是,⽬前在 Flutter 社区中,还没有⼀个完美的可视化库。⽬前的 Flutter 可视化库都存在⼀些不尽如⼈意的地⽅,例如:
由 Google 内部开发,代码质量很⾼。但是它提供的图表种类很少,仅有最常见的线图、柱状图、饼图等⼏种,且没有曲线平滑等常⽤的功能。此外它似乎是⼀个实验性质的项⽬,没有任何的⽂档或介绍,虽然源代码放在了GitHub上,但明确表⽰不会处理任何 issue 和 PR,似乎也好久没有特性更新了。
是 pub.dev 上⽬前⼈⽓最⾼的可视化库,它有较为酷炫的设计和动画,是⼀位 开发的。但是它的个⼈风格太明显了,不太适⽤于统计或严肃的场景。
较为完善和专业,但它是⼀个闭源的商业软件,仅提供收费的使⽤许可,对于很多开发者来说并不适合。
为了构建复杂的可视化图表,我们做过 ,通过 Webview 的⽅式将 Web 中的 Echarts 引⼊到 Flutter App 中,满⾜很多复杂的可视化需求,但是 Webview 在性能和兼容性等⽅⾯还是存在诸多问题,对于性能和稳定性要求⾼的图表,还是需要⼀个 Flutter 原⽣的可视化⽅案。
近年来,前端的数据可视化也有了长⾜的发展,图形语法(Grammar of Graphics)的理论逐渐被应⽤到了前端可视化库中。图形语法是Leland Wilkinson 在其所著的《The Grammar of Graphics》⼀书中提出的理论,该理论是⼀套⽤来描述所有统计图形深层特性的语法规则。
基于图形语法的理念,可视化库就不⽤受到饼图、线图、柱状图这样传统分类的限制,将数据可视化抽象成不同的图形标记、坐标系、度量的组合,⼤⼤提升了可视化库的扩展性和灵活性。应⽤图形语法的前端可视化库有 系列、阿⾥的 系列、微软的 等。
基于以上的背景,诞⽣了 :⼀个基于图形语法的 Flutter 可视化库。
⽰例
⼀个简单的⽰例:
graphic.Chart(
data: [
{ 'genre': 'Sports', 'sold': 275 },
{ 'genre': 'Strategy', 'sold': 115 },
{ 'genre': 'Action', 'sold': 120 },
{ 'genre': 'Shooter', 'sold': 350 },
{ 'genre': 'Other', 'sold': 150 },
],
scales: {
'genre': graphic.CatScale(
accessor: (map) => map['genre'] as String,
),
'sold': graphic.NumScale(
accessor: (map) => map['sold'] as num,
nice: true,
)
},
geoms: [graphic.IntervalGeom(
position: graphic.PositionAttr(field: 'genre*sold'),
flutter开发appshape: graphic.ShapeAttr(values: [
Interval(radius: Radius.circular(5)) ]),
)],
axes: {
'genre': graphic.Defaults.horizontalAxis,
'sold': graphic.Defaults.verticalAxis,
},
)
更多⽰例请参考 :
特性
图形语法
所谓数据可视化,可以粗略的概况为:将数据通过某种规则转换为对应图形的视觉通道属性(颜⾊、形状、⼤⼩、位置等),然后将具有这
些属性的图形渲染出来。这⼀过程在图形语法中具体表现为:
在 Graphic 的实现上,接⼝和类名的设计主要参考了 AntV。核⼼概念如下:
Geom:⼏何标记,组成图表的⼏何图形
Coord:坐标系,图表的坐标系,⽬前有笛卡尔坐标系(Cartesian)和极坐标系(Polar)
Scale:度量,将数据缩放到 [0, 1] 的区间,以便映射到视觉通道属性
Attr:视觉通道属性,包括位置、颜⾊、形状、⼤⼩等,值由经过度量变换的数据决定,被应⽤到⼏何标记上
这些概念对于了解图形语法的⼈,特别是使⽤过 AntV 的⼈应该不陌⽣,如果没有接触过可以参考 AntV 的 。我们认为图形语法将会是未来数据可视化发展的⼤⽅向,不管现在是否使⽤相关的可视化库,图形语法都是值得学习了解的。
声明式图表
Web ⽣态中的⼤部分可视化库都是命令式的,绘制图表通过语句调⽤⼀系列函数实现,AntV 也不例外。但 Flutter 中推崇的是声明式、响应式的视图。通过 build 函数返回值中树状的参数结构配置视图的结构。值得⼀提的是这也是 Web Canvas 和 Flutter CustomPaint 组件的重要差别。
因此 Graphic 的接⼝设计也采⽤了声明式的,通过 graphic.Chart 组件的参数对所有信息进⾏配置,当视图的组件树更新时图表⾃动重新绘制。当然,后期会对重绘进⾏⼀些优化。
⾃定义 Shape
图表之所以分门别类、变化万千,最主要的就是形状这⼀属性的多样。因此在所有视觉通道中,形状也是最复杂的,形状的可定制化程度决定了可视化库的扩展性。
Graphic 中形状 Shape 这⼀属性的类型是函数或⾼阶函数,传⼊⼏何标记各视觉通道的属性值,组合出图形对象,供渲染引擎使⽤。⽤户可⾃⼰编写函数的实现,即⾃定义的 Shape。
List<graphic.RenderShape> triangleInterval(
List<graphic.AttrValueRecord> attrValueRecords,
graphic.CoordComponent coord,
Offset origin,
) {
// Implementation of attrValueRecords => renderShapes
}
展望
⽬前 Graphic 的开发主要完成了静态的图表。后续将添加交互、动画等特性,以及 Tooltip、legend 等附属组件。
特性和接⼝尚不稳定,欢迎试⽤,但应⽤到⽣产环境需谨慎。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论