Public
Edited
Jan 29, 2023
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) => Math.abs(baseStatTotal(mon) / mon.baseExp - 2.222) < 0.2
),
{ columns: ["total", "baseExp"] }
)
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) => Math.abs(baseStatTotal(mon) / mon.baseExp - 2) < 0.1
),
{ columns: ["total", "baseExp"] }
)
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) =>
![2, 2.222, 2.85, 5].some(
(ratio) => Math.abs(baseStatTotal(mon) / mon.baseExp - ratio) < 0.1
)
),
{ columns: ["total", "baseExp", "evYield"] }
)
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) =>
Math.abs(baseStatTotal(mon) / mon.baseExp - 5) < 0.1 &&
evYieldTotal(mon) !== 1
),
{ columns: ["total", "baseExp", "evYield"] }
)
Insert cell
pokemonTable(
pokedexList.filter(
(mon) =>
Math.abs(baseStatTotal(mon) / mon.baseExp - 2.85) < 0.1 &&
evYieldTotal(mon) !== 2
),
{ columns: ["total", "baseExp", "evYield"] }
)
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) =>
Math.abs(baseStatTotal(mon) / mon.baseExp - 2.22) < 0.1 &&
evYieldTotal(mon) !== 3
),
{ columns: ["total", "baseExp", "evYield"] }
)
Insert cell
Insert cell
Insert cell
pokemonTable(
pokedexList.filter(
(mon) =>
mon.evYield &&
evYieldTotal(mon) === 3 &&
mon.prevo &&
evYieldTotal(getPokemon(mon.prevo)) === 1
)
)
Insert cell
// Pokemon that yield the same number of EVs as a previous evolution
pokedexList
.filter((mon) => {
if (!mon.evYield || !mon.prevo) return false;
const prevo = getPokemon(mon.prevo);
return evYieldTotal(mon) === evYieldTotal(prevo);
})
.map((mon) => mon.name)
Insert cell
Insert cell
// pokemon with 3 EVs that are don't have prevos
pokemonTable(
pokedexList.filter((mon) => {
if (!mon.evYield) return false;
if (mon.prevo || (mon.baseSpecies && getPokemon(mon.baseSpecies).prevo))
return false;
if (
isMega(mon) ||
isLegendary(mon) ||
isMythical(mon) ||
isUltraBeast(mon) ||
isParadox(mon)
)
return false;
return evYieldTotal(mon) === 3;
})
)
Insert cell
Insert cell
// base evolutions with more than 1 EV
pokemonTable(
pokedexList.filter((mon) => {
if (!mon.evYield) return false;
if (mon.prevo || !mon.evos) return false;
return evYieldTotal(mon) > 1;
})
)
Insert cell
Insert cell
// final evolutions that yield only 1 EV
pokemonTable(
pokedexList.filter((mon) => {
if (!mon.evYield) return false;
if (mon.evos) return false;
return evYieldTotal(mon) < 2;
})
)
Insert cell
Insert cell
// Pokemon that yield EVs in three things
pokemonTable(
pokedexList.filter(
(mon) => mon.evYield && Object.keys(mon.evYield).length > 2
),
{ columns: ["evYield"] }
)
Insert cell
// 1EV pokemon who don't yield their highest stat
pokemonTable(
pokedexList.filter((mon) => {
if (Object.keys(mon.evYield).length !== 1) return false;
const stat = Object.keys(mon.evYield)[0];
return mon.baseStats[stat] !== Math.max(...Object.values(mon.baseStats));
return true;
}),
{ columns: ["hp", "atk", "def", "spa", "spd", "spe", "evYield"] }
)
Insert cell
Insert cell
{
const panzoom = vl
.selectInterval()
.bind("scales")
.translate(
"[mousedown[!event.shiftKey], window:mouseup] > window:mousemove!"
)
.zoom("wheel!");

const brush = vl
.selectInterval()
.resolve("union")
.on("[mousedown[event.shiftKey], window:mouseup] > window:mousemove!")
.translate(
"[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"
)
.zoom(null);
return (
vl
// .markImage({ width: imgSize, height: imgSize })
.markPoint()
.data(
pokedexList
.filter((mon) => mon.baseExp)
.map((mon) => ({
...mon,
baseExp: mon.baseExp,
evYieldTotal: evYieldTotal(mon),
baseStatTotal: baseStatTotal(mon),
img: getSpriteUrl(mon)
}))
)
.params(panzoom, brush)
.width(600)
.height(400)
.encode(
vl.x().fieldQ("baseStatTotal"),
// vl.y().fieldQ("baseExp"),
vl.y().fieldQ("catchRate"),
vl.tooltip().field("name"),
vl.color().field("evYieldTotal")
// vl.url().fieldN("img")
)
.render({ renderer: "svg" })
);
}
Insert cell
Insert cell
pokemonTable(
Object.values(
_.pickBy(
_.groupBy(pokedexList, (mon) => mon.catchRate),
(x, key) => x.length === 1 && key !== "null"
)
).flat(),
{ columns: ["catchRate"] }
)
Insert cell
pokemonTable(
pokedexList.filter((mon) => {
return mon.catchRate > 3 && (isLegendary(mon) || isMythical(mon));
}),
{ columns: ["catchRate"] }
)
Insert cell
Insert cell
{
const tally = Object.fromEntries(
types.map((type) => [
type,
Object.fromEntries(growthRates.map((rate) => [rate, []]))
])
);
for (const mon of pokedexList) {
if (mon.growthRate) {
for (const type of mon.types) {
tally[type][mon.growthRate].push(mon);
}
}
}
const table = [];
for (const type of types) {
for (const growthRate of growthRates) {
table.push({ type, growthRate, count: tally[type][growthRate].length });
}
}
return vl
.markCircle()
.data(table)
.encode(
vl.x().field("type"),
vl.y().field("growthRate"),
vl.size().fieldQ("count"),
vl.tooltip().fieldQ("count")
)
.render();
}
Insert cell
import {
pokedexList,
getPokemon,
getSpriteUrl,
evYieldTotal,
baseStatTotal,
isLegendary,
isSubLegendary,
isGmax,
isMythical,
isMega,
isParadox,
isUltraBeast,
types,
growthRates
} from "@tesseralis/pokemon-dataviz"
Insert cell
import { pokemonTable } from "@tesseralis/pokemon-table"
Insert cell
import { vl } from "@vega/vega-lite-api-v5"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more