This commit is contained in:
MuslemRahimi 2025-03-05 12:41:08 +01:00
parent c04652b9ea
commit ff6143fe1c
4 changed files with 117 additions and 159 deletions

View File

@ -1,19 +1,15 @@
<script lang="ts"> <script lang="ts">
import { Chart } from "svelte-echarts";
import { displayCompanyName, stockTicker } from "$lib/store"; import { displayCompanyName, stockTicker } from "$lib/store";
import { formatString } from "$lib/utils"; import {
import { abbreviateNumber } from "$lib/utils"; abbreviateNumber,
removeCompanyStrings,
formatString,
} from "$lib/utils";
import { onMount } from "svelte"; import { onMount } from "svelte";
import { init, use } from "echarts/core";
import { PieChart } from "echarts/charts";
import { GridComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import TableHeader from "$lib/components/Table/TableHeader.svelte"; import TableHeader from "$lib/components/Table/TableHeader.svelte";
import DownloadData from "$lib/components/DownloadData.svelte"; import DownloadData from "$lib/components/DownloadData.svelte";
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte"; import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
import Infobox from "$lib/components/Infobox.svelte"; import highcharts from "$lib/highcharts.ts";
use([PieChart, GridComponent, CanvasRenderer]);
export let data; export let data;
@ -27,68 +23,89 @@
let shareholderList = rawData?.shareholders; let shareholderList = rawData?.shareholders;
let displayList = shareholderList?.slice(0, 50); let displayList = shareholderList?.slice(0, 50);
let optionsPieChart; let config;
let institutionalOwner = 0;
let otherOwner = 0;
let topHolders = 0; let topHolders = 0;
const plotPieChart = () => { function plotData() {
if (rawData?.ownershipPercent !== undefined) { shareholderList = shareholderList?.filter((item) => item?.ownership <= 100);
shareholderList = shareholderList?.filter(
(item) => item?.ownership <= 100,
);
topHolders = 0;
otherOwner = 0;
institutionalOwner =
rawData?.ownershipPercent > 100 ? 99.99 : rawData?.ownershipPercent;
otherOwner = institutionalOwner === 0 ? 0 : 100 - institutionalOwner; let institutionalOwner =
topHolders = shareholderList rawData?.ownershipPercent > 100 ? 99.99 : rawData?.ownershipPercent || 0;
?.slice(0, 10) let otherOwner = institutionalOwner === 0 ? 0 : 100 - institutionalOwner;
?.reduce((total, shareholder) => total + shareholder?.ownership, 0);
const options = { const options = {
chart: {
type: "column",
backgroundColor: "#09090B",
plotBackgroundColor: "#09090B",
height: 360, // Set the maximum height for the chart
animation: false, animation: false,
grid: { },
left: "0%", credits: { enabled: false },
right: "0%", legend: {
top: "0%", enabled: true,
bottom: "10%", animation: false,
containLabel: true, itemStyle: { color: "#fff" },
}, },
series: [ title: {
{ text: `<h3 class="mt-3 mb-1">${removeCompanyStrings($displayCompanyName)} Ownership Distribution</h3>`,
name: "Shareholders", useHTML: true,
type: "pie", style: { color: "white" },
radius: ["40%", "50%"], },
padAngle: 5, xAxis: {
itemStyle: { categories: [""],
borderRadius: 3, animation: false,
}, },
label: { yAxis: {
show: false, title: { text: null, style: { color: "#fff" } },
position: "center", opposite: true,
}, gridLineWidth: 1,
silent: true, // Disable interactivity gridLineColor: "#111827",
data: [ labels: {
{ formatter: function () {
value: institutionalOwner, return this.value + "%";
name: "Institutions",
itemStyle: { color: "#3F83F8" },
}, // Set color for 'Institutions'
{
value: otherOwner,
name: "Others",
itemStyle: { color: "#fff" },
},
],
}, },
], style: { color: "#fff" },
}; },
},
tooltip: {
enabled: false,
},
plotOptions: {
series: {
color: "white",
animation: false,
dataLabels: {
enabled: false,
color: "white",
style: {
fontSize: "13px",
fontWeight: "bold",
},
},
},
},
series: [
{
name: "Institutional Owner",
data: [institutionalOwner],
animation: false,
color: "#1E40AF",
borderColor: "#1E40AF",
},
{
name: "Other Owner",
data: [otherOwner],
animation: false,
color: "#D97706",
borderColor: "#D97706",
},
],
};
return options; return options;
} else return null; }
};
totalCalls = rawData?.totalCalls ?? 0; totalCalls = rawData?.totalCalls ?? 0;
totalPuts = rawData?.totalPuts ?? 0; totalPuts = rawData?.totalPuts ?? 0;
@ -102,7 +119,7 @@
putCallRatio = 0; putCallRatio = 0;
} }
optionsPieChart = plotPieChart(); config = plotData();
let charNumber = 30; let charNumber = 30;
@ -229,8 +246,6 @@
<section class="overflow-hidden text-white h-full pb-8"> <section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden"> <main class="overflow-hidden">
<Infobox text={htmlOutput} />
{#if shareholderList?.length !== 0} {#if shareholderList?.length !== 0}
<div class="pb-2 rounded-md bg-default sm:bg-default"> <div class="pb-2 rounded-md bg-default sm:bg-default">
<div class="text-white text-[1rem] mt-3"> <div class="text-white text-[1rem] mt-3">
@ -260,53 +275,14 @@
>. >.
</div> </div>
{#if optionsPieChart !== null} <div
<div class="flex flex-row items-center sm:-mt-5"> class="border border-gray-800 rounded w-full mt-3"
<div class="app w-56"> use:highcharts={config}
<Chart {init} options={optionsPieChart} class="chart w-full" /> ></div>
</div>
<div class="flex flex-col items-center sm:pt-0 m-auto">
<div class="flex flex-row items-center mr-auto mb-5">
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-4 h-4 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-sm sm:text-[1rem] inline-block">
Others: {otherOwner >= 99.99
? 99.99
: otherOwner?.toFixed(2)}%
</span>
</div>
<div class="flex flex-row items-center mr-auto">
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-4 h-4 bg-blue-500 border-4 box-content border-[#27272A] rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-sm sm:text-[1rem] inline-block">
Institutions: {institutionalOwner <= 0.01
? "< 0.01%"
: institutionalOwner?.toFixed(2) + "%"}
</span>
</div>
</div>
</div>
{/if}
</div> </div>
{#if putCallRatio !== 0} {#if putCallRatio !== 0}
<h1 <h1 class="text-white font-semibold text-xl sm:text-2xl mb-3 mt-5">
class="text-white font-semibold text-xl sm:text-2xl mb-3 mt-5 sm:-mt-5"
>
Options Activity Options Activity
</h1> </h1>
@ -492,30 +468,33 @@
</div> </div>
{/if} {/if}
<h3 class="text-white font-semibold text-xl sm:text-2xl mb-3 mt-5"> <div class="flex flex-row items-center justify-between mb-3">
Top Shareholders <h3 class="text-white font-semibold text-xl sm:text-2xl">
</h3> Top Shareholders
</h3>
{#if topHolders !== 0} {#if topHolders !== 0}
<span class="text-white text-[1rem"> <span class="text-white text-[1rem">
The Top 10 shareholders collectively own <span class="font-semibold" The Top 10 shareholders collectively own <span class="font-semibold"
>{topHolders <= 0.01 >{topHolders <= 0.01
? "< 0.01%" ? "< 0.01%"
: topHolders?.toFixed(2) + "%"}</span : topHolders?.toFixed(2) + "%"}</span
> >
of the {$displayCompanyName} of the {$displayCompanyName}
</span> </span>
{/if} {/if}
<div class="flex justify-end items-end ml-auto w-fit mt-5"> <div class="flex justify-end items-end ml-auto w-fit">
<DownloadData <DownloadData
{data} {data}
rawData={shareholderList} rawData={shareholderList}
title={`13-institute-${$stockTicker}`} title={`13-institute-${$stockTicker}`}
/> />
</div>
</div> </div>
<div <div
class="flex justify-start items-center w-full m-auto mt-6 overflow-x-auto" class="flex justify-start items-center w-full m-auto mt-3 overflow-x-auto"
> >
<table <table
class="table table-sm table-compact bg-table border border-gray-800 w-full" class="table table-sm table-compact bg-table border border-gray-800 w-full"
@ -608,21 +587,3 @@
{/if} {/if}
</main> </main>
</section> </section>
<style>
.app {
height: 300px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */
}
@media (max-width: 640px) {
.app {
height: 150px;
width: 150px;
}
}
.chart {
width: 100%;
}
</style>

View File

@ -934,11 +934,11 @@
{:else if column.type === "percentSign"} {:else if column.type === "percentSign"}
{#if item[column.key] > 0} {#if item[column.key] > 0}
<span class="text-[#00FC50]" <span class="text-[#00FC50]"
>+{item[column.key]?.toFixed(2)}%</span >+{abbreviateNumber(item[column.key]?.toFixed(2))}%</span
> >
{:else if item[column.key] < 0} {:else if item[column.key] < 0}
<span class="text-[#FF2F1F]" <span class="text-[#FF2F1F]"
>{item[column.key]?.toFixed(2)}%</span >{abbreviateNumber(item[column.key]?.toFixed(2))}%</span
> >
{:else} {:else}
<span class="text-[#fff]" <span class="text-[#fff]"

View File

@ -3,7 +3,6 @@
import Table from "$lib/components/Table/Table.svelte"; import Table from "$lib/components/Table/Table.svelte";
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte"; import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
import SEO from "$lib/components/SEO.svelte"; import SEO from "$lib/components/SEO.svelte";
import cardBackground from "$lib/images/bg-hedge-funds.png";
import defaultAvatar from "$lib/images/hedge-fund-avatar.png"; import defaultAvatar from "$lib/images/hedge-fund-avatar.png";

View File

@ -11,21 +11,19 @@
export let data; export let data;
</script> </script>
<SEO
title={`${$displayCompanyName} (${$stockTicker}) 13F Institute Ownership · Stocknear`}
<SEO title={`${$displayCompanyName} (${$stockTicker}) 13F Institute Ownership · Stocknear`}
description={`Get the latest 13F Institute Ownership of ${$displayCompanyName} (${$stockTicker}).`} description={`Get the latest 13F Institute Ownership of ${$displayCompanyName} (${$stockTicker}).`}
/> />
<section class="w-full bg-default overflow-hidden text-white h-full"> <section class="w-full bg-default overflow-hidden text-white h-full">
<div class="w-full flex h-full overflow-hidden"> <div class="w-full flex h-full overflow-hidden">
<div <div
class="w-full relative flex justify-center items-center overflow-hidden" class="w-full relative flex justify-center items-center overflow-hidden"
> >
<div class="sm:pl-7 sm:pb-7 sm:pt-7 w-full m-auto mt-2 sm:mt-0"> <div class="sm:pl-7 sm:pb-7 sm:pt-7 w-full m-auto mt-2 sm:mt-0">
<div class="w-full mb-6"> <div class="w-full">
<h1 class="text-xl sm:text-2xl text-white font-bold mb-4"> <h1 class="text-xl sm:text-2xl text-white font-bold">
13F Institute Ownership 13F Institute Ownership
</h1> </h1>
</div> </div>