diff --git a/src/lib/components/FailToDeliver.svelte b/src/lib/components/FailToDeliver.svelte index b365858f..95dc61dc 100644 --- a/src/lib/components/FailToDeliver.svelte +++ b/src/lib/components/FailToDeliver.svelte @@ -5,21 +5,19 @@ assetType, etfTicker, } from "$lib/store"; - import { Chart } from "svelte-echarts"; - import { abbreviateNumber, monthNames } from "$lib/utils"; - - import { init, use } from "echarts/core"; - import { LineChart } from "echarts/charts"; - import { GridComponent, TooltipComponent } from "echarts/components"; - import { CanvasRenderer } from "echarts/renderers"; + import { + abbreviateNumber, + monthNames, + removeCompanyStrings, + } from "$lib/utils"; + import highcharts from "$lib/highcharts.ts"; export let data; export let rawData = []; - use([LineChart, GridComponent, TooltipComponent, CanvasRenderer]); + let config = null; let isLoaded = false; - let optionsData; let avgFailToDeliver; let weightedFTD; @@ -92,117 +90,130 @@ }); const totalNumber = failToDeliverList?.reduce((acc, item) => acc + item, 0); - avgFailToDeliver = (totalNumber / failToDeliverList?.length)?.toFixed(0); + avgFailToDeliver = Math?.floor(totalNumber / failToDeliverList?.length); - const option = { - silent: true, - tooltip: { - trigger: "axis", - hideDelay: 100, - borderColor: "#969696", // Black border color - borderWidth: 1, // Border width of 1px - backgroundColor: "#313131", // Optional: Set background color for contrast - textStyle: { - color: "#fff", // Optional: Text color for better visibility + const options = { + credits: { + enabled: false, + }, + chart: { + // Removed global type so each series can define its own type. + backgroundColor: "#09090B", + plotBackgroundColor: "#09090B", + height: 360, + animation: false, + }, + title: { + text: `

${removeCompanyStrings($displayCompanyName)} FTD

`, + style: { + color: "white", }, - formatter: function (params) { - // Get the timestamp from the first parameter - const timestamp = params[0].axisValue; - - // Initialize result with timestamp - let result = timestamp + "
"; - - // Add each series data - params.forEach((param) => { - const marker = - ''; - result += - marker + - param.seriesName + - ": " + - abbreviateNumber(param.value, false, true) + - "
"; - }); - - return result; - }, - axisPointer: { - lineStyle: { - color: "#fff", + useHTML: true, + }, + plotOptions: { + series: { + color: "white", + animation: false, + dataLabels: { + enabled: false, + style: { + fontSize: "13px", + fontWeight: "bold", + }, + formatter: function () { + return abbreviateNumber(this.y); + }, }, }, }, - animation: false, - grid: { - left: "3%", - right: "3%", - bottom: "2%", - top: "5%", - containLabel: true, + legend: { + enabled: false, }, + tooltip: { + useHTML: true, + backgroundColor: "#fff", + style: { + color: "black", + fontSize: "16px", + padding: "10px", + }, + borderRadius: 2, + borderWidth: 1, + borderColor: "#ffffff", + formatter: function () { + return `${new Date( + this?.x, + ).toLocaleDateString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + })}
${abbreviateNumber(this.y)}`; + }, + }, + xAxis: { - type: "category", - boundaryGap: false, - data: dates, - axisLabel: { - color: "#fff", - formatter: function (value) { - const dateParts = value.split("-"); + categories: dates, + labels: { + style: { + color: "#fff", + }, + formatter: function () { + const dateParts = this.value.split("-"); const day = dateParts[2].substring(0); - const monthIndex = parseInt(dateParts[1]) - 1; + const monthIndex = parseInt(dateParts[1], 10) - 1; return `${day} ${monthNames[monthIndex]}`; }, }, }, yAxis: [ { - type: "value", - splitLine: { - show: false, + gridLineWidth: 0, + labels: { + enabled: false, }, - axisLabel: { - show: false, + title: { + text: null, }, }, { - type: "value", - splitLine: { - show: false, + gridLineWidth: 0, + labels: { + enabled: false, }, - position: "right", - axisLabel: { - show: false, + title: { + text: null, }, + opposite: true, }, ], series: [ { - name: "Price", - data: priceList, - type: "line", - itemStyle: { - color: "#fff", + // FTD Shares area series drawn first (behind the line) + name: "FTD Shares", + type: "area", + data: failToDeliverList, + fillOpacity: 1, + yAxis: 1, + color: "#E11D48", + marker: { + fillColor: "transparent", }, - showSymbol: false, }, { - name: "FTD Shares", - data: failToDeliverList, + // Price line series drawn on top + name: "Price", type: "line", - areaStyle: { opacity: 1 }, - yAxisIndex: 1, - itemStyle: { - color: "#E11D48", + data: priceList, + color: "#fff", + marker: { + fillColor: "transparent", }, - showSymbol: false, + lineWidth: 2, }, ], }; - return option; + return options; } $: { @@ -215,7 +226,7 @@ data?.getStockQuote?.avgVolume) * 100 )?.toFixed(2); - optionsData = getPlotOptions(); + config = getPlotOptions(); } isLoaded = true; } @@ -224,8 +235,8 @@
-
-

FTD Chart

+
+

FTD Chart

{#if isLoaded} @@ -235,55 +246,15 @@ Over the past year, {$displayCompanyName} has seen a monthly average of {abbreviateNumber(avgFailToDeliver)} fail to deliver shares. -
- - -
-
- + >{avgFailToDeliver?.toLocaleString("en-US")} + fail to deliver shares.
-
- - - - Price - -
-
- - - - Share Quantity - -
-
+ class="chart mt-5 sm:mt-0 border border-gray-800 rounded" + use:highcharts={config} + >
Date + Price FTD Shares @@ -371,6 +343,12 @@ {item?.date} + + {item?.price} + + diff --git a/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+page.svelte b/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+page.svelte index 722feed7..51a6ea2b 100644 --- a/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+page.svelte +++ b/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+page.svelte @@ -77,7 +77,7 @@ {#if rawData?.length !== 0}