104 lines
2.4 KiB
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> |