容我猜测一下,各位是因为什么情况下搜到这篇博客的吧。
情况一: 自己根据最大值和造假数据,结果发现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);
})
差不多就是这样了,嘿嘿。。。。
嘶~回想到困扰心头、如迷雾般缭绕的技术难题,现在清晰而又渺小。不禁感慨,成长的路途恰似一场奇妙的魔法之旅,随着知识的魔杖轻轻挥舞,曾经的荆棘满布已然变为繁花盛景,过往的艰难险阻也不过是铸就今日从容的阶石。