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,13 +38,18 @@
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;
@ -45,27 +57,27 @@
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,20 +153,20 @@
} }
}) })
.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">
<main class="overflow-hidden ">
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label for="governmentContractInfo" 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
@ -165,70 +177,81 @@
</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}
government contracts, amassing {abbreviateNumber(totalAmount, true)}
in revenue. The company has averaged {avgNumberOfContracts} contracts
per year, with a peak of {displayMaxContracts} contracts in {displayYear}.
</div> </div>
</div> </div>
<div class="pb-2 rounded-lg bg-[#09090B]"> <div class="pb-2 rounded-lg bg-[#09090B]">
<div class="app w-full h-[300px] mt-5"> <div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" /> <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="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
<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> 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"
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"> >
<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 # of Contracts
</span> </span>
</div> </div>
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"> <div
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div> class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
<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"> <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 Amount
</span> </span>
</div> </div>
</div> </div>
{/if} {/if}
{:else} {:else}
<div class="flex justify-center items-center h-80"> <div class="flex justify-center items-center h-80">
<div class="relative"> <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"> <label
<span class="loading loading-spinner loading-md text-gray-400"></span> 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> </label>
</div> </div>
</div> </div>
{/if} {/if}
</main> </main>
</section> </section>
<style>
<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) {
@ -240,5 +263,4 @@
.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,16 +35,19 @@
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(
(acc, curr) => {
const { date, notionalAmount, notionalQuantity } = curr; const { date, notionalAmount, notionalQuantity } = curr;
if (acc[date]) { if (acc[date]) {
@ -54,47 +62,57 @@
} }
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,14 +192,13 @@
$: 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">
<section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden ">
<div class="flex flex-row items-center"> <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"> <label
for="swapInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
Swap Data Swap Data
</label> </label>
<InfoModal <InfoModal
@ -192,91 +209,103 @@
</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-[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
amount of {abbreviateNumber(avgNotionalAmount, true)} and an average
notional quantity of {abbreviateNumber(avgNotionalQuantity)}.
</div> </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} {#each tabs as item, i}
<button <button
on:click={() => changeTab(i)} on:click={() => changeTab(i)}
class="group relative z-[1] rounded-full px-3 py-1 {activeIdx === i class="group relative z-[1] rounded-full px-3 py-1 {activeIdx ===
i
? 'z-0' ? 'z-0'
: ''} "> : ''} "
>
{#if activeIdx === i} {#if activeIdx === i}
<div <div class="absolute inset-0 rounded-lg bg-purple-600"></div>
class="absolute inset-0 rounded-lg bg-purple-600"
></div>
{/if} {/if}
<span <span
class="relative text-sm block font-medium duration-200 text-white"> class="relative text-sm block font-medium duration-200 text-white"
>
{item.title} {item.title}
</span> </span>
</button> </button>
{/each} {/each}
</div> </div>
<div class="app w-full h-[300px] mt-5"> <div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" /> <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="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
<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> 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"
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"> >
<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 Notional Amount
</span> </span>
</div> </div>
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"> <div
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div> class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
<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"> <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 Notional Quantity
</span> </span>
</div> </div>
</div> </div>
{/if} {/if}
{:else} {:else}
<div class="flex justify-center items-center h-80"> <div class="flex justify-center items-center h-80">
<div class="relative"> <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"> <label
<span class="loading loading-spinner loading-md text-gray-400"></span> 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> </label>
</div> </div>
</div> </div>
{/if} {/if}
</main> </main>
</section> </section>
<style>
<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) {
@ -288,5 +317,4 @@
.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>