vue 数据可视化大屏 实现进度条效果,效果通过颜色实现渐变色进度条。
演示地址
使用组件
<template>
<div class="cardBody">
<div class="cardBodyList">
<list></list>
</div>
</div>
</template>
<script>
import WOW from "wow.js";
import numcard from "@/components/numcard/numcard.vue";
import gsap from 'gsap'
import list from './list.vue'
export default {
name: "title",
data() {
return {}
},
components: {numcard, list},
watch: {},
mounted() {
var that = this;
var wow = new WOW({
boxClass: "wow",
animateClass: "animated",
offset: 0,
mobile: true,
live: true,
scrollContainer: null,
resetAnimation: true,
});
wow.init();
gsap.to(this.$refs.icon, {
duration: 1, y: 3, repeat: -1, delay: 2, yoyo: true, onComplete: () => {
console.log('动画完成')
}
})
},
}
</script>
<style lang="scss" scoped>
.cardBody {
position: relative;
width: calc(100% - 70px);
margin: 0 auto;
height: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
.cardBodyList {
position: relative;
width: 100%;
height: calc(100% - 60px);
}
.cardBodyItem {
width: calc(100% - 0px);
height: 100%;
height: 93px;
position: relative;
background: url("./assets/cardbg.png") no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
.infoBody {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
width: calc(100% - 110px);
flex-direction: row;
align-content: flex-start;
.infoBottom {
display: flex;
width: 100%;
position: relative;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
}
.title {
font-size: 16px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #FFFFFF;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
padding-top: 10px;
img {
width: 10px;
height: 18px;
margin-right: 7px;
}
}
.info {
margin-left: 0px;
width: 100%;
}
.num {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
span {
font-size: 12px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #7989A6;
margin-left: 5px;
margin-top: 5px;
}
}
.tb {
display: flex;
justify-content: flex-end;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
img {
width: 10px;
height: 13px;
margin-left: 8px;
}
.tbTitle {
font-size: 12px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #FFFFFF;
margin-right: 7px;
}
.tbDescMinus {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 16px;
font-family: DIN-Bold;
font-weight: bold;
color: #30E17F;
}
.tbDesc {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 16px;
font-family: DIN-Bold;
font-weight: bold;
color: rgba(237, 37, 80, 1);
}
}
:deep(.num) {
.real-time-num {
font-size: 26px;
font-family: DIN;
font-weight: normal;
color: #FFFFFF;
width: auto;
}
.real-time-num-item {
text-shadow: 0 0 8px rgba(66, 163, 236, 1.00);
}
}
.icon {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
background: url("./assets/cardiconbg.png") no-repeat;
width: 58px;
height: 68px;
margin-left: 20px;
background-size: 100% 100%;
margin-right: 15px;
img {
height: 30px;
}
}
}
}
</style>
组件代码
<template>
<div class="list">
<div class="listBody scrollBar">
<progressBar :index="index" :total="total" :item="item" v-for="(item,index) in list" :key="index"></progressBar>
</div>
</div>
</template>
<script>
import WOW from "wow.js";
import numcard from "@/components/numcard/numcard.vue";
import gsap from 'gsap'
import progressBar from './progressBar.vue'
export default {
name: "title",
data() {
return {
list: [{
title: '糕点饼干',
num: 80,
color: 'rgba(130, 202, 253, 1)',
color2: 'rgba(22, 153, 255, 1)',
}, {
title: '禽肉及杂碎',
num: 70,
color: 'rgba(107, 192, 172, 1)',
color2: 'rgba(104, 230, 167, 1)',
}, {
title: '其他饮料',
num: 60,
color: 'rgba(108, 207, 246, 1)',
color2: 'rgba(0, 198, 195, 1)',
}, {
title: '可可、巧克力、代可可脂巧克力及其制品',
num: 50,
color: 'rgba(166, 98, 192, 1)',
color2: 'rgba(143, 105, 241, 1)',
}, {
title: '发酵酒',
num: 50,
color: 'rgba(253, 192, 74, 1)',
color2: 'rgba(244, 130, 50, 1)',
}]
}
},
computed: {
total() {
var total = 0
this.list.forEach((type) => {
total += type.num
});
return total
}
},
components: {numcard, progressBar},
watch: {},
mounted() {
var that = this;
var wow = new WOW({
boxClass: "wow",
animateClass: "animated",
offset: 0,
mobile: true,
live: true,
scrollContainer: null,
resetAnimation: true,
});
wow.init();
gsap.to(this.$refs.icon, {
duration: 1, y: 3, repeat: -1, delay: 2, yoyo: true, onComplete: () => {
console.log('动画完成')
}
})
},
}
</script>
<style lang="scss" scoped>
.list {
position: relative;
width: 100%;
height: 100%;
.title {
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #FFFFFF;
height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
}
.listBody {
position: relative;
width: 100%;
height: calc(100% - 46px);
overflow-y: scroll;
}
.progressBarInner {
height: 10px;
background: linear-gradient(180deg, #04CEF7 0%, #1263FF 100%);
opacity: 1;
width: 0%;
max-width: calc(100% - 60px);
}
.progressBarl {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
.line {
height: 12px;
width: 2px;
background: #04CEF7;
opacity: 1;
margin-left: 2px;
}
</style>
子组件进度
/**
* @Author: 858834013@qq.com
* @Name: progressBar
* @Date: 2023年04月27日
* @Desc:
*/
<template>
<div class="progressBarBody">
<div class="progressBarBodyl">
<div class="progressBarBodylTitle">
<img src="./assets/icon_1.png" alt=""> <span>top.{{ index + 1 }}</span><span>{{ item.title }}</span>
</div>
<div class="progressBarBottom">
<div class="progressBar">
<div class="progressBarInner"
:class="'progressBarInner'+(index+1)"
ref="progressBarInner"></div>
</div>
</div>
</div>
<div class="progressBarBodyr">
<div class="zbtitle"><span v-if="index==0">批次数</span></div>
<div class="width">
195
</div>
</div>
</div>
</template>
<script>
import gsap from 'gsap'
export default {
name: "progressBar",
components: {},
props: {
index: {
type: Number,
default() {
return 0
}
},
item: {
type: Object,
default() {
return {};
}
},
total: {
type: Number,
default() {
return 0
}
},
},
computed: {
width: function () {
return ((this.item.num / this.total) * 100).toFixed(0)
}
},
data() {
return {}
},
watch: {},
mounted() {
var that = this;
gsap.to(this.$refs.progressBarInner, {
duration: 1, width: this.width + '%', delay: 3, onComplete: () => {
console.log('动画完成')
}
})
},
methods: {}
}
</script>
<style lang="scss" scoped>
.progressBarBody {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: nowrap;
width: 100%;
flex-direction: row;
align-content: flex-start;
margin-top: 10px;
.progressBarBodyl {
width: calc(100% - 50px);
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
.progressBarBodylTitle {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #9DB9E9;
img {
margin-right: 14px;
}
span {
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #CAD7F5;
margin-right: 15px;
}
}
.progressBarBottom {
display: flex;
width: calc(100% - 0px);
margin-left: 38px;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
height: 30px;
align-content: flex-start;
.Num {
font-size: 22px;
font-family: DIN;
font-weight: normal;
color: #FFFFFF;
margin-left: 16px;
text-shadow: 0 0 10px rgba(14, 156, 255, 1.00);
}
}
}
.progressBarBodyr {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
.zbtitle {
height: 15px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #9DB9E9;
align-content: flex-start;
}
.width {
width: 62px;
height: 22px;
background: linear-gradient(0deg, rgba(#0570E9, 0.2) 0%, rgba(#0ECFF8, 0.2) 100%);
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #FFFFFF;
margin-top: 10px;
}
}
}
.progressBar {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
background: url("./assets/jindux0.png") no-repeat;
background-size: 410px 100%;
height: 9px;
width: calc(100% - 0px);
position: relative;
.progressBarInner {
position: relative;
left: 0;
height: 9px;
width: 0%;
background: url("./assets/jindux5.png") no-repeat;
background-size: 410px 100%;
}
.progressBarInner1 {
background: url("./assets/jindux1.png") no-repeat;
background-size: 410px 100%;
}
.progressBarInner2 {
background: url("./assets/jindux2.png") no-repeat;
background-size: 410px 100%;
}
.progressBarInner3 {
background: url("./assets/jindux3.png") no-repeat;
background-size: 410px 100%;
}
.progressBarInner4 {
background: url("./assets/jindux4.png") no-repeat;
background-size: 410px 100%;
}
.Num {
font-size: 16px;
font-family: DIN-Bold;
font-weight: bold;
color: #0BFFF1;
margin-left: 10px;
}
}
</style>