ChartsRace.vue 2.5 KB
Newer Older
hucy's avatar
hucy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
<script setup lang="ts">
import * as echarts from 'echarts';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
type EChartsOption = echarts.EChartsOption;
type ECharts = echarts.ECharts;

const colorList = {
  A: '#F6E3C5',
  B: '#A0D995',
  C: '#6CC4A1',
  D: '#4CACBC',
  E: '#DF7861',
} as any;

defineExpose({
  run,
  setTimer,
  clearTimer,
});

const chartsRaceRef = ref<any>(null);

const state = reactive({
  data: [] as number[],
  timer: null as any,
});

onMounted(() => {
  getChart();
});

onUnmounted(() => {
  clearTimer();
});

var raceChart: ECharts;
function getChart() {
  if (raceChart != null && raceChart != undefined) {
    raceChart.dispose();
  }
  raceChart = echarts.init(chartsRaceRef.value);
  let option: EChartsOption;

  for (let i = 0; i < 5; ++i) {
    state.data.push(Math.round(Math.random() * 200));
  }

  option = {
    grid: {
      top: 10,
      bottom: 30,
      left: 40,
      right: 60,
    },
    xAxis: {
      max: 'dataMax',
    },
    yAxis: {
      type: 'category',
      data: ['A', 'B', 'C', 'D', 'E'],
      inverse: true,
      animationDuration: 300,
      animationDurationUpdate: 300,
      max: 4, // only the largest ${max + 1} bars will be displayed
    },
    series: [
      {
        realtimeSort: true,
        type: 'bar',
        itemStyle: {
          color: function (param) {
            return colorList[param.name] || '#9EB23B';
          },
        },
        data: state.data,
        label: {
          show: true,
          position: 'right',
          valueAnimation: true,
        },
        barWidth: 60,
      },
    ],
    legend: {
      show: true,
    },
    animationDuration: 0,
    animationDurationUpdate: 3000,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear',
  };
  setTimer();
  option && raceChart.setOption(option);
}

function run() {
  for (var i = 0; i < state.data.length; ++i) {
    if (Math.random() > 0.9) {
      state.data[i] = Math.round(Math.random() * 2000);
    } else {
      state.data[i] = Math.round(Math.random() * 200);
    }
  }
  raceChart.setOption<EChartsOption>({
    series: [
      {
        type: 'bar',
        data: state.data,
      },
    ],
  });
}

function setTimer() {
  if (state.timer) {
    clearTimer();
  }
  setTimeout(function () {
    run();
  }, 0);
  state.timer = setInterval(function () {
    run();
  }, 3000);
}
function clearTimer() {
  clearInterval(state.timer);
}
</script>
<template>
  <div class="fit" ref="chartsRaceRef"></div>
</template>

<style lang="scss" scoped></style>