更多关于Apache ECharts的文档,请阅读:
《Apache ECharts教程》
- 5 分钟上手 ECharts
- ECharts 5 新特性
- ECharts 5 升级指南
- 在打包环境中使用 ECharts
- ECharts 基础概念概览
- 个性化图表的样式
- ECharts 中的样式简介
- 异步数据加载和更新
- 使用 dataset 管理数据
- 使用 transform 进行数据转换第一部分
- 使用 transform 进行数据转换第二部分
- 在图表中加入交互组件
- 移动端自适应
- 数据的视觉映射
- ECharts 中的事件和行为
- 动态排序柱状图
- 小例子:自己实现拖拽
- 小例子:实现日历图
- 旭日图
- 自定义系列
- 富文本标签
- 服务端渲染
- 使用 Canvas 或者 SVG 渲染
- 地理坐标系和地图系列的 SVG 底图
- 在图表中支持无障碍访问
- 使用 ECharts GL 实现基础的三维可视化
- 在微信小程序中使用 ECharts
数据转换器 “filter”
echarts 内置提供了能起过滤作用的数据转换器。我们只需声明 transform.type: “filter”,以及给出数据筛选条件。如下例:
option = {
dataset: [{
source: [
['Product', 'Sales', 'Price', 'Year'],
['Cake', 123, 32, 2011],
['Latte', 231, 14, 2011],
['Tofu', 235, 5, 2011],
['Milk Tee', 341, 25, 2011],
['Porridge', 122, 29, 2011],
['Cake', 143, 30, 2012],
['Latte', 201, 19, 2012],
['Tofu', 255, 7, 2012],
['Milk Tee', 241, 27, 2012],
['Porridge', 102, 34, 2012],
['Cake', 153, 28, 2013],
['Latte', 181, 21, 2013],
['Tofu', 395, 4, 2013],
['Milk Tee', 281, 31, 2013],
['Porridge', 92, 39, 2013],
['Cake', 223, 29, 2014],
['Latte', 211, 17, 2014],
['Tofu', 345, 3, 2014],
['Milk Tee', 211, 35, 2014],
['Porridge', 72, 24, 2014]
]
}, {
transform: {
type: 'filter',
config: { dimension: 'Year', '=': 2011 }
// 这个筛选条件表示,遍历数据,筛选出维度( dimension )
// 'Year' 上值为 2011 的所有数据项。
}
}],
series: {
type: 'pie',
datasetIndex: 1
}
};
这是 filter 的另一个例子的效果:
在 “filter” transform 中,有这些要素:
关于维度( dimension ):
config.dimension 指定了维度,能设成这样的值:
- 设定成声明在 dataset 中的维度名,例如 config: { dimension: ‘Year’, ‘=’: 2011 }。不过, dataset 中维度名的声明并非强制,所以我们也可以
- 设定成 dataset 中的维度 index (index 值从 0 开始)例如 config: { dimension: 3, ‘=’: 2011 }。
关于关系比较操作符:
关系操作符,可以设定这些: >(gt)、>=(gte)、<(lt)、<=(lte)、=(eq)、!=(ne、<>)、reg。(小括号中的符号或名字,是别名,设置起来作用相同)。他们首先基本地能基于数值大小进行比较,然后也有些额外的功能特性:
- 多个关系操作符能声明在一个 {} 中,例如 { dimension: ‘Price’, ‘>=’: 20, ‘<’: 30 }。这表示“与”的关系,即,筛选出价格大于等于 20 小于 30 的数据项。
- data 里的值,不仅可以是数值( number ),也可以是“类数值的字符串”(“ numeric string ”)。“类数值的字符串”本身是一个字符串,但是可以被转换为字面所描述的数值,例如 ’ 123 '。转换过程中,空格(全角半角空格)和换行符都能被消除( trim )。
- 如果我们需要对日期对象(JS Date)或者日期字符串(如 ‘2012-05-12’)进行比较,我们需要手动指定 parser: ‘time’,例如 config: { dimension: 3, lt: ‘2012-05-12’, parser: ‘time’ }。
- 纯字符串比较也被支持,但是只能用在 = 或 != 上。而 >, >=, <, <= 并不支持纯字符串比较,也就是说,这四个操作符的右值,不能是字符串。
- reg 操作符能提供正则表达式比较。例如, { dimension: ‘Name’, reg: /\s+Müller\s*$/ } 能在 ‘Name’ 维度上选出姓 ‘Müller’ 的数据项。
关于逻辑比较:
我们也支持了逻辑比较操作符 与或非( and | or | not ):
option = {
dataset: [{
source: [...]
}, {
transform: {
type: 'filter',
config: {
// 使用 and 操作符。
// 类似地,同样的位置也可以使用 “or” 或 “not”。
// 但是注意 “not” 后应该跟一个 {...} 而非 [...] 。
and: [
{ dimension: 'Year', '=': 2011 },
{ dimension: 'Price', '>=': 20, '<': 30 }
]
}
// 这个表达的是,选出 2011 年价格大于等于 20 但小于 30 的数据项。
}
}],
series: {
type: 'pie',
datasetIndex: 1
}
};
and/or/not 自然可以被嵌套,例如:
transform: {
type: 'filter',
config: {
or: [{
and: [{
dimension: 'Price', '>=': 10, '<': 20
}, {
dimension: 'Sales', '<': 100
}, {
not: { dimension: 'Product', '=': 'Tofu' }
}]
}, {
and: [{
dimension: 'Price', '>=': 10, '<': 20
}, {
dimension: 'Sales', '<': 100
}, {
not: { dimension: 'Product', '=': 'Cake' }
}]
}]
}
}
关于解析器( parser ):
还可以指定“解析器”( parser )来对值进行解析后再做比较。现在支持的解析器有:
- parser: ‘time’:把原始值解析成时间戳( timestamp )后再做比较。这个解析器的行为,和 echarts.time.parse 相同,即,当原始值为时间对象( JS Date 实例),或者是时间戳,或者是描述时间的字符串(例如 ‘2012-05-12 03:11:22’ ),都可以被解析为时间戳,然后就可以基于数值大小进行比较。如果原始数据是其他不可解析为时间戳的值,那么会被解析为 NaN。
- parser: ‘trim’:如果原始数据是字符串,则把字符串两端的空格(全角半角)和换行符去掉。如果不是字符串,还保持为原始数据。
- parser: ‘number’:强制把原始数据转成数值。如果不能转成有意义的数值,那么转成 NaN。在大多数场景下,我们并不需要这个解析器,因为按默认策略,“像数值的字符串”就会被转成数值。但是默认策略比较严格,这个解析器比较宽松,如果我们遇到含有尾缀的字符串(例如 ‘33%’, 12px),我们需要手动指定 parser: ‘number’,从而去掉尾缀转为数值才能比较。
这个例子显示了如何使用 parser: ‘time’:
option = {
dataset: [{
source: [
['Product', 'Sales', 'Price', 'Date'],
['Milk Tee', 311, 21, '2012-05-12'],
['Cake', 135, 28, '2012-05-22'],
['Latte', 262, 36, '2012-06-02'],
['Milk Tee', 359, 21, '2012-06-22'],
['Cake', 121, 28, '2012-07-02'],
['Latte', 271, 36, '2012-06-22'],
...
]
}, {
transform: {
type: 'filter',
config: {
{ dimension: 'Date', '>=': '2012-05', '<': '2012-06', parser: 'time' }
}
}
}]
}
形式化定义:
最后,我们给出,数据转换器 “filter” 的 config 的形式化定义:
type FilterTransform = {
type: 'filter';
config: ConditionalExpressionOption;
};
type ConditionalExpressionOption =
true | false | RelationalExpressionOption | LogicalExpressionOption;
type RelationalExpressionOption = {
dimension: DimensionName | DimensionIndex;
parser?: 'time' | 'trim' | 'number';
lt?: DataValue; // less than
lte?: DataValue; // less than or equal
gt?: DataValue; // greater than
gte?: DataValue; // greater than or equal
eq?: DataValue; // equal
ne?: DataValue; // not equal
'<'?: DataValue; // lt
'<='?: DataValue; // lte
'>'?: DataValue; // gt
'>='?: DataValue; // gte
'='?: DataValue; // eq
'!='?: DataValue; // ne
'<>'?: DataValue; // ne (SQL style)
reg?: RegExp | string; // RegExp
};
type LogicalExpressionOption = {
and?: ConditionalExpressionOption[];
or?: ConditionalExpressionOption[];
not?: ConditionalExpressionOption;
};
type DataValue = string | number | Date;
type DimensionName = string;
type DimensionIndex = number;
数据转换器 “sort”
“sort” 是另一个内置的数据转换器,用于排序数据。目前主要能用于在类目轴( axis.type: ‘category’ )中显示排过序的数据。例如:
option = {
dataset: [{
dimensions: ['name', 'age', 'profession', 'score', 'date'],
source: [
[' Hannah Krause ', 41, 'Engineer', 314, '2011-02-12'],
['Zhao Qian ', 20, 'Teacher', 351, '2011-03-01'],
[' Jasmin Krause ', 52, 'Musician', 287, '2011-02-14'],
['Li Lei', 37, 'Teacher', 219, '2011-02-18'],
[' Karle Neumann ', 25, 'Engineer', 253, '2011-04-02'],
[' Adrian Groß', 19, 'Teacher', null, '2011-01-16'],
['Mia Neumann', 71, 'Engineer', 165, '2011-03-19'],
[' Böhm Fuchs', 36, 'Musician', 318, '2011-02-24'],
['Han Meimei ', 67, 'Engineer', 366, '2011-03-12'],
]
}, {
transform: {
type: 'sort',
// 按分数排序
config: { dimension: 'score', order: 'asc' }
}
}],
series: {
type: 'bar',
datasetIndex: 1
},
...
};
数据转换器 “sort” 还有一些额外的功能:
- 可以多重排序,多个维度一起排序。见下面的例子。
- 排序规则是这样的:
- 默认按照数值大小排序。其中,“可转为数值的字符串”也被转换成数值,和其他数值一起按大小排序。
- 对于其他“不能转为数值的字符串”,也能在它们之间按字符串进行排序。这个特性有助于这种场景:把相同标签的数据项排到一起,尤其是当多个维度共同排序时。见下面的例子。
- 当“数值及可转为数值的字符串”和“不能转为数值的字符串”进行排序时,或者它们和“其他类型的值”进行比较时,它们本身是不知如何进行比较的。那么我们称呼“后者”为“incomparable”,并且可以设置 incomparable: ‘min’ | ‘max’ 来指定一个“incomparable”在这个比较中是最大还是最小,从而能使它们能产生比较结果。这个设定的用途,比如可以是,决定空值(例如 null, undefined, NaN, ‘’, ‘-’)在排序的头还是尾。
- 过滤器 filter: ‘time’ | ‘trim’ | ‘number’ 可以被使用,和数据转换器 “filter” 中的情况一样。
- 如果要对时间进行排序(例如,值为 JS Date 实例或者时间字符串如 ‘2012-03-12 11:13:54’),我们需要声明 parser: ‘time’。
- 如果需要对有后缀的数值进行排序(如 ‘33%’, ‘16px’)我们需要声明 parser: ‘number’。
这是一个“多维度排序”的例子。
option = {
dataset: [{
dimensions: ['name', 'age', 'profession', 'score', 'date'],
source: [
[' Hannah Krause ', 41, 'Engineer', 314, '2011-02-12'],
['Zhao Qian ', 20, 'Teacher', 351, '2011-03-01'],
[' Jasmin Krause ', 52, 'Musician', 287, '2011-02-14'],
['Li Lei', 37, 'Teacher', 219, '2011-02-18'],
[' Karle Neumann ', 25, 'Engineer', 253, '2011-04-02'],
[' Adrian Groß', 19, 'Teacher', null, '2011-01-16'],
['Mia Neumann', 71, 'Engineer', 165, '2011-03-19'],
[' Böhm Fuchs', 36, 'Musician', 318, '2011-02-24'],
['Han Meimei ', 67, 'Engineer', 366, '2011-03-12'],
]
}, {
transform: {
type: 'sort',
config: [
// 对两个维度按声明的优先级分别排序。
{ dimension: 'profession', order: 'desc' },
{ dimension: 'score', order: 'desc' }
]
}
}],
series: {
type: 'bar',
datasetIndex: 1
},
...
};
最后,我们给出数据转换器 “sort” 的 config 的形式化定义。
type SortTransform = {
type: 'filter';
config: OrderExpression | OrderExpression[];
};
type OrderExpression = {
dimension: DimensionName | DimensionIndex;
order: 'asc' | 'desc';
incomparable?: 'min' | 'max';
parser?: 'time' | 'trim' | 'number';
};
type DimensionName = string;
type DimensionIndex = number;
使用外部的数据转换器
除了上述的内置的数据转换器外,我们也可以使用外部的数据转换器。外部数据转换器能提供或自己定制更丰富的功能。下面的例子中,我们使用第三方库 ecStat 提供的数据转换器。
生成数据的回归线:
// 首先要注册外部数据转换器。
echarts.registerTransform(ecStatTransform(ecStat).regression);
option = {
dataset: [{
source: rawData
}, {
transform: {
// 引用注册的数据转换器。
// 注意,每个外部的数据转换器,都有名空间(如 'ecStat:xxx','ecStat' 是名空间)。
// 而内置数据转换器(如 'filter', 'sort')没有名空间。
type: 'ecStat:regression',
config: {
// 这里是此外部数据转换器所需的参数。
method: 'exponential'
}
}
}],
xAxis: { type: 'category' },
yAxis: {},
series: [{
name: 'scatter',
type: 'scatter',
datasetIndex: 0
}, {
name: 'regression',
type: 'line',
symbol: 'none',
datasetIndex: 1
}]
};
一些使用外部转换器的例子:
- 聚集
- 直方图
- 简单聚类
- 线性回归线
- 指数回归线
- 对数回归线
- 多项式回归线