Skip to content

@mosaicajs/deck

@mosaicajs/deck draws a Mosaica map with deck.gl, for an app that builds its own Deck. If you want a ready-made map, the <mosaica-map> element in @mosaicajs/components wraps this package and handles the camera for you.

MosaicaLayer is a deck.gl layer that draws what a store from @mosaicajs/client publishes: the points, density, the artifacts' names and outlines, and the selected region. It fetches nothing itself. Your app owns the camera. Each time the view state changes, pass the camera to viewInputOf and give the result to the store's setView. The store fetches what the new view needs, and the layer redraws when the store's projections change.

The rest of the package works alongside the layer. resolvePick turns a deck.gl pick into the item or artifact under the pointer. frameMatches and cameraFitting find the camera that shows the filtered items. basemapLayers draws a world outline, map tiles or an image under the points. DensityCounter fetches the counts that density is drawn from, and the layer keeps one of its own unless you pass yours. Colouring, Sizing and the named palettes and ramps are the choices for colouring and sizing points by a column.

Example

import {Deck, OrthographicView} from '@deck.gl/core';
import {createStore} from '@mosaicajs/client';
import {MosaicaLayer, viewInputOf} from '@mosaicajs/deck';

type Camera = {target: [number, number, number]; zoom: number};

const store = createStore({viewerUrl: 'http://localhost:8080', token});
let viewState: Camera = {target: [256, 256, 0], zoom: 0};

// Tell the store where the camera is. viewInputOf returns null until /v1/meta has arrived.
function tell() {
  const input = viewInputOf(store, viewState, deck.width, deck.height);
  if (input) store.setView(input);
}

const deck = new Deck<OrthographicView>({
  parent: document.getElementById('map') as HTMLDivElement,
  views: new OrthographicView({flipY: true}),
  viewState,
  controller: true,
  layers: [new MosaicaLayer({id: 'mosaica', store})],
  onViewStateChange: ({viewState: next}) => {
    viewState = next as Camera;
    deck.setProps({viewState});
    tell();
  }
});

store.subscribe('meta', (meta) => {
  if (meta) tell();
});

Basemaps

BasemapOptions

BasemapOptions = object

Options for basemapLayers.

Properties

Property Type Description
camera? DensityCamera The current camera. Map tiles are fetched for the area it shows, at its zoom. Without it, tiles for the whole frame are fetched at a coarse zoom.
colours? Partial\<WorldColours> Colours for the world outline in place of the defaults for scheme.
scheme? "light" | "dark" The map's background, light or dark. The world outline is drawn a little darker than a light background and a little lighter than a dark one. Defaults to light.

BasemapValue

BasemapValue = "world" | "none" | { attribution?: string; tiles: string; } | { bounds?: readonly [number, number, number, number]; image: string; }

What to draw under the points of a view:

  • 'world': land, coastlines and country borders from the server's world outline, projected as the view's points are. Only for a view with a map projection.
  • 'none': nothing.
  • {tiles, attribution}: raster map tiles. tiles is the tile server's URL template, with {z}, {x} and {y}, and attribution the credit the tile server asks for. Only for a view with a ViewInfo.tileScheme. There is no default tile server.
  • {image, bounds}: one image, stretched over bounds without reprojection. bounds is [x0, y0, x1, y1] in the view's own coordinates: longitude and latitude in degrees on a geographic view, x and y otherwise. Leave it out to cover the whole frame.

WorldColours

WorldColours = object

The colours of the world outline, each RGBA from 0 to 255.

Properties

Property Type Description
land Rgba The land's fill.
line Rgba The coastlines and the country borders.

basemapLayers()

basemapLayers(store: Pick\<Store, "basemapWorld">, view: ViewInfo, value: BasemapValue, options?: BasemapOptions): Promise\<Layer\<{ }>[]>

The deck.gl layers that draw value under view. Put them before the MosaicaLayer in the Deck's layers. For 'none' the list is empty. The code that draws basemaps is loaded the first time you call this, so a page without a basemap never loads it.

For map tiles, call it again with the new camera when the camera moves. Repeated calls are cheap: the world outline is fetched once per server, and a camera that still shows the same tiles reuses the image already drawn.

Parameters

Parameter Type Description
store Pick\<Store, "basemapWorld"> The store, whose server serves the world outline.
view ViewInfo The view drawn, from meta.views.
value BasemapValue What to draw.
options? BasemapOptions The background, colours and camera.

Returns

Promise\<Layer\<{ }>[]>

The layers. Rejects with Error if value is not a valid basemap or does not suit view (see basemapMisfit), or if the world outline fails to load.


basemapMisfit()

basemapMisfit(view: ViewInfo, value: BasemapValue): string | null

Why value cannot be drawn under view, as a sentence that says what to use instead, or null if it can. The world outline needs a view with a map projection, and map tiles need a view with a ViewInfo.tileScheme.

Colour

DensityCounter

Fetches the counts that density is drawn from, for the area around a camera. It registers an aggregate with the store, so the counts cover only what the viewer may see under the store's filters, and it fetches again when the filters, the highlight or the store's view (coordinate system) change. While a highlight is set, it counts the highlighted items.

Tell it where the camera is with look and what to draw with set. Once the camera has rested for DENSITY_SETTLE_MS, it fetches cells of about the chosen size on screen over the viewport and a margin round it, so a short pan needs no new request. Until the first answer for the view arrives, or after the server refuses one, counts returns the coarser counts that come with the map's tiles. After that it returns the last answer until the next one arrives. onChange is called whenever the counts to draw change.

A MosaicaLayer with a store keeps a counter of its own. Make one yourself and pass it as the layer's densityCounter if your own code also needs the counts, as <mosaica-map> does for its density key.

Constructors

Constructor

new DensityCounter(store: Store, onChange: () => void, settleMs?: number): DensityCounter

Parameters
Parameter Type Default value Description
store Store undefined The store to fetch through.
onChange () => void undefined Called whenever the counts to draw change.
settleMs? number DENSITY_SETTLE_MS How long the camera must rest before counts are fetched, in milliseconds.

Methods

counts()

counts(): DensityCounts | null

The counts to draw, or null while density is off or there are none. Until the first answer for the current view arrives, these are the coarser counts that come with the map's tiles.

dispose()

dispose(): void

Stop fetching counts and unsubscribe from the store.

look()

look(camera: DensityCamera): void

Tell the counter the camera has moved or the canvas has been resized.

set()

set(settings: DensitySettings): void

Turn density on or off and choose the cell size. Turning it off drops the counts held.

stops()

stops(): ResolutionStop[]

The cell sizes density can be drawn at for the current camera. Every stop is enabled until the counter has a camera and the store has meta.

Returns

ResolutionStop[]


CategoryPalette

CategoryPalette = object

A qualitative palette, for colouring a category column.

Properties

Property Type Description
colourBlindSafe boolean Whether the colours stay distinguishable under protanopia, deuteranopia and tritanopia.
colours readonly Rgb[] The colours, given to category values in order of rank.
title string The palette's name as a menu shows it.

CategoryPaletteName

CategoryPaletteName = "tableau10" | "okabe-ito" | "set2" | "dark2"

The name of a qualitative palette for a category column: tableau10 (Tableau 10, ten colours), okabe-ito (Okabe and Ito's eight, distinguishable under the common colour-vision deficiencies), set2 and dark2 (ColorBrewer's, eight each).


Colouring

Colouring = object

How to colour marks by a column: a palette for a category column, a ramp for a number column, and any colours you choose for single category values. The same choices colour the legend.

Properties

Property Type Description
palette CategoryPaletteName The palette for a category column.
ramp RampName The ramp for a number column.
reverse boolean Whether the ramp runs from its high end to its low end.
scale RampScale How a number is placed on the ramp.
values Readonly\<Record\<string, Readonly\<Record\<string, string>>>> Colours you choose for single category values, as #rrggbb, keyed by column and then by category key. A chosen colour replaces the value's palette colour. A key that is not among the column's drawn values has no effect.

DensityCamera

DensityCamera = object

A deck.gl OrthographicView camera over the 512-unit world, with the canvas size.

Properties

Property Type Description
height number The canvas height in CSS pixels.
target readonly number[] The world point at the centre of the canvas, [x, y] in world units. A missing coordinate reads as 0.
width number The canvas width in CSS pixels.
zoom number deck's zoom: the canvas shows 2 ** zoom pixels per world unit.

DensityCell

DensityCell = object

One cell of DensityCounts.

Properties

Property Type Description
count number The items counted in the cell.
position [number, number] The cell's centre in world units.
x number The cell's column at its depth, from 0 at the world's left edge.
y number The cell's row at its depth, from 0 at the world's top edge.

DensityColours

DensityColours = "warm-grey" | "viridis" | "cividis" | "magma" | "greys"

The colours density is drawn in: warm-grey, one neutral colour that strengthens with the count, or one of the ramps viridis, cividis, magma and greys. A ramp runs whichever way makes dense areas dark on a light map and bright on a dark one.


DensityCounts

DensityCounts = object

Counts of items by cell, which density is drawn from. At depth d the view's square is divided into 2^d by 2^d cells, so each depth halves the cell's width. Only cells with a count are listed.

Properties

Property Type Description
cells readonly DensityCell[] The cells, in any order.
depth number The depth the cells are at.

DensityMode

DensityMode = "none" | "smooth" | "hex" | "grid" | "contours"

How density is drawn: none, smooth (a soft wash), hex (hexagonal bins), grid (square cells) or contours (lines of equal density).


DensityScale

DensityScale = "linear" | "log"

How a cell's count is placed between zero and the largest count drawn: linear, in proportion to the count, or log, in proportion to log(1 + count), which suits counts that span several orders of magnitude.


DensitySettings

DensitySettings = object

The settings DensityCounter.set takes.

Properties

Property Type Description
cellPx number The cell size on screen in CSS pixels, rounded to the nearest of DENSITY_CELL_SIZES.
on boolean Whether density is drawn. While it is off, the counter fetches nothing and holds nothing.

Ramp

Ramp = object

A colour ramp, for colouring a number column. Colours between its stops are interpolated linearly in RGB.

Properties

Property Type Description
diverging boolean Whether the ramp diverges from a midpoint, which takes the ramp's middle colour. The midpoint is zero if the range spans zero, and the middle of the range otherwise.
stops readonly Rgb[] The stops from the low end to the high end.
title string The ramp's name as a menu shows it.

RampName

RampName = "viridis" | "cividis" | "magma" | "greys" | "red-blue"

The name of a colour ramp for a number column: viridis, cividis and magma (perceptually uniform, dark to light), greys (light to dark) and red-blue (diverging, red below the midpoint and blue above it).


RampScale

RampScale = "linear" | "log"

How a number is placed on a ramp: linear, in proportion to the value, or log, in proportion to log(1 + (v โˆ’ min)), so that a long tail does not push most values into one colour. On a diverging ramp, log applies on each side of the midpoint.


ResolutionStop

ResolutionStop = object

One cell size density can be drawn at, at the current camera. A menu of resolutions can disable the stops that are not enabled.

Properties

Property Type Description
depth number The depth of the cells fetched for this size at the camera's zoom (see DensityCounts).
enabled boolean Whether the server's selection.maxAggregateCells allows this many cells over the area fetched.
px number The cell size on screen, in CSS pixels.

CATEGORY_PALETTES

const CATEGORY_PALETTES: Readonly\<Record\<CategoryPaletteName, CategoryPalette>>

The qualitative palettes, by name. The most frequent category values among the marks drawn take the palette's colours in order, and a value keeps its colour as the camera moves. Values past the end of the palette are drawn grey.


DEFAULT_COLOURING

const DEFAULT_COLOURING: Colouring

The default colouring: Tableau 10 for categories, Viridis on a linear scale for numbers, and no chosen colours.


DEFAULT_DENSITY_CELL_PX

const DEFAULT_DENSITY_CELL_PX: 12 = 12

The cell size density is drawn at by default, in CSS pixels.


DENSITY_CELL_SIZES

const DENSITY_CELL_SIZES: readonly number[]

The cell sizes on screen that density can be drawn at, in CSS pixels, from coarse to fine.


DENSITY_SETTLE_MS

const DENSITY_SETTLE_MS: 200 = 200

How long the camera must rest before DensityCounter fetches counts, in milliseconds.


RAMPS

const RAMPS: Readonly\<Record\<RampName, Ramp>>

The colour ramps, by name.


cellDepth()

cellDepth(zoom: number, cellPx: number): number

The depth whose cells are closest to cellPx wide on screen at zoom, measured on a log scale. A cell at depth d is 512 ยท 2^zoom / 2^d pixels wide.

Returns

number


nearestStop()

nearestStop(px: number): number

The size in DENSITY_CELL_SIZES nearest px, measured on a log scale.

Returns

number


resolutionStops()

resolutionStops(camera: DensityCamera, limit: number): ResolutionStop[]

Each size in DENSITY_CELL_SIZES at camera, with its depth and whether its cells over the area fetched number at most limit, the server's selection.maxAggregateCells.

Other

MosaicaLayer

A deck.gl layer that draws a Mosaica map. Give it a store and it draws the store's projections and redraws whenever they change. From bottom to top it draws the outlines of the hovered and opened artifacts, density, the points as marks, the artifacts' names, the selected region and a ring round the picked mark. The props are MosaicaLayerProps.

The layer fetches nothing itself. The store decides what to fetch from the camera you give it, and the layer draws every mark the store holds. Use it in an OrthographicView with flipY: true. It draws in a world square 512 units across, and viewInputOf converts that view's camera for the store's setView. It cannot be used in a geographic MapView or with MapLibre.

The layer does not handle hover or clicks. Pass the pick info from deck's onHover or onClick to resolvePick to find the item or artifact under the pointer, then set the props that show it, such as selectedWorldXY and hoveredArtifact. If the artifact's layer declares shapes, call the store's needShape with its id: the outline appears once the shape arrives. Otherwise the outline is the artifact's bounding box. Only an artifact drawn at clusterLevel is outlined.

Extends

  • default\<MosaicaLayerInternalProps>

Constructors

Constructor

new MosaicaLayer(...propObjects: Partial\<LayerProps & object & object & object & Required\<CompositeLayerProps> & Required\<LayerProps>>[]): MosaicaLayer

Inherited from

CompositeLayer<MosaicaLayerInternalProps>.constructor


LayerTimings

LayerTimings = object

What one render of a MosaicaLayer cost and drew, passed to onTimings. Times are in milliseconds. On a render that draws no marks, slabMs, densityMs and the mark figures are 0.

Properties

Property Type Description
densityMs number Time spent building the density layers. It excludes the smooth wash's image, which is built after the render, and the aggregation deck.gl does for the other modes.
labels number Names placed.
labelsMs number Time spent placing names.
layersMs number Time for the whole render.
lutMs number Time spent updating the texture that colours marks by artifact.
lutWrites number How many times the texture that colours marks by artifact has been written since the layer was created.
markAlpha number The opacity the marks are drawn at, from 0 to 1, multiplied by their colour's own alpha.
markCount number The number of marks the radius and opacity were chosen for, stand-ins included.
markRadius number The mark radius drawn, in pixels. While marks are sized by a column, the largest.
outlines number Outline parts drawn. An artifact in several pieces has several parts.
outlinesDrawn number Artifacts outlined: 0, 1 or 2 (the hovered and the opened).
outlinesMs number Time spent building the outlines.
slabMs number Time spent writing newly arrived marks into the GPU buffers.

MosaicaLayerProps

MosaicaLayerProps = CompositeLayerProps & object

The props of a MosaicaLayer: deck.gl's CompositeLayerProps and the props below, all optional. pickable defaults to true.

Usually you set store and the layer reads marks, depth, artifacts, meta, legend and status from the store's projections. You can set any of those six yourself, and your value is drawn in place of the store's. Without a store, set the ones you need; the rest draw nothing.

Type Declaration

Name Type Description
artifacts? ArtifactsProjection | null The artifacts to name, outline and colour by. Defaults to the store's artifacts.
clusterLevel? number The level of a stacked or tiered artifact layer to colour, name and outline artifacts at. Defaults to the coarsest level served. On a nested or dag layer it has no default, and each mark takes the nearest artifact served.
colouring? Colouring The palette, ramp and per-value colours used when colouring by a column. Defaults to DEFAULT_COLOURING.
density? DensityMode How density is drawn under the marks: none, smooth (a soft wash), hex (hexagons), grid (square cells) or contours (lines of equal density). Defaults to none.
densityColours? DensityColours | null The colours density is drawn in. Defaults to null, which draws the smooth wash in warm grey while marks are drawn, and Viridis otherwise.
densityCounter? DensityCounter | null A DensityCounter to draw density from, if you keep one yourself. Defaults to null, in which case a layer with a store keeps its own counter, which follows the layer's camera, density and densityResolution.
densityCounts? DensityCounts | null The counts by cell that density is drawn from. Set it to draw counts you fetched yourself. Defaults to null, which draws the counts from densityCounter or the layer's own counter.
densityResolution? number The size on screen of a density cell, in CSS pixels, for the layer's own counter. Defaults to 12.
densityScale? DensityScale How a cell's count maps to its colour, its opacity in the wash and the contour levels: linear or log. Defaults to log.
densityStrength? number How strongly density is drawn, from 0 (not at all) to 1 (fully). Defaults to 1.
depth? number The tile depth of the frame drawn. Defaults to 0. With a store, 0 reads the store's view.depth.
drag? [number, number, number, number] | null The box the user is dragging, [x0, y0, x1, y1] in world units. It is drawn in place of region, with a fainter fill. Defaults to null.
dragPolygon? [number, number][] | null The lasso the user is drawing, as world points. It is drawn in place of regionPolygon and drag, with a fainter fill. Defaults to null.
highlighting? boolean Whether a highlight is set. If it is, the marks it matches keep their colour and are drawn larger with a glow, and the rest are drawn faint grey. The layer does not read this from the store, so pass the store's view.highlighting. Defaults to false.
hoveredArtifact? bigint | null The mosaicaId of the artifact under the pointer, which is outlined. Defaults to null.
labels? boolean Whether to draw the artifacts' names, with the count of the one under the pointer. Defaults to true.
legend? LegendProjection | null The column the marks are coloured and sized by. Defaults to the store's legend. Its colourBy is a column, or cluster:<layer> to colour each mark by the artifact it belongs to. Its sizeBy is a number column. The store fetches a column with the points only after you call its setColourBy, setSizeBy or setPointColumns.
marks? MarksProjection | null The marks to draw. Defaults to the store's marks.
meta? Meta | null The server's /v1/meta response, which describes the columns and artifact layers. Defaults to the store's meta. Without it every mark is drawn in one colour.
onDrawn? ((drawn: number, provisional: number) => void) | null Called after each render with the number of marks drawn: drawn marks of the current frame, and provisional stand-ins from another depth, shown until the frame's own marks arrive. Defaults to null.
onTimings? ((t: LayerTimings) => void) | null Called after each render with what it cost and drew. Defaults to null.
openedArtifact? bigint | null The mosaicaId of the opened artifact, which is outlined. While marks are coloured by artifact, every mark outside it is dimmed. Defaults to null.
pointOpacity? number | null A fixed mark opacity from 0 to 1, multiplied by the colour's own alpha. Defaults to null, which chooses it from the number of marks: 0.8 for ten thousand or fewer, down to 0.34 for a million, plus 0.015 per zoom level up to zoom 10, and at most 0.9.
points? boolean Whether to draw the marks. Density, outlines, names and the selection are drawn either way. Defaults to true.
radius? number | null A fixed mark radius in pixels. Defaults to null, which chooses a radius from the number of marks and the zoom: 2 px for ten thousand marks or fewer, down to 1.1 px for a million, plus 0.05 px per zoom level up to zoom 10. While the legend has a sizeBy, sizing is used instead.
region? [number, number, number, number] | null The selected region as a box, [x0, y0, x1, y1] in world units. Defaults to null.
regionPolygon? [number, number][] | null The selected region as a polygon of world points. If it has two or more points it is drawn in place of region and drag. Defaults to null.
scheme? "light" | "dark" Whether the map's background is light or dark. The colours of names, outlines, the picked mark's ring and the selected region are chosen to suit it. Defaults to dark.
selectedWorldXY? [number, number] | null Where to draw a ring round the picked mark, in world units. resolvePick returns it as worldXY. Defaults to null, no ring.
sizing? Sizing How marks are sized while the legend has a sizeBy. A radius that is not a positive finite number is replaced by the default's. For the rank scale, call the store's setSizeBy(column, {rank: true}), or every mark is drawn at the smallest size. Defaults to DEFAULT_SIZING.
status? PresentedStatus The map's status. Defaults to idle. With a store, idle reads the store's status. No marks are drawn while it is refused.
store? Store | null The store to draw. The layer redraws whenever its projections change. Defaults to null.

OrthographicCamera

OrthographicCamera = object

The part of a deck.gl OrthographicView view state that viewInputOf reads.

Properties

Property Type Description
target readonly number[] The world point at the centre of the canvas, [x, y] in world units. A missing coordinate reads as 0.
zoom number deck's zoom: the canvas shows 2 ** zoom pixels per world unit, so at 0 the 512-unit world is 512 pixels wide.

Picked

Picked = { id: bigint; kind: "mark"; worldXY: [number, number] | null; } | { id: bigint; kind: "artifact"; } | { kind: "miss"; } | { hasIds: boolean; idCount: number; index: number; kind: "broken"; layer: string | null; }

What resolvePick found under the pointer, by kind:

  • mark: an item. id is its mosaicaId, and worldXY the mark's position in world units, or the pointer's if the mark's position is not known, or null if neither is known.
  • artifact: an artifact's name. id is the artifact's mosaicaId.
  • miss: nothing.
  • broken: a hit the layer cannot resolve to an id, which is a bug in the layer. It is kept apart from a miss so that you can report it. layer is the sublayer's id, hasIds whether it has ids and idCount how many.

PickInfo

PickInfo = object

The fields of deck.gl's PickingInfo that resolvePick reads. Pass deck's PickingInfo as it is.

Properties

Property Type Description
coordinate? number[] | null The pointer's position in world units, used as a mark's worldXY if the mark's own position is not known.
index number The index of the hit within the sublayer's data, or -1 for no hit.
layer? { id: string; props: object; } | null The layer deck reports, read when sourceLayer is absent.
sourceLayer? { id: string; props: object; } | null The sublayer that drew the hit.

Rgb

Rgb = readonly [number, number, number]

An RGB colour, each channel 0โ€“255.


DEFAULT_DENSITY_SCALE

const DEFAULT_DENSITY_SCALE: DensityScale = 'log'

The density scale used when none is set: log.


cameraFitting()

cameraFitting(box: readonly [number, number, number, number], width: number, height: number, fill?: number): object

The deck.gl camera that fits a box of the world into a canvas. It centres the box and zooms until the box fills fill of the canvas's width or height, whichever it reaches first, up to a zoom of MAX_DEPTH. Spread the result into the OrthographicView view state.

Parameters

Parameter Type Default value Description
box readonly [number, number, number, number] undefined [x0, y0, x1, y1] in world units, as frameMatches gives it.
width number undefined The canvas width in CSS pixels.
height number undefined The canvas height in CSS pixels.
fill? number 0.92 The share of the canvas the box fills.

Returns

object

Name Type
target [number, number, number]
zoom number

densityCountAt()

densityCountAt(position: number, max: number, scale: DensityScale): number

The count at position on scale, the inverse of densityPosition. Use it to label a density key.

Returns

number


densityPosition()

densityPosition(count: number, max: number, scale: DensityScale): number

Where count falls on scale, from 0 for no items to 1 for max: count / max under linear, and log1p(count) / log1p(max) under log. The count is clamped to [0, max], and the result is 0 if max is 0 or less.

Returns

number


frameMatches()

frameMatches(store: Store, options?: object): Promise\<[number, number, number, number] | null>

Finds the box round the items that the store's filters match, so you can move the camera there with cameraFitting. The box is [x0, y0, x1, y1] in world units, made of whole cells 2 units wide, or wider if the server's selection.maxAggregateCells is low. It holds every match, so one item far from the rest widens it.

The count goes through the store, so the box covers only items this viewer may see, under the store's filters and selected region. If the filters change before the answer arrives, the store asks again. The promise waits for the store's /v1/meta.

Parameters

Parameter Type Description
store Store The store whose filters are matched.
options? { signal?: AbortSignal; } -
options.signal? AbortSignal Aborts the search, which then resolves to null.

Returns

Promise\<[number, number, number, number] | null>

The box, or null if no item matches, if the server refuses or does not allow the count, or once signal aborts.

Example

const box = await frameMatches(store);
if (box) {
  viewState = {...viewState, ...cameraFitting(box, deck.width, deck.height)};
  deck.setProps({viewState});
  tell();
}

resolvePick()

resolvePick(info: PickInfo): Picked

Finds the item or artifact under the pointer from a deck.gl pick on a MosaicaLayer. Pass it the pick info that deck gives onHover or onClick. Only marks and artifact names can be picked, so anything else, such as an outline or the density wash, is a miss.

Example

new Deck({
  // ...
  onClick: (info) => {
    const picked = resolvePick(info);
    if (picked.kind === 'mark') store.pick(picked.id);
  }
});

viewInputOf()

viewInputOf(store: Pick\<Store, "frame" | "dataXY">, camera: OrthographicCamera, width: number, height: number): ViewInput | null

Converts a deck.gl OrthographicView camera into the ViewInput that the store's setView takes. Call it whenever the view state or the canvas size changes. The box the canvas shows is clamped to the world and converted to the current view's data coordinates.

Parameters

Parameter Type Description
store Pick\<Store, "frame" | "dataXY"> The store, which converts world units to data coordinates.
camera OrthographicCamera The view state's target and zoom.
width number The canvas width in CSS pixels.
height number The canvas height in CSS pixels.

Returns

ViewInput | null

The view input, or null until the store has /v1/meta.

Size

SizeScale

SizeScale = "linear" | "log" | "rank"

How a number is placed between the smallest and largest size: linear, in proportion to the value; log, in proportion to log(1 + (v โˆ’ min)), so a long tail does not leave most marks at the smallest size; or rank, by the value's rank in a sample of the values drawn, which spreads skewed values evenly. The rank is an estimate, because the marks drawn are themselves a sample.


Sizing

Sizing = object

How to size marks by a number column: the radius in pixels of the smallest and largest values, and the scale between them.

Properties

Property Type Description
max number The radius in pixels of the largest value.
min number The radius in pixels of the smallest value. A mark with no value, or a value that is not finite, is drawn as a ring, at this radius or 3 px, whichever is larger.
scale SizeScale How a value is placed between min and max.

DEFAULT_SIZING

const DEFAULT_SIZING: Sizing

The default sizing: 2 to 9 pixels on a linear scale.