aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-16 00:09:44 -0500
committermat <github@matdoes.dev>2022-05-16 00:09:44 -0500
commitcd9748e59f1dd9ef31afb22195b8d5a1346ec5c3 (patch)
treed6f134b778a6a2b9ff9f00a4f4d24196191dba53
parent41dc70e3af49fc11383d0dff3bbe8f006272bed9 (diff)
downloadskyblock-stats-cd9748e59f1dd9ef31afb22195b8d5a1346ec5c3.tar.gz
skyblock-stats-cd9748e59f1dd9ef31afb22195b8d5a1346ec5c3.tar.bz2
skyblock-stats-cd9748e59f1dd9ef31afb22195b8d5a1346ec5c3.zip
start adding auctionprices page
-rw-r--r--src/lib/APITypes.d.ts19
-rw-r--r--src/lib/AuctionPriceScatterplot.svelte49
-rw-r--r--src/routes/auctionprices.svelte114
-rw-r--r--src/routes/index.svelte2
4 files changed, 183 insertions, 1 deletions
diff --git a/src/lib/APITypes.d.ts b/src/lib/APITypes.d.ts
index 6402721..6429e8b 100644
--- a/src/lib/APITypes.d.ts
+++ b/src/lib/APITypes.d.ts
@@ -434,3 +434,22 @@ export interface AccessoryBagUpgrades {
list: string[]
}
}
+
+export interface SimpleAuctionSchema {
+ /** The UUID of the auction so we can look it up later. */
+ id: string
+ coins: number
+ /**
+ * The timestamp as **seconds** since epoch. It's in seconds instead of ms
+ * since we don't need to be super exact and so it's shorter.
+ */
+ ts: number
+ /** Whether the auction was bought or simply expired. */
+ success: boolean
+ bin: boolean
+}
+export interface ItemAuctionsSchema {
+ /** The id of the item */
+ _id: string
+ auctions: SimpleAuctionSchema[]
+}
diff --git a/src/lib/AuctionPriceScatterplot.svelte b/src/lib/AuctionPriceScatterplot.svelte
new file mode 100644
index 0000000..f887725
--- /dev/null
+++ b/src/lib/AuctionPriceScatterplot.svelte
@@ -0,0 +1,49 @@
+<script lang="ts">
+ import type { ItemAuctionsSchema } from './APITypes'
+
+ export let item: ItemAuctionsSchema
+
+ let maxCoins: number = item.auctions.reduce((max, auction) => Math.max(max, auction.coins), 0)
+
+ let currentTimestamp = Math.floor(Date.now() / 1000)
+
+ let lowestCoinsAuction = item.auctions.reduce(
+ (min, auction) => (auction.coins < min.coins ? auction : min),
+ { coins: Infinity, ts: currentTimestamp }
+ )
+
+ let earliestTimestamp = item.auctions.length > 0 ? item.auctions[0].ts : 0
+
+ let minutesBetween = (currentTimestamp - earliestTimestamp) / 360
+
+ let gridWidth = 100 / minutesBetween
+</script>
+
+<svg viewBox="0 0 100 100" class="item-auction-history">
+ <defs>
+ <pattern id="grid-{item._id}" width={gridWidth} height="10" patternUnits="userSpaceOnUse">
+ <path d="M {gridWidth} 0 L 0 0 0 10" fill="none" stroke="#fff2" stroke-width="1" />
+ </pattern>
+ </defs>
+ <rect width="100%" height="100%" fill="url(#grid-{item._id})" />
+
+ {#each item.auctions as auction}
+ {@const timestampPercentage =
+ (auction.ts - earliestTimestamp) / (currentTimestamp - earliestTimestamp)}
+ <circle
+ cx={timestampPercentage * 100}
+ cy={100 - (auction.coins / maxCoins) * 100}
+ r="1"
+ stroke-width="4"
+ fill={auction.bin ? '#11b' : '#1b1'}
+ />
+ {/each}
+ <!-- {item.auctions} -->
+</svg>
+
+<style>
+ .item-auction-history {
+ height: 10em;
+ width: 100%;
+ }
+</style>
diff --git a/src/routes/auctionprices.svelte b/src/routes/auctionprices.svelte
new file mode 100644
index 0000000..f464f7b
--- /dev/null
+++ b/src/routes/auctionprices.svelte
@@ -0,0 +1,114 @@
+<script lang="ts" context="module">
+ import type { Load } from '@sveltejs/kit'
+ import { API_URL } from '$lib/api'
+
+ export const load: Load = async ({ params, fetch }) => {
+ const data = await fetch(`${API_URL}auctionprices`).then(r => r.json())
+
+ return {
+ props: {
+ data,
+ },
+ }
+ }
+</script>
+
+<script lang="ts">
+ import Header from '$lib/Header.svelte'
+ import Head from '$lib/Head.svelte'
+ import { millisecondsToTime, TIER_COLORS, colorCodes, cleanId, toTitleCase } from '$lib/utils'
+ import type { ItemAuctionsSchema, ItemListData, ItemListItem } from '$lib/APITypes'
+ import Item from '$lib/minecraft/Item.svelte'
+ import AuctionPriceScatterplot from '$lib/AuctionPriceScatterplot.svelte'
+
+ export let data: ItemAuctionsSchema[]
+
+ let query: string = ''
+
+ let pageHeight = 0
+ $: {
+ pageHeight = 0
+ }
+
+ function checkScroll() {
+ let pageHeightTemp = window.scrollY + window.innerHeight
+ if (pageHeightTemp <= pageHeight) return
+ pageHeight = pageHeightTemp
+ if (pageHeight >= document.body.scrollHeight - 1000) {
+ }
+ }
+</script>
+
+<Head title="SkyBlock Item List" />
+<Header />
+
+<svelte:window on:scroll={checkScroll} />
+
+<main>
+ <h1>SkyBlock Auction Prices</h1>
+ <div class="filter-items-settings">
+ <input type="text" id="filter-items-tier" placeholder="Search..." bind:value={query} />
+ </div>
+ <div class="item-list">
+ {#each data as item (item._id)}
+ {@const binAuctions = item.auctions.filter(i => i.bin)}
+ {@const normalAuctions = item.auctions.filter(i => !i.bin)}
+ <div class="item-container">
+ <h2>{cleanId(item._id.toLowerCase())}</h2>
+ <div class="auctions-info-text">
+ {#if binAuctions.length > 0}
+ <p>
+ Lowest recent BIN: <b>
+ {binAuctions.reduce((a, b) => (a.coins < b.coins ? a : b)).coins.toLocaleString()} coins
+ </b>
+ </p>
+ {/if}
+ {#if normalAuctions.length > 0}
+ <p>
+ Lowest recent auction: <b>
+ {normalAuctions
+ .reduce((a, b) => (a.coins < b.coins ? a : b))
+ .coins.toLocaleString()} coins
+ </b>
+ </p>
+ {/if}
+ </div>
+ <div class="item-scatterplot">
+ <AuctionPriceScatterplot {item} />
+ </div>
+ </div>
+ {/each}
+ {#if data.length === 0}
+ No results
+ {/if}
+ </div>
+</main>
+
+<style>
+ p {
+ margin: 0;
+ }
+ .item-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+ grid-gap: 1em;
+ margin-top: 1em;
+ }
+ .item-container {
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ background: rgba(0, 0, 0, 0.1);
+ padding: 0.75em;
+ border-radius: 1em;
+ }
+
+ .item-scatterplot {
+ margin-top: 1em;
+ }
+
+ .auctions-info-text {
+ color: var(--theme-darker-text);
+ }
+ .auctions-info-text b {
+ color: var(--theme-main-text);
+ }
+</style>
diff --git a/src/routes/index.svelte b/src/routes/index.svelte
index 4c11a88..d22f854 100644
--- a/src/routes/index.svelte
+++ b/src/routes/index.svelte
@@ -49,7 +49,7 @@
<section>
<h2>Other SkyBlock tools</h2>
<ul id="other-tools-list">
- <li><a>Auction prices (coming soon)</a></li>
+ <li><a href="/auctionprices">Auction prices</a></li>
<li><a href="/leaderboards">Leaderboards</a></li>
<li><a>Bazaar (coming soon)</a></li>
<li><a href="/chat">Fake chat generator</a></li>