core
Auto-generated from exported functions tagged #api in the source. See
imports and re-exports for how to
import these from a plugin.
buildColorRampLut
An RGBA lookup table over sampleColorRamp, laid out as the Nx1
texture both GPU backends upload and the Canvas2D twins index — entry i is
the color at t = i / (N - 1). N comes off the shader that samples it, so
the table and rampColor's texel mapping cannot disagree.
// type signature
(stops: readonly ColorRampStop[]) => Uint8Array<ArrayBuffer>
relight
Move a color's OKLCH lightness by lightnessShift and scale its chroma,
holding its hue.
For extending a categorical palette past its length. Cycling a nine-color list over a 24-chromosome karyotype repeats the color outright; cycling it with a lightness shift per lap gives the hue back as a variant still told apart from the original — tab20's construction, which pairs a light and a dark of each hue.
SHIFT rather than a fixed lightness, and SCALE rather than a fixed chroma, because a categorical palette is uneven on purpose: category10's brown and its red are 5 degrees apart in hue and are told apart by chroma alone, so re-lighting both to one (lightness, chroma) makes them the same color. Keeping each color's own relative chroma keeps brown reading as brown.
In OKLCH rather than through lighten/darken, which work in sRGB, where
the same coefficient moves a yellow and a blue by visibly different amounts:
a lap has to read as one tone across the whole palette or it reads as noise.
// type signature
(color: string, lightnessShift: number, chromaScale?: number) => string
sampleColorRamp
The color at t in [0, 1] across a list of EVENLY SPACED stops, linearly
interpolated per channel. t is clamped, so the ends are the end stops
rather than an extrapolation past them, and a one-stop ramp is that stop
everywhere.
// type signature
(stops: readonly ColorRampStop[], t: number) => ColorRampStop
SessionPaletteProvider
Make JBrowse follow the host's light/dark state — the whole of it, in one mount:
<SessionPaletteProvider session={session} mode={myAppIsDark ? 'dark' : 'light'}>
{tracks}
</SessionPaletteProvider>
mode is optional. Left out, JBrowse follows prefers-color-scheme and
re-themes when the OS preference changes, through the same session write an
explicit mode takes — so a host whose dark mode is the OS preference mounts
this with a session and nothing else. Pass a mode as soon as the host has a
toggle of its own, since the media query cannot see it.
A component rather than a documented pair of calls because the pair has a
half that can be left out with nothing to show for it. PaletteProvider is
the name a host reaches for, and it colors the React side alone; the session
write is what reaches the RPC worker, which bakes feature labels into the
rendered image. So a host that mounts only the provider gets light-mode
labels on a dark page, from a canvas whose every other pixel is right, and
nothing errors. See useSessionPalette for the mechanism.
The session is the only thing that resolves a palette here, so a host
supplying colors of its own mounts PaletteProvider directly instead.
// type signature
({ session, mode, children, }: { session: ThemeModeSession; mode?: "dark" | "light" | undefined; children: ReactNode; }) => Element
stopsFromRampLut
n evenly spaced legend stops read straight out of a
buildColorRampLut byte table — the same 256×1 RGBA array
uploadColorRampLut hands the GPU and the Canvas2D fillStyle LUTs index —
formatted for SvgGradientLegend. It holds one claim by construction: the
swatch at bar fraction t is byte-identical to the ramp entry at t on
both backends. Alpha rides opacity (the juicebox fade), never baked into
the color string.
// type signature
(lut: Uint8Array<ArrayBufferLike>, n: number) => GradientStop[]
VIRIDIS_STOPS
The 256 viridis stops, fully opaque. Feed them to buildColorRampLut for the texture/fillStyle form, or to sampleColorRamp for legend stops.
// type signature
readonly ColorRampStop[]