diff --git a/src/routes/market-mover/+page.svelte b/src/routes/market-mover/+page.svelte index fe25e08e..aa0488b7 100644 --- a/src/routes/market-mover/+page.svelte +++ b/src/routes/market-mover/+page.svelte @@ -5,13 +5,12 @@ import logo from '$lib/images/top_winner_logo.png'; import { abbreviateNumber } from '$lib/utils'; import MiniPlot from '$lib/components/MiniPlot.svelte'; import { onMount } from 'svelte'; -import * as Tabs from "$lib/components/shadcn/tabs/index.js"; import ArrowLogo from "lucide-svelte/icons/move-up-right"; export let data; let isLoaded = false; const rawData = data?.getMiniPlotsIndex; - +let timePeriod = '1D' let priceDataSP500; let priceDataNasdaq; let priceDataDowJones; @@ -81,109 +80,51 @@ rawData?.forEach(({ symbol, priceData, changesPercentage, previousClose }) => { let outputList = data?.getDailyGainerLoserActive; -let gainerLoserActive = outputList?.gainers['1D'] -let displaySection = 'gainer' -let order = 'highToLow'; -let sortBy = ''; // Default sorting by change percentage - +let gainerLoserActive = outputList?.gainers[timePeriod] let buttonText = 'Top Winners'; -function changeOrder(state:string) { - if (state === 'highToLow') - { - order = 'lowToHigh'; - } - else { - order = 'highToLow'; - } - } - -const sortByChange = (tickerList) => { - return tickerList?.sort(function(a, b) { - if(order === 'highToLow') +const tabs = [ { - return b?.changesPercentage - a?.changesPercentage; - } - else { - return a?.changesPercentage - b?.changesPercentage; - } - - }); - } - -const sortByPrice = (tickerList) => { - return tickerList?.sort(function(a, b) { - if(order === 'highToLow') + title: "Gainers", + }, { - return a?.price - b?.price; - } - else { - return b?.price - a?.price; - } - - }); - } - -const sortByVolume = (tickerList) => { - return tickerList?.sort(function(a, b) { - if(order === 'highToLow') + title: "Losers", + }, { - return b?.volume - a?.volume; - } - else { - return a?.volume - b?.volume; - } - - }); - } - -const sortByMarketCap = (tickerList) => { - return tickerList?.sort(function(a, b) { - if(order === 'highToLow') - { - return b?.marketCap - a?.marketCap; - } - else { - return a?.marketCap - b?.marketCap; - } - }); -} - + title: "Active", + }, + ]; -function changeSection(state) { +let activeIdx = 0; - displaySection = state; - const timePeriod = '1D'; - sortBy = ''; - order = ''; - - if (state === 'gainer') +function changeSection(index) { + activeIdx = index; + + if (index === 0) { gainerLoserActive = outputList?.gainers[timePeriod]; buttonText = 'Top Winners' } - else if (state === 'loser') + else if (index === 1) { gainerLoserActive = outputList?.losers[timePeriod]; buttonText = 'Top Losers' } - else if (state === 'active') + else if (index === 2) { gainerLoserActive = outputList?.active[timePeriod]; buttonText = 'Most Active' } - -} +} function selectTimeInterval(event) { - sortBy = ''; - order = ''; + - const timePeriod = event.target.value === 'oneDay' ? '1D' : event.target.value === 'oneWeek' ? '1W' : event.target.value === 'oneMonth' ? '1M' : event.target.value === 'threeMonths' ? '3M' : '6M'; + timePeriod = event.target.value === 'oneDay' ? '1D' : event.target.value === 'oneWeek' ? '1W' : event.target.value === 'oneMonth' ? '1M' : event.target.value === 'threeMonths' ? '3M' : '6M'; if (buttonText === 'Top Winners') @@ -198,31 +139,95 @@ function selectTimeInterval(event) { { gainerLoserActive = outputList?.active[timePeriod]; } - } onMount( () => { isLoaded = true; }) - $: { - if(order) - { - - // Add this condition for market cap sorting - if (sortBy === 'marketCap') { - gainerLoserActive = sortByMarketCap(gainerLoserActive); - } - else if (sortBy === 'change') { - gainerLoserActive = sortByChange(gainerLoserActive); - } - else if (sortBy === 'price') { - gainerLoserActive = sortByPrice(gainerLoserActive); - } - else if (sortBy === 'volume') { - gainerLoserActive = sortByVolume(gainerLoserActive); + +let sortOrders = { + symbol: 'none', + name: 'none', + change: 'none', + price: 'none', + marketCap: 'none', + volume: 'none', +}; + +// Generalized sorting function +function sortData(key) { + // Reset all other keys to 'none' except the current key + for (const k in sortOrders) { + if (k !== key) { + sortOrders[k] = 'none'; } } + + // Cycle through 'none', 'asc', 'desc' for the clicked key + const orderCycle = ['none', 'asc', 'desc']; + let originalData = []; + + if (buttonText === 'Top Winners') + { + originalData = data?.getDailyGainerLoserActive?.gainers[timePeriod] + } + else if (buttonText === 'Top Losers') + { + originalData = data?.getDailyGainerLoserActive?.losers[timePeriod] + } + else if (buttonText === 'Most Active') + { + originalData = data?.getDailyGainerLoserActive?.active[timePeriod] + } + + const currentOrderIndex = orderCycle.indexOf(sortOrders[key]); + sortOrders[key] = orderCycle[(currentOrderIndex + 1) % orderCycle.length]; + + const sortOrder = sortOrders[key]; + + // Reset to original data when 'none' and stop further sorting + if (sortOrder === 'none') { + gainerLoserActive = [...originalData]; // Reset to original data (spread to avoid mutation) + return; + } + + // Define comparison functions for each key + const compareFunctions = { + symbol: (a, b) => { + const symbolA = a.symbol.toUpperCase(); + const symbolB = b.symbol.toUpperCase(); + return sortOrder === 'asc' ? symbolA.localeCompare(symbolB) : symbolB.localeCompare(symbolA); + }, + name: (a, b) => { + const nameA = a.name.toUpperCase(); + const nameB = b.name.toUpperCase(); + return sortOrder === 'asc' ? nameA.localeCompare(nameB) : nameB.localeCompare(nameA); + }, + change: (a, b) => { + const numA = parseFloat(a?.changesPercentage); + const numB = parseFloat(b?.changesPercentage); + return sortOrder === 'asc' ? numA - numB : numB - numA; + }, + price: (a, b) => { + const numA = parseFloat(a?.price); + const numB = parseFloat(b?.price); + return sortOrder === 'asc' ? numA - numB : numB - numA; + }, + marketCap: (a, b) => { + const numA = parseFloat(a.marketCap); + const numB = parseFloat(b.marketCap); + return sortOrder === 'asc' ? numA - numB : numB - numA; + }, + volume: (a, b) => { + const numA = parseFloat(a.volume); + const numB = parseFloat(b.volume); + return sortOrder === 'asc' ? numA - numB : numB - numA; + }, + }; + + // Sort using the appropriate comparison function + gainerLoserActive = [...originalData].sort(compareFunctions[key]); } @@ -319,7 +324,7 @@ $: charNumber = $screenWidth < 640 ? 20 : 30; {#if isLoaded} -
| Symbol | -Name | -{ sortBy = 'change'; changeOrder(order); }} class="whitespace-nowrap cursor-pointer text-white font-semibold text-[1rem] text-end"> + | sortData('symbol')} class="cursor-pointer select-none text-white font-semibold text-[1rem] whitespace-nowrap"> + Symbol + + | +sortData('name')} class="cursor-pointer select-none text-white font-semibold text-[1rem] whitespace-nowrap"> + Name + + | +sortData('change')} class="cursor-pointer select-none text-end text-white font-semibold text-[1rem] whitespace-nowrap"> % Change - + | -{ sortBy = 'price'; changeOrder(order); }} class="cursor-pointer text-white font-semibold text-end text-[1rem]"> + | sortData('price')} class="cursor-pointer select-none text-end text-white font-semibold text-[1rem] whitespace-nowrap"> Price - + | -{ sortBy = 'marketCap'; changeOrder(order); }} class="whitespace-nowrap cursor-pointer text-white font-semibold text-[1rem] text-end"> + | sortData('marketCap')} class="cursor-pointer select-none text-end text-white font-semibold text-[1rem] whitespace-nowrap"> Market Cap - + | -{ sortBy = 'volume'; changeOrder(order); }} class="cursor-pointer text-white font-semibold text-[1rem] text-end"> + | sortData('volume')} class="cursor-pointer select-none text-end text-white font-semibold text-[1rem] whitespace-nowrap"> Volume - + |
|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -418,15 +440,15 @@ $: charNumber = $screenWidth < 640 ? 20 : 30; {/if} | -- ${item?.price?.toFixed(2)} + | + {item?.price?.toFixed(2)} | -- {item?.marketCap !== null ? abbreviateNumber(item?.marketCap, true) : '-'} + | + {item?.marketCap !== null ? abbreviateNumber(item?.marketCap) : '-'} | -+ | {item?.volume !== null ? abbreviateNumber(item?.volume) : '-'} | @@ -482,7 +504,7 @@ $: charNumber = $screenWidth < 640 ? 20 : 30;