一、前言
在正式内容开始之前,先来介绍一下炎凰数据的鸿鹄平台,它是一个一站式异构数据分析平台,提供了从数据接入、存储查询到上层应用的整体解决方案。鸿鹄提供产品开箱即用的数据格式化功能,通过鼠标点选即可将查询结果快速生成图表,并添加至仪表板中。鸿鹄同时提供了折线图、面积图、条形图、柱状图、散点图、地图、饼图、量规图和词云图等丰富的内嵌图表。
鸿鹄一站式异构数据即时分析平台
鸿鹄典型场景展示
作为鸿鹄可视化部分的基础图表库,接下来首先介绍 Echarts 的基础概念和特性。
二、Echarts的基本介绍
1、Echarts历史
Apache Echarts 官网截图及 Echarts下载量
根据官网定义,Echarts 是一个基于 JavaScript 开源的可视化图表库。其历史最早可追溯到 2013 年,由百度发起。2018 年 1 月进入了 Apache 软件孵化器。在这期间,其发展势头一直较好。它的推广类型和样例,以及一些使用配置项在这段时间得到了逐步完善。2021 年 1 月 26 日,Apache 软件基金会宣布 Echarts 为顶级(top level)项目。当时最新的版本发布会参与人数达到 5000人,用户热度很高,而且不断地上升。到目前为止,GitHub 上的 star 数已经突破 4000,NPM 周下载量达到 57 万多。
Echarts 的最新版本为 5.4.1。经历多个大版本迭代后,它也积累了比较丰富的经验。可以看到它正在被越来越广泛地应用,也受到了大家的认可。
2、Echarts 特性
Echarts 的特性和优势场景很多,主要包括以下几个方面。
Echarts 特性
① 丰富的配置选项和可视化图表类型
Echarts 提供的图表类型非常丰富,稍后会详细介绍。常规的有折线图、柱状图、散点图、饼图、K 线图等。还有用于统计的图,用于数据可视化的地图、热力图,关系数据库用到的关系图,以及用于 BI 的漏斗图等。
② 强大的交互式组件
交互是从数据中发掘信息的重要手段。Echarts 提供了图例、视觉映射、数据区域缩放、toolip、数据筛选等开箱即用的交互组件,可以对数据进行多维度的筛选、细节展示等。除了交互组件还有事件响应,如点击、鼠标移动、拖拽等,Echarts 对这些交互动作的支持也是比较好的。
③ ZRender Canvas 和 SVG 渲染器支持
Echarts 底层是依赖矢量通用库 ZRender 实现的,所以它天然的对于 Canvas 和 SVG 这两种渲染器都有比较透明的支持。Canvas 更适合绘制图形元素比较多的场合,比如热力图,或者地理坐标系、平行坐标系上面的大规模线图。SVG 有它的优势,但内存占用率可能会很高,解决这个问题对移动端比较重要,用户使用浏览器内置缩放功能的时候,才不会觉得模糊。一般来说,在软硬件条件或者环境都比较好、数据也不是特别大的场景,可以选用任意一种渲染器,在需要的时候还可以进行切换。
④ 对移动设备的支持和跨平台
Echarts 针对移动端做了比较细致的优化,而且因为它支持 SVG,使移动端的内存占用问题得到了一些缓解。
⑤ 浏览器的兼容性
要做到对多种浏览器的支持,包括对历史版本的支持,这是现在大家挑选图表库的一个基本要求。Echarts 支持绝大部分浏览器,例如 IE、Chrome、Firefox、Safari 等。Echarts 另一个优势在于它的文档,包括使用手册、配置项手册等。其中的示例详细且全面,包括中英文版本。社区对问题的反馈和修复也很积极。如果遇到了问题,可以用中文交流,很多问题都能在社区直接找到解决方案。
三、配置选项和自定义属性
在对 Echarts 有了基础的了解之后,接下来介绍鸿鹄里面如何应用这些配置,如何自定义配置项。
1、Echarts 配置项
Echarts 配置项
Echarts 提供了丰富的配置项,使用非常灵活方便。无论是最常见的标题组件、图例组件,还是坐标系组件和各种图表组件,它的配置属性值都是比较多的,基本上能够满足大部分图表开发的需求。
以最常见的图例组件配置为例。下面的样例生成了一个地形统计的柱状图。其中,option 对象包含了很多属性,包括数据集的数据源。这里的数据按年份分为 5 组,从 2012 年至 2016 年。每组包含 4 种数据,分别是森林、草原、沙漠和沼泽。除此以外,组件还包括 color、legend(图例)等其它的配置项。这里的图例中显示的值是 false。
图例的配置项及显示图例
接下来做一个简单的更改,让这个图例显示出来。可以直接把 false 改成 true,这时图例就直接显示在柱状图的上方了。当然,图例的位置、整体的显示形式等都可以在图例组件里面找到相应的属性去调整。
2、Echarts SetOption
介绍了 option 对象后,我们再看它的 setOption 方法。setOption 由 echartsInstance 实例来使用。这个实例是由 echarts.init 创建出来的。这里面不光能更改配置项,其他所有的参数包括数据都可以通过 setOption 来完成。
接下来看一个例子。下图右边的柱状图,上面叠加了一个折线图。两组用来生成柱和线的数据都是随机的。X 轴是时间轴。
Echarts 图表 setOption 方法样例
在左侧的代码中有一个定时调用的函数 setInterval,差不多每 2 秒更新一次图表。其中就调用了图表的 setOption方法。横轴每个间隔差不多 2 秒。Echarts 自动判断并且合并新的参数和数据去刷新图表。如果开启了动画,还可以看到数据之间的差异,通过动画去表现数据的变化,就如同随着时间轴在往前挪动。整个过程都有着很好的用户体验。
3、鸿鹄的图表配置项
了解了 Echarts 的数据和参数配置项,以及实例的 setOption 方法之后,接下来介绍鸿鹄如何实现配置项效果。
在仪表板中,每一个图表对应的图形组件定义为 widget。首先进入编辑模式。点击图表的编辑按钮(小铅笔),会弹出一个可拖拽的模态框。上面是一个图表类型的可选下拉框,可以将图表类型自由设定为柱状图、线图、散点图或条形图等。中间是分类的标签页。里面按照常用的分类,将一些比较具体的配置项放到不同的标签页里。
鸿鹄的图表配置项
第一个是常规标签页。主要是一些通用的标题显示配置,包括标题的显示、标题的内容、颜色、字号、位置等。
第二个是柱状图标签页。主要是柱状图相关的配置项,包括显示堆叠、条形宽度,以及是否更改显示数值、提示类型等。
第三个是 X 轴或 Y 轴标签页。对于二维坐标图表类型,都可以在这里进行配置。可以更改X轴的名称、标签的位置、样式、显示所有刻度、是否打开刻度尺等。
4、鸿鹄的自定义配置项
在商业软件中没有办法把所有的选项都做成 UI 的操作放到界面里。Echarts 解决这个问题的办法是在 setOption 的时候,把组件对象放在一个在线的 IDE 里面,编写完之后,针对这些配置项去渲染生效。
鸿鹄也有类似的做法,增加了一个自定义的标签页来对图表进行定制化扩展。
如图所示。自定义标签页里面是一个输入文本框,或者叫 AceEditor(用 JavaScript 编写的可嵌入代码编辑器)。AceEditor 包装了用户输入的配置项,可以让用户有比较好的编辑输入体验。
自定义标签的语法检查和自动补全
这样做有几个好处:
首先是支持 JSON 语法检查。比如非法值的高亮提示,如图中的 “validKey”。
另一个是配置选项自动补全,高亮提示。Echarts 提供的关键字是比较多的,鸿鹄的做法是把关键词加到的 AceEditor 的 auto complete 里面,进行自动补全,用户输入的时候可以即时高亮提示。
第三个是应用效果即时预览。用户在界面里面自定义好的配置可以即时生效,便于查看效果是不是想要的。
以下面的饼图为例。这是一张典型 access_log 日志文件 method 返回状态码生成的饼图,如 get、post 等方法。在饼图的配置界面里已经预置了显示标签、详细标签、标签位置等标签。现在想实现更多的配置或者想要更酷炫的效果,可以通过自定义配置编辑器来自定义图表。
这里我们准备了一段能够生成玫瑰图效果的代码,将代码直接复制到自定义配置编辑器里面,点击应用配置按钮,就可以把这些配置应用在图形上面,经过 Echarts 渲染,从而生成类似玫瑰图的效果。
自定义编辑器
即时预览图表效果
除此以外,用户还可以修改其中的一些参数,比如 style、color、radius 等等。在输入过程中就可以查看效果。最后存为 widget 并存到仪表板。这些自定义输入的选项,也会和图表类型的对象一起存储。
四、扩展和自定义类型图表
1、鸿鹄的图表类型
鸿鹄的图表类型大致可分为三类:来自于 Echarts 的图表、自定义图表和第三方图表。
① 来自于Echarts的图表
第一类是继承自 Echarts 内建的图形。Echarts 自带了很多开箱即用的图表类型,包括折线图、面积图、条形图、柱状图、饼图、散点图、气泡图、地图等。
折线图
面积图
条形图
柱状图
饼图
散点图
气泡图
地图
气泡地图
气泡地图是鸿鹄额外封装的一种地图。底层是用地图作坐标系,地图坐标系的上一层用 scada chart,用类似散点图的方式来显示数值。图中有数据的点或者圆,代表该区域有数据,区域的面积越大,代表数值越高,或者频率越高。
② 自定义图表
下面举 3 个自定义图表的例子。包括单值趋势图、富文本类型图、表格类型图。
单值趋势图
单值趋势图主要用于可视化指标的显示,或者一种趋势的显示。
单值趋势图
如图所示,可以看到中间有个数值 21,它代表了一个变化的数值。数值的右边就是趋势的标记。下面的迷你图是一个根据数据变化的折线图。为了让单值趋势图的颜色可以适配不同的场景,鸿鹄提供了两种着色方式,可以根据数值或者是趋势来着色。数值着色相当于设置数值范围,比如例中可以设置大于 20 小于 100 的数值显示一种颜色,大于100 或者小于 20 显示另一种颜色。趋势着色是按照趋势变化进行着色,作为一种趋势的解释。比如红色代表升,绿色代表降,或者相反。
富文本类型图
富文本类型图方便用户自己管理一些漂亮的文字,或者插入图片、视频等等。它底层实现用的是 Quill JS,Quill JS 本身就是一个比较强大的富文本编辑器。鸿鹄把它做成了一个图形组件,形成了一种内置的图形。
富文本类型图
表格类型图
第三种也是数据可视化当中用得比较多的图表类型——表格。鸿鹄把表格封装成了内置的表格图形组件,如图所示。
表格类型图
这几种典型的自定义图形,还需要适配一些方法,尽量和已有的 Echarts 基础类型的图形一致。比如 setOption、setData、convertOptionToForm 等。另外还需要额外实现一些事件 eventHandle,最常见的比如鼠标的点击事件。
以单值趋势图为例,当点击单值元素 21 的时候,需要传递过来的数据信息就包括点击的字段名、字段值,还有字段的类型等等。
表格也是类似的。当点击单元格的时候,需要获取到点击的单元,包括字段名对应的数值,以及所在行、所在列的信息。这些信息在进行表钻取或者联动的时候会使用。
表格事件信息
③ 第三方图表
除了自定义的图之外,还有第三方包装的 Echarts 的图形,比如词云图。鸿鹄使用的是 echarts-wordcloud。词云图是对文本的出现频率予以数据化展现,文字越大说明出现的频率越高。
词云图
echarts-wordcloud JS 程序库使用也比较方便。可以指定图表的类型,即 word cloud。词云图提供了一些配置项,比如图的形状,上图中是 Diamond(菱形),还有颜色、文字的角度等选项。
2、鸿鹄的扩展图表类型
除了内置的图形外,鸿鹄同样支持用户扩展图表类型。接下来介绍鸿鹄以应用 APP 的方式去自定义图表的过程。
首先在 APP 应用中指定可视化图表的描述文件,即 viz.toml,位于 APP_HOME 下面。它的内容如下。
使用 APP 扩展图表
首先是注册一个 key 值,这里是 sample-chart,代表扩展的图表。需要注意的是,key 是唯一的,即同一个 APP 中不能用相同的 key 重复注册。
name 表示图表后显示的名字,即 Sample Chart。
option_class 表示图表文件所在的位置,这是一个相对路径。
export 表示图表注册的名称。
接下来添加一个真实的图表类型,雷达图。首先更改样例的描述文件 viz.toml,如下图所示。
添加一个 radar-chart 图表
完成描述文件后,打开图表文件。对于用户自己新建的图表,需要在 setData 方法中添加图形的处理方法。传入的参数包括 data 和 dimensions。
自定义图表文件
data 是图表对应的数据集,是一个对象数组,每个对象是一行。dimensions 是数据集的描述,包括列名、数据类型等信息。最终画图的时候,图表组件会把这些参数传给 Echarts。效果如图所示。
扩展 Radar 图
图表类型是 radar chart,图表的名字就是描述文件里面定义的名字。通过这种方法就可以将自定义图表添加进来。
四、场景展示数据可视化
刚才讨论了图表库和丰富的配置项,接下来进行可视化呈现。这部分分为图表布局、图表大小调整、钻取行为、仪表板的标记等几块进行介绍。
1、图表布局
图表布局
首先介绍 Echarts 的图表容器大小。图形大小初始化的时候一般推荐把图形传入一个 Div 节点作为父容器,这样 Echarts 图表的大小默认即为该节点的大小。
另外,Echarts 在响应容器大小变化的时候提供了 resize 方法,它可以改变图形的大小。比如在 main 容器里面定义了一个高度 400、宽度是页面 100% 的节点,希望在浏览器宽度改变的时候始终保持图表宽度是页面的 100%。这种情况下,我们可以在 window 的事件监听器里监听浏览器大小改变的事件,然后再调用 Echarts 的 resize 方法,去改变图表的大小。
使用 window 事件监听器调用图表的 resize 方法
值得一提的是,Echarts 的 resize 方法默认没有参数,但可以通过参数传递设置参数值,比如过渡动画(animation)、时长(duration)或者是缓动等。
接下来看一下鸿鹄图表布局的具体实现。
鸿鹄图表布局样例
例子中是一个 react 项目,用 react grid layout 组件库来实现。react grid layout 类似一个网格布局系统,它的好处是响应式和支持断点布局,可以进行拖拽,以及 item 的缩放。这里默认把一行分成了 24 份。
2、图表 Resize
接下来介绍 resize 方法的具体实现。下图创建了一个网站流量统计的样例仪表板。仪表板图表组件使用 grid layout 进行布局。
鸿鹄图表仪表板
当图表组件大小发生改变的时候,组件会获取最新的图表高度信息、大小信息,通过监听页面大小是否发生变化,在数据更新里面会调用 resize 方法改变图表的尺寸。在本例中,拖拽图表完成大小改变的过程渲染比较顺滑。
改变图表大小
3、钻取行为
钻取行为
仪表板作为最常用的功能组件,不仅要实现数据可视化呈现,还要满足用户对数据的交互探索。对于 Echarts 而言,用户对图表的操作经常会触发相应的事件,开发者可以监听这些事件,通过回调函数进行相应的处理。比如跳转到一个地址,或者弹出对话框,或者是做数据的下钻等。
Echarts里面鼠标事件包括 click、doubleClick、mouseDown、mouseMove、mouseUp、mouseOver 等。所有鼠标事件都会包含像 EventsParams 这样的参数包,它是一个包含当前图形数据信息的对象,如上图所示。比如 seriesType,表示当前图表的类型,如折线图、条形图或者饼图。
以上是 Echarts 的事件处理,接下来介绍鸿鹄常用的钻取交互行为。钻取在数据可视化分析中十分常见,它的特点是能够一层一层往下钻取数据,挖掘数据背后的关联。在鸿鹄里面,钻取更像是配置工具,可以在单击仪表板的数据点、表格行,或者其他可视化元素的时候触发配置好的操作。比如配置钻取链接到默认搜索执行自动辅助查询,单击图形上的可视化元素就会获得字段值,接下来通过补全查询中的搜索语句打开查询页面完成查询。
获取 EventsParams 以后,就可以执行 click 事件回调,即钻取动作。下面这段代码钻取的动作包括:链接到 URL、自动辅助查询、自定义查询语句、设置标记。
钻取行为代码
4、仪表板的标记
鸿鹄中的标记类似程序变量,一个输入标记由标记名称和标记值组成。如果在仪表板图表的搜索中使用了标记,就可以传递需要的数值。标记名称的语法使用$...$分割符。⽐如,如果将查询字段输入标记定义为“field”,数据来源定义为 “source”,则搜索为SELECT $field$ from $source$。
鸿鹄里面是有几种不同类型的标记。
① 文本类型标记
首先进入仪表板编辑状态,点击仪表板标题右侧的操作按钮“添加输入”,得到添加输入对话框。
在仪表板中添加文本类型标记
默认标记类型为文本框,输入标记名称 “token”,标记值为 “accessToken”,
然后点击“确定”按钮完成添加输入。如下图所示。
定义文本类型标记
② 选择器类型标记
第二种是选择器类型。选择器类型标记分为两种。第一种可以支持预定义选项,即定义好一些选项作为选择器的选项值。
预定义选项
另一种支持从查询中提取结果。如下图所示。在图中的例子中,将返回的 distinct t2.country 值作为字段信息(标记的选项)。
从查询中提取
③ 时间类型标记
时间类型输入可以用来控制图表的查询时间范围。可以把时间查询范围作为一个标记,在想用到变化时间的地方去使用。下面介绍时间类型标记的操作方法。
首先,展开“输入类型”下拉选项,点击“时间”。
定义时间类型标记
接下来,设置“标记名称”为 time,“显示标签”输入时间标记,“默认标记值”选择相对时间和最近(过去)一天。
输入需要绑定的标记
最后,点击“确定”按钮添加完成后,可以得到显示标记名为“时间标记”的时间输入,其默认选项值为“最近(过去)一天”。
时间类型标记效果
④ 钻取设置标记
第四种是钻取设置标记,在后面样例中进行介绍。
下面通过一个仪表板样例来展示标记的工作方式。首先在仪表版里配置几种不同类型的标记,从上到下分别是文本类型、选择器类型、时间类型、钻取设置类型。
文本输入标记样例
在第一个例子中,通过配置文本标记来进行过滤。左侧输入了 access,可以把 access log 相关的数据查出来显示在右边。每当文本标记更新的时候,相应的查询语句,包括整个图表的数据,也会进行相应的更新。
第二个例子是选择器类型标记。例子中预定义了请求状态的选项,分别是 2XX、3XX、4XX、5XX、所有请求状态。每当切换选项的时候,都会触发右边的关联图表,重新进行查询并获取新的结果,最后把更新的结果显示出来。
选择器输入标记样例
第三个例子是时间类型标记。可以把时间查询范围的作为一个标记,例子中选30分钟,通过时间标记值的变化更新图表信息。
时间类型标记样例
最后一个例子是钻取设置标记。在例子中,点击左边的饼图,比如美国,就会触发右边的联动图表去做新的查询。
钻取设置标记样例
关于可视化技术还有非常多丰富的内容,例如:
① 大数据图表可视化优化 。
② 仪表板可视化架构。
③ 颜色和自定义主题等等。