浅析前端数据可视化
数据可视化就是以图表的方式将数据进行分类展示,以显示各组数据之间的联系及变化趋势等特点。前端数据可视化可以用在大屏监控,后台管理等场景中本篇blog将以echarts为基础着重介绍图表的基本组成部分及使用方式。
基本概念
图表容器
不管是基于svg还是canvas进行渲染,图表都需要一个容器
//以echarts为例初始化container
const myChart = echarts.init(<DOM_ELEMENT>);
图表容器需要指定宽度和高度,未指定会导致图表宽高为0
动画
在数据变化时显示动画效果可以让图表更生动,echart内部已经内置了动画功能,且提供了一些配置项对动画进行配置。
echarts内动画分为入场动画和更新动画:
入场动画相关的api:
- animationDuration 动画时常
- animationEasing 变化曲线
- animationDelay 延时触发
更新动画相关的api:
- animationDurationUpdate 动画时常
- animationEasingUpdate 变化曲线
- animationDelayUpdate 延时触发
这几项可以直接在option内配置,下面看个例子
option = {
// some code
series: [
{
name: 'bar',
type: 'bar',
data: data1,
emphasis: {
focus: 'series'
},
animationDelay: function(idx) {
return idx * 10;
}
},
{
name: 'bar2',
type: 'bar',
data: data2,
emphasis: {
focus: 'series'
},
animationDelay: function(idx) {
return idx * 10 + 100;
}
}
],
animationEasing: 'elasticOut', //动画变化曲线
animationDelayUpdate: function(idx) {
return idx * 5; //延时动画
}
};
缩放
对于地图等细节比较多的图需要提供缩放功能,echart内已经实现了简单的缩放
const option = {
dataZoom:[
{
type: 'inside'
}
]
}
tooltip
tooltip是用于与用户交互的重要组件,用于展示数据项的细节信息,下面看一个简单的tooltip配置
tooltip: {
trigger: "item", //触发方式
axisPointer:{
type: "shadow" //与坐标轴交互样式
}
},
echart提供了formatter对tooltip进行自定义(比如对原始数据格式化),下面看一个官方文档的例子
{
name: 'Temperature',
type: 'line',
yAxisIndex: 1,
tooltip: {
valueFormatter: value => value + ' °C'
},
data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
legend
legend就是图例,用于标识图表中数据项的信息
//官方文档legend示例代码
option = {
legend: {
// Try 'horizontal'
orient: 'vertical',
right: 10,
top: 'center'
},
dataset: {
source: [
['product', '2015', '2016', '2017'],
['Matcha Latte', 43.3, 85.8, 93.7],
['Milk Tea', 83.1, 73.4, 55.1],
['Cheese Cocoa', 86.4, 65.2, 82.5],
['Walnut Brownie', 72.4, 53.9, 39.1]
]
},
xAxis: { type: 'category' },
yAxis: {},
series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
};
数据标签
以柱状图为例,数据标签就是显示在柱子上方的文字,echart内的label可以进行高度定制化,这里了解数据标签是什么即可
label: {
normal: {
position: 'top',
distance: 10,
show: true,
formatter: ['Label Text'].join('\n'),
backgroundColor: '#eee',
borderColor: '#555',
color: '#fff'
//some code
}
}
事件
我们可以像监听DOM事件一样监听图表内的事件,图标内的事件可以分为鼠标事件和组件交互事件。
鼠标事件
鼠标事件主要就是用户click,hover等行为触发的事件。下面看一下监听click事件(hover等同理)
//官方文档click示例
myChart.setOption(option);
//用户的相关行为(例如click,hover)会触发回调,params就是与用户交互的数据项
myChart.on('click', function(params) {
window.open('https://www.baidu.com/s?wd=' + encodeURIComponent(params.name));
});
交互事件
与图表交互会触发相应的回调,例如图例的开启与关闭,动画开始与结束等等
//legend状态变化触发legendselectchanged
myChart.on('legendselectchanged', function(params) {
// 获取点击图例的选中状态
var isSelected = params.selected[params.name];
// 在控制台中打印
console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name);
// 打印所有图例的状态
console.log(params.selected);
});
部分事件可以用代码直接触发,看一下官方的dispatch示例
// 取消之前高亮的图形
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: currentIndex
});
currentIndex = (currentIndex + 1) % dataLen;
// 高亮当前图形
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: currentIndex
});
// 显示 tooltip
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: currentIndex
});
动画的结束也是可以监听的事件,下面是监听rendered事件的例子
chart.setOption({
animationDuration: 1000
//...
});
function onRendered() {
const dataUrl = chart.getDataURL();
// ...
// 后续如果有交互,交互发生重绘也会触发该事件,因此使用完就需要移除
chart.off('rendered', onRendered);
}
chart.on('rendered', onRendered);
个人认为对于图标库怎么用并不是数据可视化的重点,而是要熟悉一个图表的基本结构(例如包含坐标轴,图例等内容),像echarts这样的库看文档即可知道使用方法。
总结一下图表的组成
常见图表种类
柱状图
柱状图通过柱子高度代表数据大小
//官方文档柱状图示例
option = {
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {},
series: [
{
type: 'bar',
data: [23, 24, 18, 25, 27, 28, 25],
//stack: 'x' 堆叠或者并列
},
{
type: 'bar',
data: [26, 24, 18, 22, 23, 20, 27],
//stack: 'x'
}
]
};
折线图
折线图用来展示数据的变化趋势,下面看一下基础的折线图配置
option = {
xAxis: {
data: ['A', 'B', 'C', 'D', 'E']
},
yAxis: {},
series: [
{
data: [10, 22, 28, 43, 49],
type: 'line',
stack: 'x' //堆叠
},
{
data: [5, 4, 3, 5, 10],
type: 'line',
stack: 'x', //堆叠
//areaStyle: { 区域面积
// color: '#ff0',
// opacity: 0.5
//}
// smooth: true 平滑
// step: 'start' | 'middle' | 'end' 阶梯
}
]
};
饼图
饼图用于表示数据的占比及各组数据的大小关系
option = {
series: [
{
type: 'pie',
data: [
{
value: 335,
name: '直接访问'
},
{
value: 234,
name: '联盟广告'
},
{
value: 1548,
name: '搜索引擎'
}
],
//radius: ['40%', '70%'] 圆环图
//roseType: 'area' 玫瑰图
}
]
};
散点图
在数据量比较大时可以表示数据的相关性(是否集中在某一个区域)
//官网文档示例
option = {
xAxis: {},
yAxis: {},
series: [
{
type: 'scatter',
data: [
[10, 5],
[0, 8],
[6, 10],
[2, 12],
[8, 9]
]
}
]
};