ECharts 柱状图
上一节我们学习到了折线图,相信大家对折线图的作用和使用场景都有所了解,这一节我们继续来看一下跟折线图相似的图形——柱状图。柱状图又称条形统计图,与折线图类似,用于表示事物多维属性之间的变化趋势。
1. 简介
官方定义:
柱状/条形图通过柱形的高度/条形的宽度 来表现数据的大小,用于有至少一个类目轴或时间轴的直角坐标系上。
慕课解释
柱状图(柱状图)使用竖直(水平)的柱子表示序列数值的图表,形如:
在 ECharts 上可通过配置项的 series 属性传入 type = bar
的对象完成柱状图配置。由于配置项繁多,官网 对此已有详尽介绍,在此不赘述。下面会提供丰富的示例,介绍柱状图的常见场景。
2. 实例解说
2.1 柱状图
在 ECharts 中,通过传入 xAxis、yAxis、series 三个关键属性,即可完成一个柱状图的配置,示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: { type: 'value' },
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'bar',
},
],
};
myChart.setOption(option);
</script>
</body>
</html>
示例效果:
示例代码有几个关键点:
- 需要传入 xAxis 显式声明 x 轴配置,示例中通过
type: category
将该轴配置为类目轴,并通过 data 属性显式定义该轴下的类目数据; - 需要传入 yAxis 显式声明 y 轴配置,示例中通过
type: value
将盖州配置为类目轴; - 柱状图通过配置项的 series 传入,且必须声明
type: bar
。示例中通过 data 属性声明了该图表的系列数据。
柱状图与折线图的形态与语义极其相似,所以在 ECharts 中两者功能、配置基本一致,唯一区别仅在于 type 属性的取值。例如上例中若修改为 type = line
,其他配置均不变更,可得图表:
2.2 条形图
条形图是用横向的柱子来展现数据,一般用于纵向的数据对比,其实就是 x 轴、y 轴对调的柱状图。例如上例中,对调 xAxis、yAxis 的配置值就可以实现条形图,示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
yAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
xAxis: { type: 'value' },
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'bar',
},
],
};
myChart.setOption(option);
</script>
</body>
</html>
示例效果:
2.3 堆叠柱状图
当需要表达多部分数据占比关系的时候,可以使用堆叠柱状图方式实现。示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
title: { text: '每日销售额', left: 'center', top: 10 },
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: { type: 'value' },
series: [
{
data: [820, 912, 899, 786, 1290, 1330, 1320],
type: 'bar',
name: '水果',
// 通过定义 stack 属性启动堆叠模式
// 相同 stack 值的序列会堆叠在一起
stack: 'search engine',
},
{
data: [840, 1002, 789, 934, 1090, 1728, 1468],
type: 'bar',
name: '蔬菜',
stack: 'search engine',
},
{
data: [780, 340, 879, 624, 1588, 1624, 1890],
type: 'bar',
name: '百货',
stack: 'search engine',
},
],
legend: { data: ['水果', '蔬菜', '百货'], show: true, bottom: 0 },
label: { show: true },
};
myChart.setOption(option);
</script>
</body>
</html>
示例中,通过配置 stack 属性可启动堆叠模式,相同 stack 值的数据序列会堆叠在一起,从而形成一个体现整体数据变化的图表,示例效果:
3. 极坐标系柱状图
柱状图同样支持极坐标系,不过程度并不如折线图。在极坐标系中,通常使用二维数组 (r, ∠a)
表示坐标点,其中 r 表示坐标点离远点的距离;∠a 表示坐标点的角度。但这种二维数组形态在柱状图下并不能生效,例如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
polar: {},
angleAxis: {
type: 'value',
startAngle: 0,
min: 0,
max: 360,
},
radiusAxis: {},
series: [
{
coordinateSystem: 'polar',
type: 'bar',
data: [
[1, 2],
[3, 4],
],
},
],
};
myChart.setOption(option);
</script>
</body>
</html>
示例效果:
示例图中所有 bar 混杂在一起,无法传达出数据的含义。这是因为柱状图是一种二维图形,而极坐标点的表达式无法表达平面信息,所以上例这种 angleAxis、radiusAxis 均为数值型的柱状图在 ECharts 中是没有意义的。
不过,只要选定任意轴为类目轴,就可以使用极坐标勾画柱状图,例如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
polar: {},
angleAxis: {
type: 'category',
startAngle: 0,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
radiusAxis: { type: 'value' },
series: [
{
coordinateSystem: 'polar',
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'bar',
},
],
};
myChart.setOption(option);
</script>
</body>
</html>
示例效果:
极坐标下的柱状图同样支持堆叠效果,比如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
angleAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
polar: {},
radiusAxis: { type: 'value' },
series: [
{
coordinateSystem: 'polar',
data: [820, 912, 899, 786, 1290, 1330, 1320],
type: 'bar',
name: '水果',
stack: 'search engine',
},
{
coordinateSystem: 'polar',
data: [840, 1002, 789, 934, 1090, 1728, 1468],
type: 'bar',
name: '蔬菜',
stack: 'search engine',
},
{
coordinateSystem: 'polar',
data: [780, 340, 879, 624, 1588, 1624, 1890],
type: 'bar',
name: '百货',
stack: 'search engine',
},
],
label: { show: true },
};
myChart.setOption(option);
</script>
</body>
</html>
示例效果:
4. 渐进渲染
ECharts 4 之后,如果需要渲染的图形数据太多而出现卡顿时,可以通过设置 large = true
开启渐进渲染功能。原理上,当数据量达到几千、几万时,如果要一次性渲染这么多图形可能会造成页面卡顿甚至假死,ECharts 通过将需要渲染的数据按特定算法分成多个批次,每次渲染一个批次的数据量,尽可能快地渲染出一部分数据,减少卡顿感。下列属性用于配置渐进渲染的功能细节:
配置名 | 类型 | 默认值 | 说明 |
---|---|---|---|
large | boolean | false | 是否开启大数据量优化 |
largeThreshold | number | 400 | 启动绘制优化的阈值,在 large = true 的情况下,若数据量超过该值则启动绘制优化 |
progressive | number | 5000 | 渐进式渲染时每一帧绘制图形数量 |
progressiveThreshold | number | 3000 | 启用渐进式渲染的图形数量阈值,在单个系列的图形数量超过该阈值时启用渐进式渲染 |
progressiveChunkMode | string | mod | 渐进渲染时每一帧图形的分片方式 |
启动渐进渲染的功能很简单,只需要设置 large = true
,当数据量超过 largeThreshold 设定的阈值时,ECharts 就会启动渐进渲染功能,例如下例中渲染 50000 数据:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<button id="btnStart" type="button">开始渲染</button>
<div id="main" style="width: 800px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
<script type="text/javascript">
// 生成随机数
function generateData(count) {
var baseValue = Math.random() * 1000;
var time = +new Date(2011, 0, 1);
var smallBaseValue;
function next(idx) {
smallBaseValue = idx % 30 === 0 ? Math.random() * 700 : smallBaseValue + Math.random() * 500 - 250;
baseValue += Math.random() * 20 - 10;
return Math.max(0, Math.round(baseValue + smallBaseValue) + 3000);
}
var categoryData = [];
var valueData = [];
for (var i = 0; i < count; i++) {
categoryData.push(echarts.format.formatTime('yyyy-MM-dd\nhh:mm:ss', time));
valueData.push(next(i).toFixed(2));
time += 1000;
}
return {
categoryData: categoryData,
valueData: valueData,
};
}
var data = generateData(500000);
console.log('generate done');
var chart = echarts.init(document.getElementById('main'));
var option = {
toolbox: {
feature: {
saveAsImage: {},
},
},
xAxis: { type: 'category', data: data.categoryData },
yAxis: { type: 'value' },
series: [
{
data: data.valueData,
type: 'bar',
// 是否开启大数据量优化
large: true,
// 数据优化的启动阈值
largeThreshold: 1000,
},
],
};
document.getElementById('btnStart').addEventListener('click', function() {
chart.setOption(option);
});
</script>
</body>
</html>
示例效果:
在渐进渲染模式下,可以通过 progressive、progressiveChunkMode 调整渲染效果。progressive 用于配置每帧绘制的图形数量,当 progressive 值越小时每帧的渲染效率越高,视觉效果越平滑,但总的渲染时长也会相应越长,对比 progressive = 1000
与 progressive = 5000
的效果:
progressiveChunkMode 用于配置图形的分片方式,可选值:
- sequential 按照数据的顺序分片。缺点是渲染过程不自然;
- mod 取模分片,即每个片段中的点会遍布于整个数据,从而能够视觉上均匀得渲染。
对比 progressiveChunkMode = sequential
与 progressiveChunkMode = mod
的效果:
5. 动画
柱状图支持动画效果,只需设置 animation = true
即可启动动画功能。与动画相关配置包括:
配置名 | 类型 | 默认值 | 说明 |
---|---|---|---|
animation | boolean | false | 是否启动动画效果 |
animationThreshold | number | 2000 | 关闭动画的阈值,在 animation = true 的情况下,若数据量超过该值则关闭动画效果 |
animationDuration | number | function | 1000 | 初始动画的时长 |
animationEasing | string | cubicOut | 初始动画的缓动效果 |
animationDelay | number | function | 初始动画的延迟 | |
animationDurationUpdate | number | 300 | 数据更新动画时长 |
animationEasingUpdate | string | cubicOut | 数据更新动画的缓动效果 |
animationDelayUpdate | number | function | 数据更新动画的延迟 |
默认配置下,只需设置 animation = true
即可启动动画效果,简单示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Echarts Example</title>
</head>
<body>
<button id="btnStart" type="button">开始渲染</button>
<div id="main" style="width: 600px;height: 400px"></div>
<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: { text: '动画效果示例' },
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: { type: 'value' },
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'bar',
// 启动动画效果
animation: true,
},
],
};
document.getElementById('btnStart').addEventListener('click', function() {
myChart.setOption(option);
});
</script>
</body>
</html>
示例效果:
与 CSS3 动画类似,下列属性可以微调动画执行的细节:
- animationDuration: 初始动画执行周期;
- animationEasing: 初始动画的缓动效果,只能使用内置的缓动函数,可选值请参考 缓动示例;
- animationDelay: 初始动画延迟时间,支持数值或函数类型。
通过设置,可以调整出更加生动的动画效果,例如在上例基础上设置如下属性:
{
animation: true,
animationEasing: 'elasticOut',
animationDuration: function(index) {
return index * 300;
},
}
示例效果如下:
细心的读者应该已经注意到,上述配置表中存在两类属性,一是初始动画,即图表首次渲染动画;二是数据更新动画,即在图表初始化后,通过调用 setOption 或 appendData 函数促使数据发生变化时执行的动画效果,相关属性包括:
- animationDurationUpdate:数据更新动画执行周期;
- animationEasingUpdate:数据更新动画的缓动效果,只能使用内置的缓动函数,可选值请参考 缓动示例;
- animationDelayUpdate:数据更新动画延迟时间。
例如在上例基础上,动画配置修改为:
{
animation: true,
animationEasingUpdate: 'elasticOut',
animationDurationUpdate: function(index) {
return index * 100;
},
}
注意初始化与插入数据时,动画效果的差异:
6. 小结
本节结合实例讲述 Echarts 柱状图的各类功能特性,包括普通柱状图、条形图、堆叠柱状图、极坐标柱状图等场景的应用与功能特性;并进一步地,讨论如何通过渐进渲染方式提升大数据场景的性能优化,以及如何结合动画特性提供更具交互感的柱状图应用。