浅析前端数据可视化


浅析前端数据可视化

数据可视化就是以图表的方式将数据进行分类展示,以显示各组数据之间的联系及变化趋势等特点。前端数据可视化可以用在大屏监控,后台管理等场景中本篇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"  //与坐标轴交互样式
  }
},

tooltip

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' }]
};

legend

数据标签

以柱状图为例,数据标签就是显示在柱子上方的文字,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这样的库看文档即可知道使用方法。

总结一下图表的组成

consist

常见图表种类

柱状图

柱状图通过柱子高度代表数据大小

//官方文档柱状图示例
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'
    }
  ]
};

bar

折线图

折线图用来展示数据的变化趋势,下面看一下基础的折线图配置

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'   阶梯
    }
  ]
};

line

饼图

饼图用于表示数据的占比及各组数据的大小关系

option = {
  series: [
    {
      type: 'pie',
      data: [
        {
          value: 335,
          name: '直接访问'
        },
        {
          value: 234,
          name: '联盟广告'
        },
        {
          value: 1548,
          name: '搜索引擎'
        }
      ],
      //radius: ['40%', '70%']     圆环图
      //roseType: 'area'           玫瑰图
    }
  ]
};

pie

散点图

在数据量比较大时可以表示数据的相关性(是否集中在某一个区域)

//官网文档示例
option = {
  xAxis: {},
  yAxis: {},
  series: [
    {
      type: 'scatter',
      data: [
        [10, 5],
        [0, 8],
        [6, 10],
        [2, 12],
        [8, 9]
      ]
    }
  ]
};

scatter


Author: Maple
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Maple !
  TOC