This commit is contained in:
MuslemRahimi 2025-02-25 20:40:56 +01:00
parent 0d320f9be1
commit 78ceb29592
6 changed files with 19 additions and 325 deletions

View File

@ -1,32 +1,8 @@
<script lang="ts">
import { screenWidth } from "$lib/store";
import { abbreviateNumberWithColor } from "$lib/utils";
import InfoModal from "$lib/components/InfoModal.svelte";
import { Chart } from "svelte-echarts";
import { init, use } from "echarts/core";
import { LineChart, BarChart } from "echarts/charts";
import {
GridComponent,
TooltipComponent,
LegendComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
use([
LineChart,
BarChart,
GridComponent,
TooltipComponent,
LegendComponent,
CanvasRenderer,
]);
export let tickerFlow = [];
let isLoading = false;
let optionsData = null;
function findLastNonNull(dataArray, key) {
for (let i = dataArray.length - 1; i >= 0; i--) {
@ -68,262 +44,6 @@
return formattedDate;
}
function getPlotOptions() {
isLoading = true;
let dates = tickerFlow?.map((item) => item?.time);
const priceList = tickerFlow?.map((item) =>
item?.close !== null ? item?.close?.toFixed(2) : item?.close,
);
const netCallPremList = tickerFlow?.map((item) => item?.net_call_premium);
const netPutPremList = tickerFlow?.map((item) => item?.net_put_premium);
const volumeList = tickerFlow?.map((item) => item?.net_volume);
const positiveVolume = volumeList.map((v) => (v >= 0 ? v : "-"));
const negativeVolume = volumeList.map((v) => (v < 0 ? v : "-"));
const options = {
silent: true,
animation: false,
legend: {
data: ["Price", "Vol", "Net Call Premium", "Net Put Premium"],
textStyle: {
color: "#fff",
},
axisPointer: {
lineStyle: {
color: "#fff",
},
},
},
tooltip: {
trigger: "axis",
hideDelay: 100,
borderColor: "#969696",
borderWidth: 1,
backgroundColor: "#313131",
textStyle: {
color: "#fff",
},
formatter: function (params) {
const timestamp = params[0].axisValue;
let result = timestamp + "<br/>";
// Find volume value and determine color
const volParams = params.find((p) => p.seriesName.includes("Vol"));
const volIndex = volParams?.dataIndex ?? 0;
const volValue = volumeList[volIndex];
const volColor = volValue >= 0 ? "#90EE90" : "#FF6B6B";
// Sort and filter params
const filteredParams = params
.filter(
(p) =>
!p.seriesName.includes("Vol") ||
p.seriesName === "Positive Vol",
)
.map((p) => {
if (p.seriesName.includes("Vol")) {
return {
...p,
seriesName: "Vol",
value: volValue,
color: volColor,
};
}
return p;
})
.sort((a, b) => {
if (a.seriesName === "Vol") return 1;
if (b.seriesName === "Vol") return -1;
return 0;
});
filteredParams.forEach((param) => {
const marker =
'<span style="display:inline-block;margin-right:4px;' +
"border-radius:10px;width:10px;height:10px;background-color:" +
param.color +
'"></span>';
result +=
marker +
param.seriesName +
": " +
abbreviateNumberWithColor(param.value, false, true) +
"<br/>";
});
return result;
},
axisPointer: {
lineStyle: {
color: "#fff",
},
},
},
axisPointer: {
link: [{ xAxisIndex: [0, 1] }],
},
grid: [
{
left: $screenWidth < 640 ? "3%" : "0%",
right: $screenWidth < 640 ? "3%" : "0%",
top: $screenWidth < 640 ? "15%" : "5%",
height: "60%",
containLabel: true,
},
{
left: "3%",
right: "3%",
bottom: "5%",
height: "20%",
containLabel: true,
},
],
xAxis: [
{
type: "category",
boundaryGap: false,
data: dates,
axisLabel: {
color: "#fff",
formatter: (value, index) => {
const [datePart, timePart] = value.split(" ");
let [hours, minutes] = timePart.split(":").map(Number);
// Only show labels at 30-minute intervals (XX:00 and XX:30)
if (minutes % 30 === 0) {
const amPm = hours >= 12 ? "PM" : "AM";
hours = hours % 12 || 12;
return minutes === 0
? `${hours} ${amPm}`
: `${hours}:30 ${amPm}`;
}
return "";
},
interval: 30,
},
},
{
type: "category",
gridIndex: 1,
data: dates,
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
yAxis: [
{
type: "value",
gridIndex: 0,
position: "left",
splitLine: {
show: false,
},
axisLabel: {
color: "#fff",
show: true,
},
scale: true,
min: (value) => Math.floor(value.min * 0.999),
max: (value) => Math.ceil(value.max * 1.001),
},
{
type: "value",
gridIndex: 0,
position: "right",
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
{
type: "value",
gridIndex: 1,
position: "right",
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
series: [
{
name: "Price",
type: "line",
data: priceList,
yAxisIndex: 0,
xAxisIndex: 0,
showSymbol: false,
lineStyle: { color: "#fff" },
itemStyle: { color: "#fff" },
smooth: true,
},
{
name: "Net Call Premium",
type: "line",
data: netCallPremList,
yAxisIndex: 1,
xAxisIndex: 0,
showSymbol: false,
lineStyle: { color: "#90EE90" },
itemStyle: { color: "#90EE90" },
smooth: true,
},
{
name: "Net Put Premium",
type: "line",
data: netPutPremList,
yAxisIndex: 1,
xAxisIndex: 0,
showSymbol: false,
lineStyle: { color: "#FF6B6B" },
itemStyle: { color: "#FF6B6B" },
smooth: true,
},
{
name: "Positive Vol",
type: "line",
data: positiveVolume,
xAxisIndex: 1,
yAxisIndex: 2,
showSymbol: false,
areaStyle: {
opacity: 1,
color: "#19AA75",
},
itemStyle: { color: "#19AA75" },
},
{
name: "Negative Vol",
type: "line",
data: negativeVolume,
xAxisIndex: 1,
yAxisIndex: 2,
showSymbol: false,
areaStyle: {
opacity: 1,
color: "#F71F4F",
},
itemStyle: { color: "#F71F4F" },
},
],
};
isLoading = false;
return options;
}
optionsData = tickerFlow ? getPlotOptions() : null;
</script>
<section class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden">
@ -334,7 +54,7 @@
>
<main class="w-full">
<div class="w-full m-auto">
{#if optionsData !== null}
{#if tickerFlow?.length > 0}
<label
for="dailyNetPutCallPrem"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-2xl font-bold w-fit"
@ -414,26 +134,14 @@
</div>
</div>
</div>
<!--
<div>
<div class="app w-full h-[250px] mt-5">
{#if isLoading}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-secondary z-10 rounded-md 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-white"
></span>
</label>
</div>
</div>
{:else}
<Chart {init} options={optionsData} class="chart" />
{/if}
</div>
<div
class="chart border border-gray-800 rounded"
use:highcharts={config}
></div>
</div>
-->
{/if}
</div>
</main>
@ -441,20 +149,3 @@
</div>
</div>
</section>
<style>
.app {
height: 400px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */
}
@media (max-width: 640px) {
.app {
height: 400px;
}
}
.chart {
width: 100%;
}
</style>

View File

@ -156,6 +156,7 @@
backgroundColor: "#09090B",
plotBackgroundColor: "#09090B",
height: 360,
width: 850,
animation: false,
},
title: {

View File

@ -36,7 +36,7 @@
</ul>
</div>
<div class="w-full overflow-hidden m-auto mt-5">
<div class="w-full overflow-hidden m-auto mt-5 sm:max-w-[1400px]">
<div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden">
<div
class="relative flex justify-center items-start overflow-hidden w-full"

View File

@ -10,7 +10,6 @@
import highcharts from "$lib/highcharts.ts";
export let data;
let isLoading = false;
let config = null;
//let sectorData = data?.getData?.sectorData || [];
let topPosNetPremium = data?.getData?.topPosNetPremium || [];
@ -211,8 +210,6 @@
?.slice(0, 50);
};
function getPlotOptions() {
isLoading = true;
// Determine the base date (using the first data point, or fallback to today)
const baseDate =
marketTideData && marketTideData.length
@ -261,7 +258,7 @@
backgroundColor: "#09090B",
plotBackgroundColor: "#09090B",
height: 360, // Set the maximum height for the chart
width: 970,
reflow: true, // Automatically resize the chart when the container resizes
animation: false,
},
@ -423,7 +420,6 @@
},
};
isLoading = false;
return options;
}
@ -519,7 +515,7 @@
</div>
<div
class="chart border border-gray-800 rounded"
class=" border border-gray-800 rounded w-full"
use:highcharts={config}
></div>
{/if}
@ -742,3 +738,10 @@
</div>
</div>
</section>
<style lang="scss">
.chart {
width: 100%;
transition: none;
}
</style>

View File

@ -283,7 +283,6 @@
backgroundColor: "#09090B",
plotBackgroundColor: "#09090B",
height: 360, // Set the maximum height for the chart
width: 970,
animation: false,
},

View File

@ -305,7 +305,7 @@
{/if}
{#if tickerFlow?.length > 0}
<div class="w-full mb-10">
<div class="w-full">
<TickerFlow {tickerFlow} />
</div>
{/if}