vue-echarts实现动态柱状图排序+全屏展示

374 阅读2分钟
在vue中实现echarts动态柱状图排序
  1. 使用 screenfull 来进行全屏展示,这样可以完全大屏展示,去除项目中的菜单-导航;需要先安装screenfull npm install screenfull@4.2.0
  2. series中需要设置 realtimeSort: false,
  3. 在获取数据值时,是一个二维数组,数组的第一项是具体排序值,需要对它值进行sort排序,才可以有序从高到低

(p3-juejin.byteimg.com/tos-cn-i-k3…?)

<template>
  <div class="fullscreen" style="width:100%;height:100vh;">
    <div>
      <i class="el-icon-full-screen" id="fullscreen_button"></i>
    </div>
    <div class='full-echarts' style="width:100%;height:100vh;" ref="fullEcharts" id="fullscreen_content">
        <div ref="chart" style="width:100%;height:100vh;"></div>
    </div>
  </div>
</template>

<script>
import echarts from 'echarts'
import screenfull from 'screenfull'
import axios from 'axios'
export default {
  data () {
    return {
      chartInstace: null,
      option: null,
    };
  },
  methods: {
    init () {
      let myChart = echarts.init(this.$refs.chart);
      let ROOT_PATH ='https://fastly.jsdelivr.net/gh/apache/echarts-website@asf-site/examples';
      var option;
      const updateFrequency = 2000;
      const dimension = 0;
      const countryColors = {
        Australia: '#00008b',
        Canada: '#f00',
        China: '#ffde00',
        Cuba: '#002a8f',
        Finland: '#003580',
        France: '#ed2939',
        Germany: '#000',
        Iceland: '#003897',
        India: '#f93',
        Japan: '#bc002d',
        'North Korea': '#024fa2',
        'South Korea': '#000',
        'New Zealand': '#00247d',
        Norway: '#ef2b2d',
        Poland: '#dc143c',
        Russia: '#d52b1e',
        Turkey: '#e30a17',
        'United Kingdom': '#00247d',
        'United States': '#b22234'
      };
      axios.all([axios({
        url: 'https://fastly.jsdelivr.net/npm/emoji-flags@1.3.0/data.json'
      }), axios({
        url: ROOT_PATH + '/data/asset/data/life-expectancy-table.json',
      })]).then(res => {
        const flags = res[0].data
        const data = res[1].data
        const years = []
        for (let i = 0; i < data.length; ++i) {
          if (years.length == 0 || years[years.length - 1] != data[i][4]) {
            years.push(data[i][4])
          }
        }
        const getFlag = (countryName) => {
          if (!countryName) {
            return '';
          }
          return (
            flags.find(function (item) {
              return item.name === countryName;
            }) || {}
          ).emoji;
        }
        let startIndex = 10;
        let startYear = years[startIndex];
        option = {
          grid: {
            top: 30,
            bottom: 30,
            left: 50,
            right: 80,
            containLabel: true,
          },
          xAxis: {
            max: 'dataMax',
            axisLabel: {
              formatter: function (n) {
                return Math.round(n) + '';
              }
            }
          },
          dataset: {
            source: data.slice(1).filter(function (d) {
              return d[4] === startYear;
            })
          },
          yAxis: {
            type: 'category',
            inverse: true,
            max: 18,
            axisLabel: {
              show: true,
              fontSize: 14,
              formatter: function (value) {
                return value + '{flag|' + getFlag(value) + '}';
              },
              rich: {
                flag: {
                  fontSize: 25,
                  padding: 5
                }
              }
            },
            animationDuration: 300,
            animationDurationUpdate: 300,
          },
          series: [
            {
              // 重要点:对动态数据进行排序
              realtimeSort: false,
              seriesLayoutBy: 'column',
              type: 'bar',
              itemStyle: {
                color: function (param) {
                  //param。value是data中的每一行数据,param.value[3]是国家名称
                  return countryColors[param.value[3]] || '#5470c6';
                }
              },
              //使用dataset中的dimension列作为x轴,第3列作为y轴
              encode: {
                x: dimension,
                y: 3
              },
              label: {
                show: true,
                precision: 1,
                position: 'right',
                valueAnimation: true,
                fontFamily: 'monospace'
              }
            }
          ],
          // Disable init animation.
          animationDuration: 0,
          animationDurationUpdate: updateFrequency,
          animationEasing: 'linear',
          animationEasingUpdate: 'linear',
          graphic: {
            elements: [
              {
                type: 'text',
                right: 160,
                bottom: 60,
                style: {
                  text: startYear,
                  font: 'bolder 80px monospace',
                  fill: 'rgba(100, 100, 100, 0.25)'
                },
                z: 100
              }
            ]
          }
        };
        myChart.setOption(option);
        window.onresize = myChart.resize;
        for (let i = startIndex; i < years.length - 1; ++i) {
          (function (i) {
            setTimeout(function () {
              updateYear(years[i + 1]);
            }, (i - startIndex) * updateFrequency);
          })(i);
        }
        function updateYear (year) {
          let source = data.slice(1).filter(function (d) {
            return d[4] === year;
          });
          option.series[0].data = source;
          // 重要点:对数据进行重大到小排序
          option.series[0].data.sort((a, b) => { return b[0] - a[0] })
          option.graphic.elements[0].style.text = year;
          myChart.setOption(option);
          window.onresize = myChart.resize;
        }
      })
    }
  },
  mounted () {
    //实现模块全屏
    const element = document.getElementById('fullscreen_content');//指定全屏区域元素
    document.getElementById('fullscreen_button').addEventListener('click', () => {
      if (screenfull.enabled) {
        screenfull.request(element);
      }
    });
    this.init()
  }
}
</script>
<style lang='scss' scoped>
.full-echarts {
  background-color: #fff;
}
</style>