update color scheme

This commit is contained in:
MuslemRahimi 2024-11-07 19:40:42 +01:00
parent 990c818727
commit e6d42b8f9d
6 changed files with 339 additions and 289 deletions

View File

@ -68,7 +68,7 @@
class="stroke-current {score >= 7 class="stroke-current {score >= 7
? 'text-[#00FC50]' ? 'text-[#00FC50]'
: score >= 4 : score >= 4
? 'text-[#FF9E21]' ? 'text-[#FBCE3C]'
: 'text-[#FF2F1F]'}" : 'text-[#FF2F1F]'}"
stroke-width="3" stroke-width="3"
stroke-dasharray="100.48" stroke-dasharray="100.48"

View File

@ -82,7 +82,7 @@
<div class="fixed z-[100] bottom-8 sm:bottom-10 right-8 sm:right-16"> <div class="fixed z-[100] bottom-8 sm:bottom-10 right-8 sm:right-16">
<label <label
for="feedbackInfo" for="feedbackInfo"
class="inline-flex items-center justify-center w-12 h-12 sm:w-full sm:h-10 font-medium bg-gray-700 sm:bg-[#FFEDE5] ml-1 mr-0 sm:mr-2 rounded-full cursor-pointer" class="inline-flex items-center justify-center w-12 h-12 sm:w-full sm:h-10 font-semibold bg-gray-700 sm:bg-[#FBCE3C] ml-1 mr-0 sm:mr-2 rounded-full cursor-pointer"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -111,10 +111,10 @@
> >
<label <label
for="feedbackInfo" for="feedbackInfo"
class="cursor-pointer modal-backdrop bg-[#fff] bg-opacity-[0.05]" class="cursor-pointer modal-backdrop bg-[#fff] bg-opacity-[0.1]"
></label> ></label>
<div class="modal-box w-full bg-[#000]"> <div class="modal-box w-full bg-[#09090B] border border-gray-600">
<div class="flex flex-row items-center pt-5"> <div class="flex flex-row items-center pt-5">
<h1 class="text-white text-xl sm:text-2xl font-bold"> <h1 class="text-white text-xl sm:text-2xl font-bold">
Your Feedback matters! Your Feedback matters!
@ -185,10 +185,10 @@
<button <button
on:click={() => sendFeedback()} on:click={() => sendFeedback()}
class="mb-4 px-3 py-2 bg-purple-600 smhover:bg-purple-700 {rating?.length !== class="mb-4 px-3 py-2 bg-[#FBCE3C] sm:hover:bg-[#e8b305] {rating?.length !==
0 && inputValue?.length !== 0 0 && inputValue?.length !== 0
? 'opacity-100 cursor-pointer' ? 'opacity-100 cursor-pointer'
: 'opacity-60 cursor-not-allowed'} w-11/12 rounded-lg m-auto text-white font-semibold text-md" : 'opacity-60 cursor-not-allowed'} w-11/12 rounded-lg m-auto text-black font-semibold text-md"
> >
Send Feedback Send Feedback
</button> </button>

View File

@ -1,13 +1,20 @@
<script lang="ts"> <script lang="ts">
import { governmentContractComponent, displayCompanyName, stockTicker, screenWidth, getCache, setCache } from '$lib/store'; import {
import InfoModal from '$lib/components/InfoModal.svelte'; governmentContractComponent,
import { Chart } from 'svelte-echarts'; displayCompanyName,
stockTicker,
screenWidth,
getCache,
setCache,
} from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
import { Chart } from "svelte-echarts";
import { abbreviateNumber } from "$lib/utils"; import { abbreviateNumber } from "$lib/utils";
import { init, use } from 'echarts/core'; import { init, use } from "echarts/core";
import { BarChart } from 'echarts/charts'; import { BarChart } from "echarts/charts";
import { GridComponent } from 'echarts/components'; import { GridComponent } from "echarts/components";
import { CanvasRenderer } from 'echarts/renderers'; import { CanvasRenderer } from "echarts/renderers";
use([BarChart, GridComponent, CanvasRenderer]); use([BarChart, GridComponent, CanvasRenderer]);
let isLoaded = false; let isLoaded = false;
@ -15,7 +22,7 @@
let optionsData; let optionsData;
let avgNumberOfContracts = 0; let avgNumberOfContracts = 0;
let displayMaxContracts = 0; let displayMaxContracts = 0;
let displayYear = 'n/a'; let displayYear = "n/a";
let totalAmount; let totalAmount;
let totalContract; let totalContract;
@ -31,41 +38,46 @@
numList?.push(item?.numOfContracts); numList?.push(item?.numOfContracts);
}); });
totalContract = rawData?.reduce((sum, item) => sum + item?.numOfContracts, 0); totalContract = rawData?.reduce(
(sum, item) => sum + item?.numOfContracts,
0,
);
totalAmount = rawData?.reduce((sum, item) => sum + item?.amount, 0); totalAmount = rawData?.reduce((sum, item) => sum + item?.amount, 0);
avgNumberOfContracts = Math.floor(totalContract / rawData?.length); avgNumberOfContracts = Math.floor(totalContract / rawData?.length);
const { year: yearWithMaxContracts, numOfContracts: maxContracts } = rawData?.reduce( const { year: yearWithMaxContracts, numOfContracts: maxContracts } =
(max, contract) => (contract?.numOfContracts > max?.numOfContracts ? contract : max), rawData?.reduce(
rawData?.at(0) (max, contract) =>
); contract?.numOfContracts > max?.numOfContracts ? contract : max,
rawData?.at(0),
);
displayYear = yearWithMaxContracts; displayYear = yearWithMaxContracts;
displayMaxContracts = maxContracts; displayMaxContracts = maxContracts;
const option = { const option = {
silent: true, silent: true,
tooltip: { tooltip: {
trigger: 'axis', trigger: "axis",
hideDelay: 100, // Set the delay in milliseconds hideDelay: 100, // Set the delay in milliseconds
}, },
animation: false, animation: false,
grid: { grid: {
left: '2%', left: "2%",
right: $screenWidth < 640 ? '0%' : '2%', right: $screenWidth < 640 ? "0%" : "2%",
bottom: '0%', bottom: "0%",
top: '10%', top: "10%",
containLabel: true, containLabel: true,
}, },
xAxis: { xAxis: {
data: dates, data: dates,
type: 'category', type: "category",
axisLabel: { axisLabel: {
color: '#fff', color: "#fff",
}, },
}, },
yAxis: [ yAxis: [
{ {
type: 'value', type: "value",
splitLine: { splitLine: {
show: false, // Disable x-axis grid lines show: false, // Disable x-axis grid lines
}, },
@ -74,32 +86,32 @@
}, },
}, },
{ {
type: 'value', type: "value",
splitLine: { splitLine: {
show: false, // Disable x-axis grid lines show: false, // Disable x-axis grid lines
}, },
axisLabel: { axisLabel: {
show: false, // Hide y-axis labels show: false, // Hide y-axis labels
}, },
position: 'right', position: "right",
}, },
], ],
series: [ series: [
{ {
name: '# of Contracts', name: "# of Contracts",
data: numList, data: numList,
type: 'line', type: "line",
yAxisIndex: 1, yAxisIndex: 1,
itemStyle: { itemStyle: {
color: '#fff', // Change bar color to white color: "#fff", // Change bar color to white
}, },
}, },
{ {
name: 'Amount', name: "Amount",
data: amountList, data: amountList,
type: 'bar', type: "bar",
itemStyle: { itemStyle: {
color: '#FF9E21', // Change bar color to orange color: "#FBCE3C", // Change bar color to orange
}, },
}, },
], ],
@ -109,27 +121,27 @@
} }
const getGovernmentContract = async (ticker) => { const getGovernmentContract = async (ticker) => {
const cachedData = getCache(ticker, 'getGovernmentContract'); const cachedData = getCache(ticker, "getGovernmentContract");
if (cachedData) { if (cachedData) {
rawData = cachedData; rawData = cachedData;
} else { } else {
const postData = { ticker: ticker, path: 'government-contract' }; const postData = { ticker: ticker, path: "government-contract" };
const response = await fetch('/api/ticker-data', { const response = await fetch("/api/ticker-data", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify(postData), body: JSON.stringify(postData),
}); });
rawData = await response?.json(); rawData = await response?.json();
setCache(ticker, rawData, 'getGovernmentContract'); setCache(ticker, rawData, "getGovernmentContract");
} }
governmentContractComponent.set(rawData?.length !== 0); governmentContractComponent.set(rawData?.length !== 0);
}; };
$: { $: {
if ($stockTicker && typeof window !== 'undefined') { if ($stockTicker && typeof window !== "undefined") {
isLoaded = false; isLoaded = false;
const ticker = $stockTicker; const ticker = $stockTicker;
const asyncFunctions = [getGovernmentContract(ticker)]; const asyncFunctions = [getGovernmentContract(ticker)];
@ -141,104 +153,114 @@
} }
}) })
.catch((error) => { .catch((error) => {
console.error('An error occurred:', error); console.error("An error occurred:", error);
}); });
isLoaded = true; isLoaded = true;
} }
} }
</script> </script>
<section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden">
<section class="overflow-hidden text-white h-full pb-8"> <div class="flex flex-row items-center">
<main class="overflow-hidden "> <label
for="governmentContractInfo"
<div class="flex flex-row items-center"> class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
<label for="governmentContractInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"> >
US Government Contract US Government Contract
</label> </label>
<InfoModal <InfoModal
title={"Government Contract"} title={"Government Contract"}
content={"Government contracts are agreements between the local government and companies for goods or services. They can be substantial revenue sources for companies, particularly in sectors like defense, technology, and infrastructure. Winning contracts can enhance a company's stability and credibility, but it often involves competitive bidding and compliance with strict regulations."} content={"Government contracts are agreements between the local government and companies for goods or services. They can be substantial revenue sources for companies, particularly in sectors like defense, technology, and infrastructure. Winning contracts can enhance a company's stability and credibility, but it often involves competitive bidding and compliance with strict regulations."}
id={"governmentContractInfo"} id={"governmentContractInfo"}
/> />
</div> </div>
{#if isLoaded} {#if isLoaded}
{#if rawData?.length !== 0}
{#if rawData?.length !== 0}
<div class="w-full flex flex-col items-start"> <div class="w-full flex flex-col items-start">
<div class="text-white text-sm sm:text-[1rem] mt-2 mb-2 w-full"> <div class="text-white text-sm sm:text-[1rem] mt-2 mb-2 w-full">
Since 2015, {$displayCompanyName} has secured a total of {totalContract} government contracts, amassing {abbreviateNumber(totalAmount,true)} in revenue. The company has averaged {avgNumberOfContracts} contracts per year, with a peak of {displayMaxContracts} contracts in {displayYear}. Since 2015, {$displayCompanyName} has secured a total of {totalContract}
</div> government contracts, amassing {abbreviateNumber(totalAmount, true)}
</div> in revenue. The company has averaged {avgNumberOfContracts} contracts
per year, with a peak of {displayMaxContracts} contracts in {displayYear}.
<div class="pb-2 rounded-lg bg-[#09090B]">
<div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" />
</div> </div>
</div> </div>
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
# of Contracts
</span>
</div>
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"> <div class="pb-2 rounded-lg bg-[#09090B]">
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div> <div class="app w-full h-[300px] mt-5">
<div class="w-3 h-3 bg-[#FFAD24] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div> <Chart {init} options={optionsData} class="chart" />
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"> </div>
Amount
</span>
</div>
</div> </div>
<div
{/if} class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
>
{:else} <div
<div class="flex justify-center items-center h-80"> class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
<div class="relative"> >
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"> <div
<span class="loading loading-spinner loading-md text-gray-400"></span> class="h-full transform -translate-x-1/2"
</label> aria-hidden="true"
</div> ></div>
<div
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
>
# of Contracts
</span>
</div>
<div
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
>
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#FFAD24] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
>
Amount
</span>
</div>
</div> </div>
{/if} {/if}
{:else}
<div class="flex justify-center items-center h-80">
</main> <div class="relative">
</section> <label
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
<style> </label>
</div>
</div>
{/if}
</main>
</section>
<style>
.app { .app {
height: 300px; height: 300px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */ max-width: 100%; /* Ensure chart width doesn't exceed the container */
} }
@media (max-width: 640px) { @media (max-width: 640px) {
.app { .app {
height: 210px; height: 210px;
}
} }
}
.chart { .chart {
width: 100%; width: 100%;
} }
</style>
</style>

View File

@ -1,28 +1,33 @@
<script lang="ts"> <script lang="ts">
import { abbreviateNumber } from "$lib/utils"; import { abbreviateNumber } from "$lib/utils";
import { swapComponent, stockTicker, screenWidth, getCache, setCache } from '$lib/store'; import {
import InfoModal from '$lib/components/InfoModal.svelte'; swapComponent,
import { Chart } from 'svelte-echarts'; stockTicker,
import { init, use } from 'echarts/core'; screenWidth,
import { ScatterChart } from 'echarts/charts'; getCache,
import { GridComponent, TooltipComponent } from 'echarts/components'; setCache,
import { CanvasRenderer } from 'echarts/renderers'; } from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
import { Chart } from "svelte-echarts";
import { init, use } from "echarts/core";
import { ScatterChart } from "echarts/charts";
import { GridComponent, TooltipComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
export let data: any; // Add type for `data` if possible export let data: any; // Add type for `data` if possible
use([ScatterChart, GridComponent, TooltipComponent, CanvasRenderer]); use([ScatterChart, GridComponent, TooltipComponent, CanvasRenderer]);
let isLoaded = false; let isLoaded = false;
const tabs = [ const tabs = [{ title: "Effective Date" }, { title: "Expiration Date" }];
{ title: "Effective Date" },
{ title: "Expiration Date" },
];
let activeIdx = 0; let activeIdx = 0;
function changeTab(index: number) { function changeTab(index: number) {
activeIdx = index; activeIdx = index;
optionsData = getPlotOptions(activeIdx === 0 ? 'effectiveDate' : 'expirationDate'); optionsData = getPlotOptions(
activeIdx === 0 ? "effectiveDate" : "expirationDate",
);
} }
let rawData: any[] = []; let rawData: any[] = [];
@ -30,71 +35,84 @@
let avgNotionalAmount: number | undefined; let avgNotionalAmount: number | undefined;
let avgNotionalQuantity: number | undefined; let avgNotionalQuantity: number | undefined;
function getPlotOptions(state: "effectiveDate" | "expirationDate") {
function getPlotOptions(state: 'effectiveDate' | 'expirationDate') {
const combinedData = rawData?.map((item) => ({ const combinedData = rawData?.map((item) => ({
date: state === 'effectiveDate' ? item['Effective Date'] : item['Expiration Date'], date:
notionalAmount: item['Notional amount-Leg 1'], state === "effectiveDate"
notionalQuantity: item['Total notional quantity-Leg 1'], ? item["Effective Date"]
: item["Expiration Date"],
notionalAmount: item["Notional amount-Leg 1"],
notionalQuantity: item["Total notional quantity-Leg 1"],
})); }));
// Group data by date and sum the values // Group data by date and sum the values
const groupedData = combinedData.reduce((acc, curr) => { const groupedData = combinedData.reduce(
const { date, notionalAmount, notionalQuantity } = curr; (acc, curr) => {
const { date, notionalAmount, notionalQuantity } = curr;
if (acc[date]) { if (acc[date]) {
acc[date].notionalAmount += notionalAmount; acc[date].notionalAmount += notionalAmount;
acc[date].notionalQuantity += notionalQuantity; acc[date].notionalQuantity += notionalQuantity;
} else { } else {
acc[date] = { acc[date] = {
date, date,
notionalAmount, notionalAmount,
notionalQuantity, notionalQuantity,
}; };
} }
return acc; return acc;
}, {} as Record<string, any>); },
{} as Record<string, any>,
);
const result = Object.values(groupedData); const result = Object.values(groupedData);
result?.sort((a, b) => new Date(a?.date).getTime() - new Date(b?.date).getTime()); result?.sort(
(a, b) => new Date(a?.date).getTime() - new Date(b?.date).getTime(),
);
const dates = result?.map((item) => item?.date); const dates = result?.map((item) => item?.date);
const notionalAmount = result?.map((item) => item?.notionalAmount); const notionalAmount = result?.map((item) => item?.notionalAmount);
const notionalQuantity = result?.map((item) => item?.notionalQuantity); const notionalQuantity = result?.map((item) => item?.notionalQuantity);
const totalNotionalAmount = notionalAmount?.reduce((acc, item) => acc + item, 0); const totalNotionalAmount = notionalAmount?.reduce(
(acc, item) => acc + item,
0,
);
avgNotionalAmount = totalNotionalAmount / notionalAmount?.length; avgNotionalAmount = totalNotionalAmount / notionalAmount?.length;
const totalNotionalQuantity = notionalQuantity?.reduce((acc, item) => acc + item, 0); const totalNotionalQuantity = notionalQuantity?.reduce(
(acc, item) => acc + item,
0,
);
avgNotionalQuantity = totalNotionalQuantity / notionalQuantity?.length; avgNotionalQuantity = totalNotionalQuantity / notionalQuantity?.length;
const option = { const option = {
silent: true, silent: true,
tooltip: { tooltip: {
trigger: 'axis', trigger: "axis",
hideDelay: 100, hideDelay: 100,
}, },
animation: false, animation: false,
grid: { grid: {
left: '3%', left: "3%",
right: '3%', right: "3%",
bottom: '0%', bottom: "0%",
top: '10%', top: "10%",
containLabel: true, containLabel: true,
}, },
xAxis: { xAxis: {
type: 'category', type: "category",
boundaryGap: false, boundaryGap: false,
data: dates, data: dates,
axisLabel: { axisLabel: {
color: '#fff', color: "#fff",
}, },
}, },
yAxis: [ yAxis: [
{ {
type: 'value', type: "value",
splitLine: { splitLine: {
show: false, show: false,
}, },
@ -103,11 +121,11 @@
}, },
}, },
{ {
type: 'value', type: "value",
splitLine: { splitLine: {
show: false, show: false,
}, },
position: 'right', position: "right",
axisLabel: { axisLabel: {
show: false, show: false,
}, },
@ -115,20 +133,20 @@
], ],
series: [ series: [
{ {
name: 'Notional Amount', name: "Notional Amount",
type: 'scatter', type: "scatter",
data: dates?.map((date, index) => [date, notionalAmount[index]]), data: dates?.map((date, index) => [date, notionalAmount[index]]),
itemStyle: { itemStyle: {
color: '#8F54F4', color: "#8F54F4",
}, },
}, },
{ {
name: 'Notional Quantity', name: "Notional Quantity",
type: 'scatter', type: "scatter",
data: dates?.map((date, index) => [date, notionalQuantity[index]]), data: dates?.map((date, index) => [date, notionalQuantity[index]]),
yAxisIndex: 1, yAxisIndex: 1,
itemStyle: { itemStyle: {
color: '#FF9E21', color: "#FBCE3C",
}, },
}, },
], ],
@ -138,35 +156,35 @@
} }
async function getSwapData(ticker: string) { async function getSwapData(ticker: string) {
const cachedData = getCache(ticker, 'getSwapData'); const cachedData = getCache(ticker, "getSwapData");
if (cachedData) { if (cachedData) {
rawData = cachedData; rawData = cachedData;
} else { } else {
try { try {
const postData = { ticker, path: 'swap-ticker' }; const postData = { ticker, path: "swap-ticker" };
const response = await fetch('/api/ticker-data', { const response = await fetch("/api/ticker-data", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify(postData), body: JSON.stringify(postData),
}); });
if (!response.ok) throw new Error('API request failed'); if (!response.ok) throw new Error("API request failed");
rawData = await response.json(); rawData = await response.json();
setCache(ticker, rawData, 'getSwapData'); setCache(ticker, rawData, "getSwapData");
} catch (error) { } catch (error) {
console.error('Failed to fetch swap data:', error); console.error("Failed to fetch swap data:", error);
rawData = []; rawData = [];
} }
} }
$swapComponent = rawData?.length !== 0; // Correct the use of `$` $swapComponent = rawData?.length !== 0; // Correct the use of `$`
} }
$: if ($stockTicker && typeof window !== 'undefined') { $: if ($stockTicker && typeof window !== "undefined") {
isLoaded = false; isLoaded = false;
activeIdx = 0; activeIdx = 0;
getSwapData($stockTicker).then(() => { getSwapData($stockTicker).then(() => {
optionsData = getPlotOptions('effectiveDate'); optionsData = getPlotOptions("effectiveDate");
isLoaded = true; isLoaded = true;
}); });
} }
@ -174,119 +192,129 @@
$: charNumber = $screenWidth < 640 ? 20 : 40; $: charNumber = $screenWidth < 640 ? 20 : 40;
</script> </script>
<section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden">
<div class="flex flex-row items-center">
<label
for="swapInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
Swap Data
</label>
<InfoModal
title={"Swap Data"}
content={"Swaps in the stock market are derivative contracts to exchange cash flows or assets, used for risk management, speculation, and enhancing market liquidity."}
id={"swapInfo"}
/>
</div>
{#if isLoaded}
<section class="overflow-hidden text-white h-full pb-8"> {#if rawData?.length !== 0}
<main class="overflow-hidden ">
<div class="flex flex-row items-center">
<label for="swapInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
Swap Data
</label>
<InfoModal
title={"Swap Data"}
content={"Swaps in the stock market are derivative contracts to exchange cash flows or assets, used for risk management, speculation, and enhancing market liquidity."}
id={"swapInfo"}
/>
</div>
{#if isLoaded}
{#if rawData?.length !== 0}
<div class="w-full flex flex-col items-start"> <div class="w-full flex flex-col items-start">
<div class="text-white text-[1rem] mt-2 mb-2 w-full"> <div class="text-white text-[1rem] mt-2 mb-2 w-full">
The swap data from the past 100 days shows an average notional amount of {abbreviateNumber(avgNotionalAmount,true)} and an average notional quantity of {abbreviateNumber(avgNotionalQuantity)}. The swap data from the past 100 days shows an average notional
</div> amount of {abbreviateNumber(avgNotionalAmount, true)} and an average
notional quantity of {abbreviateNumber(avgNotionalQuantity)}.
</div>
</div> </div>
<div class="pb-2 rounded-lg bg-[#09090B]"> <div class="pb-2 rounded-lg bg-[#09090B]">
<div
<div class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-lg p-1 mt-4"> class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-lg p-1 mt-4"
{#each tabs as item, i} >
<button {#each tabs as item, i}
on:click={() => changeTab(i)} <button
class="group relative z-[1] rounded-full px-3 py-1 {activeIdx === i on:click={() => changeTab(i)}
? 'z-0' class="group relative z-[1] rounded-full px-3 py-1 {activeIdx ===
: ''} "> i
{#if activeIdx === i} ? 'z-0'
<div : ''} "
class="absolute inset-0 rounded-lg bg-purple-600" >
></div> {#if activeIdx === i}
{/if} <div class="absolute inset-0 rounded-lg bg-purple-600"></div>
<span {/if}
class="relative text-sm block font-medium duration-200 text-white"> <span
{item.title} class="relative text-sm block font-medium duration-200 text-white"
</span> >
</button> {item.title}
{/each}
</div>
<div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" />
</div>
</div>
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
<div class="w-3 h-3 bg-[#8F54F4] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
Notional Amount
</span> </span>
</div> </button>
{/each}
</div>
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"> <div class="app w-full h-[300px] mt-5">
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div> <Chart {init} options={optionsData} class="chart" />
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div> </div>
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block">
Notional Quantity
</span>
</div>
</div> </div>
<div
{/if} class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
>
{:else} <div
<div class="flex justify-center items-center h-80"> class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
<div class="relative"> >
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"> <div
<span class="loading loading-spinner loading-md text-gray-400"></span> class="h-full transform -translate-x-1/2"
</label> aria-hidden="true"
</div> ></div>
<div
class="w-3 h-3 bg-[#8F54F4] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
>
Notional Amount
</span>
</div>
<div
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
>
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
>
Notional Quantity
</span>
</div>
</div> </div>
{/if} {/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
</label>
</div>
</div>
{/if}
</main>
</section>
<style>
</main>
</section>
<style>
.app { .app {
height: 300px; height: 300px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */ max-width: 100%; /* Ensure chart width doesn't exceed the container */
} }
@media (max-width: 640px) { @media (max-width: 640px) {
.app { .app {
height: 210px; height: 210px;
}
} }
}
.chart { .chart {
width: 100%; width: 100%;
} }
</style>
</style>

View File

@ -408,7 +408,7 @@
type: "bar", type: "bar",
showSymbol: false, showSymbol: false,
itemStyle: { itemStyle: {
color: "#FF9E21", // Change bar color to white color: "#FBCE3C", // Change bar color to white
}, },
}, },
{ {

View File

@ -97,7 +97,7 @@
// Define categories in the exact order you specified // Define categories in the exact order you specified
const categories = ["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"]; const categories = ["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"];
const colors = ["#9E190A", "#D9220E", "#FF9E21", "#31B800", "#008A00"]; const colors = ["#9E190A", "#D9220E", "#FBCE3C", "#31B800", "#008A00"];
// Create a consistent mapping for data // Create a consistent mapping for data
const formattedData = rawAnalystList.map((item) => const formattedData = rawAnalystList.map((item) =>
@ -216,7 +216,7 @@
color: [ color: [
[0.2, "#9E190A"], [0.2, "#9E190A"],
[0.4, "#D9220E"], [0.4, "#D9220E"],
[0.6, "#FF9E21"], [0.6, "#FBCE3C"],
[0.8, "#31B800"], [0.8, "#31B800"],
[1, "#008A00"], [1, "#008A00"],
], ],
@ -409,7 +409,7 @@
symbol: "none", symbol: "none",
lineStyle: { lineStyle: {
type: "dashed", type: "dashed",
color: "#FF9E21", color: "#FBCE3C",
}, },
}, },
{ {
@ -533,7 +533,7 @@
? 'text-[#00FC50]' ? 'text-[#00FC50]'
: ['Strong Sell', 'Sell']?.includes(consensusRating) : ['Strong Sell', 'Sell']?.includes(consensusRating)
? 'text-[#FF2F1F]' ? 'text-[#FF2F1F]'
: 'text-[#FF9E21]'}">{consensusRating}</span : 'text-[#FBCE3C]'}">{consensusRating}</span
> >
</div> </div>
</div> </div>