建站宝盒专业版-一起学习数据可视化图表库及字

摘要: 期待本文在使大伙儿对 F2、图型英语的语法有基本掌握的同时,能变成源代码阅读文章全过程中的一个小助手,给大伙儿的技术性选型、技术性实践活动产生协助。is 的开源系统数据图...

--------

建站宝盒专业版

-------

is 的开源系统图表计划方案 F2 的源代码阅读文章,也有该库的一大情况——图型英语的语法的掌握学习培训。大家会从具体要求情况考虑,谈到图表计划方案大的情况、图型英语的语法这个阵营的基本观念,随后进到 F2 源代码的扼要剖析,其大致的学习培训剖析思路是:总体构架区划 —— 各控制模块分工 —— 关键控制模块设计方案完成。源代码剖析之后,又回到要求情况,纪录了在特殊的要求场景中,怎样应用掌握到的专业知识和情况处理具体难题——图表库的小程序自然环境兼容。

写下本文的诱因、初衷

1.1 npm install @antv/f2

本文起止于一个业务流程上的要求,从该要求大家能够提炼出三个重要词:

挪动端数据信息管理看板字节小程序为载体互动式图表

业界有十分多出色的图表库计划方案,如百度搜索的 ECharts,可是对标挪动端小程序的完善图表库基本上都还没。依据这三个重要词,is 的开源系统图表计划方案 F2。


1.2 README.md

会涉及到的

图型英语的语法之九牛一毛:一组定义、许多图表F2 设计方案、图型英语的语法封裝简析控制模块/工作能力完成计划方案(互动式、动漫)*Canvas 实践活动、优化对策

不会涉及到的

F2/G2 API 列举或总毕业界图表库的横向比照Canvas 更最底层的3D渲染基本原理可视性化中的数据信息解决

本文大一部分內容出于自身在新项目起动和完成全过程中,对图表库的接入和源代码学习培训。同时,会略微扩展到一些通用性的可视性化基本、图型英语的语法定义、也有从通用性到 F2 具体实践活动的制图对策,和关键依靠的3D渲染模块 Canvas。

在此也应当划定本文不会涉及到的內容,最先本文不会聊许多实际的库 API,这不太具备通用性性和普适性;同时,由于也只是图表库的入门客户,体验不深不广,都还没充足的资质去做深层次客观性的横向比对和点评;此外,大家的视角会放在 Canvas 3D渲染模块这一层以上,因此也不会涉及到 Canvas 更最底层的內容;最终,大家还不会聊到数据信息解决,包含数据信息加载时的预解决、adjust 作用等,这也是一个大话题,而且涉及到到的数学课和统计分析学成份太高。

大致的学习培训情况和范畴圈定以后,大家接下来掌握一下有关数据信息可视性化、数据信息图表的业界大情况,也有「图型英语的语法」这个关键定义。


2. 有“史”有“衷”

新项目历史时间、设计方案初衷、构架演进


2./search?q=visualization

在 F2 的老前辈 —— G2 的设计方案文本文档中有这么一句话: “将数据信息投射到图型,同时提升一些輔助信息内容,让客户读懂数据信息。”

这反应了可视性化的实质,大家还能够从在其中整理出可视性化的一般性步骤:

数据信息解决:对数据信息的生产加工,使数据信息更具备本质逻辑性,对人类自身、或优化算法、或图象解决要求提升可了解性;图型投射:从数据信息,到部位 / 尺寸 / 色调等具备区别度的信息内容的 map;图型展现:点线面,在各种各样媒体上的3D渲染;輔助信息内容:视觉效果安全通道跟数据信息之间的投射关联,将会是一些参照、一些规范,如座标轴、图表中的图例、更进一步的輔助文字等。

可视性化行业中的一大阵营扛着 「图型英语的语法」 大旗,大家先对其开展大致感受、理性了解。


2.1.1 The Grammar of Graphic

它是一本想要为图型学、数学课、测算机科学研究这个交叉式行业创建系统软件化叙述的经典著作,同时也是学术界十分具备份量的著作。作者 Leland Wilkinson 是一名统计分析学家,因此应用了十分严实的、方式化的系统软件叙述,来创建实体模型和自身论证,內容因而会比较不太好懂,本人也没能详细看完,但有一些重要定义大家能够有大致的理性感受。

单拎大家的主题,图表这一块来说,图型英语的语法将图表的这个数据信息展现定义看做「数据信息」和「几何图形图型的视觉效果特点」关联的結果,图表自身,能够被觉得是互相正交和的特点组成而成的結果。这个定义也是大家在应用相近 G2、F2 这样的图型英语的语法封裝库中能很直观感受到的。

立即来了解一下两个正交和的定义:

Visual Cue 数据信息点特点: Position 部位Length 长度Angle 角度Direction 方向Shapes 样子Area or Volume 面/体积Color 色调(Saturation 饱和状态度、Hue 色相)

Coordinate 座标系:Cartesian 笛卡尔座标系、Polar 极座标系、*Geographic 自然地理座标系(自然地理座标系在大家的图表库中经常独立抽出,is 的 L7)

将上面二者开展 正交和 ,构成叙述工作能力丰富多彩的图表们:

以上三张图源:Data Points 教材 (英文版正交和图被分开故应用汉语版素材图)

这样的设计方案和梳理,使根据图型英语的语法封裝的图表库不一样于别的的“零售”式、“授人以鱼”式的图表(即按直观的图表种类做为立即插口,开展配备化的图表开发设计,如大哥 ECharts),G2、F2 有一套自身的表明系统软件,图表开发设计者能够用其开展图表叙述。

但其实不是说这两种阵营有孰优孰劣之分:

图表英语的语法自身是比较完善的一种观念、一个叙述管理体系,并不是完成规范,客观事实上其自身的学习培训成本费也是不低的;根据此的图表库也一样,一刚开始上手应用的情况下有点反直觉,学习培训曲线图比较险峻,跟想像中的配备化图表区别较大,同时若无图型英语的语法有关情况,早期也经常很难从文本文档找到想掌握的內容;图表库也是商品,也要考虑到客户体验、应用门坎,因此需要找到设计方案社会学与学习培训成本费之间的均衡点;种类化的图表库相比之下也许显得唠叨、堵塞用、叙述工作能力稍差,但又更非常容易做到体积存缩,合乎客户直觉地简易按需引入和针对性优化;大伙儿都在聊 noCode, lowCode,当今业界一些可视性化服务平台应用的图表依靠還是趋向于 ECharts 等,会不会配备化的图表在这样的运用场景下更受亲睐,或反之是具备系统软件叙述性的英语的语法更非常容易接入?能够留为大家的对外开放性难题。

详细介绍过图型英语的语法这个阵营以后,便可以刚开始了解该阵营中的出色商品了。蚂蚁金服可视性化精英团队的 G2、F2 将先后出场。


2.1.is G2 - Grammar of Graphic

要聊 F2,先说说 G2。G2 is 的第一代图型英语的语法封裝库,G2 就取自 The Grammar of Graphic 里边两个 G。2014 年起动,17 年末开源系统的 G2,其引认为傲的图型英语的语法基础理论基本,也是遭受上面提到的 The Grammar of Graphic 作者 Leland Wilkinson 的立即毫无疑问的。

它在蚂蚁內部的前身也是基本的配备化图表库,后来大伙儿发现这样的图表库和已有的大佬 ECharts、HighCharts 精准定位重合,同时本身的开发设计扩展也很麻烦,非常容易遭受短板,加上数据信息剖析大户 R 語言 ggplot2 时兴,is 期待调剂方向,这时候其初衷和总体目标,就变为了一个图型英语的语法封裝的可视性化工厂具库了。

G2 并不是本文的关键,大家简易看看其发展趋势,14 年下旬起动图型英语的语法库 G2 的宣布开发设计,G2 的基本构架亲身经历了以下的演进:

以上照片梳理自 G2 官方各环节构架图

历经至今 (2020) 六年的发展趋势,G2 自身也有许多调剂,例如最底层模块从单一 Canvas 到 SVG、Webgl 的适用,互动、数据信息解决控制模块的抽离、顶层图表运用库的进一步封裝,“螺旋升高”到后边又想要做整合,F2 能够从 G2 装包产出,立即从最底层3D渲染模块完全适配多端等,构想和设计方案都是是非非常有野心的,期待能有 ECharts zRender 那样出色的更多设计方案出現。


2.1.is F2 - Fast, Flexible

F2 也是来自要求,服务于要求。15-16 年付款宝钱包业务流程发展趋势,挪动端资金展现要求冒出。挪动端钱包,在编码尺寸上十分受到限制,因此 AntV 精英团队刚开始根据已有的 G2,自研朝向挪动端图表库,一刚开始叫 G2-Mobile,跟老前辈 G2 用的是同一套构架,只是顶层完成有一些差别,但这也带来了较高维护保养成本费和一些麻烦。一直到 3.0 时期,G2-Mobile 才完善起来,设计方案、构架方面都开展升級,更名 F2,“复用”了 G2 的取名词义,取自 Fast 和 Flexible。至于为何是 Fast 和 Flexible,后边的设计方案事例和 demo 应用中大家能够感受一下。

发展趋势至今,大家在新项目选用到的 3.7,其构架大约是这样的。假如说到更远,就是跟上面 G2 一起谈的整合了。

2.2 code

立即应用官方可线上编写的 demo 感受应用实际效果:F2 官方网站 - Examples 示例(zh/examples/basic)

在上面的详细地址中,大伙儿能够动手能力一起直观感受一下 F2 的应用。

// 前面引包、建立 Chart 案例、加载数据信息都未消多说,立即看到最重要的图型叙述英语的语法
// 一行编码画图表
// 基本柱状图
chart.interval().position('genre*sold').color('genre');
// 改成二维座标散点
chart.point().position('genre*sold');
// 配备:给所有散点加上统一的色调
chart.point().position('genre*sold').color('#face15');
// 上面提到的都是大家的 Visual Cue 定义,它是很非常容易更改的,再来个折线
chart.line().position('genre*sold').color('#ffee15');
// 仅有 Visual Cue,Coordinate 怎样变化呢
chart.coord('polar');
// 假如觉得观感不佳,还能够做更详尽的配备
chart.source(data, {
 sold: {
 min: 0,
 max: 500,
拷贝编码

对新项目情况和历史时间都有一定的掌握,也早已直观感受到这个库的应用全过程,应当就对其 philosophy 有大致的掌握了。接下来会进到实际的源代码学习培训全过程。


3. 走“码”观“画”

构架控制模块简析、访问编码、看看图表库是怎样画图的


3.1 git clone is/F2.git

构架图信息内容量将会有点不够,立即读一读各个控制模块里边的编码,看看各自负责了甚么工作中,控制模块之间的数据信息流又是如何的。以便便捷了解,大家需要自下而上地看这张构架图:

这一层是不一样自然环境下的制图模块,全部库对对其的依靠关键是两件事儿:

根据制图指令开展3D渲染,各个自然环境下的兼容也最先在这一步进行;

恶性事件系统软件,在第四一部分大家会细心聊到一个设计方案。


3.1.2 正中间层 Shape

这个控制模块立即联接了单独数据信息点到 Canvas 上的绘图全过程,将会稍显繁杂唠叨。假如看源代码,会发现 F2 的 Shape 有两种:

Graphic 基本图型中的 Shape —— 3D渲染模块中的 Shape 完成。

这是 3.x 版本号中 F2 对3D渲染模块的彻底更新改造,跟原来的 G 是配对的。Graphic 层的 Shape 是最底层的“图型”定义,出示了与制图模块 Canvas 的联接公路桥梁。整套 Shape 应用 OOP 中的常见来举事例的那种典型承继关联开展设计方案,大致层级为:

基类 Element 维护保养了制图元素这个定义,维护保养本身层级、可见性特性,完成元素绘图中如引流矩阵转换、挪动的方式,根据再次测算其制图点座标完成(父类维护保养公共性特性、基本方式)。

拓展 Element 完成的有两个定义:

Shape: 内嵌图型(包含照片)的基类,做这一层包装是对基本图型的统一,对外曝露统一的绘图和包围着盒获得方式,但方式中启用的实际的相对路径建立、包围着盒测算方式交到各个实际的 Shape 如 rect, circle, line 去重新写过。实际 Shape:矩形框、圆形、线等实际图型,会依照本身样子特点 override 绘图相对路径、包围着盒测算插口。Group: 组成图型类,是对基本图型的“装包”解决,包围着盒合拼、统一建立消毁。

Graphic 的 Shape 还容许客户拓展加上自定图型,丰富多彩制图模块能立即适用的绘图基本图型。客户只需要界定图型的绘图相对路径和包围着盒测算便可,与实际内嵌图型的方法同样,graphic 会使其承继自 Shape 建立,能够在制图模块中合别的图型一样立即应用。

Geometry 中的 Shape —— 数据信息的立即投射(图中的数据信息条柱、数据信息散点)。

这个 Shape 应用加工厂方式的设计方案,各个实际图型根据在这个加工厂中申请注册,代理商 Geometry 中的实际图型(数据信息点特点 Line/Point/Interval 等)插口,随后完成对应 geom 的绘图方式,这个绘图方式就是启用 Graphic 中实际 Shape 的相对路径绘图,加上到画布上。Geom 一部分內容在下面的 Geometry 控制模块还会实际涉及到。

Animation

动漫完成,F2 出示了申请注册式的动漫通道,适用自定动漫解决。同时内嵌了很多默认设置动漫,适用对图表中的数据信息元素 Shape 出現、升级、掩藏的全过程加上动漫,且适用很多内嵌的缓动涵数。是一个相对性独立的控制模块,在第四一部分中大家也会探讨一个设计方案细节

Component

说白了,组件。这一部分的內容比较杂,完成的是一些绘图图表全过程中能够抽象性出来固化的通用性成份,称为组件。

如座标轴、HTML(为客户能够自主加上的 HTML 輔助元素出示一个配备通道,关键做的是帮忙建立连接点、投射 CSS、画布中合理布局)、文字、目录、Tooltip 悬窗展现的主视图组件。

听起来应当是 Shape 或 Plugin 呀?

Shape 应当是数据信息在图中的反映和意味着,ponent 也有自身的3D渲染、包围着盒测算逻辑性,但应当跟 shape 有定义上的区别;Plugin 应当要有自身独立的情况管理方法逻辑性,申请注册并寄生于 Chart 行为主体之上,ponent ponent 的应用方正是图表构成如座标轴和 plugins 如 Tooltip、Legend。
Scale

衡量,它表明的是数据信息在图表上的展现方法,这一部分內容也早已抽离出 F2 自身,做为附加的专用工具库房,可是做为适用制图的一个正中间控制模块,应当掌握一下。

衡量出示的是可视性化图表中数据信息信息内容对图象信息内容的投射规范,能够把源数据信息某个维度的室内空间范畴比作界定域,变换后的图型特性室内空间比作值域,期间的变换公路桥梁就是 scale。能够适用大家对归类、時间(离散或持续)、持续数据信息、分段数据信息等开展变换和过滤。

通俗化来讲,就是最终图表上面某个轴向应当对数据信息做如何的删改改,大家在演试中加载数据信息,设置了 sold 字段值的最大最少值,就是在手动式变更它的 scale。抽离这个定义,有益于完成座标轴和数据信息图的对应联动。


Coordinate

座标轴类,扩展完成了 cartesian 笛卡尔直角座标系和 polar 极座标系。

两种座标系各有完成不一样的 convertPoint 和 invertPoint 涵数,依据座标系标准,解决归一化后的点数据信息并回到結果座标,考虑对应的制图要求(归一化也是一个关键的设计方案,大家在聊 Geometry 时将提到)。


Attributes

是全部视觉效果安全通道的管理方法类,视觉效果安全通道,是可视性化编号的重要。点线面这样的几何图形样子能够完成一种标识,标识协助人眼开展归类、汇聚鉴别。

而如座标轴(一维、二维)部位、色调、样子、角度、长度这样的视觉效果安全通道是具体标值在视觉效果上的投射,完成判定/定量分析实际效果;归类 + 定量分析,才造成了可视性化的实际效果。

attrs 类,关键是出示一个基类,完成数据信息到视觉效果安全通道的投射,对外曝露获得制图数据信息的插口,如操纵部位、全透明度、色调等,应用方是后边要提到的 Geometry,它操纵着每一个数据信息到大家所见的图案设计的投射。

Adjust

说白了是一种“调剂”专用工具, 系数据信息解决工作能力的一种数据信息专用工具封裝,行为主体也早已拆分出去了,关键用于将原始数据信息做可视性化层级上的一些修整,使其绘图出来的图表更具备可看性。

为考虑不一样图表的数据信息展现要求,当今适用四种方式:

stack 层叠: 如层叠面积图、层叠柱状图dodge 排序散开: 排序并在范畴内匀称遍布,如排序柱状图jitter 扰动散开: 能够使本来的归类数据信息中同一类的多个数据信息实体线打散,使其保存排序实际效果但不重合,如排序散点symmetric 对称性: 使数据信息对称性展现,如漏斗图,河流图
3.1.3 顶层

Geometry

先看看这个大类,它是绘图各种各样图型的基本。图型英语的语法两个正交和定义中,数据信息的立即投射——图型就是由 Geometry 操纵。

Chart 原始化的情况下,会将各种各样 geoms 原始化,并把在其中每一个基本 geom 的制图指令挂载到 Chart 上,变成 Chart 的可启用方式,如刚刚的示例中大家用 line 方式建立折线图、用 point 方式建立散点图,都是立即启用了 Geometry 中根据 Line、Point 出示给 Chart 的方式。

Chart 原始化 geoms 的情况下也维护保养了当今 geoms 目录,后续 Chart 对数据信息在图表中的投射元素的维护保养,都根据这个 geom 案例目录开展。Chart 会告之 geom 数据信息信息内容、客户配备、座标轴信息内容等绘图的必要数据信息,并且会将 geom 的 container 限定为其绘图层级中的 middlePlot,正中间层中。后边会详细介绍到这个分层实体模型。

进行了数据信息和配备的下发、方式到 Chart 上的挂载,geom 在数据信息第一次加载或转变时会有一些解决工序:

attrs 解决,一些制图特性的设定和维护保养数据信息解决,包含: 从基本数据字面量到 [0, 1] 范畴的归一化,从而完成图表总体的数据信息统一,便捷绘图;归一化是一个比较恰当的设计方案,获得到数据信息并根据 scale 明确绘图范畴后,会得到数据信息维度上的值域,将每一个数据信息开展归一化实际操作,得到一类型似“占比”的数据信息,再依据画布地区尺寸投射成实际的像素部位,这个扼要的全过程完成了数据信息的提前准备,将数据信息范畴限制为一个 0-1 间的数,为各个控制模块消费数据信息、座标轴转换、制图转换出示了便捷adjust 数据信息调剂,以考虑不一样的图表数据信息展现要求;数据信息排列。 Interaction

挪动端关键的互动是 touch 系列,这个控制模块对恶性事件系统软件做了进一步包装(恶性事件系统软件的最底层仿真模拟在后边的第四一部分会详尽详细介绍),比照如 touch 恶性事件组成产生的 pan 平移、pinch 放缩、swipe 轻扫等恶性事件的实际解决做了包装,便捷按需引入。

Chart

图表行为主体基本,数据信息加载、英语的语法应用的通道。Chart 类从一个 F2 自身完成的恶性事件系统软件拓展而来,根据简易的 eventListener 维护保养也有 on/off 和 emit 对应挂载卸载、开启恶性事件,完成全部图表的通讯和各个控制模块的联动。

针对除图表行为主体以外的各种各样輔助软件,如 Tooltip 悬窗、Legend 图例等选用申请注册体制。

register 的情况下把 chart 目标传入,软件能够自身独立配备、维护保养情况、进行3D渲染,像 Tooltip 的互动也根据恶性事件系统软件来完成,各个软件自主申请注册解决涵数到 Chart 上一起解决Chart 只需要维护保养 plugins 目录,Chart 能够根据这个目录在恶性事件钩子开启时对各个 plugin 开展 notify,软件自身对全局性的这些恶性事件开展自定的响应,升级情况
3.2 What happened?

当大家建立一个 Chart 案例、加载数据信息、建立图型英语的语法指令、最终开启 render 的情况下,产生了甚么?

3.2.1 new Chart() initCanvas 依据传入信息内容,包含 canvas 实体线 / 左右文 / DOM 元素,也有宽高、pixelRatio、字体样式族,建立 Canvas 目标,这个目标封裝了具体的 Canvas 目标,完成恶性事件通讯,曝露绘图、resize、消毁插口,后续的最底层绘图都在此基本勤奋行initLayout 合理布局原始化,Canvas 做为图表总体基类,需要管理方法图表的数据信息投射、座标轴、輔助信息内容、题目、图例等的合理布局,这一步结适用户自定的和默认设置的配备开展合理布局initLayers 建立 Chart 的分层实体模型,根据在 Canvas 上加上绘图组,完成图表画布三层的分层构造 座标轴关键在最底层,数据信息投射一部分(折线、散点、柱)在正中间层,輔助信息内容如輔助线、浮窗,关键在顶层这只是定义上的分层,具体上 F2 依靠的還是单一的 Canvas,沒有分层级,这样只是给定义上的实际操作带来了便捷。在挪动端小图的场景下,同时维护保养三层 Canvas,还要维持对齐、解决重合,成本费比解决交叉式重绘更高 initEvent 全局性 Chart 需要管控的恶性事件申请注册,关键是数据信息升级和图表总体 resize 时的开启和必要的再次测算,别的恶性事件会由别的组件管控initScaleController 为数据信息各个维度的值域投射专业建立了 controller,原始化时应当挂载上,并维护保养 Chart 的 scale 配备initAxisController 座标轴这个实体线的 controller 挂载,为的是将原始化结束的三层构造中顶部和底部告之座标轴管理方法器,以便后续绘图
3.2.2 chart.source(data) Chart 自身 data 情况 set假如同时传入了 scale 配备,会启用 scaleController 对各字段 scale 配备开展增加量的改动,并升级全部受危害的配备,升级方法是全量的,拿到每一个 field 数据信息,再次开展投射数据信息归一化解决会在实际的 Geometry 中,上面大家早已提及了
3.2.3 chart.interval().position().color()

详细的 Geometry API 示例应当是这样的:

// Type 能够是 point 点,line 线,interval 柱等等,实际上定义应当是更抽象性的 Visual Cue
chart.()
// 字段分析,通俗化易懂:x*y / [x, y] 表明以数据信息的 x 维度和 y 维度各自为横纵轴
 .position()
// 制图特性:尺寸、色调、样子
 .size()
 .color()
 .shape()
// 别的专用工具:数据信息调剂、Canvas 制图特性、动漫
 .adjust()
 .style()
 .animate();
拷贝编码
Geometry 对接建立数据信息投射图型的指令,以上面的语句为例: 原始化 Interval 柱状图案例,分析带进来的主要参数,与默认设置配备 mix 转化成绘图配备分析字段 field,明确以数据信息源中甚么字段名做为数据信息的各个维度,同时还会升级 scale,它立即危害拿到数据信息后的绘图范畴、粒度关联更多配备化的制图特性,如图案设计尺寸,色调,填充样子开展数据信息调剂、制图特性、动漫加上 这些 API 实际操作的全过程,实际上都是维护保养该 geom 內部 config 目标的全过程,它实质就是一份配备数据信息,升级结束明确以后,在 render 的情况下才依据这些配备新项目开展绘图
3.2.4 chart.render() 第一次3D渲染的原始化实际操作:开启数据信息过滤器,过滤器是一个目录,由互动界定加上,例如 Legend 软件,在点一下条目地情况下会开启数据信息维度的显示信息或掩藏,这时候候需要维护保养过滤逻辑性;原始化座标轴并挂载到 Chart 上;附加实际操作如多座标轴对齐、数据信息 adjust 等3D渲染座标轴,Chart 会从 Geometry 这个管理方法数据信息投射的构件中拿到当今数据信息的 scale 信息内容,例如笛卡尔座标系中会拿 X Y 两轴的基本信息内容,这确保了座标系和数据信息的联动性。之后 axisController 自身依据数据信息建立座标轴,应用前面提到的 axis 组件,按需3D渲染,将需要3D渲染的图型加上到 Canvas 上刚开始解决正中间层,为正中间层建立 canvas clip,将后续 Geometry 的绘图限定在这个子画布内,之后逐一开启 geoms 的 paint,这里的 paint 实际上也是假绘图,并沒有真正刚开始3D渲染,而是将每一个图型的相对路径和制图特性都配备好,加上到 canvas 上刚开始解决顶层,最先要对顶层內容开展一遍排列。这里的排列 F2 根据对每一个图元本身的 zIndex 开展维护保养,同时在绘图之前行行排列,zIndex 升序,后边绘图的会全自动遮盖前面的这般就进行了三层內容的层叠加上,而且确保了次序,最终会启用 canvas.draw 刚开始绘图,展现详细图表
3.2.5 简易说说升级绘图

在上面的步骤中能够看到,F2 在图表3D渲染全过程中统一开了一些贷款口子(例如一些恶性事件全局性 emit、积极查验的一部分共享资源配备数据信息等),便捷软件或互动、动漫工作能力引入干涉绘图全过程和绘图实际效果。因此图表升级和互动3D渲染也是不难了解的:

图表数据信息升级步骤大致同样,由于重合,基本都要开启挺多种绘的,可是 AntV 有一些重绘时的优化,如部分3D渲染,能够降低损害互动造成的升级,根据软件完成:

例1:Tooltip 软件根据配备项告之 Chart 是不是需要在顶层加上 Tooltip 元素,而且根据互动分辨操纵本身的生命周期。

例如在监测得手指导按的情况下,拿到恶性事件,测算点一下地区获得应当展现的详尽信息内容,应用 Component 出示的基本制图组件加载数据信息开展获得绘图信息内容,将绘图信息内容加载 canvas 涂层配备中,同时开启 canvas.draw 重绘,再次测算顶层需要3D渲染的元素,此时新增的新项目也被添加,就进行了绘图。

例2:Legend 点一下挑选,在 3.2.4 中提到了。chart render 时会走一层数据信息过滤器,这层过滤器是 Legend 软件能够干涉的,Legend 在产生互动(如客户点一下下图的 men 条目使其置灰,当今的挑选情况就被升级到数据信息过滤器中,chart 再次3D渲染时数据信息即被剔除。

掌握过构架上和全部制图步骤的宏观经济完成,接下来从两个关键的细节设计方案来深层次讨论 F2 是怎样处理一些重要难题的。


4. 略探一二

细看两个重要的设计方案细节:互动 动漫

图源:F2 库房中 README 示例


4.1 「互动式」如何做

Overview first, Zoom and Filter, then Details-on-Demand.

F2:概览第一,聚焦过滤,再按需查询

F2 默认设置依靠的3D渲染模块是 Canvas (终究只是二维图表,更繁杂的 WebGL 不谈,Canvas 和 SVG 的选择能够看到 AntV 有关模块挑选的探讨,连接一样可见文末),Canvas API 规范出示的是一种 immediate-mode API,与之相对性的是 retained-mode API,简易了解这两种方式就是,前者就像白纸,API 启用就像一笔一笔往上面画图案设计,画上去了就拆不开了;后者就像乐高,一张图将会有其自身的层级构造,內部的构造情况是被保存下来的,能够类比大家更熟习的 DOM 构造。

在 Canvas 这类“及时”制图的自然环境下,其实不能了解当今画布上面客户姿势意欲互动的连接点/元素,实际上压根沒有所谓连接点和元素的定义,整张画布就是一张 bitmap,因此元素的定义需要图表库来维护保养。

挪动端最基本的互动恶性事件是“点一下”“触碰”,怎样拓展出一套详细的,适用包含图表互动需要的:放缩、平移、轻扫、手指滞留预览、选中等互动,也是需要处理的难题。

因此要完成互动,需要处理两个难题:

怎样接纳原生态的互动恶性事件,包装成图表库能够消费的更详细的恶性事件系统软件——EventController;怎样将互动恶性事件投射到具体其实不存在的元素定义;

大家先看比较直观易懂的第二个难题能够如何处理。


4.1.1 从最简易的元素点一下恶性事件刚开始

实际恶性事件开启先无论,先看看已知某恶性事件开启,了解网络热点座标,怎样解决

测算

画几个不重合的形态各异的圆维护保养一个数字能量数组储存圆的信息内容 点一下时从全部 Canvas 元素的点一下恶性事件拿到点一下网络热点在元素内的座标 clientX/Y逐一分辨圆心到网络热点的间距和半径的关联可知是不是点一下了某个圆了解是某个圆了,互动就好说啦 重合如何办?最底层优先选择?顶层优先选择? 只需要操纵遍历图型数字能量数组时的次序、是不是“懒遍历”(找到一个就回到)

Trick

一个 Canvas 画布实际上是一张 bitmap,针对一个点一下部位,该像素的色值是最立即的信息内容,需要的测算量非常少获得色调,随后能够觉得客户点一下了该色调的图型色调碰撞?能够用一层看看不到的离屏 Canvas 同歩绘图同位图做互动层,每一个元素转化成一个任意不反复的色调,全透明度能够在离屏 Canvas 屏蔽重合难题?只能完成顶层优先选择的互动恶性事件,或再维护保养重合色调;全透明度?难顶;多层 Canvas?难顶;可是能够适用更繁杂的不规律图型

各有优劣——结合应用

简易图型:算

繁杂图型:能简化?简化,算;不可以简化?取色

取色的成本只在绘图时要3D渲染双层,后续互动速度很快

F2 中应用的关键還是第一种方法,由于 F2 的挪动端互动状况都不太繁杂,互动精度要求低,图表 Canvas 实体线也不会太大,简易的几何图形图型包围着盒测算便可以考虑要求了。


4.1.2 触碰点精准定位能做了随后呢?

本来是依靠于 hammer.js,这个“锤子”就是专业解决挪动端手式互动的,非常是多指触控等的互动适用。可是由于它还依靠访问器自然环境,这对期待全服务平台可用的 F2 来讲是一个缺点,因此 F2 也在渐渐地摆脱这个库。自身完成了一套多指触控。现阶段应当還是逐渐转移的环节。可是实际上现思路比较简易清楚。

基础理论上,要是能够处理分辨当今电脑鼠标/手式互动产生在哪一个“元素”上,别的恶性事件都能够仿真模拟了。同时,朝向挪动端 F2 实际上比基本的 PC 端图表要解决的互动分辨更简易:

PC 端有虚似指针,因此有 hover、move、click、drag 等恶性事件需要解决;挪动端只需要解决 click 和 touch;touch(start, *move, end, *cancel x) -- mouse (1move, down, up) -- click: 先开启 touch 恶性事件,在其中有起止 start,将会有 move,停止的 end 或出现异常停止的 cancel,cancel 将 block 后续的恶性事件开启;后开启 mouse 恶性事件,各自是唯一的 move 和后续紧跟的 down 和 up;最终开启 click 恶性事件。

F2 自身完成一个 Controller,根据 touch 系列恶性事件监视,仿真模拟出详细的手式实际操作。沒有太多深奥的技术性,设计方案逻辑性也比较清楚,但编码比较难提炼,并且如今還是逐渐摆脱 hammer.js 的适配环节,将会有点难理清晰,因此这里画了一个互动步骤的时钟频率图,一起看看如何仿真模拟手式互动:

一些细节、关键点笔记:

这个 Controller 帮 Chart 层屏蔽了 Canvas 自身的恶性事件解决,包含互动编码序列、速度、点数不一样致使的不一样实际操作判断,都封裝成单独恶性事件,这样解决响应会十分便捷所谓代理商,实际上是对每一个恶性事件加上自定的 EventListener,代理商后原恶性事件会再被抛出,这里就省略了多一点触控恶性事件中,会有 touches 特性储存全部点信息内容;多点恶性事件则仅有一个单一的 point扩展恶性事件,根据库本身完成的简易恶性事件管理方法抛出的。在这一层只需要解决好全部 controller 逻辑性和恶性事件步骤,剩余的交到顶层消费这些恶性事件:press、pan、pinch、swipe。开启这些恶性事件的情况下 Controller 会按顺序开启 start 和 end,并在 processEvent 标识该恶性事件的开展。

大家早已处理了落点测算、恶性事件包装,那当互动恶性事件产生,大家的恶性事件消费便可以开展了:针对需要响应的恶性事件开展监视,之后历经分辨开展附加3D渲染便可。

4.2 「动漫」如何做

通俗化易懂:动漫在大家这样的数据信息展现类平常图表中,将会针对数据信息的具体展现、剖析輔助功效其实不是很大,但它是提高客户体验,提升图表自身的高級感的关键专用工具。

F2 中动漫的行为主体是表明数据信息投射图型的 Shape,大家前面说过 Shape,维护保养的实际上是本身的部位、重要点、制图特性等数据信息,动漫,就是根据逐帧更改 Shape 的特性来完成的。

许多有关自定动漫、默认设置动漫的內容,逻辑性比较繁杂就不详尽讲了。大家探讨一个重要难题:在前面提到的3D渲染方式中,动漫这个全过程是怎样勾入全部 Chart 的 render 中的?

要处理这个难题,有两个重要的情况专业知识需要掌握:


4.2.1 缓动涵数 easing function

动漫的完成中,动漫速度经常是操纵动漫实际效果的一个关键维度,需要有多种方式适用动漫开展的速度跟時间的关联投射,这样的方式就是缓动涵数。以便适用多样性的动漫,F2 本身内嵌了一系列缓动涵数。当今大致包含:

一次线形缓动(能够了解为匀速);二次、三次缓动(包括淡入、淡出、淡入淡出);延展性缓动(包含回弹、精准定位抖动、反弹);

有关缓动实际效果的展现,能够在文末参照连接看到缓动曲线图也有动漫实际效果,电脑鼠标 hover 在对应的涵数图之上,会有一个光标,它的挪动速度能够表明该缓动涵数完成的速度操纵实际效果。


4.2.2 插值器 interpolator

插值器也是动漫行业一个比较关键的定义了,不详尽进行,并且其在大家简易的二维动漫中其实不繁杂,大致掌握一下其情况和主要用途便可。插值器经常是用于建立所谓“补间动漫”的专用工具涵数。在 F2 中,关键适用了两类型型的插值:

纯标值的插值,用于建立如全透明度、尺寸、一维部位之间转变的补间;引流矩阵插值,用于建立如散点部位转变、引流矩阵转变的补间。

插值器的方式大约是接纳起止和停止两个情况,转化成一个能够接受一个表明全部动漫进度的主要参数 t,回到该进度下数据信息正中间值的涵数,用最简易的标值插值器来举例就行了(下面编码片断来自 F2 源码):

function interpolateNumber(a, b) {
 a = +a;
 b -= a;
 return function(t) {
 return a + b * t;
拷贝编码

回到的涵数接受一个 t,表明当今进度,这个涵数能够用于测算 a --- b 的标值转变中,历经時间 t 以后的标值状况。这里的 t 是用当今动漫早已实行的時间 t' / duration 算出来的比值。假如用 4.2.1 中提到的缓动涵数再对 t 包装一层,就完成了标值转变的缓动。


4.2.3 逐帧3D渲染

帧的定义,由 requestAnimationFrame 来开启

这里 F2 做了一个兼容,访问器自然环境下,存在 requestAnimationFrame 方式,则立即应用,不存在的话会 fallback 应用 setTimeout(fn, 16) 替代,近似做到每秒 60 帧实际效果。

当大家原始化一个动漫时,是建立了一个 Animator 类,需要三个主要参数,能够帮大家大致了解动漫的实行架构

动漫的目标 Shape(是各个意味着数据信息的图型在开展着动漫)Shape 本身特性 Attrs 做为动漫的內容(动漫內容是图型的尺寸、样子、色调、部位等随時间的逐帧更改)需要动漫实际效果的行为主体自身保存的 timeline 目标,这个目标能够完成动漫生命周期操纵

Timeline 目标是操纵动漫实行的最少模块,遭受全局性默认设置申请注册的动漫管理方法器的操纵。管理方法器会默认设置将全局性的 Shapes 动漫加上到 Timeline 的动漫序列中,当监视 Canvas 将刚开始更新,就会刚开始“播发动漫”,动漫播发结束,做到更改化环节的最后情况,canvas 升级也就完毕了,就会“终止播发”

动漫恶性事件,是由 Animator 目标的 to 方式传出的,普遍的方式是将某个 Shape 确当前情况 animate to 某个新的情况,建立动漫的情况下能够从此获知起止和停止情况,明确这个动漫的全过程是要更改哪一个 Shape 的甚么特性,耗时多久,这就建立了一个动漫恶性事件

Timeline 操纵器,就是对动漫恶性事件的消费。最先它会维护保养時间轴,动漫播发全过程中根据 requestAnimationFrame 不断启用本身的 update 涵数,update 涵数升级当今時间,查验动漫序列,逐一取出事了件,分辨动漫实行进度,假如还在进度中,则应用上面提到的缓动涵数和插值器测算动漫进度,将动漫目标的特性升级为获得到的插值,这时候候 Canvas 中的图型信息内容就升级了,全部动漫恶性事件序列遍历完以后,启用 Canvas 的 draw 方式开展升级,就完成了动漫实际效果

这个全过程中 Timeline 也担负了一部分动漫序列的维护保养工作中,假如消费全过程中,发现有些 Shape 早已被消毁了,则其动漫也不可该再维护保养,Timeline 会将其从目录中移除假如 Timeline 查验进度发现某动漫早已实行结束,则還是保存动漫恶性事件,下次升级将会还要实行,但本次 update 能够绕过了

因此,实际上我一刚开始的念头禁止确,并不是动漫全过程“勾入” render 全过程,而是动漫做为 canvas 绘图全过程中的“装点”,在图型变化时做为一个正中间全过程,由 Timeline 开展操纵和3D渲染。


5. 水土不服情况

为何?如何做?做得怎样?

兼容包 tt-f2 (取名取自 F2 官方的手机微信兼容包 wx-f2,针死对头条/字节颤动小程序的兼容) Github 详细地址可见文末。

从这一一部分刚开始,大家回到了具体的落地场景,来看看要在字节小程序上应用 F2 遇到了甚么难题,能够怎样处理。

5.1 关键

当大家在字节小程序上立即引入并刚开始应用 F2 这个图表英语的语法库来画图表,大家会遇到以下难题:

官方 Demo


具体引入状况


操纵台不正确


5.2 病理学

既然图型、大致的图表架构,乃至图例、数据信息投射都早已画出来了,表明图表库自身的运作是基本 OK 的,而且依照大家前面的源代码学习培训,F2 基本是纯 JS 自然环境下运行的,有关依靠也在慢慢降低,因此绘图主要表现出现异常,色调遗失,很有将会是最底层制图 API 的难题。具体上官方在对手机微信小程序做的兼容中也提到,基础理论上要是出示了一样的 Canvas 运作自然环境,便可以一切正常进行图表绘图。

带着这个难题,大家先看看 HTML5 规范和字节颤动小程序给出的 CanvasContext 有木有甚么 GAP:

(注:以下数据信息比照是截止 2020.10 的数据信息。HTML5 Canvas 规范来自 MDN,字节小程序插口来自小程序官方文本文档。同时,HTML5 规范中试验性、已废料、未规范化的特性或方式已被忽视)

做完如上梳理以后,大家基本能够判断 demo 图表款式出現难题,是绘图的情况下可写特性所有无效致使。至于小程序自然环境正下方法上的一些 GAP,调研以后发现危害不大,关键是环状渐变色、纹路绘图、文本描边这三块作用有没有法防止的缺失,别的沒有对齐的 API 在 F2 源码中都沒有用到。

至于这样的沒有与 HTML5 规范对齐的 API 设计方案的初衷,特别是制图特性不适用可写的难题,根据掌握和资询,获知这样的设计方案出于以下的一些考虑到:

Canvas 组件从基本库 1.0.0 刚开始适用,以便减少小程序开发设计者的转移成本费,基本工作能力的设计方案基本和手机微信小程序对齐,手机微信小程序的 Canvas Context 制图特性可写特点也是 18 年 2 月左右,基本库 v1.9.90 以后才适用的。这样的设计方案将会也和小程序与 Web 的差别相关。大家了解小程序主视图组件和 JS 逻辑性各自运作在3D渲染层 (webview) 和逻辑性层 (jscore) 中,Canvas 制图命令的完成涉及到从 webview 到 jscore 的通讯,提升运作特性,做了特性设定和绘图的分离出来,set[[propName]] 只是将实际操作放入 action 目录,真实的绘图要启用 draw API,统一实行,以此降低经常通讯的状况。

此外,也有一个小难题。刚刚操纵台輸出了一片鲜红色出错,都是形如 不适用色调:#fff 的出错信息内容。这是由于字节小程序不适用 RGB 色调的 HEX 简写。这个难题根本原因比较简易。


5.3 偏方

5.3.1 先“挑软柿子捏”

RGB 的 HEX 简写(形如 #ffff00 --- #ff0),在库源代码各部都有,在 ECharts 之类的别的库也是这般。没方法根据甚么配备新项目来遮盖掉。但大家能够开展编码更换:

这样的 HEX 简写以标识符串的方式出現在库源代码中,而且都是以 # 开始,紧跟三个 HEX 标识符 正则表达式表述式配对:/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])(['"])/g将其更换为:'#$1$1$2$2$3$3$4' 的方式实际上就是很粗鲁地把正中间的三组单独缩写拆出来复原为两位,并保存原先的井号和末尾引号 replace 软件适用对特定文档夹內容开展扫描仪更换,应用上方正则表达式配对更换便可 npm 在 script 中出示了 postinstall 重要字,能够在这个钩子中添加指令,运作更换脚本制作
// package.json
"scripts": {
 "postinstall": "node ./util/hexFormatter.js"
// hexFormatter.js
const replace = require('replace');
replace({
 regex: /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])(['"])/g,
 replacement: '#$1$1$2$2$3$3$4',
 paths: ['../@antv/f2'],
 recursive: true,
 silent: true,
拷贝编码

这个做法有点小难题都还没深究:npm 中一切正常运行,假如应用 yarn 做为检修口理器,在升级包或安裝别的包以后,原来的更换实际操作会被复原回去,大致推断是 yarn 会分辨 node_modules/* 是不是被伪造,而且复原时不会开启 postinstall 脚本制作。

5.3.2 抹平 Canvas 差别

历经上面的 API 调研和 diff,清晰了 Canvas 左右文自然环境的差别所属。方式上的 GAP 现阶段沒有比较好的计划方案去填平,可是由于很多插口 F2 并沒有应用,而极少数缺点造成的危害,在普遍场景中基本能够忽视,因此小程序 Canvas 的方式基本是能够承载制图要求的。

重中之重是处理小程序彻底沒有出示可写特性的难题。因此期待可以将对 CanvasContext 中特性的写恳求变为对小程序 CanvasContext 中一系列 set 插口的启用,答案就比较显著了,就是将写恳求代理商出来,手动式启用插口。说到代理商,那 ES6 的 Proxy、Reflect,或是最原生态的 defineProperty 都能够做。实际上这几者基本都是对 getter setter 的被劫持,以便最简化,也以便不考虑到 ES6 适配的难题,大家立即用 defineProperty 试一试。有了上面的 diff 依据,兼容起来其实不难:

const MAP = {
 fillStyle: "setFillStyle",
 font: "setFontSize",
 globalAlpha: "setGlobalAlpha",
 lineCap: "setLineCap",
 lineJoin: "setLineJoin",
 lineWidth: "setLineWidth",
 miterLimit: "setMiterLimit",
 shadowOffsetX: "setShadow",
 shadowOffsetY: "setShadow",
 shadowBlur: "setShadow",
 shadowColor: "setShadow",
 strokeStyle: "setStrokeStyle",
 textAlign: "setTextAlign",
 textBaseline: "setTextBaseline",
// 提取可配备的 fontSize
const fontSizeReg = /(\d*)px/;
export default (ctx) = {
 Object.keys(MAP).forEach((key) = {
 Object.defineProperty(ctx, key, {
 set(val) {
 const setter = MAP[key];
 if (!ctx[setter]) {
 return;
 // 对设定 font 的恳求,只应用 setFontSize 设定字号
 if (key === "font" fontSizeReg.test(val)) {
 const match = fontSizeReg.exec(val);
 ctx[setter](match[1]);
 return;
 // 考虑到自主加上自变量储存 shadow 各字段
 // 每次都启用 setShadow 开展全量设定
 if (key === "shadow" Array.isArray(val)) {
 ctx[`_${key}`] = val;
 ctx[setter](
 ctx._shadowOffsetX || 0,
 ctx._shadowOffsetY || 0,
 ctx._shadowBlur || 0,
 ctx._shadowColor || ""
 return;
 ctx[setter](val);
 return ctx;
拷贝编码

由于原始化 Chart 目标的情况下,总要传入一个 CanvasContext 或其元素。大家能够对 Chart 开展一次承继,其子类 TTChart 在原始化的情况下,拿到 CanvasContext 先回做一层包装被劫持,应用上面的方式设定各个特性的 setter,然后再交到父类,原 Chart 做原始化实际操作,后续 Chart 根据这个 Canvas 左右文制图时,对接的 API 就是大家兼容过的了。

兼容实际效果以下,基本能够做到官方 demo 的主要表现了,只是宽高没对应设定罢了,数据信息展现、动漫、互动早已能够完成(互动上需要给小程序中的 canvas 连接点关联 touch 系列的恶性事件监视,手动式 dispatch)。

5.4 复诊 官方也在做兼容勤奋,未来可期;Canvas 能够兼容,GAP 是能够接纳的。字节系小程序的 Canvas 2D 左右文基本库有上面这些 API 与 HTML5 规范存在 GAP,兼容上有一些系统漏洞,但不会带来很大的压根性危害;库内小量依靠了访问器 BOM、DOM 的自然环境,但由于官方的成心转移在渐渐地淡出,例如前面提到的手式实际操作,自身完成,摆脱 hammer.js,这是好的进展;可是相近原先出示的容许客户引入自定 HTML 的作用因为小程序沒有 DOM 插口将会一直有缺点。能够怎样兼容?提早预留连接点部位?自定连接点彻底转译画出来?F2 官方可否出示更高程度的自定贷款口子,容许客户自身扩展一些软件? 客观事实上相近这样的实际操作是能够完成的,对实际数据信息的互动产生时 F2 出示了回调函数通道,我的新项目中就根据这样的贷款口子自身完成了自定的 Tooltip。
6. 善始善终

回望总结

简易回望一下本文的內容。

由于可视性化这个话题還是比较大的,即便实际到某个特点独特的库,也還是有很多內容会涉及到到。在这次共享中,关键涉及到了以下几大块內容:

可视性化话题上基本定义的掌握,从 2.1 可视性化定义详细介绍、图型英语的语法引入,在此基本上讲到根据图型英语的语法的 AntV 家的图表库和各有精准定位发展趋势。随后在 2.2 有了大致的上手感受,掌握应用图表库的平常场景是如何的,体会图型英语的语法的反映。走马看花地访问了现有架构下 F2 是如何设计方案的,关键有多少个作用控制模块和认知能力上的实体线,根据简易访问编码和数据信息流动性,明确各有岗位职责,然后再回到实际的应用场景中,看看这个库是如何 work 的。接下来比较详尽地掌握了两个作用控制模块的实际完成,选择这两个作用控制模块也是由于觉得其比较独立,非常容易抽离出来弄搞清楚,并且有一定设计方案构思,学习培训参照的使用价值较高。回到最开始的起始点,回到这次学习培训的起动情况——要求,看到在搞清楚基本原理以后,遇到难题大家能够怎样兼容的一个小 case。
7. 一点思索

对外开放性话题

7.1 更看好、更想要应用标榜图型英语的语法的 G2(-Plot)、F2,還是配备化、作用化的大哥哥 ECharts 之类的呢?

大哥還是大哥,客户量大和小区活跃度高。终究如今也是 Apache 旗下开源系统商品了,并且接入门坎相形之下会更低。做为老前辈级的库,ECharts 也累积了许多优化实践活动和工作经验,也有很多强劲专用工具如 ZRender,它完成了 SVG 和 Canvas 两大阵营的最底层抹平,本人觉得是是非非常强大的设计方案,把上面提到的 immediate-mode 和 retained-mode 这两个方式的规范做到统一封裝,光这一点在兼容性、优化上就可以铸就很大优点。

刚刚提到了 noCode, lowCode,配备化的确是无需 code,可是 noCode, lowCode 自身的一个难点关键点是订制性够不足强,尽管之前掌握到的 360 精英团队的一个可视性化编写器,用的图表库一部分就关键是 ECharts,但图型英语的语法的叙述工作能力能够说具备更高的灵便性和拓展性,会不会发展趋势到某种程度的情况下实际上能做得更好。


作者:字节前端开发

经典著作权归作者全部。商业服务转载请联络作者得到受权,非商业服务转载请注明出处。 ---------

建站宝盒专业版

------------


联系我们

全国服务热线:4000-399-000 公司邮箱:343111187@qq.com

  工作日 9:00-18:00

关注我们

官网公众号

官网公众号

Copyright?2020 广州凡科互联网科技股份有限公司 版权所有 粤ICP备10235580号 客服热线 18720358503

技术支持:如何注册小程序