master @ 68 LINES
[ HISTORY ] [ UP ]
┌─ ASTRO ────────────────────────────────────────────────────────────────────┐
│ --- │
│ import "./DungeonDistributionChart.scss"; │
│ import type { StatsSpecCountBucket } from "../../../lib/types"; │
│ │
│ interface Props { │
│ buckets: Record<string, StatsSpecCountBucket>; │
│ // unique scope id so multiple charts on a page can each find their own data isl │
│ and │
│ scope: string; │
│ } │
│ │
│ const { buckets, scope } = Astro.props; │
│ │
│ // mirrors the spec chart bucket selector; Top 50 is omitted because each │
│ // dungeon has its own top-50 list so the bars would all be identical │
│ const BUCKET_TABS: Array<{ key: string; label: string }> = [ │
│ { key: "all_runs", label: "All Runs" }, │
│ { key: "gold_runs", label: "Gold" }, │
│ { key: "platinum_runs", label: "Platinum" }, │
│ { key: "title_runs", label: "Title" }, │
│ ]; │
│ │
│ const dataJson = JSON.stringify(buckets); │
│ --- │
│ │
│ <figure │
│ class="dungeon-distribution-chart" │
│ data-scope={scope} │
│ data-buckets={dataJson} │
│ > │
│ <div class="dungeon-distribution-chart__controls"> │
│ <nav │
│ class="dungeon-distribution-chart__tabs" │
│ role="tablist" │
│ aria-label="Run filter" │
│ > │
│ { │
│ BUCKET_TABS.map((b, i) => ( │
│ <button │
│ type="button" │
│ class:list={[ │
│ "dungeon-distribution-chart__tab", │
│ { active: i === 0 }, │
│ ]} │
│ role="tab" │
│ aria-selected={i === 0 ? "true" : "false"} │
│ data-bucket-key={b.key} │
│ > │
│ {b.label} │
│ </button> │
│ )) │
│ } │
│ </nav> │
│ </div> │
│ <div class="dungeon-distribution-chart__canvas"> │
│ { │
│ /* Filled by DungeonDistributionChart.ts on mount; kept empty server-side. * │
│ / │
│ } │
│ </div> │
│ </figure> │
│ │
│ <script> │
│ import { initDungeonDistributionCharts } from "./DungeonDistributionChart.ts"; │
│ initDungeonDistributionCharts(); │
│ document.addEventListener("astro:page-load", () => │
│ initDungeonDistributionCharts(), │
│ ); │
│ </script> │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ASTRO ──────────────────────────────┐
│ --- │
│ import "./DungeonDistributionChart.scss"; │
│ import type { StatsSpecCountBucket } from ". │
│ ./../../lib/types"; │
│ │
│ interface Props { │
│ buckets: Record<string, StatsSpecCountBuck │
│ et>; │
│ // unique scope id so multiple charts on a │
│ page can each find their own data island │
│ scope: string; │
│ } │
│ │
│ const { buckets, scope } = Astro.props; │
│ │
│ // mirrors the spec chart bucket selector; T │
│ op 50 is omitted because each │
│ // dungeon has its own top-50 list so the ba │
│ rs would all be identical │
│ const BUCKET_TABS: Array<{ key: string; labe │
│ l: string }> = [ │
│ { key: "all_runs", label: "All Runs" }, │
│ { key: "gold_runs", label: "Gold" }, │
│ { key: "platinum_runs", label: "Platinum" │
│ }, │
│ { key: "title_runs", label: "Title" }, │
│ ]; │
│ │
│ const dataJson = JSON.stringify(buckets); │
│ --- │
│ │
│ <figure │
│ class="dungeon-distribution-chart" │
│ data-scope={scope} │
│ data-buckets={dataJson} │
│ > │
│ <div class="dungeon-distribution-chart__co │
│ ntrols"> │
│ <nav │
│ class="dungeon-distribution-chart__tab │
│ s" │
│ role="tablist" │
│ aria-label="Run filter" │
│ > │
│ { │
│ BUCKET_TABS.map((b, i) => ( │
│ <button │
│ type="button" │
│ class:list={[ │
│ "dungeon-distribution-chart__t │
│ ab", │
│ { active: i === 0 }, │
│ ]} │
│ role="tab" │
│ aria-selected={i === 0 ? "true" │
│ : "false"} │
│ data-bucket-key={b.key} │
│ > │
│ {b.label} │
│ </button> │
│ )) │
│ } │
│ </nav> │
│ </div> │
│ <div class="dungeon-distribution-chart__ca │
│ nvas"> │
│ { │
│ /* Filled by DungeonDistributionChart. │
│ ts on mount; kept empty server-side. */ │
│ } │
│ </div> │
│ </figure> │
│ │
│ <script> │
│ import { initDungeonDistributionCharts } f │
│ rom "./DungeonDistributionChart.ts"; │
│ initDungeonDistributionCharts(); │
│ document.addEventListener("astro:page-load │
│ ", () => │
│ initDungeonDistributionCharts(), │
│ ); │
│ </script> │
└──────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET