mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-18 03:57:06 +08:00
v0.3.8
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
<script setup>
|
||||
import {
|
||||
ArcElement,
|
||||
Chart as ChartJS,
|
||||
Tooltip,
|
||||
} from "chart.js";
|
||||
import { computed } from "vue";
|
||||
import { Doughnut } from "vue-chartjs";
|
||||
|
||||
ChartJS.register(ArcElement, Tooltip);
|
||||
|
||||
const props = defineProps({
|
||||
rate: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const percentage = computed(() => {
|
||||
const rate = Number(props.rate);
|
||||
if (!Number.isFinite(rate)) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(0, Math.min(100, rate * 100));
|
||||
});
|
||||
|
||||
const label = computed(() => {
|
||||
const rate = Number(props.rate);
|
||||
if (!Number.isFinite(rate)) {
|
||||
return "--";
|
||||
}
|
||||
return `${percentage.value.toFixed(2)}%`;
|
||||
});
|
||||
|
||||
function getSegmentBorderRadius(dataIndex) {
|
||||
const radius = 5;
|
||||
|
||||
if (percentage.value <= 0) {
|
||||
return dataIndex === 1
|
||||
? {
|
||||
outerStart: radius,
|
||||
outerEnd: radius,
|
||||
innerStart: radius,
|
||||
innerEnd: radius,
|
||||
}
|
||||
: 0;
|
||||
}
|
||||
|
||||
if (percentage.value >= 100) {
|
||||
return dataIndex === 0
|
||||
? {
|
||||
outerStart: radius,
|
||||
outerEnd: radius,
|
||||
innerStart: radius,
|
||||
innerEnd: radius,
|
||||
}
|
||||
: 0;
|
||||
}
|
||||
|
||||
return dataIndex === 0
|
||||
? {
|
||||
outerStart: radius,
|
||||
outerEnd: 0,
|
||||
innerStart: radius,
|
||||
innerEnd: 0,
|
||||
}
|
||||
: {
|
||||
outerStart: 0,
|
||||
outerEnd: radius,
|
||||
innerStart: 0,
|
||||
innerEnd: radius,
|
||||
};
|
||||
}
|
||||
|
||||
const chartData = computed(() => ({
|
||||
labels: ["命中", "未命中"],
|
||||
datasets: [
|
||||
{
|
||||
data: [percentage.value, Math.max(0, 100 - percentage.value)],
|
||||
backgroundColor: ["#4ade80", "#373737"],
|
||||
borderWidth: 0,
|
||||
hoverBorderWidth: 0,
|
||||
selfJoin: false,
|
||||
borderRadius: ({ dataIndex }) => getSegmentBorderRadius(dataIndex),
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
const chartOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
cutout: "82%",
|
||||
rotation: -90,
|
||||
circumference: 180,
|
||||
animation: {
|
||||
duration: 450,
|
||||
},
|
||||
events: [],
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<div
|
||||
class="relative h-[82px] w-[132px] shrink-0"
|
||||
role="img"
|
||||
:aria-label="`缓存命中率 ${label}`"
|
||||
>
|
||||
<Doughnut class="h-full w-full" :data="chartData" :options="chartOptions" />
|
||||
<div class="pointer-events-none absolute inset-x-0 bottom-[10px] flex justify-center">
|
||||
<div
|
||||
class="text-[20px] leading-none text-white"
|
||||
style="font-family: var(--font-num)"
|
||||
>
|
||||
{{ label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user