Files
shoot-miniprograms/src/components/RingBarChart.vue

107 lines
2.2 KiB
Vue
Raw Normal View History

2025-09-25 10:16:23 +08:00
<script setup>
import { ref, computed } from "vue";
const props = defineProps({
data: {
type: Object,
default: () => ({}),
},
2025-10-11 09:06:56 +08:00
total: {
type: Number,
default: 0,
},
2025-09-25 10:16:23 +08:00
});
const barColor = (rate) => {
if (rate >= 0.4) return "#FDC540";
if (rate >= 0.2) return "#FED847";
return "#ffe88f";
};
const bars = computed(() => {
2025-10-11 09:06:56 +08:00
const newList = new Array(12).fill({ ring: 0, rate: 0 }).map((_, index) => {
2025-09-25 10:16:23 +08:00
let ring = index;
if (ring === 11) ring = "M";
if (ring === 0) ring = "X";
return {
ring: ring,
2025-10-11 09:06:56 +08:00
rate: props.data[index] || 0,
2025-09-25 10:16:23 +08:00
};
});
2025-10-11 09:06:56 +08:00
[newList[0], newList[11]] = [newList[11], newList[0]];
2025-09-25 10:16:23 +08:00
return newList.reverse();
});
const ringText = (ring) => {
if (ring === 11) return "X";
if (ring === 0) return "M";
return ring;
};
</script>
<template>
<view class="container">
<view>
2025-09-25 14:22:03 +08:00
<view v-for="(b, index) in bars" :key="index">
2025-10-09 18:14:07 +08:00
<text v-if="b && b.rate">
2025-10-11 09:06:56 +08:00
{{ total === 0 ? `${Number((b.rate * 100).toFixed(1))}%` : b.rate }}
2025-09-27 10:09:02 +08:00
</text>
2025-09-25 14:22:03 +08:00
<view
:style="{
2025-10-11 09:06:56 +08:00
background: barColor(total === 0 ? b.rate : b.rate / total),
2025-10-31 10:22:02 +08:00
height:
Math.max((total === 0 ? b.rate : b.rate / total) * 240) + 'rpx',
2025-09-25 14:22:03 +08:00
}"
>
</view>
2025-09-25 10:16:23 +08:00
</view>
</view>
<view>
<text v-for="(b, index) in bars" :key="index">
{{ b && b.ring !== undefined ? b.ring : "" }}
</text>
</view>
</view>
</template>
<style scoped>
2025-10-11 09:06:56 +08:00
.container {
min-height: 150rpx;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
2025-09-25 10:16:23 +08:00
.container > view {
padding: 0 10rpx;
}
.container > view:first-child {
display: flex;
align-items: flex-end;
justify-content: space-around;
2025-09-25 10:59:49 +08:00
min-height: 50rpx;
2025-09-25 10:16:23 +08:00
}
.container > view:first-child > view {
2025-09-25 14:22:03 +08:00
display: flex;
flex-direction: column;
align-items: center;
font-size: 18rpx;
color: #333;
2025-10-11 09:06:56 +08:00
width: 5vw;
2025-09-25 14:22:03 +08:00
}
.container > view:first-child > view > view {
2025-10-11 09:06:56 +08:00
width: 100%;
2025-09-25 10:16:23 +08:00
transition: all 0.3s ease;
height: 0;
}
.container > view:last-child {
display: grid;
grid-template-columns: repeat(12, 1fr);
border-top: 1rpx solid #333;
font-size: 22rpx;
color: #333333;
}
.container > view:last-child > text {
text-align: center;
}
</style>