实现思路:
1、自定义布局,总人数 27个 灰色色块写死,并通过定位置于底层
2、占比部分,带有 27个 渐变色块部分,定位置于上层,通过判断渲染不同的渐变占比
3、需要将每一列的渐变颜色,用数组的形式将每个颜色写死,并根据下标去循环渲染
一、组件
<template>
<div class="num_shili">
<div class="num_tiao_temp"></div>
<span>未上线</span>
</div>
<div class="num_list">
<div class="num_item" v-for="(num, nIndex) of numList" :key="nIndex">
<div>{{ num.totalJoinExamStudentCount }}人</div>
<div class="num_tiao">
<div class="num_tiao_ch" v-for="n in 27" :key="n"></div>
</div>
<div class="num_tiao1">
<div class="num_tiao_ch1" v-for="(color, coIndex) in num.colors" :key="coIndex"
:style="'background:' + color + '!important;'">
</div>
</div>
<div class="num_tiao_text">{{ num.schoolName }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { TCountDistributionModel } from '@/model/datacenter';
import { reactive, ref, watch } from 'vue';
import color from './../config/colors'
const numList = ref<Array<TCountDistributionModel>>()
type TProps = {
numList: Array<TCountDistributionModel> | undefined
}
const props = withDefaults(defineProps<TProps>(), {
})
watch(() => props.numList, (newVal, oldVal) => {
numList.value = newVal as TCountDistributionModel[]
}, {
deep: true
})
setTimeout(() => {
numList.value && numList.value.map((item: TCountDistributionModel, iIndex: number) => {
if (iIndex === 0) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color1.slice(0, num)
} else if (iIndex === 1) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color2.slice(0, num)
} else if (iIndex === 2) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color3.slice(0, num)
} else if (iIndex === 3) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color4.slice(0, num)
} else if (iIndex === 4) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color5.slice(0, num)
} else if (iIndex === 5) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color6.slice(0, num)
} else if (iIndex === 6) {
let ratio = item.onlineStudentCount / item.totalJoinExamStudentCount
let num = Math.round(27 * ratio)
item.colors = color.color7.slice(0, num)
}
})
}, 500)
</script>
<style lang="scss" scoped>
.num_shili {
display: flex;
align-items: center;
color: #fff;
height: 50px;
.num_tiao_temp {
width: 56px;
height: 16px;
border-radius: 16px;
background: #596A9F;
}
span {
margin-left: 10px;
white-space: nowrap;
font-size: 14px;
}
}
.num_tiao_ch {
height: 8px;
background: #596A9F;
border-radius: 5px;
margin: 10px 0;
}
.num_list {
display: flex;
align-items: center;
color: #fff;
justify-content: space-between;
flex-direction: row;
.num_item {
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
position: relative;
width: 50px;
.num_tiao {
width: 50px;
margin: 10px 0;
}
.num_tiao1 {
position: absolute;
bottom: 94px;
left: 0;
z-index: 1000;
margin: 10px 0;
.num_tiao_ch1 {
width: 50px;
height: 8px;
margin: 10px 0;
border-radius: 5px;
background: transparent;
}
.num_tiao_ch1:last-child {
margin: 0;
}
}
.num_tiao_text {
width: 20px;
}
}
}
</style>
二、颜色文件 colors.ts,对应颜色需要写死
const color1 = [
'#5F32F6', '#5F32F6', '#5F32F6', '#5F32F6', '#5F32F6', '#5F32F6', '#5F32F6', '#5F32F6',
'#825CFF', '#825CFF', '#825CFF', '#825CFF', '#825CFF',
'#825CFF', '#825CFF', '#825CFF', '#825CFF', '#825CFF',
'#9F8AE9', '#9F8AE9', '#9F8AE9', '#9F8AE9', '#9F8AE9',
'#9F8AE9', '#9F8AE9', '#9F8AE9', '#9F8AE9'].reverse()
const color2 = [
'#F75962', '#F75962', '#F75962', '#F75962', '#F75962', '#F75962', '#F75962', '#F75962',
'#FF6A73', '#FF6A73', '#FF6A73', '#FF6A73', '#FF6A73',
'#FF6A73', '#FF6A73', '#FF6A73', '#FF6A73', '#FF6A73',
'#FF858C', '#FF858C', '#FF858C', '#FF858C', '#FF858C',
'#FF858C', '#FF858C', '#FF858C', '#FF858C'].reverse()
const color3 = [
'#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD',
'#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6',
'#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6',
'#40FDFF', '#40FDFF', '#40FDFF', '#40FDFF', '#40FDFF',
'#40FDFF', '#40FDFF', '#40FDFF', '#40FDFF'].reverse()
const color4 = [
'#FF652E', '#FF652E', '#FF652E', '#FF652E', '#FF652E', '#FF652E', '#FF652E', '#FF652E',
'#F2855F', '#F2855F', '#F2855F', '#F2855F', '#F2855F',
'#F2855F', '#F2855F', '#F2855F', '#F2855F', '#F2855F',
'#FC9570', '#FC9570', '#FC9570', '#FC9570', '#FC9570',
'#FC9570', '#FC9570', '#FC9570', '#FC9570'].reverse()
const color5 = [
'#0A7FFF', '#0A7FFF', '#0A7FFF', '#0A7FFF', '#0A7FFF', '#0A7FFF', '#0A7FFF', '#0A7FFF',
'#3897FE', '#3897FE', '#3897FE', '#3897FE', '#3897FE',
'#3897FE', '#3897FE', '#3897FE', '#3897FE', '#3897FE',
'#52A5FF', '#52A5FF', '#52A5FF', '#52A5FF', '#52A5FF',
'#52A5FF', '#52A5FF', '#52A5FF', '#52A5FF'].reverse()
const color6 = [
'#E902A4', '#E902A4', '#E902A4', '#E902A4', '#E902A4', '#E902A4', '#E902A4', '#E902A4',
'#FF3AC4', '#FF3AC4', '#FF3AC4', '#FF3AC4', '#FF3AC4',
'#FF3AC4', '#FF3AC4', '#FF3AC4', '#FF3AC4', '#FF3AC4',
'#FF59CD', '#FF59CD', '#FF59CD', '#FF59CD', '#FF59CD',
'#FF59CD', '#FF59CD', '#FF59CD', '#FF59CD'].reverse()
const color7 = [
'#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD', '#02CBCD',
'#06E0E2', '#06E0E2', '#06E0E2', '#06E0E2', '#06E0E2',
'#06E0E2', '#06E0E2', '#06E0E2', '#06E0E2', '#06E0E2',
'#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6',
'#0FF4F6', '#0FF4F6', '#0FF4F6', '#0FF4F6'].reverse()
export default{
color1,
color2,
color3,
color4,
color5,
color6,
color7
}
希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~