Deck analysis shows total cost; tidier analysis layout
A "cost" tile totals the USD price of every copy in the deck (commander included, maybeboard not). The stat tiles now span the panel and size to their values, with the color bars and mana curve sharing the row below, and the left-hand panels no longer spread out to match the analysis panel's height. Closes #20
This commit is contained in:
@@ -2620,7 +2620,11 @@ tbody tr:hover {
|
||||
grid-template-areas:
|
||||
"commander stats"
|
||||
"meta stats"
|
||||
"legality stats";
|
||||
"legality stats"
|
||||
". stats";
|
||||
/* The last row takes whatever height the analysis panel adds, so the
|
||||
left-hand panels stack together instead of spreading out to match. */
|
||||
grid-template-rows: auto auto auto 1fr;
|
||||
align-items: start;
|
||||
}
|
||||
}
|
||||
@@ -2701,12 +2705,25 @@ tbody tr:hover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
min-width: 220px;
|
||||
flex: 1 1 240px;
|
||||
min-width: 0;
|
||||
}
|
||||
/* The analysis tiles span the panel above the bars and curve. They size to
|
||||
their value (a "$1,234" cost is wider than a card count) and share out any
|
||||
spare width, wrapping on narrow screens rather than squeezing a value past
|
||||
its tile's edges. */
|
||||
.deck-stats .stat-tiles-row {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.deck-stats .stat-tile {
|
||||
flex: 1 0 auto;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.deck-stats-curve {
|
||||
flex: 1;
|
||||
min-width: 220px;
|
||||
max-width: 420px;
|
||||
/* Shares the row with the color bars, or takes the full width once they
|
||||
wrap onto separate lines. */
|
||||
flex: 1 1 240px;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,9 @@ interface DeckStats {
|
||||
uniqueCards: number;
|
||||
landCount: number;
|
||||
avgManaValue: number;
|
||||
/** USD for every copy in the deck, commander included; cards without a
|
||||
* known price count as $0. */
|
||||
totalCost: number;
|
||||
curve: {
|
||||
label: string;
|
||||
count: number;
|
||||
@@ -175,11 +178,17 @@ function computeDeckStats(contents: DeckEntry[]): DeckStats {
|
||||
}
|
||||
}
|
||||
|
||||
// Unlike the rest, cost counts the commander: it's a card you have to buy.
|
||||
const totalCost = contents
|
||||
.filter((e) => !e.is_maybeboard)
|
||||
.reduce((sum, e) => sum + e.price_usd * e.quantity, 0);
|
||||
|
||||
return {
|
||||
totalCards,
|
||||
uniqueCards: cards.length,
|
||||
landCount,
|
||||
avgManaValue,
|
||||
totalCost,
|
||||
curve,
|
||||
colorCounts,
|
||||
colorlessCount,
|
||||
@@ -190,6 +199,14 @@ function computeDeckStats(contents: DeckEntry[]): DeckStats {
|
||||
};
|
||||
}
|
||||
|
||||
/** "$84.50", or whole dollars once it's big enough that cents are noise. */
|
||||
function formatCost(usd: number): string {
|
||||
return `$${usd.toLocaleString(undefined, {
|
||||
minimumFractionDigits: usd >= 100 ? 0 : 2,
|
||||
maximumFractionDigits: usd >= 100 ? 0 : 2,
|
||||
})}`;
|
||||
}
|
||||
|
||||
/** A prominent, art-forward display for a deck's commander (Commander/Brawl). */
|
||||
function CommanderHero({
|
||||
card,
|
||||
@@ -1207,14 +1224,15 @@ export function DeckView({
|
||||
<div className="deck-top-stats">
|
||||
<div className="panel deck-stats">
|
||||
<div className="deck-stats-head section-label">Deck analysis</div>
|
||||
<div className="stat-tiles-row">
|
||||
<StatTile value={deckStats.totalCards} label="cards" />
|
||||
<StatTile value={deckStats.uniqueCards} label="unique" />
|
||||
<StatTile value={deckStats.landCount} label="lands" />
|
||||
<StatTile value={deckStats.avgManaValue.toFixed(2)} label="avg MV" />
|
||||
<StatTile value={formatCost(deckStats.totalCost)} label="cost" />
|
||||
</div>
|
||||
<div className="deck-stats-body">
|
||||
<div className="deck-stats-numbers">
|
||||
<div className="stat-tiles-row">
|
||||
<StatTile value={deckStats.totalCards} label="cards" />
|
||||
<StatTile value={deckStats.uniqueCards} label="unique" />
|
||||
<StatTile value={deckStats.landCount} label="lands" />
|
||||
<StatTile value={deckStats.avgManaValue.toFixed(2)} label="avg MV" />
|
||||
</div>
|
||||
<div className="deck-stats-curve-label">Color identity</div>
|
||||
<ColorDistributionBar
|
||||
colorCounts={deckStats.colorCounts}
|
||||
|
||||
Reference in New Issue
Block a user