From f458c051b1ffc5cfdf8c7a3d9738bef2be145475 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Thu, 20 Feb 2025 20:47:28 +0100 Subject: [PATCH] bugfixing --- src/routes/pricing/+page.svelte | 10 +- .../profile/employees/+layout.svelte | 74 +-- .../[tickerID]/profile/employees/+page.svelte | 31 +- .../statistics/market-cap/+page.svelte | 20 +- .../statistics/revenue/+page.server.ts | 6 +- .../statistics/revenue/+page.svelte | 513 ++++-------------- 6 files changed, 166 insertions(+), 488 deletions(-) diff --git a/src/routes/pricing/+page.svelte b/src/routes/pricing/+page.svelte index 4818531c..b0dda56b 100644 --- a/src/routes/pricing/+page.svelte +++ b/src/routes/pricing/+page.svelte @@ -74,6 +74,11 @@ } + + - -
diff --git a/src/routes/stocks/[tickerID]/profile/employees/+layout.svelte b/src/routes/stocks/[tickerID]/profile/employees/+layout.svelte index 397bcdc2..4fccc659 100644 --- a/src/routes/stocks/[tickerID]/profile/employees/+layout.svelte +++ b/src/routes/stocks/[tickerID]/profile/employees/+layout.svelte @@ -61,53 +61,57 @@ Company Employees {#each similarStocks?.slice(0, 8) as item, index} - {item?.name?.length > 30 - ? item?.name?.slice(0, 30) + "..." - : item?.name} - {item?.employees !== null && - item?.employees !== undefined - ? parseFloat(item?.employees).toLocaleString( - "en-US", - { - maximumFractionDigits: 2, - minimumFractionDigits: 0, - }, - ) - : "n/a"} - + {#if item?.name} + {item?.name?.length > 30 + ? item?.name?.slice(0, 30) + "..." + : item?.name} + {item?.employees !== null && + item?.employees !== undefined + ? parseFloat(item?.employees).toLocaleString( + "en-US", + { + maximumFractionDigits: 2, + minimumFractionDigits: 0, + }, + ) + : "n/a"} + + {/if} {/each} - - Employee Rankings - + {/if} diff --git a/src/routes/stocks/[tickerID]/profile/employees/+page.svelte b/src/routes/stocks/[tickerID]/profile/employees/+page.svelte index 9552bbb3..f3c3dd11 100644 --- a/src/routes/stocks/[tickerID]/profile/employees/+page.svelte +++ b/src/routes/stocks/[tickerID]/profile/employees/+page.svelte @@ -1,9 +1,5 @@ - {#if Number(item?.employeeCount - historyList[index + 1]?.employeeCount)} - {new Intl.NumberFormat("en")?.format( + {new Intl.NumberFormat("en").format( item?.employeeCount - historyList[index + 1]?.employeeCount, )} @@ -664,25 +659,27 @@ - {#if index + 1 - historyList?.length === 0} + {#if index === historyList?.length - 1} n/a - {:else if item?.employeeCount - historyList[index + 1]?.employeeCount > 0} + {:else if item?.employeeCount > historyList[index + 1]?.employeeCount} +{( ((item?.employeeCount - historyList[index + 1]?.employeeCount) / - item?.employeeCount) * + historyList[index + 1]?.employeeCount) * 100 - )?.toFixed(2)}% + ).toFixed(2)}% - {:else if item?.employeeCount - historyList[index + 1]?.employeeCount < 0} + {:else if item?.employeeCount < historyList[index + 1]?.employeeCount} -{( - ((historyList[index + 1]?.employeeCount - - item?.employeeCount) / - item?.employeeCount) * + (Math.abs( + item?.employeeCount - + historyList[index + 1]?.employeeCount, + ) / + historyList[index + 1]?.employeeCount) * 100 - )?.toFixed(2)}% + ).toFixed(2)}% {:else} n/a diff --git a/src/routes/stocks/[tickerID]/statistics/market-cap/+page.svelte b/src/routes/stocks/[tickerID]/statistics/market-cap/+page.svelte index aaf93112..ef589e14 100644 --- a/src/routes/stocks/[tickerID]/statistics/market-cap/+page.svelte +++ b/src/routes/stocks/[tickerID]/statistics/market-cap/+page.svelte @@ -711,29 +711,29 @@ - {#if index + 1 - tableList?.length === 0} - - - {:else if item?.marketCap - tableList[index + 1]?.marketCap > 0} + {#if index === tableList?.length - 1} + n/a + {:else if item?.marketCap > tableList[index + 1]?.marketCap} +{( ((item?.marketCap - tableList[index + 1]?.marketCap) / - item?.marketCap) * + tableList[index + 1]?.marketCap) * 100 )?.toFixed(2)}% - {:else if item?.marketCap - tableList[index + 1]?.marketCap < 0} + {:else if item?.marketCap < tableList[index + 1]?.marketCap} -{( - Math?.abs( - (tableList[index + 1]?.marketCap - - item?.marketCap) / - item?.marketCap, + Math.abs( + (item?.marketCap - + tableList[index + 1]?.marketCap) / + tableList[index + 1]?.marketCap, ) * 100 )?.toFixed(2)}% {:else} - - + n/a {/if} diff --git a/src/routes/stocks/[tickerID]/statistics/revenue/+page.server.ts b/src/routes/stocks/[tickerID]/statistics/revenue/+page.server.ts index af090b24..87dd329c 100644 --- a/src/routes/stocks/[tickerID]/statistics/revenue/+page.server.ts +++ b/src/routes/stocks/[tickerID]/statistics/revenue/+page.server.ts @@ -1,12 +1,12 @@ export const load = async ({ locals, params }) => { - const getHistoricalMarketCap = async () => { + const getHistoricalRevenue = async () => { const { apiKey, apiURL } = locals; const postData = { ticker: params.tickerID, }; // make the POST request to the endpoint - const response = await fetch(apiURL + "/historical-market-cap", { + const response = await fetch(apiURL + "/historical-revenue", { method: "POST", headers: { "Content-Type": "application/json", @@ -24,6 +24,6 @@ export const load = async ({ locals, params }) => { // Make sure to return a promise return { - getHistoricalMarketCap: await getHistoricalMarketCap(), + getHistoricalRevenue: await getHistoricalRevenue(), }; }; diff --git a/src/routes/stocks/[tickerID]/statistics/revenue/+page.svelte b/src/routes/stocks/[tickerID]/statistics/revenue/+page.svelte index aaf93112..71b0065a 100644 --- a/src/routes/stocks/[tickerID]/statistics/revenue/+page.svelte +++ b/src/routes/stocks/[tickerID]/statistics/revenue/+page.svelte @@ -18,11 +18,10 @@ export let data; - let optionsData; + let optionsData = null; - let rawData = data?.getHistoricalMarketCap || []; + let rawData = data?.getHistoricalRevenue || {}; let tableList = []; - let changePercentageYearAgo = 0; let timePeriod = "3Y"; const tabs = [ @@ -35,229 +34,22 @@ ]; let activeIdx = 0; - function getMarketCapCategory(marketCap) { - const BILLION = 1_000_000_000; - const MILLION = 1_000_000; - - const marketCapNavigation = [ - { - threshold: 200 * BILLION, - name: "Mega-Cap", - link: "/list/market-cap/mega-cap-stocks", - }, - { - minThreshold: 10 * BILLION, - maxThreshold: 200 * BILLION, - name: "Large-Cap", - link: "/list/market-cap/large-cap-stocks", - }, - { - minThreshold: 2 * BILLION, - maxThreshold: 10 * BILLION, - name: "Mid-Cap", - link: "/list/market-cap/mid-cap-stocks", - }, - { - minThreshold: 300 * MILLION, - maxThreshold: 2 * BILLION, - name: "Small-Cap", - link: "/list/market-cap/small-cap-stocks", - }, - { - minThreshold: 50 * MILLION, - maxThreshold: 300 * MILLION, - name: "Micro-Cap", - link: "/list/market-cap/micro-cap-stocks", - }, - { - maxThreshold: 50 * MILLION, - name: "Nano-Cap", - link: "/list/market-cap/nano-cap-stocks", - }, - ]; - - if (!marketCap) return null; - - // Convert string to number if needed - const capValue = - typeof marketCap === "string" ? parseFloat(marketCap) : marketCap; - - return marketCapNavigation.find((category) => { - if (category.threshold) { - return capValue >= category.threshold; - } - if (category.minThreshold && category.maxThreshold) { - return ( - capValue >= category.minThreshold && capValue < category.maxThreshold - ); - } - if (category.maxThreshold) { - return capValue < category.maxThreshold; - } - return false; - }); - } - - function computeYearOverYearChange(rawData) { - if (rawData.length < 2) { - return null; // Not enough rawData to compute change - } - - // Step 1: Get the last entry in the list - const lastEntry = rawData[rawData.length - 1]; - const lastDate = new Date(lastEntry.date); - const lastMarketCap = data?.getStockQuote?.marketCap; - - // Step 2: Find the entry closest to one year before the last date - let closestEntry = null; - for (let i = rawData.length - 2; i >= 0; i--) { - const entryDate = new Date(rawData[i].date); - const oneYearAgo = new Date(lastDate); - oneYearAgo.setFullYear(lastDate.getFullYear() - 1); - - // Check if the entry is close to one year ago - if (entryDate <= oneYearAgo) { - closestEntry = rawData[i]; - break; - } - } - - if (!closestEntry) { - return null; // No suitable entry found for comparison - } - - const previousMarketCap = closestEntry.marketCap; - - // Step 3: Calculate the percentage change - const change = - ((lastMarketCap - previousMarketCap) / previousMarketCap) * 100; - - return change; - } - - function filterEndOfYearDates(data) { - // Step 1: Group data by year - const groupedByYear = data.reduce((acc, item) => { - const year = new Date(item.date).getFullYear(); - if (!acc[year]) { - acc[year] = []; - } - acc[year].push(item); - return acc; - }, {}); - - // Step 2: For each year, find the entry with the latest date - const annualData = Object.values(groupedByYear).map((yearData) => { - return yearData.reduce((latest, current) => { - return new Date(latest.date) > new Date(current.date) - ? latest - : current; - }); - }); - - return annualData; - } - - function filterEndOfQuarterDates(data) { - // Step 1: Group data by year and quarter - const groupedByQuarter = data?.reduce((acc, item) => { - const date = new Date(item?.date); - const year = date.getFullYear(); - const quarter = Math?.floor(date?.getMonth() / 3) + 1; // Get the quarter (1-4) - - const key = `${year}-Q${quarter}`; - if (!acc[key]) { - acc[key] = []; - } - acc[key].push(item); - return acc; - }, {}); - - // Step 2: For each year-quarter group, find the entry with the latest date - const quarterlyData = Object?.values(groupedByQuarter)?.map( - (quarterData) => { - return quarterData?.reduce((latest, current) => { - return new Date(latest?.date) > new Date(current?.date) - ? latest - : current; - }); - }, - ); - - return quarterlyData; - } - function changeTablePeriod(index) { activeIdx = index; if (activeIdx === 0) { - tableList = filterEndOfYearDates(rawData); + tableList = rawData?.annual; } else { - tableList = filterEndOfQuarterDates(rawData); + tableList = rawData?.quarter; } tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date)); } - optionsData = plotData(); - tableList = filterEndOfYearDates(rawData); - tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date)); - changePercentageYearAgo = computeYearOverYearChange(rawData); - async function changeStatement(state) { timePeriod = state; optionsData = await plotData(); } - function filterDataByTimePeriod(rawData, timePeriod) { - let dates = []; - let marketCapList = []; - const now = new Date(); - - // Calculate the date threshold based on the selected time period - let thresholdDate; - switch (timePeriod) { - case "1M": - thresholdDate = new Date(now); - thresholdDate.setMonth(now.getMonth() - 1); - break; - case "6M": - thresholdDate = new Date(now); - thresholdDate.setMonth(now.getMonth() - 6); - break; - case "1Y": - thresholdDate = new Date(now); - thresholdDate.setFullYear(now.getFullYear() - 1); - break; - case "3Y": - thresholdDate = new Date(now); - thresholdDate.setFullYear(now.getFullYear() - 3); - break; - case "5Y": - thresholdDate = new Date(now); - thresholdDate.setFullYear(now.getFullYear() - 5); - break; - case "10Y": - thresholdDate = new Date(now); - thresholdDate.setFullYear(now.getFullYear() - 10); - break; - case "Max": - default: - thresholdDate = new Date(0); // Set to the earliest possible date - break; - } - - // Filter the data based on the threshold date - rawData?.forEach((item) => { - const itemDate = new Date(item?.date); - if (itemDate >= thresholdDate) { - dates?.push(item?.date); - marketCapList?.push(item?.marketCap); - } - }); - - return { dates, marketCapList }; - } - function plotData() { const filteredData = filterDataByTimePeriod(rawData, timePeriod); @@ -355,45 +147,18 @@ return options; } - const exportData = (format = "csv") => { - if (data?.user?.tier === "Pro") { - // Add headers row - const csvRows = []; - csvRows.push("date,market-cap"); - // Add data rows - const filteredData = filterDataByTimePeriod(rawData, "Max"); - const { dates, marketCapList } = filteredData; - - dates.forEach((date, index) => { - csvRows.push(`${date},${marketCapList[index]}`); - }); - - // Create CSV blob and trigger download - const csv = csvRows.join("\n"); - const blob = new Blob([csv], { type: "text/csv" }); - const url = window.URL.createObjectURL(blob); - const a = document.createElement("a"); - a.setAttribute("hidden", ""); - a.setAttribute("href", url); - a.setAttribute( - "download", - `${$stockTicker?.toLowerCase()}_market_cap.csv`, - ); - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - } else { - goto("/pricing"); + $: { + if ($stockTicker) { + tableList = rawData?.annual; + tableList?.sort((a, b) => new Date(b?.date) - new Date(a?.date)); } - }; - - $: capCategory = getMarketCapCategory(data?.getStockQuote?.marketCap); + }
@@ -410,22 +175,7 @@ {#if rawData?.length !== 0}
0 - ? "increased" - : changePercentageYearAgo < 0 - ? "decreased" - : "unchanged" - } by ${abbreviateNumber( - changePercentageYearAgo?.toFixed(2), - )}% in one year.`} + text="Apple had revenue of $124.30B in the quarter ending December 28, 2024, with 3.95% growth. This brings the company's revenue in the last twelve months to $395.76B, up 2.61% year-over-year. In the fiscal year ending September 28, 2024, Apple had annual revenue of $391.04B with 2.02% growth." />
-
- Market Cap - โ— +
+ Revenue (ttm)
- {abbreviateNumber(data?.getStockQuote?.marketCap)}
@@ -448,22 +199,14 @@
-
- Category - โ— +
+ Revenue Growth
{#if capCategory} - - {capCategory.name} - - {:else} - n/a - {/if}{rawData?.growthRevenue}%
@@ -471,30 +214,62 @@
-
- 1-Year Change - โ— +
+ Price / Sales Ratio
{changePercentageYearAgo > 100 - ? "> 100" - : changePercentageYearAgo?.toFixed(1)}%{rawData?.priceToSalesRatio} +
+
+ +
+
+ Revenue / Employee +
+
+ {abbreviateNumber( + rawData?.revenuePerEmployee, + true, + )} +
+
+ +
+
+ Employees +
+
+ {rawData?.employees?.toLocaleString("en-US")} +
+
+
+
+ Market Cap +
+
+ {abbreviateNumber(data?.getStockQuote?.marketCap)} -
- - {changePercentageYearAgo >= 0 ? "Positive" : "Negative"} - Trend - -
@@ -503,121 +278,23 @@ class="flex flex-col sm:flex-row items-start sm:items-center w-full sm:mt-10 mb-8" >

- Historical Chart + Revenue Chart

-
- - - - - - - Select time frame - - - - changeStatement("1M")} - class="cursor-pointer hover:bg-primary" - > - 1 Month - - changeStatement("6M")} - class="cursor-pointer hover:bg-primary" - > - 6 Months - - changeStatement("1Y")} - class="cursor-pointer hover:bg-primary" - > - 1 Year - - changeStatement("3Y")} - class="cursor-pointer hover:bg-primary" - > - 3 Years - - changeStatement("5Y")} - class="cursor-pointer hover:bg-primary" - > - 5 Years - - changeStatement("10Y")} - class="cursor-pointer hover:bg-primary" - > - 10 Years - - changeStatement("Max")} - class="cursor-pointer hover:bg-primary" - > - Max - - - - -
- + >
+
+ {#if optionsData !== null} +
+
-
- -
- -
+ {/if}

- Market Cap History + Revenue History

Date Market CapRevenue % Change - {@html abbreviateNumber(item?.marketCap, false, true)} + {@html abbreviateNumber(item?.revenue, false, true)} - {#if index + 1 - tableList?.length === 0} - - - {:else if item?.marketCap - tableList[index + 1]?.marketCap > 0} + {#if index === tableList?.length - 1} + n/a + {:else if item?.revenue > tableList[index + 1]?.revenue} +{( - ((item?.marketCap - - tableList[index + 1]?.marketCap) / - item?.marketCap) * + ((item?.revenue - + tableList[index + 1]?.revenue) / + tableList[index + 1]?.revenue) * 100 )?.toFixed(2)}% - {:else if item?.marketCap - tableList[index + 1]?.marketCap < 0} + {:else if item?.revenue < tableList[index + 1]?.revenue} -{( - Math?.abs( - (tableList[index + 1]?.marketCap - - item?.marketCap) / - item?.marketCap, + Math.abs( + (item?.revenue - + tableList[index + 1]?.revenue) / + tableList[index + 1]?.revenue, ) * 100 )?.toFixed(2)}% {:else} - - + n/a {/if}