130 lines
3.1 KiB
Vue
130 lines
3.1 KiB
Vue
<template>
|
|
<v-row>
|
|
<v-col cols="12">
|
|
<v-card>
|
|
<v-card-item>
|
|
<v-card-title>Balance sheet</v-card-title>
|
|
</v-card-item>
|
|
<v-card-text>
|
|
<v-skeleton-loader class="chart-loader" v-if="balanceSheet.loading" />
|
|
<ag-charts-vue class="chart" v-else :options="options" />
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { BalanceSheet, EmployeeCount, getBalanceSheet } from '@/api';
|
|
import { defineLoader } from '@/api/loader';
|
|
import { AgAxisLabelFormatterParams, 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 balanceSheet = defineLoader<BalanceSheet[]>(() => getBalanceSheet(props.tickers));
|
|
|
|
const options = computed(() => {
|
|
if (balanceSheet.loading) return null;
|
|
|
|
const currencyFormat = (num: number) => {
|
|
return '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
|
|
}
|
|
|
|
const renderer = (params: any) => {
|
|
return {
|
|
title: params.title,
|
|
content: params.xValue + ': ' + currencyFormat(params.yKey.startsWith('old') ?
|
|
(params.datum[params.yKey.replace('old', 'total')]) :
|
|
(params.yValue)),
|
|
}
|
|
};
|
|
|
|
return {
|
|
theme: 'ag-material',
|
|
data: balanceSheet.data,
|
|
series: [
|
|
{
|
|
type: 'column',
|
|
xKey: 'ticker',
|
|
yKey: 'current_assets',
|
|
yName: 'Current Assets',
|
|
stackGroup: 'Assets',
|
|
fill: '#004D40',
|
|
stroke: '#004D40'
|
|
},
|
|
{
|
|
type: 'column',
|
|
xKey: 'ticker',
|
|
yKey: 'old_assets',
|
|
yName: 'Total Assets',
|
|
stackGroup: 'Assets',
|
|
fill: '#4DB6AC',
|
|
stroke: '#4DB6AC'
|
|
},
|
|
{
|
|
type: 'column',
|
|
xKey: 'ticker',
|
|
yKey: 'current_debt',
|
|
yName: 'Current Debt',
|
|
stackGroup: 'Debt',
|
|
fill: '#880E4F',
|
|
stroke: '#880E4F'
|
|
},
|
|
{
|
|
type: 'column',
|
|
xKey: 'ticker',
|
|
yKey: 'old_debt',
|
|
yName: 'Total Debt',
|
|
stackGroup: 'Debt',
|
|
fill: '#F06292',
|
|
stroke: '#F06292'
|
|
}
|
|
].map(e => ({
|
|
...e,
|
|
highlightStyle: {
|
|
item: { fillOpacity: 0 },
|
|
series: { enabled: false }
|
|
},
|
|
tooltip: { renderer: renderer },
|
|
})),
|
|
axes: [
|
|
{
|
|
type: 'category',
|
|
position: 'bottom',
|
|
},
|
|
{
|
|
type: 'number',
|
|
position: 'left',
|
|
label: {
|
|
format: '$~s',
|
|
formatter: (params: AgAxisLabelFormatterParams) =>
|
|
params?.formatter?.(params.value)
|
|
.replace('k', 'K')
|
|
.replace('G', 'B') ?? ''
|
|
},
|
|
},
|
|
],
|
|
legend: {
|
|
position: 'bottom',
|
|
},
|
|
};
|
|
});
|
|
|
|
onMounted(() => {
|
|
balanceSheet.load();
|
|
});
|
|
</script> |