Echarts柱状图空状态和值为0的数据展示

容我猜测一下,各位是因为什么情况下搜到这篇博客的吧。

情况一: 自己根据最大值和造假数据,结果发现tootip显示的数值为你自己造的数据,你造的数据肯定不是为0的,因为那样柱体没有高度,但是你造的值大于0 ,鼠标移入tootipo显示又不对哈哈哈

情况二:可能实现了全是0 的空状态的显示,但是对于有数据,但是某些柱子的值为0的不知道怎么处理

情况三:可能实现了空状态都是0的(后端直接返回空数组或者null,也就是没返回值的情况),也实现鼠标移入不显示tootip,但是月的数据有间隔显示,不显示tootip,又不知道为0的到底是哪天的,

等等...

嘿嘿,恭喜你,这篇博客可以解决哒,不用再发愁了!

想要的效果:tab切换显示周的柱状图或者月的柱状图,整体没数据时,默认一个灰色的短的柱子,如果有数据的值为0时,也是默认一个灰色的短的柱子,有数据的话,就正常显示带颜色的柱子,哎呀呀,其实很简单啦,开始我想的太复杂了,嘿嘿

思路:

1、echarts的配置项手册有提供series里有提供一个barMinHeight属性(柱体的最小高度),设置这个字段值为10;这样你就发现即使数据的值为0,柱子的高度也会显示有;

2、接着就是怎么给柱体设置颜色了,写法有很多,但是适合当前需求的只有一种,那么echarts所需要的data数据类型就是下图这样啦,在里面可以自定义柱体的颜色


3、那么将数据处理成这样就可以啦,嘿嘿。

4、遍历后端返回的数据(有数据情况),根据值是否大于0判断显示不同的颜色

实现的效果如下图:

我是把echarts的柱状图封成了一个可复用的组件,封装echarts图表我发现个世纪难题,超级无敌巨大bug,封装成一个组件,当然是为了提高复用的啊,但是在同一个页面多次引用同一个echarts图表组件,需要确保echarts图表的唯一性,所以要动态渲染id,不然数据就渲染不成功,也不会报错,所以这个地方要尤其注意下,封装的柱状图组件代码如下:

<template>
  <div :id="id" class="bar-sty"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
  props: {
    // 渲染图表的唯一id
    id: String,
    // data为echarts展示的数据
    data: {
      type: Array,
      default: () => {
        return []
      }
    },
    // x轴显示的数据
    categoryData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 因为是要复用的,且周有7条数据,月有30条数据,柱体的宽带也设置动态的
    barWidth: {
      type: Number,
      default: () => {
        return 0
      }
    },
    // x轴间隔显示,这里月会用到
    interval: {
      type: Number,
      default: () => {
        return 0
      }
    },
    // 柱状图的圆角,也是因为周和月的数据长度不同,所以设置的动态的
    barRadius: {
      type: Array,
      default: () => {
        return []
      }
    },
  },
  data() {
    return {
    }
  },
  watch: {
    // 监听data和x轴都有数据的情况下再渲染图表
    data(newData) {
      if (newData.length > 0 && this.categoryData.length > 0) {
        this.renderChart();
      }
    },
    categoryData(newCategoryData) {
      if (this.data.length > 0 && newCategoryData.length > 0) {
        this.renderChart();
      }
    }
  },
  mounted() {
    // 获取DOM元素,初始化Echarts图表对象,但不设置数据
    const chartDom = document.getElementById(this.id);
    const myChart = echarts.init(chartDom);
    // 将局部变量赋值给组件实例的属性,以便在其他方法中可以访问
    this.myChart = myChart;
    this.chartDom = chartDom;
    // 首次加载时尝试渲染图表(如果数据已经准备好)
    if (this.data.length > 0 && this.categoryData.length > 0) {
      this.renderChart();
    }
  },
  methods: {
    renderChart() {
      const option = {
        grid: {
          show: false,
          left: "0%",
          bottom: "15%",
          right: "0%"
        },
        tooltip: {
          show: true
        },
        xAxis: {
          type: 'category',
          data: this.categoryData,
          axisTick: {
            show: false
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: "rgba(235, 239, 244, 1)"
            }
          },
          axisLabel: {
            show: true,
            color: "#1E1714",
            interval: this.interval
          }
        },
        yAxis: [{
          type: "value",
          show: false
        }],
        series: [
          {
            barMinHeight: 10,
            barWidth: this.barWidth,
            data: this.data,
            type: 'bar',
            barMinWidth: 10,
            // 取消鼠标移入高亮
            emphasis: {
              disabled: true,
              focus: 'none'
            },
            itemStyle: {
              borderRadius: this.barRadius, // 设置圆角的半径,顺序为左上、右上、右下、左下
            }
          }
        ]
      };
      this.myChart.setOption(option);
    }
  }
}
</script>

<style lang="less" scoped>
// 宽高设置100%,撑满父级元素
.bar-sty {
  width: 100%;
  height: 100%;
}
</style>

父组件:

<bar-change-com class="bar-area" :data="moreDayData" :categoryData="categoryData" :barWidth="barWidth"
          :interval="interval" id="inviteId" :barRadius="barRadius"></bar-change-com>
<-- 同一个页面多次引用同一个echarts图表组件,要确保id唯一 -->
<bar-change-com class="bar-area" :data="moreDayData" :categoryData="categoryData" :barWidth="barWidth"
          :interval="interval" id="inviteId" :barRadius="barRadius"></bar-change-com>

在父组件处理数据:我这里用到了dayjs插件,有需要可以引入

后端有返数据的话这样处理:

this.registerDataInfo.last7DaysUserDataList.forEach((item) => {
            let date = new Date(item.dateTime * 1000);
            let weekDay = date.getDay();
            let weekDayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
            let shortWeekDay = weekDayNames[weekDay].substring(0, 2);
            this.categoryData.push(shortWeekDay);
            // 根据item.num的值显示不同柱体颜色
            let color = item.num > 0 ? '#0DA0F3' : '#EBEFF4';
            let newItem = {
              value: item.num,
              itemStyle: {
                color: color
              }
            };
            this.moreDayData.push(newItem);
          });

后端没返回数据的话(自己造数据为0的情况):

dayjs.locale('en'); // 设置dayjs为英文环境
          const today = dayjs();
          for (let i = 0; i < 7; i++) {
            const day = today.subtract(i, 'day');
            const weekDay = day.format('ddd').substring(0, 2);
            this.categoryData.push(weekDay);
          }
          // 反转数组,使得顺序是从前往后(过去到现在)
          this.categoryData.reverse();
          let dataArr = [0, 0, 0, 0, 0, 0, 0];
          dataArr.forEach((item) => {
            // 根据item.num的值显示不同柱体颜色
            let color = item > 0 ? '#0DA0F3' : '#EBEFF4';
            let newItem = {
              value: item,
              itemStyle: {
                color: color
              }
            };
            this.moreDayData.push(newItem);
          })

差不多就是这样了,嘿嘿。。。。

嘶~回想到困扰心头、如迷雾般缭绕的技术难题,现在清晰而又渺小。不禁感慨,成长的路途恰似一场奇妙的魔法之旅,随着知识的魔杖轻轻挥舞,曾经的荆棘满布已然变为繁花盛景,过往的艰难险阻也不过是铸就今日从容的阶石。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值