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

96 lines
2.5 KiB
Vue

<template>
<FlightChart
title="Flights per month"
type="bar"
height="220"
:options="chartOptions"
:series="series"
/>
</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[]
upcomingFlights: Flight[]
}>()
const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
const monthIndex = (f: Flight): number => {
const date = new Date(f.departure_date)
return Number(new Intl.DateTimeFormat('en', {
timeZone: f.departure_airport.timezone,
month: 'numeric',
}).format(date)) - 1 // numeric returns 1-12, convert to 0-indexed
}
const countByMonth = (list: Flight[]) =>
MONTHS.map((_, i) => list.filter(f => monthIndex(f) === i).length)
const series = computed(() => [
{ name: 'Flown', data: countByMonth(props.flights) },
{ name: 'Upcoming', data: countByMonth(props.upcomingFlights) },
])
const chartOptions = computed(() => ({
chart: {
type: 'bar',
stacked: true,
toolbar: { show: false },
background: 'transparent',
fontFamily: 'inherit',
},
theme: { mode: 'dark' },
plotOptions: {
bar: {
borderRadius: 3,
borderRadiusWhenStacked: 'last',
columnWidth: '55%',
},
},
colors: ['#4da6ff', '#ffc107'],
dataLabels: { enabled: false },
grid: {
borderColor: 'rgba(255,255,255,0.05)',
yaxis: { lines: { show: true } },
xaxis: { lines: { show: false } },
},
xaxis: {
categories: MONTHS,
axisBorder: { show: false },
axisTicks: { show: false },
labels: {
style: { colors: '#445566', fontSize: '12px' },
},
},
yaxis: {
labels: {
style: { colors: '#445566', fontSize: '12px' },
},
},
legend: {
position: 'top',
horizontalAlign: 'right',
labels: { colors: '#778899' },
markers: { width: 8, height: 8, radius: 2 },
itemMargin: { horizontal: 12 },
},
tooltip: {
theme: 'dark',
shared: true,
intersect: false,
},
states: {
hover: { filter: { type: 'lighten', value: 0.1 } },
active: { filter: { type: 'none' } },
},
}))
</script>
<style scoped>
</style>