This repository has been archived on 2023-06-18. You can view files and clone it, but cannot push or open issues or pull requests.
va-project/stockingly-frontend/src/components/EmployeesChart.vue

104 lines
2.4 KiB
Vue

<template>
<v-card variant="outlined">
<v-card-item>
<v-card-title>Employees over time</v-card-title>
</v-card-item>
<v-card-text>
<v-skeleton-loader class="chart-loader" v-if="employees.loading" />
<ag-charts-vue class="chart" v-else :options="options" />
</v-card-text>
</v-card>
</template>
<script setup lang="ts">
import { EmployeeCount, getEmployees } from '@/api';
import { defineLoader } from '@/api/loader';
import { time } from 'ag-charts-community';
import { DateTime } from 'luxon';
import { roundTo } from 'round-to';
import { onMounted, computed } from 'vue';
import { AgChartsVue } from 'ag-charts-vue3';
const renderer = (params: any) => ({
title: params.title,
content: DateTime.fromMillis(params.xValue).year + ': ' + roundTo(params.yValue, 0),
});
const props = defineProps<{
tickers: string[],
colors: string[]
}>();
const getTickerColor = (ticker: string) => props.colors[props.tickers.indexOf(ticker)];
const employees = defineLoader<EmployeeCount[]>(() => getEmployees(props.tickers));
const options = computed(() => {
if (employees.loading) return null;
const minDate = DateTime.utc(2012);
const maxDate = DateTime.utc(2023);
return {
theme: 'ag-material',
data: employees.data?.map(e => ({ ...e, year: Date.parse(e.year) })),
series: props.tickers.map((t: string) => ({
xKey: 'year',
yKey: t,
yName: t,
stroke: getTickerColor(t),
tooltip: { renderer: renderer },
marker: {
fill: getTickerColor(t),
stroke: getTickerColor(t)
}
})),
axes: [
{
type: 'time',
position: 'bottom',
min: minDate.toJSDate(),
max: maxDate.toJSDate(),
tick: {
interval: time.year
},
label: {
autoRotate: true,
autoRotateAngle: 335,
format: '%Y'
},
gridStyle: [{
lineDash: [Infinity]
}, {
lineDash: [Infinity]
}],
title: {
enabled: true,
text: 'Year'
},
},
{
type: 'number',
position: 'left',
min: 0,
gridStyle: [{
lineDash: [Infinity]
}, {
lineDash: [Infinity]
}],
title: {
enabled: true,
text: '# of employees'
},
},
],
legend: {
position: 'bottom',
},
};
});
onMounted(() => {
employees.load();
});
</script>