diff --git a/src/lib/components/FinancialChart.svelte b/src/lib/components/FinancialChart.svelte index ff6b5288..5067b6a0 100644 --- a/src/lib/components/FinancialChart.svelte +++ b/src/lib/components/FinancialChart.svelte @@ -1,61 +1,27 @@ -
+{#if !isLoaded} +
+ +
+{:else} + +
+
+{/if} diff --git a/src/lib/highcharts.ts b/src/lib/highcharts.ts index 6260ef0b..f72ff679 100644 --- a/src/lib/highcharts.ts +++ b/src/lib/highcharts.ts @@ -17,6 +17,9 @@ export default (node, config) => { const createChart = () => { chart = Highcharts.chart(node, { ...config, + accessibility: { + enabled: false, + }, chart: { ...(config.chart || {}), events: { diff --git a/src/routes/stocks/[tickerID]/financials/+page.svelte b/src/routes/stocks/[tickerID]/financials/+page.svelte index 13c5e447..5d77f5e5 100644 --- a/src/routes/stocks/[tickerID]/financials/+page.svelte +++ b/src/routes/stocks/[tickerID]/financials/+page.svelte @@ -5,21 +5,20 @@ coolMode, timeFrame, } from "$lib/store"; - import { abbreviateNumber, removeCompanyStrings } from "$lib/utils"; + import { removeCompanyStrings } from "$lib/utils"; import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js"; import { Button } from "$lib/components/shadcn/button/index.js"; //import * as XLSX from 'xlsx'; import FinancialTable from "$lib/components/FinancialTable.svelte"; import FinancialChart from "$lib/components/FinancialChart.svelte"; - import { goto } from "$app/navigation"; import SEO from "$lib/components/SEO.svelte"; - import Lazy from "svelte-lazy"; export let data; let isLoaded = true; let tableList = []; + let processedData = {}; let income = []; let fullStatement = []; @@ -250,6 +249,61 @@ } }; + // Pre-process all data once instead of in each component + function preprocessFinancialData() { + processedData = {}; + + // Precompute mapping from propertyName to config for quick lookup + const configMap = {}; + statementConfig.forEach((item) => { + if (item && item.propertyName) { + configMap[item.propertyName] = item; + } + }); + + // Precompute xList from income (reverse order) + const xList = []; + for (let i = income.length - 1; i >= 0; i--) { + const statement = income[i]; + const year = statement.calendarYear.slice(-2); + const quarter = statement.period; + xList.push( + filterRule === "annual" ? "FY" + year : "FY" + year + " " + quarter, + ); + } + + // Process each field using precomputed config and xList + fields.forEach((field) => { + const statementKey = field.key; + const config = configMap[statementKey]; + if (!config) return; + + const valueList = []; + // Loop through income in reverse to match xList order + for (let i = income.length - 1; i >= 0; i--) { + const statement = income[i]; + const rawValue = Number(statement[config.propertyName]); + // Round to two decimals + const value = parseFloat(rawValue.toFixed(2)); + valueList.push(value); + } + + processedData[statementKey] = { + xList, // re-use the precomputed labels + valueList, + labelName: config.label, + }; + }); + + // Build tableList once for all charts and sort by date (newest first) + tableList = income.map((statement) => ({ + date: statement.date, + // Add more properties if needed + })); + + tableList.sort((a, b) => new Date(b.date) - new Date(a.date)); + } + $: { if ($timeFrame || activeIdx) { if (activeIdx === 0) { @@ -260,6 +314,7 @@ fullStatement = data?.getIncomeStatement?.quarter; } income = filterStatement(fullStatement, $timeFrame); + preprocessFinancialData(); } } @@ -279,66 +334,63 @@ {#if isLoaded}
-
+

{removeCompanyStrings($displayCompanyName)} Income Statement

+
+ {#each tabs as item, i} + {#if data?.user?.tier !== "Pro" && i > 0} + + {:else} + + {/if} + {/each} +
{#if income?.length > 0} -
-
- {#each tabs as item, i} - {#if data?.user?.tier !== "Pro" && i > 0} - - {:else} - - {/if} - {/each} -
-
-
@@ -443,19 +495,14 @@ {#if $coolMode}
- {#each fields as item} - - - + {#each fields as item, i} + {/each}
{:else}