echarts - 将具有相同值的轴标签分组

echarts - group axis labels with the same value

我正在尝试用 echarts 构建一个条形图,其中每个条形都有一个与之关联的小时和日期。如何对日期进行分组,以免它们重复?如果图表相应地放大/平移,这也应该更新。感谢您的帮助!

我有什么:

我想要什么:

以及我目前的代码:

<template>
    <div class="bar-chart">
      <v-chart :options="chartOptionsBar" theme="dark" :autoresize="true" ref="chart"></v-chart>
    </div>
</template>

<style lang="sass">
.echarts
  height: 100%
  width: 100%

</style>

<style lang="sass" scoped>
.bar-chart
  width: 100%
  height: 250px
</style>

<script>
import ECharts from 'vue-echarts'
import {RejectionHistoryRequest} from "@/pb/isotronic/hosted/central/gatekeeper/productionapi/rpc/proto/AnalyticsService_pb";
import {customerId, grpcApiUrl} from "@/helper";
import {AnalyticsClient} from "@/pb/isotronic/hosted/central/gatekeeper/productionapi/rpc/proto/AnalyticsService_grpc_web_pb";

export default {
  components: {
    'v-chart': ECharts
  },
  created() {
    this.analytics = new AnalyticsClient(grpcApiUrl(), null, null);
  },
  props: {
    machineName: String,
  },
  computed: {
    chartOptionsBar() {
      let that = this;
      let option = {
        grid: {
          bottom: 110
        },
        xAxis: [
          {
            type: 'category',
            data: that.graphData.categoryData,
          },
          {
            type: 'category',
            data: that.graphData.categoryDates
          }
        ],
        yAxis: [{
          name: "Rejected Vials [ % ]",
          nameLocation: "middle",
          nameGap: 40,
        }],
        series: [
          {
            type: 'bar',
            data: that.graphData.valueData,
          }
        ],
        title: {
          text: 'Test Chart',
          left: 'center'
        },
        tooltip: {
          trigger: 'axis',
          formatter: function (param) {
            return 'Rejected Vials:<br />' + param[0].axisValue.substring(0, param[0].axisValue.length - 1) + '-' +
                (+param[0].axisValue.substring(0, param[0].axisValue.length - 1) + 1 ) + 'h<br />' + param[0].data + ' %';
          },
          axisPointer: {
            type: 'shadow',
            label: {
              show: false
            }
          }
        },
        dataZoom: [{
          type: 'inside',
          startValue: that.dataZoomStart,
        }, {
          type: 'slider',
          startValue: that.dataZoomStart
        }],
      }
      return option
    }
  },
  data() {
    return {
      graphData: {
        categoryData: [],
        valueData: [],
        categoryDates: []
      },
      dataZoomStart: 0
    }
  },
  methods: {
    generateData: function () {
      this.graphData.categoryData = []
      this.graphData.valueData = []
      let startDate = new Date(2020, 10, 25, 0);
      let endDate = new Date(2020, 10, 30, 0);
      for (let d = startDate; d <= endDate; d.setTime(d.getTime() + (60 * 60 * 1000))) {
        this.graphData.categoryData.push(startDate.getHours() + '-' + (startDate.getHours() + 1) + 'h' + ' | ' + this.$moment(startDate).format("MM/DD"))
        this.graphData.valueData.push(Math.random().toFixed(2) / 2);
      }
      this.dataZoomStart = this.graphData.categoryData.length - 24
    },
    loadRejectionHistory: function () {
      let rejectionHistoryRequest = new RejectionHistoryRequest();
      rejectionHistoryRequest.setCustomer(customerId());
      rejectionHistoryRequest.setMachineName(this.machineName);
      const categories = [];
      const reject = [];
      const dates = [];
      let stream = this.analytics.getRejectionHistory(rejectionHistoryRequest, null);
      stream.on('data', (rejectionHistoryRow) => {

        categories.push(rejectionHistoryRow.getBegin().toDate().getHours() + "h");
        dates.push(rejectionHistoryRow.getBegin().toDate().getDate() + '.' +
            (rejectionHistoryRow.getBegin().toDate().getMonth() + 1))
        reject.push((rejectionHistoryRow.getRejectionRate() * 100).toFixed(2));
      });
      stream.on('end', (end) => {
        this.graphData.categoryData = categories
        this.graphData.valueData = reject
        this.graphData.categoryDates = dates
        this.dataZoomStart = this.graphData.categoryData.length - 12
      });
    },
  },
  mounted() {
    this.loadRejectionHistory()
  }
}

尝试使用以下配置:

var myChart = echarts.init(document.getElementById('chart'));

function generateData(start, end) {
  var dates = [];
  var values = [];

  var startDate = moment(start);
  var endDate = moment(end);
  var hourDiff = endDate.diff(startDate, 'hours');

  for (var i = 0; i < hourDiff; i++) {
    dates.push(startDate.add(1, 'hours').format('YYYY-MM-DD HH:mm'));
    values.push(Math.random().toFixed(2) / 2);
  }
  return [dates, values]
}

var [dates, values] = generateData('2020-10-25 00:00', '2020-10-30 00:00');

var option = {
  xAxis: [{
    id: 'date',
    type: 'category',
    data: dates,
    position: 'top',
    axisLabel: {
      formatter: (d) => moment(d).format('DD.MM'),
      interval: 24,
    },
    splitLine: {
      show: true,
      interval: 24,
    },
  }, {
    id: 'hours',
    type: 'category',
    data: dates,
    position: 'bottom',
    axisLabel: {
      formatter: (d) => moment(d).format('HH') + 'h'
    }
  }],
  yAxis: [{
    type: 'value',
  }],
  series: [{
    name: 'value',
    type: 'bar',
    data: values,
    color: 'steelBlue'
  }],
  dataZoom: [{
      type: 'inside'
    },
    {
      type: 'slider',
      show: true,
      xAxisIndex: [0, 1],
      labelFormatter: (_v, vStr) => moment(vStr).format('HH') + 'h / ' + moment(vStr).format('DD.MM'),
    }
  ],
};

myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.min.js"></script>
<div id="chart" style="width:800px;height:400px;"></div>