This commit is contained in:
67
src/components/TagChart.vue
Normal file
67
src/components/TagChart.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div style="position: relative; height: 100%; width: 100%">
|
||||
<Doughnut :data="chartData" :options="chartOptions" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { Doughnut } from "vue-chartjs";
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
ArcElement,
|
||||
Tooltip,
|
||||
Legend,
|
||||
type ChartOptions,
|
||||
} from "chart.js";
|
||||
|
||||
ChartJS.register(ArcElement, Tooltip, Legend);
|
||||
|
||||
interface TagData {
|
||||
name: string;
|
||||
totalTime: number;
|
||||
color: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
tags: TagData[];
|
||||
}>();
|
||||
|
||||
const chartData = computed(() => ({
|
||||
labels: props.tags.map((t) => t.name),
|
||||
datasets: [
|
||||
{
|
||||
data: props.tags.map((t) => t.totalTime / (1000 * 60)), // Convert to minutes
|
||||
backgroundColor: props.tags.map((t) => t.color),
|
||||
borderColor: "#1e293b", // Matches typical dark mode bg
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
const chartOptions: ChartOptions<"doughnut"> = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: "right",
|
||||
labels: {
|
||||
color: "#e2e8f0",
|
||||
usePointStyle: true,
|
||||
padding: 20,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function (context) {
|
||||
const minutes = Math.round(context.raw as number);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
const mins = minutes % 60;
|
||||
return ` ${hours}h ${mins}m`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
cutout: "70%",
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user