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

100 lines
2.5 KiB
Vue

<template>
<FlightChart
title="Flights per day of week"
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 DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
// JS getDay() is 0=Sun, 1=Mon ... 6=Sat — remap to Mon-first
const dayIndex = (f: Flight): number => {
const date = new Date(f.departure_date)
const localDay = new Intl.DateTimeFormat('en', {
timeZone: f.departure_airport.timezone,
weekday: 'long',
}).format(date)
const idx = DAYS.indexOf(localDay)
return idx === -1 ? 0 : idx
}
const countByDay = (list: Flight[]) =>
DAYS.map((_, i) => list.filter(f => dayIndex(f) === i).length)
const series = computed(() => [
{ name: 'Flown', data: countByDay(props.flights) },
{ name: 'Upcoming', data: countByDay(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: DAYS,
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>