All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m3s
98 lines
1.9 KiB
Vue
98 lines
1.9 KiB
Vue
<template>
|
|
<div style="position: relative; height: 100%; width: 100%">
|
|
<Bar :data="chartData" :options="chartOptions" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from "vue";
|
|
import { Bar } from "vue-chartjs";
|
|
import {
|
|
Chart as ChartJS,
|
|
BarElement,
|
|
CategoryScale,
|
|
LinearScale,
|
|
Tooltip,
|
|
Legend,
|
|
BarController,
|
|
type ChartOptions,
|
|
} from "chart.js";
|
|
|
|
ChartJS.register(
|
|
BarElement,
|
|
CategoryScale,
|
|
LinearScale,
|
|
Tooltip,
|
|
Legend,
|
|
BarController,
|
|
);
|
|
|
|
interface ClientData {
|
|
name: string;
|
|
totalTime: number;
|
|
}
|
|
|
|
const props = defineProps<{
|
|
clients: ClientData[];
|
|
}>();
|
|
|
|
const chartData = computed(() => ({
|
|
labels: props.clients.map((c) => c.name),
|
|
datasets: [
|
|
{
|
|
label: "Time Tracked",
|
|
data: props.clients.map((c) => c.totalTime / (1000 * 60)), // Convert to minutes
|
|
backgroundColor: "#6366f1",
|
|
borderColor: "#4f46e5",
|
|
borderWidth: 1,
|
|
},
|
|
],
|
|
}));
|
|
|
|
const chartOptions: ChartOptions<"bar"> = {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
color: "#e2e8f0",
|
|
callback: function (value: string | number) {
|
|
const numValue =
|
|
typeof value === "string" ? parseFloat(value) : value;
|
|
const hours = Math.floor(numValue / 60);
|
|
const mins = Math.round(numValue % 60);
|
|
return hours > 0 ? `${hours}h ${mins}m` : `${mins}m`;
|
|
},
|
|
},
|
|
grid: {
|
|
color: "#334155",
|
|
},
|
|
},
|
|
x: {
|
|
ticks: {
|
|
color: "#e2e8f0",
|
|
},
|
|
grid: {
|
|
display: false,
|
|
},
|
|
},
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
display: false,
|
|
},
|
|
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`;
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
</script>
|