使用Echart线柱混合图排坑记录

在Vue中使用Echart

  • 官方文档
https://echarts.apache.org/zh/option.html#title
  • 安装
    //vue 2 
    npm install echarts vue-echarts
    npm i -D @vue/composition-api

    //vue 3
    npm install echarts vue-echarts
  • 引用
//可全局也可在要使用的文件中用
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent
} from 'echarts/components'
import ECharts, { THEME_KEY } from 'vue-echarts'

use([
  CanvasRenderer,
  PieChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent
])
  • 完整示例

    这是一个简单折线图的示例,想要触发重绘的话直接设置data的options即可。

    注意:Echart必须要设置高度,否则会出现异常情况,出现白屏的现象

    <template>
      <v-chart class="chart" :option="options" />
    </template>
    
    <script>
    
    import ECharts from 'vue-echarts'
    import 'echarts'
    export default {
      components: {
        'v-chart': ECharts,
      },
      data() {
        return {
          
        options: {
      xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
      },
      yAxis: {},
      series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: "line"
      }]
        }
    }
      },
    }
    </script>
    
    <style scoped>
    .chart {
      height: 400px;
    }
    </style>
    

    这里我们进入正题,折柱混合情况,其实也是所有的各类混合图都会遇到的问题

    来一段标准的或者说是官方示例:

    <template>
      <v-chart class="chart" :option="options" />
    </template>
    
    <script>
    
    import ECharts from 'vue-echarts'
    import 'echarts'
    export default {
      components: {
        'v-chart': ECharts,
      },
      data() {
        return {
        options: {
        legend: {
          data: ['蒸发量', '降水量']
        },
        xAxis: [
          {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            axisPointer: {
              type: 'shadow'
            }
          }
        ],
      yAxis: [
        {
          type: 'value',
          name: 'Precipitation',
          min: 0,
          max: 250,
          interval: 50,
          axisLabel: {
            formatter: '{value} ml'
          }
        }
      ],
      series: [
        {
          name: '蒸发量',
          type: 'bar',
          tooltip: {
            valueFormatter: function (value) {
              return value + ' ml';
            }
          },
          data: [
            2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
          ]
        },
        {
          name: '降水量',
          type: 'line',
          tooltip: {
            valueFormatter: function (value) {
              return value + ' ml';
            }
          },
          data: [
            2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
          ]
        }
      ]
    }
    }
      },
    }
    </script>
    
    <style scoped>
    .chart {
      height: 400px;
    }
    </style>
    

看效果是不是觉得很完美,但是现实会遇到各种各样的问题

  1. 第一个问题:两个视图的x轴不一致情况,比如说蒸发量没有二月份数据,这种情况下这样子的代码显示就不行了。

这个问题看了下官方文档找到解决方案就是使用值和x轴的值去对应,官方说明如下:

『值』与 轴类型 的关系:

  • 当某维度对应于数值轴(axis.type 为 'value' 或者 'log')的时候:

    其值可以为 number(例如 12)。(也可以兼容 string 形式的 number,例如 '12'

  • 当某维度对应于类目轴(axis.type 为 'category')的时候:

    其值须为类目的『序数』(从 0 开始)或者类目的『字符串值』。例如:

      xAxis: {
          type: 'category',
          data: ['星期一', '星期二', '星期三', '星期四']
      },
      yAxis: {
          type: 'category',
          data: ['a', 'b', 'm', 'n', 'p', 'q']
      },
      series: [{
          data: [
              // xAxis    yAxis
              [  0,        0,    2  ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
              [  '星期四',  2,    1  ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
              [  2,       'p',   2  ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
              [  3,        3,    5  ]
          ]
      }]
     // 在数据进来之后处理下数据
     // 1. 遍历各个视图的数据元,把x轴的值合并去重,然后排序,
     // 2. 给各个series设置对应的值,值每个项对应[`${item[0]}`, item[1]],就是把x轴转为字符串,然后对应y轴的值。
    render(data) {
      if (Object.keys(data).length) {
        let xdata = []
        for (let i = 0; i < this.keys.length; i++) {
          let key = this.keys[i]
          this.options.series[i].data = data[key]
            ? data[key].map(item => [`${item[0]}`, item[1]])
            : []
          let date = data[key] ? data[key].map(item => `${item[0]}`) : []
          xdata = [...xdata, ...date]
          this.options.series[i].name = key
        }
        xdata = Array.from(new Set(xdata))
        this.options.xAxis.data = xdata ? xdata.sort((a, b) => a - b) : []
      } else {
        this.clearChart()
      }
    },
    clearChart() {
      if (this.init) {
        this.$refs.chart.clear()
      }
    },

提测,感觉没啥问题,x轴排序了,然后x轴和y轴也一一对应了。但是打脸来的飞快,线图是乱的

贴个示意图

看了下发现数据源是没排过序的,所以,x轴排序了,x和y的值也是对应的,但是线图的点是顺序画的,所以要先对数据源进行排序才行

    // 在数据进来之后处理下数据
     // 1. 先将数据按照x轴大小进行排序,保证x轴数据从小到大展示
     // 2. 遍历各个视图的数据元,把x轴的值合并去重,然后排序,
     // . 给各个series设置对应的值,值每个项对应[`${item[0]}`, item[1]],就是把x轴转为字符串,然后对应y轴的值。
    render(data) {
      if (Object.keys(data).length) {
        let xdata = []
        for (let i = 0; i < this.keys.length; i++) {
          let key = this.keys[i]
          // 先将数据按照x轴大小进行排序,保证x轴数据从小到大展示
          list[key] && (list[key] = list[key].sort((a, b) => a[0] - b[0]))

          this.options.series[i].data = list[key]
            ? list[key].map(item => [`${item[0]}`, item[1]])
            : []
          let date = data[key] ? data[key].map(item => `${item[0]}`) : []
          xdata = [...xdata, ...date]
          this.options.series[i].name = key
        }
        xdata = Array.from(new Set(xdata))
        this.options.xAxis.data = xdata ? xdata.sort((a, b) => a - b) : []
      } else {
        this.clearChart()
      }
    },
    clearChart() {
      if (this.init) {
        this.$refs.chart.clear()
      }
    },

光法V3
1 声望0 粉丝