update income, balance, cashflow and ratios page
This commit is contained in:
parent
7013a83ba0
commit
99cf78c22d
@ -6,9 +6,9 @@ import { abbreviateNumber,sumQuarterlyResultsByYear } from '$lib/utils';
|
||||
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart, BarChart } from 'echarts/charts'
|
||||
import { GridComponent } from 'echarts/components'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
use([LineChart, BarChart, GridComponent, CanvasRenderer])
|
||||
use([LineChart, BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
|
||||
|
||||
export let data;
|
||||
@ -16,7 +16,8 @@ use([LineChart, BarChart, GridComponent, CanvasRenderer])
|
||||
|
||||
|
||||
let balanceSheet = [];
|
||||
let fullStatement = []
|
||||
let fullStatement = [];
|
||||
let tableList = [];
|
||||
let filterRule = 'annual';
|
||||
let optionsData;
|
||||
|
||||
@ -24,7 +25,7 @@ use([LineChart, BarChart, GridComponent, CanvasRenderer])
|
||||
let displayStatement = 'cashAndCashEquivalents';
|
||||
|
||||
|
||||
let mode = false;
|
||||
let mode = true;
|
||||
let timeFrame = '10Y';
|
||||
|
||||
|
||||
@ -234,7 +235,7 @@ function normalizer(value) {
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
let growthList = [];
|
||||
tableList = [];
|
||||
|
||||
const index = statementConfig?.findIndex((item) => item?.propertyName === displayStatement);
|
||||
|
||||
@ -242,15 +243,28 @@ function normalizer(value) {
|
||||
const statement = balanceSheet[i];
|
||||
const year = statement?.calendarYear?.slice(-2);
|
||||
const quarter = statement?.period;
|
||||
|
||||
// Determine the label based on filterRule
|
||||
if (filterRule === 'annual') {
|
||||
xList?.push('FY'+year);
|
||||
xList.push('FY' + year);
|
||||
} else {
|
||||
xList?.push('FY'+year+' '+quarter);
|
||||
xList.push('FY' + year + ' ' + quarter);
|
||||
}
|
||||
|
||||
valueList?.push((Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2));
|
||||
growthList?.push((Number(statement[statementConfig[index]?.growthPropertyName]) * 100)?.toFixed(2));
|
||||
|
||||
// Calculate the value and growth
|
||||
const value = (Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2);
|
||||
|
||||
valueList.push(value);
|
||||
|
||||
// Add the entry to tableList
|
||||
tableList.push({
|
||||
'date': statement?.date,
|
||||
'value': value,
|
||||
});
|
||||
}
|
||||
|
||||
//sort tableList by date
|
||||
tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date));
|
||||
|
||||
labelName =statementConfig[index]?.label;
|
||||
|
||||
@ -259,66 +273,55 @@ function normalizer(value) {
|
||||
|
||||
|
||||
const options = {
|
||||
xAxis: {
|
||||
data: xList,
|
||||
type: 'category',
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '0%',
|
||||
right: '0%',
|
||||
bottom: '2%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
},
|
||||
data: xList,
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#6E7079', // Change label color to white
|
||||
formatter: function (value) {
|
||||
value = Math.max(value, 0);
|
||||
return '$'+(value / denominator)?.toFixed(1) + unit; // Format value in millions
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
axisLabel: {
|
||||
color: '#fff', // Change label color to white
|
||||
formatter: function (value) {
|
||||
value = Math.max(value, 0);
|
||||
return '$'+(value / denominator)?.toFixed(1) + unit; // Format value in millions
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: '{value} %',
|
||||
},
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: labelName,
|
||||
data: valueList,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: 'Growth Rate [%]',
|
||||
data: growthList,
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: (params) => {
|
||||
// Set color based on positive or negative value
|
||||
return params.data >= 0 ? '#10DB06' : '#FF2F1F';
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: labelName,
|
||||
data: valueList,
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100,
|
||||
},
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
@ -564,10 +567,69 @@ $: {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app w-full h-[300px] m-auto">
|
||||
<div class="app w-full">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="mt-5 text-2xl text-gray-200 font-semibold">
|
||||
{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label} History
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="w-full overflow-x-scroll">
|
||||
<table class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4 ">
|
||||
<thead>
|
||||
<tr class="border border-slate-800">
|
||||
<th class="text-white font-semibold text-start text-sm sm:text-[1rem]">{filterRule === 'annual' ? 'Fiscal Year End' : 'Quarter Ends'}</th>
|
||||
<th class="text-white font-semibold text-sm sm:text-[1rem]">{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label}</th>
|
||||
<th class="text-white font-semibold text-center text-sm sm:text-[1rem]">Change</th>
|
||||
<th class="text-white font-semibold text-end text-sm sm:text-[1rem]">Growth</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tableList as item, index}
|
||||
<!-- row -->
|
||||
<tr class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] border-b-[#09090B] shake-ticker cursor-pointer">
|
||||
|
||||
<td class="text-white font-medium text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{item?.date}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{abbreviateNumber(item?.value)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-center border-b-[#09090B]">
|
||||
{item?.value-tableList[index+1]?.value !== 0 ? abbreviateNumber((item?.value-tableList[index+1]?.value)?.toFixed(2)) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-end border-b-[#09090B]">
|
||||
{#if index+1-tableList?.length === 0}
|
||||
-
|
||||
{:else}
|
||||
{#if (item?.value- tableList[index+1]?.value) > 0}
|
||||
<span class="text-[#10DB06]">
|
||||
+{(((item?.value-tableList[index+1]?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else if (item?.value - tableList[index+1]?.value ) < 0}
|
||||
<span class="text-[#FF2F1F]">
|
||||
-{(((tableList[index+1]?.value - item?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
|
||||
@ -947,16 +1009,16 @@ $: {
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
<style>
|
||||
.app {
|
||||
height: 500px;
|
||||
max-width: 1500px;
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.app {
|
||||
max-width: 520px;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,9 +6,9 @@ import { Chart } from 'svelte-echarts'
|
||||
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart, BarChart } from 'echarts/charts'
|
||||
import { GridComponent } from 'echarts/components'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
use([LineChart, BarChart, GridComponent, CanvasRenderer])
|
||||
use([LineChart, BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
|
||||
|
||||
export let data;
|
||||
@ -23,7 +23,9 @@ let filterRule = 'annual';
|
||||
let displayStatement = 'netIncome';
|
||||
|
||||
|
||||
let mode = false;
|
||||
let mode = true;
|
||||
let tableList = [];
|
||||
|
||||
let timeFrame = '10Y';
|
||||
|
||||
const statementConfig = [
|
||||
@ -195,97 +197,101 @@ function normalizer(value) {
|
||||
}
|
||||
|
||||
function plotData()
|
||||
{
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
let growthList = [];
|
||||
{
|
||||
|
||||
const index = statementConfig?.findIndex((item) => item?.propertyName === displayStatement);
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
tableList = [];
|
||||
|
||||
const index = statementConfig?.findIndex((item) => item?.propertyName === displayStatement);
|
||||
|
||||
for (let i = cashFlow?.length - 1; i >= 0; i--) {
|
||||
const statement = cashFlow[i];
|
||||
const year = statement?.calendarYear?.slice(-2);
|
||||
const quarter = statement?.period;
|
||||
|
||||
for (let i = cashFlow?.length - 1; i >= 0; i--) {
|
||||
const statement = cashFlow[i];
|
||||
const year = statement?.calendarYear?.slice(-2);
|
||||
const quarter = statement?.period;
|
||||
if (filterRule === 'annual') {
|
||||
xList?.push('FY'+year);
|
||||
} else {
|
||||
xList?.push('FY'+year+' '+quarter);
|
||||
// Determine the label based on filterRule
|
||||
if (filterRule === 'annual') {
|
||||
xList.push('FY' + year);
|
||||
} else {
|
||||
xList.push('FY' + year + ' ' + quarter);
|
||||
}
|
||||
|
||||
// Calculate the value and growth
|
||||
const value = (Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2);
|
||||
|
||||
valueList.push(value);
|
||||
|
||||
// Add the entry to tableList
|
||||
tableList.push({
|
||||
'date': statement?.date,
|
||||
'value': value,
|
||||
});
|
||||
}
|
||||
|
||||
valueList.push((Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2));
|
||||
growthList.push((Number(statement[statementConfig[index]?.growthPropertyName]) * 100)?.toFixed(2));
|
||||
}
|
||||
|
||||
labelName =statementConfig[index].label;
|
||||
const {unit, denominator } = normalizer(Math.max(...valueList) ?? 0)
|
||||
|
||||
|
||||
|
||||
const options = {
|
||||
xAxis: {
|
||||
data: xList,
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
//sort tableList by date
|
||||
tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date));
|
||||
|
||||
labelName =statementConfig[index]?.label;
|
||||
|
||||
|
||||
const {unit, denominator } = normalizer(Math.max(...valueList) ?? 0)
|
||||
|
||||
|
||||
const options = {
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '0%',
|
||||
right: '0%',
|
||||
bottom: '2%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
axisLabel: {
|
||||
color: '#6E7079', // Change label color to white
|
||||
formatter: function (value) {
|
||||
value = Math.max(value, 0);
|
||||
return '$'+(value / denominator)?.toFixed(1) + unit; // Format value in millions
|
||||
color: '#fff',
|
||||
},
|
||||
data: xList,
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff', // Change label color to white
|
||||
formatter: function (value) {
|
||||
value = Math.max(value, 0);
|
||||
return '$'+(value / denominator)?.toFixed(1) + unit; // Format value in millions
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: '{value} %',
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: labelName,
|
||||
data: valueList,
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
},
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: labelName,
|
||||
data: valueList,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: 'Growth Rate [%]',
|
||||
data: growthList,
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: (params) => {
|
||||
// Set color based on positive or negative value
|
||||
return params.data >= 0 ? '#10DB06' : '#FF2F1F';
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/*
|
||||
const exportData = (format = 'csv') => {
|
||||
@ -521,10 +527,64 @@ $: {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app w-full h-[300px] m-auto">
|
||||
<div class="app w-full">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
<div class="w-full overflow-x-scroll">
|
||||
<table class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4 ">
|
||||
<thead>
|
||||
<tr class="border border-slate-800">
|
||||
<th class="text-white font-semibold text-start text-sm sm:text-[1rem]">{filterRule === 'annual' ? 'Fiscal Year End' : 'Quarter Ends'}</th>
|
||||
<th class="text-white font-semibold text-sm sm:text-[1rem]">{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label}</th>
|
||||
<th class="text-white font-semibold text-center text-sm sm:text-[1rem]">Change</th>
|
||||
<th class="text-white font-semibold text-end text-sm sm:text-[1rem]">Growth</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tableList as item, index}
|
||||
<!-- row -->
|
||||
<tr class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] border-b-[#09090B] shake-ticker cursor-pointer">
|
||||
|
||||
<td class="text-white font-medium text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{item?.date}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{abbreviateNumber(item?.value)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-center border-b-[#09090B]">
|
||||
{item?.value-tableList[index+1]?.value !== 0 ? abbreviateNumber((item?.value-tableList[index+1]?.value)?.toFixed(2)) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-end border-b-[#09090B]">
|
||||
{#if index+1-tableList?.length === 0}
|
||||
-
|
||||
{:else}
|
||||
{#if (item?.value- tableList[index+1]?.value) > 0}
|
||||
<span class="text-[#10DB06]">
|
||||
+{(((item?.value-tableList[index+1]?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else if (item?.value - tableList[index+1]?.value ) < 0}
|
||||
<span class="text-[#FF2F1F]">
|
||||
-{(((tableList[index+1]?.value - item?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
|
||||
@ -859,16 +919,17 @@ $: {
|
||||
-->
|
||||
<!--End Export-->
|
||||
|
||||
<style>
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 500px;
|
||||
max-width: 1500px;
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.app {
|
||||
max-width: 520px;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +175,6 @@ function plotData()
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
let growthList = [];
|
||||
tableList = [];
|
||||
|
||||
|
||||
@ -195,10 +194,8 @@ function plotData()
|
||||
|
||||
// Calculate the value and growth
|
||||
const value = (Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2);
|
||||
const growth = (Number(statement[statementConfig[index]?.growthPropertyName]) * 100)?.toFixed(2);
|
||||
|
||||
valueList.push(value);
|
||||
growthList.push(growth);
|
||||
|
||||
// Add the entry to tableList
|
||||
tableList.push({
|
||||
@ -211,16 +208,7 @@ function plotData()
|
||||
tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date));
|
||||
|
||||
|
||||
if(['growthSellingGeneralAndAdministrativeExpenses']?.includes(statementConfig[index]?.growthPropertyName))
|
||||
{ growthList = [];
|
||||
// Calculate growth percentage and append to growthList
|
||||
for (let i = 1; i < valueList?.length; i++) {
|
||||
let growth = ((valueList[i] - valueList[i - 1]) / valueList[i - 1]) * 100;
|
||||
growthList?.push(growth?.toFixed(2));
|
||||
}
|
||||
growthList?.unshift("0")
|
||||
}
|
||||
|
||||
|
||||
labelName = statementConfig[index]?.label;
|
||||
|
||||
|
||||
@ -518,19 +506,19 @@ const exportData = (format = 'csv') => {
|
||||
</div>
|
||||
|
||||
|
||||
<h1 class="mt-5 text-2xl text-gray-200 font-semibold">
|
||||
<h2 class="mt-5 text-2xl text-gray-200 font-semibold">
|
||||
{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label} History
|
||||
</h1>
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="w-full overflow-x-scroll">
|
||||
<table class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4 ">
|
||||
<thead>
|
||||
<tr class="border border-slate-800">
|
||||
<th class="text-white font-semibold text-start text-[1rem]">{filterRule === 'annual' ? 'Fiscal Year End' : 'Quarter Ends'}</th>
|
||||
<th class="text-white font-semibold text-[1rem]">{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label}</th>
|
||||
<th class="text-white font-semibold text-center text-[1rem]">Change</th>
|
||||
<th class="text-white font-semibold text-end text-[1rem]">Growth</th>
|
||||
<th class="text-white font-semibold text-start text-sm sm:text-[1rem]">{filterRule === 'annual' ? 'Fiscal Year End' : 'Quarter Ends'}</th>
|
||||
<th class="text-white font-semibold text-sm sm:text-[1rem]">{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label}</th>
|
||||
<th class="text-white font-semibold text-center text-sm sm:text-[1rem]">Change</th>
|
||||
<th class="text-white font-semibold text-end text-sm sm:text-[1rem]">Growth</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -543,7 +531,7 @@ const exportData = (format = 'csv') => {
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{abbreviateNumber(item?.value,true)}
|
||||
{abbreviateNumber(item?.value)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-center border-b-[#09090B]">
|
||||
@ -575,7 +563,7 @@ const exportData = (format = 'csv') => {
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{:else}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import {numberOfUnreadNotification, displayCompanyName, stockTicker} from '$lib/store';
|
||||
import { sumQuarterlyResultsByYear } from '$lib/utils';
|
||||
import { sumQuarterlyResultsByYear, abbreviateNumber } from '$lib/utils';
|
||||
//import * as XLSX from 'xlsx';
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart, BarChart } from 'echarts/charts'
|
||||
import { GridComponent } from 'echarts/components'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
use([LineChart, BarChart, GridComponent, CanvasRenderer])
|
||||
use([LineChart, BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ export let data;
|
||||
|
||||
let ratios = [];
|
||||
let fullStatement = []
|
||||
let tableList = [];
|
||||
|
||||
let filterRule = 'annual';
|
||||
let optionsData;
|
||||
|
||||
@ -26,7 +28,7 @@ let optionsData;
|
||||
let displayStatement = 'priceEarningsRatio';
|
||||
|
||||
|
||||
let mode = false;
|
||||
let mode = true;
|
||||
let timeFrame = '10Y';
|
||||
|
||||
|
||||
@ -144,62 +146,60 @@ function changeStatement(event)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function plotData()
|
||||
{
|
||||
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
let growthList = [];
|
||||
{
|
||||
|
||||
const index = statementConfig?.findIndex((item) => item?.propertyName === displayStatement);
|
||||
|
||||
for (let i = ratios.length - 1; i >= 0; i--) {
|
||||
const statement = ratios[i];
|
||||
const year = statement?.calendarYear?.slice(-2);
|
||||
const quarter = statement?.period;
|
||||
if (filterRule === 'annual') {
|
||||
xList?.push('FY'+year);
|
||||
} else {
|
||||
xList?.push('FY'+year+' '+quarter);
|
||||
}
|
||||
|
||||
if(['returnOnEquity','returnOnAssets','returnOnCapital','dividendYield','payoutRatio','grossProfitMargin','netProfitMargin']?.includes(statementConfig[index]?.propertyName))
|
||||
{
|
||||
valueList.push((Number(statement[statementConfig[index]?.propertyName]) * 100)?.toFixed(2));
|
||||
}
|
||||
else {
|
||||
valueList.push((Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2));
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate growth percentage and append to growthList
|
||||
for (let i = 1; i < valueList.length; i++) {
|
||||
// Declare a variable to hold the growth rate.
|
||||
let growth;
|
||||
|
||||
// Check if the current value is negative and the previous value is positive.
|
||||
if (valueList[i] < 0 && valueList[i - 1] > 0 || valueList[i] < 0 && valueList[i - 1] < 0) {
|
||||
// Calculate the growth rate using the adjusted formula.
|
||||
growth = (1 - (valueList[i] / valueList[i - 1])) * 100;
|
||||
} else {
|
||||
// Calculate the growth rate using the standard formula.
|
||||
growth = (Math?.abs(valueList[i] / valueList[i - 1]) - 1) * 100;
|
||||
}
|
||||
let labelName = '-';
|
||||
let xList = [];
|
||||
let valueList = [];
|
||||
tableList = [];
|
||||
|
||||
// Format the growth rate to two decimal places and add it to the growthList.
|
||||
growthList.push(growth?.toFixed(2));
|
||||
}
|
||||
const index = statementConfig?.findIndex((item) => item?.propertyName === displayStatement);
|
||||
|
||||
growthList?.unshift("0")
|
||||
labelName =statementConfig[index]?.label;
|
||||
for (let i = ratios?.length - 1; i >= 0; i--) {
|
||||
const statement = ratios[i];
|
||||
const year = statement?.calendarYear?.slice(-2);
|
||||
const quarter = statement?.period;
|
||||
|
||||
// Determine the label based on filterRule
|
||||
if (filterRule === 'annual') {
|
||||
xList.push('FY' + year);
|
||||
} else {
|
||||
xList.push('FY' + year + ' ' + quarter);
|
||||
}
|
||||
|
||||
// Calculate the value and growth
|
||||
const value = (Number(statement[statementConfig[index]?.propertyName]))?.toFixed(2);
|
||||
|
||||
valueList.push(value);
|
||||
|
||||
// Add the entry to tableList
|
||||
tableList.push({
|
||||
'date': statement?.date,
|
||||
'value': value,
|
||||
});
|
||||
}
|
||||
|
||||
const options = {
|
||||
//sort tableList by date
|
||||
tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date));
|
||||
|
||||
labelName =statementConfig[index]?.label;
|
||||
|
||||
|
||||
const options = {
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '0%',
|
||||
right: '0%',
|
||||
bottom: '2%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
},
|
||||
data: xList,
|
||||
type: 'category',
|
||||
},
|
||||
@ -210,7 +210,7 @@ function plotData()
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#6E7079', // Change label color to white
|
||||
color: '#fff', // Change label color to white
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -219,46 +219,23 @@ function plotData()
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: '{value} %',
|
||||
},
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: `${labelName}`,
|
||||
name: labelName,
|
||||
data: valueList,
|
||||
type: 'line',
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: 'Growth Rate [%]',
|
||||
data: growthList,
|
||||
type: 'bar',
|
||||
smooth: true,
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: (params) => {
|
||||
// Set color based on positive or negative value
|
||||
return params.data >= 0 ? '#10DB06' : '#FF2F1F';
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
hideDelay: 100,
|
||||
},
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/*
|
||||
const exportData = (format = 'csv') => {
|
||||
@ -486,10 +463,64 @@ $: {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app w-full h-[300px] m-auto">
|
||||
<div class="app w-full">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
<div class="w-full overflow-x-scroll">
|
||||
<table class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4 ">
|
||||
<thead>
|
||||
<tr class="border border-slate-800">
|
||||
<th class="text-white font-semibold text-start text-sm sm:text-[1rem]">{filterRule === 'annual' ? 'Fiscal Year End' : 'Quarter Ends'}</th>
|
||||
<th class="text-white font-semibold text-sm sm:text-[1rem]">{statementConfig?.find((item) => item?.propertyName === displayStatement)?.label}</th>
|
||||
<th class="text-white font-semibold text-center text-sm sm:text-[1rem]">Change</th>
|
||||
<th class="text-white font-semibold text-end text-sm sm:text-[1rem]">Growth</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tableList as item, index}
|
||||
<!-- row -->
|
||||
<tr class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] border-b-[#09090B] shake-ticker cursor-pointer">
|
||||
|
||||
<td class="text-white font-medium text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{item?.date}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap border-b-[#09090B]">
|
||||
{abbreviateNumber(item?.value)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-center border-b-[#09090B]">
|
||||
{item?.value-tableList[index+1]?.value !== 0 ? abbreviateNumber((item?.value-tableList[index+1]?.value)?.toFixed(2)) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap font-medium text-end border-b-[#09090B]">
|
||||
{#if index+1-tableList?.length === 0}
|
||||
-
|
||||
{:else}
|
||||
{#if (item?.value- tableList[index+1]?.value) > 0}
|
||||
<span class="text-[#10DB06]">
|
||||
+{(((item?.value-tableList[index+1]?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else if (item?.value - tableList[index+1]?.value ) < 0}
|
||||
<span class="text-[#FF2F1F]">
|
||||
-{(((tableList[index+1]?.value - item?.value) / item?.value) * 100 )?.toFixed(2)}%
|
||||
</span>
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
|
||||
@ -838,16 +869,17 @@ $: {
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 500px;
|
||||
max-width: 1500px;
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.app {
|
||||
max-width: 520px;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user