add tooltip to graphs

This commit is contained in:
MuslemRahimi 2024-09-23 18:03:15 +02:00
parent 214b98eb67
commit e2d8934fe7
5 changed files with 110 additions and 179 deletions

View File

@ -126,7 +126,8 @@ function findLowestAndHighestFee(data, lastDateStr) {
},
],
series: [
{
{
name: 'Available Shares',
data: availableList,
type: 'line',
itemStyle: {
@ -135,6 +136,7 @@ function findLowestAndHighestFee(data, lastDateStr) {
showSymbol: false
},
{
name: 'Fee [%]',
data: feeList,
type: 'line',
areaStyle: {opacity: 1},

View File

@ -94,7 +94,7 @@
>
<div
class="circle"
style="left:{d.x}px;top:{d.y}px;width:{d.r * ballSize}px;height:{d.r * ballSize}px;background-color:{(index === 1 && d.data.id === 'puts') ? '#FF2F1F' : (index === 1 && d.data.id === 'calls') ? '#0FB307' : '#1E1E1E'}; border: 0px solid #000;"
style="left:{d.x}px;top:{d.y}px;width:{d.r * ballSize}px;height:{d.r * ballSize}px;background-color:{(index === 1 && d.data.id === 'puts') ? '#FF2F1F' : (index === 1 && d.data.id === 'calls') ? '#37C97D' : '#1E1E1E'}; border: 0px solid #000;"
/>
<div
class="text-group"

View File

@ -109,7 +109,8 @@ function getPlotOptions() {
},
],
series: [
{
{
name: 'Total Volume',
data: totalVolumeList,
type: 'line',
itemStyle: {
@ -118,12 +119,12 @@ function getPlotOptions() {
showSymbol: false
},
{
name: 'Short Volume',
data: shortVolumeList,
type: 'line',
areaStyle: {opacity: 1},
itemStyle: {
color: '#3B82F6' // Change bar color to white
color: '#E11D48' // Change bar color to white
},
showSymbol: false
},
@ -232,7 +233,7 @@ $: {
</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-[#536FC5] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
<div class="w-3 h-3 bg-[#E11D48] 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">
Short Volume
</span>

View File

@ -6,14 +6,13 @@
import { BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import { monthNames} from '$lib/utils';
export let data;
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
let isLoaded = false;
@ -22,25 +21,6 @@
let sentiment;
function normalizer(value) {
if (Math?.abs(value) >= 1e18) {
return { unit: 'Q', denominator: 1e18 };
} else if (Math?.abs(value) >= 1e12) {
return { unit: 'T', denominator: 1e12 };
} else if (Math?.abs(value) >= 1e9) {
return { unit: 'B', denominator: 1e9 };
} else if (Math?.abs(value) >= 1e6) {
return { unit: 'M', denominator: 1e6 };
} else if (Math?.abs(value) >= 1e5) {
return { unit: 'K', denominator: 1e5 };
} else if (Math?.abs(value) >= 1e4) {
return { unit: 'K', denominator: 1e4 };
} else {
return { unit: '', denominator: 1 };
}
}
function getPlotOptions() {
let dates = [];
let priceList = [];
@ -59,7 +39,6 @@
sentiment = netCallList?.slice(-1)?.at(0) > netPutList?.slice(-1)?.at(0) ? 'bullish' : 'bearish';
const {unit, denominator } = normalizer(Math.max(...netCallList) ?? 0)
const option = {
silent: true,
@ -69,8 +48,8 @@
},
animation: false,
grid: {
left: '1%',
right: '2%',
left: '3%',
right: '3%',
bottom: '0%',
top: '10%',
containLabel: true
@ -95,23 +74,15 @@
}
},
yAxis: [
{
type: 'value',
splitLine: {
{
type: 'value',
splitLine: {
show: false, // Disable x-axis grid lines
},
axisLabel: {
color: '#fff', // Change label color to white
formatter: function (value, index) {
// Display every second tick
if (index % 2 === 0) {
//value = Math.max(value, 0);
return '$'+(value / denominator)?.toFixed(0) + unit; // Format value in millions
} else {
return ''; // Hide this tick
}
}
},
},
axisLabel: {
show: false // Hide y-axis labels
}
},
],
@ -253,8 +224,7 @@
</div>
{/if}
{:else}

View File

@ -1,195 +1,155 @@
<script lang ='ts'>
<script lang="ts">
import { abbreviateNumber } from "$lib/utils";
import { swapComponent, stockTicker, screenWidth, getCache, setCache } 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
import { swapComponent, stockTicker, screenWidth, getCache, setCache} from '$lib/store';
import InfoModal from '$lib/components/InfoModal.svelte';
import { Chart } from 'svelte-echarts'
use([ScatterChart, GridComponent, TooltipComponent, CanvasRenderer]);
import { init, use } from 'echarts/core'
import { BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers';
export let data;
let isLoaded = false;
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
let isLoaded = false;
const tabs = [
{
title: "Effective Date",
},
{
title: "Expiration Date",
}
const tabs = [
{ title: "Effective Date" },
{ title: "Expiration Date" },
];
let activeIdx = 0;
function changeTab(index) {
function changeTab(index: number) {
activeIdx = index;
optionsData = getPlotOptions(activeIdx === 0 ? 'effectiveDate' : 'expirationDate');
}
let rawData = [];
let optionsData;
let avgNotionalAmount;
let avgNotionalQuantity;
let rawData: any[] = [];
let optionsData: any;
let avgNotionalAmount: number | undefined;
let avgNotionalQuantity: number | undefined;
function normalizer(value) {
if (Math?.abs(value) >= 1e18) {
return { unit: 'Q', denominator: 1e18 };
} else if (Math?.abs(value) >= 1e12) {
return { unit: 'T', denominator: 1e12 };
} else if (Math?.abs(value) >= 1e9) {
return { unit: 'B', denominator: 1e9 };
} else if (Math?.abs(value) >= 1e6) {
return { unit: 'M', denominator: 1e6 };
} else if (Math?.abs(value) >= 1e5) {
return { unit: 'K', denominator: 1e3 };
} else if (Math?.abs(value) >= 1e4) {
return { unit: 'K', denominator: 1e3 };
} else {
return { unit: '', denominator: 1 };
}
}
function getPlotOptions(state) {
const combinedData = rawData?.map(item => ({
function getPlotOptions(state: 'effectiveDate' | 'expirationDate') {
const combinedData = rawData?.map((item) => ({
date: state === 'effectiveDate' ? item['Effective Date'] : item['Expiration Date'],
notionalAmount: item['Notional amount-Leg 1'],
notionalQuantity: item['Total notional quantity-Leg 1']
notionalQuantity: item['Total notional quantity-Leg 1'],
}));
// Group data by date and sum the values
const groupedData = combinedData.reduce((acc, curr) => {
const { date, notionalAmount, notionalQuantity } = curr;
// If the date already exists in the accumulator, sum up the values
if (acc[date]) {
acc[date].notionalAmount += notionalAmount;
acc[date].notionalQuantity += notionalQuantity;
} else {
// Otherwise, create a new entry for this date
acc[date] = {
date,
notionalAmount,
notionalQuantity
notionalQuantity,
};
}
return acc;
}, {});
}, {} as Record<string, any>);
// Convert the grouped data back to an array
const result = Object.values(groupedData);
// Sort the result array based on the date
result?.sort((a, b) => new Date(a?.date) - new Date(b?.date));
result?.sort((a, b) => new Date(a?.date).getTime() - new Date(b?.date).getTime());
// Separate the sorted data back into individual arrays
const dates = result?.map(item => item?.date);
const notionalAmount = result?.map(item => item?.notionalAmount);
const notionalQuantity = result?.map(item => item?.notionalQuantity);
const dates = result?.map((item) => item?.date);
const notionalAmount = result?.map((item) => item?.notionalAmount);
const notionalQuantity = result?.map((item) => item?.notionalQuantity);
// Compute the average of item?.traded
const totalNotionalAmount = notionalAmount?.reduce((acc, item) => acc + item, 0);
avgNotionalAmount = totalNotionalAmount / notionalAmount?.length;
const totalNotionalQuantity = notionalQuantity?.reduce((acc, item) => acc + item, 0);
avgNotionalQuantity = totalNotionalQuantity / notionalQuantity?.length;
const option = {
silent: true,
tooltip: {
silent: true,
tooltip: {
trigger: 'axis',
hideDelay: 100, // Set the delay in milliseconds
},
animation: false,
grid: {
hideDelay: 100,
},
animation: false,
grid: {
left: '3%',
right: '3%',
bottom: '0%',
top: '10%',
containLabel: true
},
xAxis:
{
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: dates,
axisLabel: {
color: '#fff',
}
},
yAxis: [
{
type: 'value',
splitLine: {
show: false, // Disable x-axis grid lines
},
axisLabel: {
show: false // Hide y-axis labels
}
},
{
type: 'value',
splitLine: {
show: false, // Disable x-axis grid lines
color: '#fff',
},
position: 'right',
axisLabel: {
show: false // Hide y-axis labels
},
},
],
series: [
{
name: 'Notional Amount',
type: 'bar',
data: notionalAmount,
barWidth: '50%',
itemStyle: {
color: '#8F54F4'
}
},
{
name: 'Notional Quantity',
type: 'bar',
data: notionalQuantity,
barWidth: '50%',
yAxisIndex: 1,
itemStyle: {
color: '#FF9E21'
}
}
]
},
yAxis: [
{
type: 'value',
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
{
type: 'value',
splitLine: {
show: false,
},
position: 'right',
axisLabel: {
show: false,
},
},
],
series: [
{
name: 'Notional Amount',
type: 'scatter',
data: dates?.map((date, index) => [date, notionalAmount[index]]),
itemStyle: {
color: '#8F54F4',
},
},
{
name: 'Notional Quantity',
type: 'scatter',
data: dates?.map((date, index) => [date, notionalQuantity[index]]),
yAxisIndex: 1,
itemStyle: {
color: '#FF9E21',
},
},
],
};
return option;
return option;
}
async function getSwapData(ticker) {
async function getSwapData(ticker: string) {
const cachedData = getCache(ticker, 'getSwapData');
if (cachedData) {
rawData = cachedData;
} else {
try {
const postData = {ticker: ticker, path: 'swap-ticker'}
const postData = { ticker, path: 'swap-ticker' };
const response = await fetch('/api/ticker-data', {
method: 'POST',
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');
rawData = await response.json();
@ -199,7 +159,7 @@
rawData = [];
}
}
$swapComponent = rawData?.length !== 0;
$swapComponent = rawData?.length !== 0; // Correct the use of `$`
}
$: if ($stockTicker && typeof window !== 'undefined') {
@ -211,12 +171,10 @@
});
}
$: charNumber = $screenWidth < 640 ? 20 : 40;
</script>
<svelte:options immutable={true} />
<section class="overflow-hidden text-white h-full pb-8">