Echarts中有关动态柱状图的理解使用

发布于 9 个月前

Echarts中有关动态柱状图的修改使用

最近接收的一个项目中,要求实现动态显示各城市的薪资水平,要求使用Echarts实现,在官方给出的案例中有一个动态数据的案例。

官方动态柱状图案例

const categories = (function () {
  let now = new Date();
  let res = [];
  let len = 10;
  while (len--) {
    res.unshift(now.toLocaleTimeString().replace(/^\D*/, ''));
    now = new Date(+now - 2000);
  }
  return res;
})();
const categories2 = (function () {
  let res = [];
  let len = 10;
  while (len--) {
    res.push(10 - len - 1);
  }
  return res;
})();
const data = (function () {
  let res = [];
  let len = 10;
  while (len--) {
    res.push(Math.round(Math.random() * 1000));
  }
  return res;
})();
const data2 = (function () {
  let res = [];
  let len = 0;
  while (len < 10) {
    res.push(+(Math.random() * 10 + 5).toFixed(1));
    len++;
  }
  return res;
})();
option = {
  title: {
    text: 'Dynamic Data'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      label: {
        backgroundColor: '#283b56'
      }
    }
  },
  legend: {},
  toolbox: {
    show: true,
    feature: {
      dataView: { readOnly: false },
      restore: {},
      saveAsImage: {}
    }
  },
  dataZoom: {
    show: false,
    start: 0,
    end: 100
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: true,
      data: categories
    },
    {
      type: 'category',
      boundaryGap: true,
      data: categories2
    }
  ],
  yAxis: [
    {
      type: 'value',
      scale: true,
      name: 'Price',
      max: 30,
      min: 0,
      boundaryGap: [0.2, 0.2]
    },
    {
      type: 'value',
      scale: true,
      name: 'Order',
      max: 1200,
      min: 0,
      boundaryGap: [0.2, 0.2]
    }
  ],
  series: [
    {
      name: 'Dynamic Bar',
      type: 'bar',
      xAxisIndex: 1,
      yAxisIndex: 1,
      data: data
    },
    {
      name: 'Dynamic Line',
      type: 'line',
      data: data2
    }
  ]
};
app.count = 11;
setInterval(function () {
  let axisData = new Date().toLocaleTimeString().replace(/^\D*/, '');
  data.shift();
  data.push(Math.round(Math.random() * 1000));
  data2.shift();
  data2.push(+(Math.random() * 10 + 5).toFixed(1));
  categories.shift();
  categories.push(axisData);
  categories2.shift();
  categories2.push(app.count++);
  myChart.setOption({
    xAxis: [
      {
        data: categories
      },
      {
        data: categories2
      }
    ],
    series: [
      {
        data: data
      },
      {
        data: data2
      }
    ]
  });
}, 2100);

分析:

  1. categoriescategories2datadata2 分别是四个数组,用于存储横坐标和纵坐标的数据。

  2. categories 通过循环生成包含当前时间的字符串的数组,表示横坐标的类别。其中 toLocaleTimeString() 方法用于获取当前时间的字符串表示,res.unshift() 方法将当前时间字符串插入到数组的开头,now 变量则通过每次减去2000毫秒来生成之前的时间。

  3. categories2 是一个简单的递减序列数组,表示另一种横坐标的类别。

  4. datadata2 是两个随机生成的数组,用于表示柱状图和折线图的数据。

  5. option 是 ECharts 的配置项对象,其中包含了标题、提示框、图例、工具箱、数据缩放、横坐标、纵坐标和系列等配置信息。

  6. setInterval 函数中,每隔一段时间(这里是1秒),会生成新的数据并更新到 datadata2 数组中,并且删除 categories 数组中的第一个元素。这样就实现了柱状图和折线图数据的动态更新。

  7. 最后,option 对象被用于设置图表的配置项,从而更新图表的显示。

通过分析就可以发现,实现动态的关键在于对数组的处理,官方示例的处理是删除第一个元素,然后添加一个新的元素到数组末尾,然后重新设置图表属性从而实现的"动"效果。
所以要实现目标效果,我们只需要更换很坐标数据的数据来源,然后将根据时间更新换成我们需要更新的类型(比如城市名的切换),而因为我们不需要新生成元素而是想循环使用数组元素,故最简单的处理方式是将删除的元素又重新添加到数组末尾即可(其实应该采用循环链表也可以)。

项目需求效果实现

//绘制动态直方图(用于各城市薪资分析情况)
    drawBarChart() {
      // 初始化图表
      var option;
      const cities = [
        '北京', '上海', '广州', '深圳', '天津', '成都', '重庆', '杭州', '南京', '武汉',
        '西安', '长沙', '郑州', '沈阳', '青岛', '济南', '大连', '宁波', '厦门', '福州',
        '苏州', '无锡', '哈尔滨', '长春', '南昌', '贵阳', '昆明', '南宁', '石家庄', '太原',
        '兰州', '西宁', '呼和浩特', '银川', '拉萨', '乌鲁木齐'
      ];

      const salaries = [
        16234, 17129, 14451, 14213, 11021,11124,14742, 12302,
        {
          value: 13284,
          itemStyle: {color: '#fa8352'}
        }, 12984,
        10481, 11523, 12008, 11203, 9874, 8013, 9451, 9507, 8505, 8684,
        9054, 8594, 8054, 7502, 8900, 8560, 7012, 7805, 7746, 7988,
        7531, 7654, 7854, 7791, 6521, 6120
      ];

      const average = [
        10842, 11024, 9870, 9841, 9120, 7421, 8451, 8848, 8821, 8832,
        7989, 8741, 8123, 8721, 8502, 8032, 7842, 7545, 8984, 8456,
        9652, 8547, 8065, 7421, 7541, 7412, 7021, 7532, 7652, 7451,
        7685, 7123, 6505, 6021, 5545, 6742
      ];

      option = {
        title: {
          text: '各城市薪资情况'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            label: {
              backgroundColor: '#57cbb8'
            }
          }
        },
        legend: {},
        toolbox: {
          show: true,
          feature: {
            dataView: { readOnly: false },
            restore: {},
            saveAsImage: {}
          }
        },
        dataZoom: {
          show: false,
          start: 0,
          end: 100
        },
        xAxis: [
          {
            type: 'category',
            boundaryGap: true,
            data: cities.slice(0, 6) // 初始时只显示前5个城市
          }
        ],
        yAxis: [
          {
            type: 'value',
            scale: true,
            name: 'Salary',
            max: 25000,
            min: 3000,
            boundaryGap: [0.2, 0.2]
          },
          {
            type: 'value',
            scale: true,
            name: 'Average',
            max: 25000,
            min: 3000,
            boundaryGap: [0.2, 0.2]
          }
        ],
        series: [
          {
            name: '计算机/IT平均薪资',
            type: 'bar',
            data: salaries.slice(0, 6) // 初始时只显示前5个城市的计算机行业平均薪资数据
          },
          {
            name: '总平均薪资',
            type: 'line',
            data: average.slice(0, 6) // 初始时只显示前5个城市的总平均薪资数据
          }
        ]
      };

// 初始化图表
      var myChart = this.$echarts.init(document.getElementById('barChart'));

// 设置图表配置项
      myChart.setOption(option);

// 定时更新数据
      setInterval(function () {
        // 更新横坐标数据
        cities.push(cities.shift()); // 先取到数据,然后删除,然后增加到数组末尾(实现循环播放)
        // 更新对应的计算机薪水数据
        salaries.push(salaries.shift());
        // 更新对应的平均薪水数据
        average.push(average.shift());

        // 重新绘制图表,并添加动画效果
        myChart.setOption({
          xAxis: [
            {
              type: 'category',
              boundaryGap: true,
              data: cities.slice(0, 6) // 只显示前6个城市
            }
          ],
          series: [
            {
              name: '计算机/IT平均薪资',
              type: 'bar',
              data: salaries.slice(0, 6) // 只显示前6个城市的薪水数据
            },
            {
              name: '总平均薪资',
              type: 'line',
              data: average.slice(0, 6) // 只显示前6个城市的订单数据
            }
          ],
          animation: true, // 添加动画效果
        });
      }, 2000); // 每两秒更新一次数据

    }

便达到了预期效果,且突出用户城市显示

Echarts
$ cd ..