Files
FlightsAPI/resources/js/Components/FlightsGoneBy/Charts/FlightClassChart.vue
T

90 lines
2.4 KiB
Vue

<template>
<FlightChart
title="Flight Classes"
v-if="series.length"
type="donut"
height="280"
:options="chartOptions"
:series="seriesData"
/>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { Flight } from '@/Types/types'
import FlightChart from "@/Components/FlightsGoneBy/FlightChart.vue";
const props = defineProps<{
flights: Flight[]
}>()
const series = computed(() => {
const counts = new Map<string, number>()
props.flights.forEach(f => {
const cls = f.flight_class?.name ?? 'Unknown'
counts.set(cls, (counts.get(cls) ?? 0) + 1)
})
return [...counts.entries()]
.sort((a, b) => b[1] - a[1])
.map(([name, count]) => ({ name, count }))
})
const seriesData = computed(() => series.value.map(s => s.count))
const chartOptions = computed(() => ({
chart: {
type: 'donut',
background: 'transparent',
fontFamily: 'inherit',
},
theme: { mode: 'dark' },
labels: series.value.map(s => s.name),
colors: ['#4da6ff', '#ffc107', '#a150d5', '#22c55e', '#f97316', '#e11d48', '#06b6d4'],
dataLabels: {
enabled: true,
formatter: (val: number) => `${Math.round(val)}%`,
style: { fontSize: '12px', fontWeight: 400 },
dropShadow: { enabled: false },
},
plotOptions: {
pie: {
donut: {
size: '60%',
labels: {
show: true,
total: {
show: true,
label: 'Total',
fontSize: '13px',
color: '#556677',
formatter: () => props.flights.length.toString(),
},
value: {
fontSize: '22px',
fontWeight: 500,
color: '#e0e6f0',
},
},
},
},
},
legend: {
position: 'bottom',
labels: { colors: '#778899' },
markers: { width: 8, height: 8, radius: 2 },
itemMargin: { horizontal: 12, vertical: 4 },
},
stroke: { width: 0 },
tooltip: {
theme: 'dark',
y: {
formatter: (val: number) => `${val} flights`,
},
},
}))
</script>
<style scoped>
</style>