图形属性
视觉通道
简介
数据可视化的核心内容是可视化编码,是将数据信息映射成可视化元素的技术。就像数据包含属性和值,可视化编码也由两部分组成:几何标记(图形元素)和视觉通道。
- 数据属性 -> 标记:直观的代表数据的性质分类,通常是几何图形元素,例如:点、线、面、体。
- 数据值 -> 视觉通道:用于表现数据属性的定量信息,包括标记的位置、大小、形状、方向、色调、饱和度、亮度等。

视觉通道的类型
人类对视觉通道的识别有两种基本的感知模式。第一种感知模式得到的信息是关于对象本身的特征和位置等,对应视觉通道的定性性质和分类性质;第二种感知模式得到的信息是对象某一属性在数值上的大小,对应视觉通道的定量性质或者定序性质。因此我们将视觉通道分为 2 大类:
- 定性(分类)的视觉通道,如形状、颜色的色调、控件位置。
- 定量(连续、有序)的视觉通道,如直线的长度、区域的面积、空间的体积、斜度、角度、颜色的饱和度和亮度等。
然而两种分类不是绝对的,例如位置信息,既可以区分不同的分类,又可以分辨连续数据的差异。
视觉通道的表现力
进行可视化编码时我们需要考虑不同视觉通道的表现力和有效性,主要体现在下面几个方面:
- 准确性,是否能够准确的表达视觉数据之间的变化
- 可辨认性,同一个视觉通道能够编码的分类个数,即可辨识的分类个数上限
- 可分离性,不同视觉通道的编码对象放置到一起,是否容易分辨
- 视觉突出,重要的信息,是否用更加突出的视觉通道进行编码
视觉通道的表现力:

数据到视觉通道的映射
数据的字段和可视化通道之间建立对应关系的过程就是可视化编码的过程,可以
- 一个数据字段对应一个视觉通道(1:1)
- 一个数据字段对应多个视觉通道(1:n)
- 多个数据字段对应一个视觉通道(n:1)
我们看下面的示例:
- 班级的学生数
本图存在以下映射关系:
- x 轴上班级映射到位置的
视觉通道 - y 轴上学生数映射到矩形的
长度
两个映射都是 1:1 的映射。
chart.interval().position('班级*人数');
- 不同班级不同的颜色

本图存在以下映射关系:
- x 轴上班级映射到
位置 - y 轴上学生数映射到矩形的
长度 - 班级也映射到
颜色
所以班级的映射存在两个视觉通道 1:n。
chart.interval().position('班级*人数').color('班级');
- 人数和班级共同决定颜色

颜色由班级和学生人数共同决定,规则如下:
- 如果班级等于 ‘1’或者人数大于 40 则映射成红色
- 其他则映射成绿色
班级和学生人数共同决定了颜色映射,所以此映射是 n:1。
chart.interval().position('班级*人数').color('班级*人数', (grade, count) => {if (grade == '1' || count > 40) {return 'red';}return 'green';});
#
G2 视觉通道的设计
视觉通道类型
在 G2 中我们实现了如下类型的视觉通道(也称图形属性):、
- position(位置),二维坐标系内可以映射到 x,y,三维坐标系可以映射到 x,y,z。
- color(颜色),包含了色调、饱和度和亮度。
- size(大小),不同的图形对大小的定义有所差异。
- shape(形状),图形的形状决定了某个图表类型的表现方式。例如 点图,可以使用圆点、三角形、小的图片表示;线图可以使用折线、曲线、点线等表现形式。
语法设计
G2 中的视觉通道作为标记的属性存在,需要支持以下功能:
- 支持 1 :1,1 : n,n : 1 多种数据和视觉通道的映射。
- 不同的标记决定图形对视觉通道的解析各不相同。
视觉通道在 G2 的语法中这样定义:
chart.(dims,[callback])
- geom,图表类型,在后面的章节中介绍。
- attr,图表类型的属性,对应视觉通道。
- dims,参与单个视觉通道映射的字段。
- callback,如何解析视觉通道,可以不提供,G2 提供了默认的视觉通道解析方式。
除了 attr(dims,callback)的函数原型外,G2 为了用户的便利性,结合各个视觉通道的特点,也提供了更为便捷的使用方式,在本章后面有详细的介绍。
示例:
chart.point().position('a*b').color('c');chart.interval().position('a*b').color('c', c => {if (c) {return 'red';}return 'green';});
position
位置是唯一的既可以用于编码分类,又可用于编码定序或者定量的数据属性。在二维平面上有垂直方向和水平方向两个可以分离的视觉通道。所以 position 属性支持的用户输入方式:
- postion(‘dim’),仅使用一维的水平方向(x 轴)的视觉通道,此时,垂直方向的视觉通道没有数据含义。
- postion(‘dim1*dim2’),同时使用水平和垂直 2 个视觉通道。
|
| 二维点图 |

color
从可视化编码的角度对颜色进行分析,可以将颜色分为亮度、饱和度和色调三个视觉通道,其中前 2 个可以认为是定量和定序的视觉通道,而色调属于定性的视觉通道。而我们在 G2 中我们并不区分这 3 个视觉通道,因此我们认为颜色既是分类又是定量的视觉通道。所以 color 方法有更多的快捷方式:
- color(‘c’),使用默认的回调函数,读取一个数组中的颜色进行颜色的映射。
- color(‘c’,colors),指定映射的颜色类型,此时通常映射到分类数据。
- color(‘c’,’color1-color2-colorn’),指定颜色的渐变路径,在这个渐变路径映射定量(连续)的数据。
- color(‘red’) 直接指定常量,不进行数据映射。
|
| 定量(连续)数据的颜色映射 |

size
从可视化的角度分析,大小(size)是一个复杂的视觉通道,对于不同的标记含义不完全一致:
- 对于点来说 size 对应的是点的半径。
- 对于线来说 size 对应的是线的粗细。
- 对于柱状图来说 size 是柱状图的宽度。
size 的快捷方式:
- size(dim) 指定映射到 size 的字段,内置最大和最小(像素大小)。
- size(dim,max,min),指定映射到 size 字段外,还提供了最大像素和最小像素。
- size(10) 直接指定像素大小。
更多的对 size 的解释可以查看后面章节的各个图表类型中对 size 的解析。
|
| 柱状图的大小 |

shape
不同的图表类型有不同的 shape(形状),各自的章节中详细介绍。shape 这个视觉通道受其他几个视觉通道影响,比如:shape 可以将 color 映射到填充色上,也可以映射到边框上。shape 方法的使用方式比较简单,常用于映射分类数据:
- shape(‘dim’),将指定的字段映射到内置的 shapes 数组中。
- shape(‘dim’,shapes),用户自己提供 shapes 数据,来进行数据映射。
- shape(‘circle’),指定常量,映射到固定的 shape。
|
| 柱状图形状 |

概览
简介
根据几何标记可以代表的数据维度来划分,几何标记分为:
- 零维,点是常见的零维几何标记,点仅有位置信息
- 一维,常见的一维几何标记有线
- 二维,二维平面
- 三维,常见的立方体、圆柱体都是三维的几何标记

几何标记自由度
前面我们介绍过坐标系,坐标系代表了图形所在的空间维度,而图形空间的自由度是在不改变图形性质的基础下可以自由扩展的维度,自由度 = 空间维度 - 几何标记的维度,那么:
- 点在二维空间内的自由度是 2,就是说可以沿 x 轴、y 轴方向进行扩展。
- 线在二维空间内的自由度是 1,也就说线仅能增加宽度,而无法增加长度。
- 面在二维空间内的自由度是 0,我们以一个多边形为示例,在不改变代表多边形的数据前提下,我们无法增加多边形的宽度或则高度。
- 面在三维空间的自由度是 1,我们可以更改面的厚度。

几何标记的自由度与数据能够映射到图形的视觉通道 size(大小)相关,这个角度上来讲:
- 点可以映射两个数据字段字段到点的大小上(当然现实中我们仅仅映射一个)。
- 线可以映射一个数据字段字段到线的宽度。
- 柱状图的矩形可以映射一个数据字段到宽度上。
- 封闭的多边形无法使用数据映射到大小。
图表类型
我们根据图形本身的维度和其自由度将几何标记在可视化框架中的实现进行了分类:
- point(点图),虽然点的自由度是 2,但是我们一般只映射一个字段到点的 size 上,x 轴和 y 轴方向同时扩展大小。
- path(路径图)、line(线图),x 轴方向上无序的的线是 path,x 轴方向有序的线是线图,线图又分为折线图和曲线图。
- area(区域图),填充折线和 x 轴闭合的区域,构建成为区域图,区域图是二维的,其自由度是 0,无法进行 size 的扩展。
- interval(区间图)、常见的柱状图、玫瑰图、饼图都是区间图,其图形是以 y 轴方向的长度表示数据的大小,x 轴方形可以自由扩展,其自由度是 1。
- polygon(多边形),多个点构建的封闭的多边形,自由度是 0,无法进行 size 的扩展。
- heatmap(热力图),热力图使用颜色来代表数据分布,绘制的过程根据数据点在画布上的影响范围进行颜色的设置,其自由度是 2,但是我们往往只指定一个常量字段,指定点的影响范围。
- schema (自定义),无法被上面覆盖的几何标记都放到这个分类下,常见的 k 线图,箱型图,其自由度与其表达的数据相关。
各个图表的细节实现,在后面有各自的章节专门介绍。
图表类型和图形形状
我们说图表类型是几何标记在可视化框架中的一种实现方式,这是一种非常粗粒度的划分,对于每一种图表类型来说,图形在绘制的时候有不同的形状,视觉通道跟图形属性的映射方式不一样也会生成不同的图形:
- 点图,可以使用圆点、三角形、正方形、十字符号等表示点。
- 线图,可以有折线、曲线、点线等。
- 多边形,可以是实心的多边形,也可以是空心的仅有边框的多边形。

这就产生了我们在前面提到的视觉通道中 Shape(图形形状),图形形状决定了各个视觉通道和图形属性的映射,使用边框颜色还是填充颜色、使用点线还是实线,使用平滑线还是折线,都是由图形形状 Shape 决定的。
Shape 是 G2 中最灵活、内容最丰富的模块,下图是各个图表的 shape 实现:
|
| point | - ‘circle’- ‘square’- ‘bowtie’- ‘diamond’- ‘hexagon’- ‘triangle’- ‘triangle-down’- ‘hollow-circle’- ‘hollow-square’- ‘hollow-bowtie’- ‘hollow-diamond’- ‘hollow-hexagon’- ‘hollow-triangle’- ‘hollow-triangle-down’- ‘cross’- ‘tick’- ‘plus’- ‘hyphen’- ‘line’ | hollow 开头的图形都是空心的。


| line | - ‘line’- ‘dot’- ‘dash’- ‘smooth’- ‘hv’- ‘vh’- ‘hvh’- ‘vhv’ | ‘hv’, ‘vh’, ‘hvh’, ‘vhv’ 用于绘制阶梯线图。

| area | - ‘area’- ‘smooth’- ‘line’- ‘smooth-line’ | ‘area’ 和 ‘smooth-line’ 是填充内容的区域图,其他图表是空心的线图。

| interval | - ‘rect’- ‘hollow-rect’- ‘line’- ‘tick’- ‘funnel’- ‘pyramid’ | ‘hollow-rect’ 是空心的矩形,’line’ 和 ‘tick’ 都是线段,’funnel’ 用于绘制漏斗图;’pyramid’ 用于绘制金字塔图。

| polygon | - ‘polygon’ | polygon:多边形。

| schema | - ‘box’- ‘candle’ | 目前仅支持箱须图(‘box’)、K 线图(‘candle’)。


| edge | - ‘line’- ‘vhv’- ‘smooth’- ‘arc’ | vhv:直角折线,arc:弧线,分为笛卡尔坐标系、极坐标系、带权重和不带权重四种情况。

#
如何设计 Shape
对于每个 Shape 的实现,我们需要确定以下内容:
- 支持的视觉通道
- 映射到各个视觉通道的数据格式
- 图形对应的数据条数
- 图形的点的个数
支持的视觉通道
不同的 Shape 支持的视觉通道不同,以 G2 实现的视觉通道为例:
- position(位置),所有的图表类型的 Shape 都支持这个属性
- color(颜色), 所有的图表类型的 Shape 都支持这个属性,但是映射到图形的边框还是填充图形,由各个 Shape 自己决定
- size(大小),由上面介绍的几何标记的自由度决定
接收的数据格式
对于 G2 来说,接收的数据都是标准的 JSON 数组,单条数据字段的格式支持 2 种类型:
- 数值、字符串等标量值
- 数组,多个标量值构成的数组
所以对于一个 Shape 来说需要定义好各个视觉通道支持的数据字段格式,下面的示例说明这个问题
柱状图
柱状图是图表类型 interval 的一个 Shape: ‘rect’ 定义的,各个视觉通道支持的数据格式:
position 支持 3 种数据类型:
x,y 都是单个标量值,如 { name: ‘分类一’,value: 100}
- x 是单个标量值,y 是一个数组 ,如 {name: ‘分类一’,range: [10, 100]}
- x 是数组,y 是单个标量值,例如学生成绩分布 {score: [60,70],count: 90}

- color 仅支持一个标量值字段
- size 仅支持数字标量值
- opacity 支持数字标量值,范围 0-1
各个图形对数据格式的支持,我们在后面章节中一一介绍。
需要的数据条数
数据映射到图形时,数据跟图形的对应关系对于不同的图表类型(数据标记)来说各不相同:
- point(点图),点图的数据条数和图形的对应关系,可以是 1:1,也可以是 1 : n。如果对应位置的映射字段 x、y 都是单个标量,那么就是 1:1,如果 y 是数组,那么就是 1:n。
// 1: 1的数据const data = [{ month: '一月', temperature: 10 },{ month: '二月', temperature: 15 },];// 1: 2的数据const data = [{ month: '一月', temperature: [0, 10] },{ month: '二月', temperature: [5, 15] },];

- line(线图)和 path(路径图),如果对应位置的映射字段 x,y 都是单个标量多条记录对应一条线,对应关系是 n:1。如果 y 是数组,那么会生成多条记录对应关系是 n: n。同上面 point 的数据:

- interval 一条记录生成一个图形,1:1

- area(区域图), 多条数据生成一个图形,无论对应位置的对应字段的格式如何

- polygon,一条数据对应一个图形, 1: 1。
- heatmap,多条记录生成一张图 n: 1。
需要的点的个数
绘制图形时,需要根据当前的数据生成图形的点,然后使用线或者弧连接起来,不同的图形需要点的个数不同:
- point,点图绘制时只需要一个点即可
- line,path,绘制折线图/路径图时需要折线图上的多个点
- area,绘制区域图时,需要代表数据的点与 x 轴上点
interval,绘制柱状图、玫瑰图、饼图时,需要知道四个顶点

polygon,绘制多边形时,每个顶点都需要一个点
- heatmap,绘制热力图时需要多个点
更多的细节,也会在对应的图表类型章节中介绍。
