Line with spread
Two series in the same unit where the gap between them is the story (holder value against cost basis).
<LineChart days={days} series={[value, cost]} spread fmt={fmtUsd} dayFmt={fmtDay} label="…" />Every way Blocktronics draws data, grouped by the job it does. Live on DEGEN and 234 tokens. Each form works in both modes and renders to static SVG for the API and MCP
Color is chosen by the job it does. Categorical slots are fixed in order and validated for color vision deficiency in both modes. Pastels are surfaces, never data
Identity. Three slots, then fold into Other. Text stays in ink
Profit against loss, and every other polarity that isn't buying against selling
Buys, net buying, inflow and accumulation against sells, net selling, outflow and distribution. Never a candle's green and red; position and labels say the direction too
Magnitude in one hue, gray to full. Signed values meet at a gray zero. Never a rainbow
Ordered tiers in one hue, light to deep. The lightest step still clears 2:1 on the card
How a measure moves over time. One axis, nulls are gaps, the latest point is anchored.
Two series in the same unit where the gap between them is the story (holder value against cost basis).
<LineChart days={days} series={[value, cost]} spread fmt={fmtUsd} dayFmt={fmtDay} label="…" />One series whose level matters, such as active holders.
<LineChart days={days} series={[holders]} area fmt={fmtNum} dayFmt={fmtDay} label="…" />A ratio with a meaningful threshold (MVRV and break-even at 1).
<LineChart series={[mvrv]} reference={{ value: 1, label: "Break-even" }} area … />Values that change in discrete jumps, such as daily concentration snapshots.
<LineChart series={[top10, top50, top100]} curve="step" … />Comparing growth of things with different sizes. Rebased to 100 on a common day, so one axis stays honest.
<IndexedLines days={days} series={[{ key, label, values }, …]} dayFmt={fmtDay} label="…" />Counts that sum to a whole, read as both total and parts (wallets by cohort).
<StackedArea days={days} layers={cohorts} fmt={fmtNum} dayFmt={fmtDay} label="…" />A trend inside a tile or table row. No axes; the end dot is now.
<Sparkline values={mvrv} label="MVRV trend" height={40} />Many series at once without a rainbow. Same mini chart per item; the crosshair moves through all of them.
<SmallMultiples items={tokens} days={days} fmt={fmtNum} dayFmt={fmtDay} scale="independent" label="…" />Above or below a baseline. Buys against sells are green against red (the buy and sell pair: flowClass, never a candle's pair); profit against loss is indigo against magenta; gray is zero. Direction is said by position and label too, never colour alone.
A signed daily value such as net DEX flow.
<BarChart days={days} values={netflow} fmt={signedUsd} dayFmt={fmtDay} valueLabel="Net" label="…" />Two magnitudes of one unit facing each other (buy and sell volume), with the net on hover.
<MirrorBars days={days} up={buys} down={sells} net={net} upLabel="Buys" downLabel="Sells" … />Signed days laid out by week, to spot streaks and weekday rhythm.
<CalendarHeat days={days} values={netflow} fmt={signedUsd} dayFmt={fmtDay} cell={18} label="…" />The current UTC day, hour by hour. Hours still to come stay faint.
<HourBars hours={hours} values={net} fmt={signedUsd} label="…" />Who is in and who is out: a signed measure ranked across tokens.
<RankedBars items={[{ key, label, value, href }, …]} fmt={signedUsd} />Parts of one whole. A handful of parts, never close comparisons.
Up to four shares of one whole, with the headline share in the middle.
<Ring parts={bands} center={{ value: "33%", label: "Top 10" }} label="…" />An ordered split on one line, such as wallets from shrimp to whale.
<ShareBar parts={[{ key, label, value, color: ORDINAL[i] }, …]} label="…" />One share read as “n out of 100”.
<Waffle pct={profitPct} label="…" />How a two- or three-way split changes over time, when only the mix matters.
<StackedShare days={days} layers={[profit, loss]} dayFmt={fmtDay} label="…" />Size across many items with a second measure in color: market cap, colored by 7-day netflow.
const scale = treemapScale(items, TREEMAP_COLORS["netflow-7d"]); // the data's own spread, a clean step
<Treemap items={[{ key, label, value: mcap, color: flowPct, logo }, …]} valueFmt={fmtUsd} colorMax={scale.max} label="…" />The shape of the universe and where one token sits in it. The token is the accent; everyone else is gray.
How a measure spreads across tokens, with this token marked.
<Histogram values={fleetMvrv} scale="log" marker={{ value: mvrv, label: "DEGEN" }} fmt={ratio} label="…" />Every token as a dot on one scale, dodged so none overlap. Good to 300 or so.
<Beeswarm items={tokens} highlight={token} fmt={pct} label="…" />Several 0–100 scores at once, each with the fleet's median and middle half for context.
<DotPlot rows={[{ key, label, values: [score], median, band: [p25, p75] }, …]} label="…" />One value against the fleet's range, middle half and median.
<Bullet value={mcap} fleet={{ p25, median, p75, min, max }} scale="log" fmt={fmtUsd} label="…" />Order across tokens. Labels on the left, values at the tip, every row links to its token.
The top of a list by one measure.
<RankedBars items={tokens} fmt={fmtUsd} valueLabel="Market cap" />Start and end of a window per item on one scale: MVRV 30 days ago and now.
<Dumbbell items={[{ key, label, start, end }, …]} scale="log" reference={{ value: 1, label: "Break-even" }} fmt={ratio} />The same then-and-now, when the story is one item's move against the rest.
<Slope items={items} highlight={token} startLabel="30 days ago" endLabel="Now" fmt={ratio} />Tokens × measures. Signed columns diverge around zero; magnitudes use one hue. Click a header to sort.
<HeatTable rows={rows} columns={[{ key, label, kind: "div", fmt }, …]} label="…" />Two measures across tokens. Never two y-axes: a scatter puts both on their own axis.
How two measures move together across tokens, with size for a third and up to three color groups.
<Scatter points={tokens} xScale="log" groups={GRADE_BANDS} xFmt={fmtNum} yFmt={pct} xLabel="Holders" yLabel="Top 10 share" highlight={[token]} />When the answer is one number. Proportional figures, a change in ink with a polarity mark, and context.
A headline figure with its change and trend.
<StatTile label="Active holders" value="3,827" delta={{ value: 356, text: "+10.2%" }} trend={holders} />One 0–100 score with a hard ceiling.
<Gauge value={composite} caption="Composite" label="…" />A short list of 0–100 scores with their reasons, without fleet context.
<ScoreBars items={[{ key, label, score, detail }, …]} label="…" />The Blocktronics grade, A to E. Pastel surfaces carry the band; the letter is always ink.
<GradeLetter grade="B" size="m" />Identity never rides on color alone: legends, mark keys and deltas sit in ink beside a colored mark.
Two or more series. Boxes for fills and bars, lines for lines.
<Legend items={[{ label: "Buys", color: "var(--chart-pos)" }, …]} />Any sequential or diverging fill. Ends say where the color saturates.
<ScaleLegend kind="div" min="≤ −3%" mid="0" max="≥ +3%" />Charts whose marks are shapes, not series: dots, median ticks and bands.
<MarkKey items={[{ label: "DEGEN", mark: "dot" }, { label: "Median", mark: "tick" }, …]} />A signed change. The mark shows direction and whether it is good; the number stays in ink.
<Delta value={-1.8} goodWhen="down">−1.8 pts</Delta>