@mosaicajs/deck 0.1.0-rc.4 → 0.1.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/basemap.d.ts CHANGED
@@ -2,19 +2,17 @@ import type { Layer } from '@deck.gl/core';
2
2
  import { type Rgba, type Store, type ViewInfo } from '@mosaicajs/client';
3
3
  import type { DensityCamera } from './density-counter.js';
4
4
  /**
5
- * What is drawn under the points of one view:
5
+ * What to draw under the points of a view:
6
6
  *
7
- * - `'world'`: land, coastlines and country borders from the server's world outline
8
- * (`GET /v1/basemaps/world`), projected as the view's positions were. Only on a view whose
9
- * projection is not `none`.
7
+ * - `'world'`: land, coastlines and country borders from the server's world outline, projected as
8
+ * the view's points are. Only for a view with a map projection.
10
9
  * - `'none'`: nothing.
11
- * - `{tiles, attribution}`: raster tiles from `tiles`, a URL template with `{z}`, `{x}` and `{y}`,
12
- * composed at the camera's depth. `attribution` is the credit the tile server asks for. Only on a
13
- * view with a {@link ViewInfo.tileScheme}. There is no default server.
14
- * - `{image, bounds}`: one image stretched over `bounds`, `[x0, y0, x1, y1]` in the view's own
15
- * coordinates (longitude and latitude in degrees on a geographic view, whose corners are
16
- * projected; x and y otherwise), or over the whole frame where `bounds` is left out. The image is
17
- * not reprojected.
10
+ * - `{tiles, attribution}`: raster map tiles. `tiles` is the tile server's URL template, with
11
+ * `{z}`, `{x}` and `{y}`, and `attribution` the credit the tile server asks for. Only for a view
12
+ * with a {@link ViewInfo.tileScheme}. There is no default tile server.
13
+ * - `{image, bounds}`: one image, stretched over `bounds` without reprojection. `bounds` is
14
+ * `[x0, y0, x1, y1]` in the view's own coordinates: longitude and latitude in degrees on a
15
+ * geographic view, x and y otherwise. Leave it out to cover the whole frame.
18
16
  *
19
17
  * @category Basemaps
20
18
  */
@@ -43,15 +41,15 @@ export type WorldColours = {
43
41
  */
44
42
  export type BasemapOptions = {
45
43
  /**
46
- * The ground the map draws on. The world outline is a little darker than a light ground and a
47
- * little lighter than a dark one. Defaults to `light`.
44
+ * The map's background, `light` or `dark`. The world outline is drawn a little darker than a
45
+ * light background and a little lighter than a dark one. Defaults to `light`.
48
46
  */
49
47
  scheme?: 'light' | 'dark';
50
- /** Colours in place of the world outline's own for `scheme`. */
48
+ /** Colours for the world outline in place of the defaults for `scheme`. */
51
49
  colours?: Partial<WorldColours>;
52
50
  /**
53
- * The camera, for tiles: they are composed for the box it shows at its depth. Without it the
54
- * whole frame is composed at a coarse depth.
51
+ * The current camera. Map tiles are fetched for the area it shows, at its zoom. Without it, tiles
52
+ * for the whole frame are fetched at a coarse zoom.
55
53
  */
56
54
  camera?: DensityCamera;
57
55
  };
@@ -103,29 +101,28 @@ export declare function isSingle(value: object): boolean;
103
101
  */
104
102
  export declare function withoutUndefined<T>(value: T): T;
105
103
  /**
106
- * Why `value` cannot be drawn under `view`, in a sentence that says what to write instead, or
107
- * `null` where it can: the world outline needs a map projection, and tiles a
104
+ * Why `value` cannot be drawn under `view`, as a sentence that says what to use instead, or `null`
105
+ * if it can. The world outline needs a view with a map projection, and map tiles need a view with a
108
106
  * {@link ViewInfo.tileScheme}.
109
107
  *
110
108
  * @category Basemaps
111
109
  */
112
110
  export declare function basemapMisfit(view: ViewInfo, value: BasemapValue): string | null;
113
111
  /**
114
- * The deck.gl layers that draw `value` under `view`, in the 512-unit world {@link MosaicaLayer}
115
- * draws in: put them before it in the `Deck`'s `layers`. `'none'` is no layers. The code that
116
- * draws a basemap is loaded the first time this is called, so a page that draws none does not load
117
- * it.
112
+ * The deck.gl layers that draw `value` under `view`. Put them before the {@link MosaicaLayer} in
113
+ * the `Deck`'s `layers`. For `'none'` the list is empty. The code that draws basemaps is loaded the
114
+ * first time you call this, so a page without a basemap never loads it.
118
115
  *
119
- * The world outline is fetched once per server ({@link Store.basemapWorld}) and placed once per
120
- * frame. Each call returns new layer instances over the geometry already placed, so deck.gl keeps
121
- * its buffers and every map gets layers of its own; for tiles, a camera that still shows the same
122
- * tiles draws the image already composed.
116
+ * For map tiles, call it again with the new `camera` when the camera moves. Repeated calls are
117
+ * cheap: the world outline is fetched once per server, and a camera that still shows the same
118
+ * tiles reuses the image already drawn.
123
119
  *
124
- * @param store - The store whose server serves the world outline.
120
+ * @param store - The store, whose server serves the world outline.
125
121
  * @param view - The view drawn, from `meta.views`.
126
122
  * @param value - What to draw.
127
- * @throws `Error` where `value` is not one of the forms or does not fit `view` ({@link basemapMisfit}), and where the world
128
- * outline does not load or is in a format this client does not read.
123
+ * @param options - The background, colours and camera.
124
+ * @returns The layers. Rejects with `Error` if `value` is not a valid basemap or does not suit
125
+ * `view` (see {@link basemapMisfit}), or if the world outline fails to load.
129
126
  *
130
127
  * @category Basemaps
131
128
  */
package/dist/basemap.js CHANGED
@@ -115,8 +115,8 @@ const FORMS = [
115
115
  ]
116
116
  ];
117
117
  /**
118
- * Why `value` cannot be drawn under `view`, in a sentence that says what to write instead, or
119
- * `null` where it can: the world outline needs a map projection, and tiles a
118
+ * Why `value` cannot be drawn under `view`, as a sentence that says what to use instead, or `null`
119
+ * if it can. The world outline needs a view with a map projection, and map tiles need a view with a
120
120
  * {@link ViewInfo.tileScheme}.
121
121
  *
122
122
  * @category Basemaps
@@ -132,21 +132,20 @@ export function basemapMisfit(view, value) {
132
132
  return null;
133
133
  }
134
134
  /**
135
- * The deck.gl layers that draw `value` under `view`, in the 512-unit world {@link MosaicaLayer}
136
- * draws in: put them before it in the `Deck`'s `layers`. `'none'` is no layers. The code that
137
- * draws a basemap is loaded the first time this is called, so a page that draws none does not load
138
- * it.
135
+ * The deck.gl layers that draw `value` under `view`. Put them before the {@link MosaicaLayer} in
136
+ * the `Deck`'s `layers`. For `'none'` the list is empty. The code that draws basemaps is loaded the
137
+ * first time you call this, so a page without a basemap never loads it.
139
138
  *
140
- * The world outline is fetched once per server ({@link Store.basemapWorld}) and placed once per
141
- * frame. Each call returns new layer instances over the geometry already placed, so deck.gl keeps
142
- * its buffers and every map gets layers of its own; for tiles, a camera that still shows the same
143
- * tiles draws the image already composed.
139
+ * For map tiles, call it again with the new `camera` when the camera moves. Repeated calls are
140
+ * cheap: the world outline is fetched once per server, and a camera that still shows the same
141
+ * tiles reuses the image already drawn.
144
142
  *
145
- * @param store - The store whose server serves the world outline.
143
+ * @param store - The store, whose server serves the world outline.
146
144
  * @param view - The view drawn, from `meta.views`.
147
145
  * @param value - What to draw.
148
- * @throws `Error` where `value` is not one of the forms or does not fit `view` ({@link basemapMisfit}), and where the world
149
- * outline does not load or is in a format this client does not read.
146
+ * @param options - The background, colours and camera.
147
+ * @returns The layers. Rejects with `Error` if `value` is not a valid basemap or does not suit
148
+ * `view` (see {@link basemapMisfit}), or if the world outline fails to load.
150
149
  *
151
150
  * @category Basemaps
152
151
  */
package/dist/camera.d.ts CHANGED
@@ -7,26 +7,26 @@ export type OrthographicCamera = {
7
7
  zoom: number;
8
8
  };
9
9
  /**
10
- * Converts a deck.gl `OrthographicView` camera over the 512-unit world into the input
11
- * `store.setView` takes: the box the canvas covers, clamped to the world and converted to data
12
- * coordinates through the store's frame, the camera's zoom, and the canvas size.
10
+ * Converts a deck.gl `OrthographicView` camera into the {@link ViewInput} that the store's
11
+ * `setView` takes. Call it whenever the view state or the canvas size changes. The box the canvas
12
+ * shows is clamped to the world and converted to the current view's data coordinates.
13
13
  *
14
- * @param store - The store whose frame converts world units to data coordinates.
14
+ * @param store - The store, which converts world units to data coordinates.
15
15
  * @param camera - The view state's `target` and `zoom`.
16
16
  * @param width - The canvas width in CSS pixels.
17
17
  * @param height - The canvas height in CSS pixels.
18
- * @returns The view input, or `null` before `meta` has arrived, when the store has no frame.
18
+ * @returns The view input, or `null` until the store has `/v1/meta`.
19
19
  */
20
20
  export declare function viewInputOf(store: Pick<Store, 'frame' | 'dataXY'>, camera: OrthographicCamera, width: number, height: number): ViewInput | null;
21
21
  /**
22
- * The camera that fits a box of the 512-unit world into a canvas: centred on the box, at the zoom
23
- * where the box takes `fill` of the canvas along whichever side limits it, and at most
24
- * {@link MAX_DEPTH}. The rest of the canvas is the margin round the box.
22
+ * The deck.gl camera that fits a box of the world into a canvas. It centres the box and zooms until
23
+ * the box fills `fill` of the canvas's width or height, whichever it reaches first, up to a zoom of
24
+ * {@link MAX_DEPTH}. Spread the result into the `OrthographicView` view state.
25
25
  *
26
26
  * @param box - `[x0, y0, x1, y1]` in world units, as {@link frameMatches} gives it.
27
27
  * @param width - The canvas width in CSS pixels.
28
28
  * @param height - The canvas height in CSS pixels.
29
- * @param fill - The share of the canvas the box takes, 0.92 unless given.
29
+ * @param fill - The share of the canvas the box fills.
30
30
  */
31
31
  export declare function cameraFitting(box: readonly [number, number, number, number], width: number, height: number, fill?: number): {
32
32
  target: [number, number, number];
package/dist/camera.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { MAX_DEPTH } from '@mosaicajs/client';
2
2
  import { worldBbox } from '@mosaicajs/client/internal';
3
3
  /**
4
- * Converts a deck.gl `OrthographicView` camera over the 512-unit world into the input
5
- * `store.setView` takes: the box the canvas covers, clamped to the world and converted to data
6
- * coordinates through the store's frame, the camera's zoom, and the canvas size.
4
+ * Converts a deck.gl `OrthographicView` camera into the {@link ViewInput} that the store's
5
+ * `setView` takes. Call it whenever the view state or the canvas size changes. The box the canvas
6
+ * shows is clamped to the world and converted to the current view's data coordinates.
7
7
  *
8
- * @param store - The store whose frame converts world units to data coordinates.
8
+ * @param store - The store, which converts world units to data coordinates.
9
9
  * @param camera - The view state's `target` and `zoom`.
10
10
  * @param width - The canvas width in CSS pixels.
11
11
  * @param height - The canvas height in CSS pixels.
12
- * @returns The view input, or `null` before `meta` has arrived, when the store has no frame.
12
+ * @returns The view input, or `null` until the store has `/v1/meta`.
13
13
  */
14
14
  export function viewInputOf(store, camera, width, height) {
15
15
  if (!store.frame())
@@ -20,14 +20,14 @@ export function viewInputOf(store, camera, width, height) {
20
20
  return { bbox: [x0, y0, x1, y1], zoom: camera.zoom, width, height };
21
21
  }
22
22
  /**
23
- * The camera that fits a box of the 512-unit world into a canvas: centred on the box, at the zoom
24
- * where the box takes `fill` of the canvas along whichever side limits it, and at most
25
- * {@link MAX_DEPTH}. The rest of the canvas is the margin round the box.
23
+ * The deck.gl camera that fits a box of the world into a canvas. It centres the box and zooms until
24
+ * the box fills `fill` of the canvas's width or height, whichever it reaches first, up to a zoom of
25
+ * {@link MAX_DEPTH}. Spread the result into the `OrthographicView` view state.
26
26
  *
27
27
  * @param box - `[x0, y0, x1, y1]` in world units, as {@link frameMatches} gives it.
28
28
  * @param width - The canvas width in CSS pixels.
29
29
  * @param height - The canvas height in CSS pixels.
30
- * @param fill - The share of the canvas the box takes, 0.92 unless given.
30
+ * @param fill - The share of the canvas the box fills.
31
31
  */
32
32
  export function cameraFitting(box, width, height, fill = 0.92) {
33
33
  const across = Math.abs(box[2] - box[0]) || 1;
package/dist/colour.d.ts CHANGED
@@ -28,8 +28,7 @@ export declare const UNMAPPED: Rgba;
28
28
  */
29
29
  export type CategoryPaletteName = 'tableau10' | 'okabe-ito' | 'set2' | 'dark2';
30
30
  /**
31
- * A qualitative palette: its title, whether it stays distinguishable under the common colour-vision
32
- * deficiencies, and its colours in rank order.
31
+ * A qualitative palette, for colouring a category column.
33
32
  *
34
33
  * @category Colour
35
34
  */
@@ -42,9 +41,9 @@ export type CategoryPalette = {
42
41
  colours: readonly Rgb[];
43
42
  };
44
43
  /**
45
- * The qualitative palettes, by name. A value's colour is the palette's entry at its rank among the
46
- * values drawn, ordered by frequency; a value ranked past the palette's end is drawn in
47
- * {@link UNMAPPED} and listed as "Other".
44
+ * The qualitative palettes, by name. The most frequent category values among the marks drawn take
45
+ * the palette's colours in order, and a value keeps its colour as the camera moves. Values past the
46
+ * end of the palette are drawn grey.
48
47
  *
49
48
  * @category Colour
50
49
  */
@@ -58,8 +57,8 @@ export declare const CATEGORY_PALETTES: Readonly<Record<CategoryPaletteName, Cat
58
57
  */
59
58
  export type RampName = 'viridis' | 'cividis' | 'magma' | 'greys' | 'red-blue';
60
59
  /**
61
- * A colour ramp: its title, whether it diverges from a midpoint, and its stops from the low end to
62
- * the high end, interpolated linearly in RGB.
60
+ * A colour ramp, for colouring a number column. Colours between its stops are interpolated
61
+ * linearly in RGB.
63
62
  *
64
63
  * @category Colour
65
64
  */
@@ -67,8 +66,8 @@ export type Ramp = {
67
66
  /** The ramp's name as a menu shows it. */
68
67
  title: string;
69
68
  /**
70
- * Whether the ramp diverges from a midpoint: zero where the range spans zero, else the middle of
71
- * the range. The midpoint takes the ramp's middle colour.
69
+ * Whether the ramp diverges from a midpoint, which takes the ramp's middle colour. The midpoint
70
+ * is zero if the range spans zero, and the middle of the range otherwise.
72
71
  */
73
72
  diverging: boolean;
74
73
  /** The stops from the low end to the high end. */
@@ -81,38 +80,38 @@ export type Ramp = {
81
80
  */
82
81
  export declare const RAMPS: Readonly<Record<RampName, Ramp>>;
83
82
  /**
84
- * How a number is placed on a ramp: `linear` in the value, or `log`, which places
85
- * `log(1 + (v − min))` so that a long tail does not push most values into one colour. On a
86
- * diverging ramp, `log` applies either side of the midpoint.
83
+ * How a number is placed on a ramp: `linear`, in proportion to the value, or `log`, in proportion
84
+ * to `log(1 + (v − min))`, so that a long tail does not push most values into one colour. On a
85
+ * diverging ramp, `log` applies on each side of the midpoint.
87
86
  *
88
87
  * @category Colour
89
88
  */
90
89
  export type RampScale = 'linear' | 'log';
91
90
  /**
92
- * The colour choices for a column: the palette for a category, the ramp for a number, and colours
93
- * chosen for single category values. The same choices colour the marks and the legend.
91
+ * How to colour marks by a column: a palette for a category column, a ramp for a number column,
92
+ * and any colours you choose for single category values. The same choices colour the legend.
94
93
  *
95
94
  * @category Colour
96
95
  */
97
96
  export type Colouring = {
98
- /** The palette a category column's values take in order of rank. */
97
+ /** The palette for a category column. */
99
98
  palette: CategoryPaletteName;
100
- /** The ramp a number column's values are placed on. */
99
+ /** The ramp for a number column. */
101
100
  ramp: RampName;
102
101
  /** How a number is placed on the ramp. */
103
102
  scale: RampScale;
104
103
  /** Whether the ramp runs from its high end to its low end. */
105
104
  reverse: boolean;
106
105
  /**
107
- * Colours chosen for single category values, per column, per category key, as `#rrggbb`. A value
108
- * named here takes this colour in place of its palette colour. A key that is not a drawn value of
109
- * the column colours nothing.
106
+ * Colours you choose for single category values, as `#rrggbb`, keyed by column and then by
107
+ * category key. A chosen colour replaces the value's palette colour. A key that is not among the
108
+ * column's drawn values has no effect.
110
109
  */
111
110
  values: Readonly<Record<string, Readonly<Record<string, string>>>>;
112
111
  };
113
112
  /**
114
- * The colouring with nothing chosen: Tableau 10, Viridis on a linear scale, and no value's colour
115
- * chosen.
113
+ * The default colouring: Tableau 10 for categories, Viridis on a linear scale for numbers, and no
114
+ * chosen colours.
116
115
  *
117
116
  * @category Colour
118
117
  */
package/dist/colour.js CHANGED
@@ -10,9 +10,9 @@ export const UNIFORM = [120, 190, 255, ALPHA];
10
10
  export const UNMAPPED = [110, 118, 132, ALPHA];
11
11
  const hex = (h) => [parseInt(h.slice(1, 3), 16), parseInt(h.slice(3, 5), 16), parseInt(h.slice(5, 7), 16)];
12
12
  /**
13
- * The qualitative palettes, by name. A value's colour is the palette's entry at its rank among the
14
- * values drawn, ordered by frequency; a value ranked past the palette's end is drawn in
15
- * {@link UNMAPPED} and listed as "Other".
13
+ * The qualitative palettes, by name. The most frequent category values among the marks drawn take
14
+ * the palette's colours in order, and a value keeps its colour as the camera moves. Values past the
15
+ * end of the palette are drawn grey.
16
16
  *
17
17
  * @category Colour
18
18
  */
@@ -55,8 +55,8 @@ export const RAMPS = {
55
55
  'red-blue': { title: 'Red–Blue, diverging', diverging: true, stops: ['#b2182b', '#ef8a62', '#f7f7f7', '#67a9cf', '#2166ac'].map(hex) }
56
56
  };
57
57
  /**
58
- * The colouring with nothing chosen: Tableau 10, Viridis on a linear scale, and no value's colour
59
- * chosen.
58
+ * The default colouring: Tableau 10 for categories, Viridis on a linear scale for numbers, and no
59
+ * chosen colours.
60
60
  *
61
61
  * @category Colour
62
62
  */
@@ -1,26 +1,25 @@
1
1
  import { type Store } from '@mosaicajs/client';
2
2
  import { type DensityCounts } from './density.js';
3
3
  /**
4
- * The cell sizes on screen density's resolution is chosen from, in CSS pixels, coarse to fine.
4
+ * The cell sizes on screen that density can be drawn at, in CSS pixels, from coarse to fine.
5
5
  *
6
6
  * @category Colour
7
7
  */
8
8
  export declare const DENSITY_CELL_SIZES: readonly number[];
9
9
  /**
10
- * The cell size density is drawn at until one is chosen, in CSS pixels.
10
+ * The cell size density is drawn at by default, in CSS pixels.
11
11
  *
12
12
  * @category Colour
13
13
  */
14
14
  export declare const DEFAULT_DENSITY_CELL_PX = 12;
15
15
  /**
16
- * How long the camera rests before {@link DensityCounter} asks for counts, in milliseconds.
16
+ * How long the camera must rest before {@link DensityCounter} fetches counts, in milliseconds.
17
17
  *
18
18
  * @category Colour
19
19
  */
20
20
  export declare const DENSITY_SETTLE_MS = 200;
21
21
  /**
22
- * A camera over the 512-unit world, as deck's `OrthographicView` view state holds it, with the
23
- * canvas size.
22
+ * A deck.gl `OrthographicView` camera over the 512-unit world, with the canvas size.
24
23
  *
25
24
  * @category Colour
26
25
  */
@@ -35,79 +34,67 @@ export type DensityCamera = {
35
34
  height: number;
36
35
  };
37
36
  /**
38
- * One resolution stop: its cell size on screen, the depth whose cells come closest to it at the
39
- * camera's zoom, and whether that depth's cells over the asked area fit
40
- * `selection.maxAggregateCells`.
37
+ * One cell size density can be drawn at, at the current camera. A menu of resolutions can disable
38
+ * the stops that are not `enabled`.
41
39
  *
42
40
  * @category Colour
43
41
  */
44
42
  export type ResolutionStop = {
45
43
  /** The cell size on screen, in CSS pixels. */
46
44
  px: number;
47
- /** The depth whose cells are nearest that size at the camera's zoom. */
45
+ /** The depth of the cells fetched for this size at the camera's zoom (see {@link DensityCounts}). */
48
46
  depth: number;
49
- /** Whether that depth's cells over the area asked for number at most `selection.maxAggregateCells`. */
47
+ /** Whether the server's `selection.maxAggregateCells` allows this many cells over the area fetched. */
50
48
  enabled: boolean;
51
49
  };
52
50
  /**
53
- * What {@link DensityCounter} asks for.
51
+ * The settings {@link DensityCounter.set} takes.
54
52
  *
55
53
  * @category Colour
56
54
  */
57
55
  export type DensitySettings = {
58
- /** Whether density is drawn. Off, nothing is asked for and nothing is held. */
56
+ /** Whether density is drawn. While it is off, the counter fetches nothing and holds nothing. */
59
57
  on: boolean;
60
- /** The cell size on screen, in CSS pixels, taken as the nearest of {@link DENSITY_CELL_SIZES}. */
58
+ /** The cell size on screen in CSS pixels, rounded to the nearest of {@link DENSITY_CELL_SIZES}. */
61
59
  cellPx: number;
62
60
  };
63
61
  /**
64
- * The depth whose cells are closest to `cellPx` across on screen at `zoom`, nearest on a log scale.
65
- * A cell at depth `d` is `WORLD_SIZE · 2^zoom / 2^d` pixels wide.
62
+ * The depth whose cells are closest to `cellPx` wide on screen at `zoom`, measured on a log scale.
63
+ * A cell at depth `d` is `512 · 2^zoom / 2^d` pixels wide.
66
64
  *
67
65
  * @category Colour
68
66
  */
69
67
  export declare function cellDepth(zoom: number, cellPx: number): number;
70
68
  /**
71
- * The stops of {@link DENSITY_CELL_SIZES} at `camera`, each with the depth it asks for and whether
72
- * that depth fits `limit` cells over the area asked for.
69
+ * Each size in {@link DENSITY_CELL_SIZES} at `camera`, with its depth and whether its cells over
70
+ * the area fetched number at most `limit`, the server's `selection.maxAggregateCells`.
73
71
  *
74
72
  * @category Colour
75
73
  */
76
74
  export declare function resolutionStops(camera: DensityCamera, limit: number): ResolutionStop[];
77
75
  /**
78
- * The stop of {@link DENSITY_CELL_SIZES} nearest `px` on a log scale.
76
+ * The size in {@link DENSITY_CELL_SIZES} nearest `px`, measured on a log scale.
79
77
  *
80
78
  * @category Colour
81
79
  */
82
80
  export declare function nearestStop(px: number): number;
83
81
  /**
84
- * Keeps the counts density is drawn from for a camera: one `POST /v1/aggregate` grouping of cells,
85
- * registered with the store, which sends its filters and its highlight with it and asks again when
86
- * either changes. The counts are the highlighted items' under a highlight and the filtered items'
87
- * otherwise.
82
+ * Fetches the counts that density is drawn from, for the area around a camera. It registers an
83
+ * aggregate with the store, so the counts cover only what the viewer may see under the store's
84
+ * filters, and it fetches again when the filters, the highlight or the store's view (coordinate
85
+ * system) change. While a
86
+ * highlight is set, it counts the highlighted items.
88
87
  *
89
- * A camera change asks nothing while the camera moves. {@link DENSITY_SETTLE_MS} after the last
90
- * one, the counter works out the depth whose cells are nearest the chosen size on screen and asks
91
- * for that depth over the viewport and a margin, unless the counts asked for last are at that depth
92
- * and their area holds the viewport. The same request asks for up to {@link RINGS} coarser levels,
93
- * each a depth coarser over twice the reach, as the points' ring is fetched coarser further out. A
94
- * move that leaves the finest area asked for drops the registration at once, so a filter changed
95
- * during the move asks nothing for an area no longer shown. The counts held are drawn at their own
96
- * world positions until the next answer lands, so a zoom scales them with the map and a pan within
97
- * the margin asks nothing: the finest level held whose area holds the viewport is drawn, so a zoom
98
- * out draws the coarser levels' counts to the edges, and where no level holds it the widest is
99
- * drawn. A view switch asks again at once.
88
+ * Tell it where the camera is with `look` and what to draw with `set`. Once the camera has rested
89
+ * for {@link DENSITY_SETTLE_MS}, it fetches cells of about the chosen size on screen over the
90
+ * viewport and a margin round it, so a short pan needs no new request. Until the first answer for
91
+ * the view arrives, or after the server refuses one, `counts` returns the coarser counts that come
92
+ * with the map's tiles. After that it returns the last answer until the next one arrives.
93
+ * `onChange` is called whenever the counts to draw change.
100
94
  *
101
- * A depth whose cells over the area would pass `selection.maxAggregateCells` is never asked for.
102
- * Where the server refuses a request with `422` anyway, the counter asks one depth coarser, up to
103
- * three times. After any other refusal it drops the answer it held, so density is drawn from the
104
- * frame's tile counts as below, and it asks again at the camera's next rest.
105
- *
106
- * Until an answer is held for the view, density is drawn from the counts the frame's tiles carry,
107
- * which land with each viewport response ahead of its points. They count the same items, at the
108
- * tiles' coarser cells, and are not drawn once an answer is held.
109
- *
110
- * `onChange` is called when the counts to draw change.
95
+ * A {@link MosaicaLayer} with a `store` keeps a counter of its own. Make one yourself and pass it
96
+ * as the layer's `densityCounter` if your own code also needs the counts, as `<mosaica-map>` does
97
+ * for its density key.
111
98
  *
112
99
  * @category Colour
113
100
  */
@@ -128,23 +115,31 @@ export declare class DensityCounter {
128
115
  /** The tiles projection last read, and the counts derived from it. */
129
116
  private tiles;
130
117
  private readonly unsubscribe;
118
+ /**
119
+ * @param store - The store to fetch through.
120
+ * @param onChange - Called whenever the counts to draw change.
121
+ * @param settleMs - How long the camera must rest before counts are fetched, in milliseconds.
122
+ */
131
123
  constructor(store: Store, onChange: () => void, settleMs?: number);
132
- /** The camera moved or the canvas was resized. Counts are asked for once it has rested. */
124
+ /** Tell the counter the camera has moved or the canvas has been resized. */
133
125
  look(camera: DensityCamera): void;
134
- /** What to draw. Off drops the registration and the counts held at once. */
126
+ /** Turn density on or off and choose the cell size. Turning it off drops the counts held. */
135
127
  set(settings: DensitySettings): void;
136
128
  /**
137
- * The counts to draw: the last answer, while it was counted in the store's current view, and
138
- * until there is one the frame's tile counts. Nothing while density is off.
129
+ * The counts to draw, or `null` while density is off or there are none. Until the first answer
130
+ * for the current view arrives, these are the coarser counts that come with the map's tiles.
139
131
  */
140
132
  counts(): DensityCounts | null;
141
133
  /** The finest level held whose area holds the viewport, else the widest; null where none is held for the view. */
142
134
  private answered;
143
135
  /** The frame's tile counts at its depth, derived once per tiles projection; null where none. */
144
136
  private tileCounts;
145
- /** The resolution stops at the camera as it stands; every stop is enabled before a camera and `meta`. */
137
+ /**
138
+ * The cell sizes density can be drawn at for the current camera. Every stop is enabled until the
139
+ * counter has a camera and the store has `meta`.
140
+ */
146
141
  stops(): ResolutionStop[];
147
- /** Drop the registration and stop following the store. */
142
+ /** Stop fetching counts and unsubscribe from the store. */
148
143
  dispose(): void;
149
144
  private schedule;
150
145
  /** Ask for the counts at the camera, unless what was asked for last holds the viewport; `force` asks regardless. */