@mosaicajs/components 0.1.0-rc.4 → 0.1.0

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.
Files changed (52) hide show
  1. package/dist/artifact-card.d.ts +20 -26
  2. package/dist/artifact-card.js +20 -26
  3. package/dist/base.d.ts +21 -29
  4. package/dist/base.js +18 -26
  5. package/dist/basemap.d.ts +2 -2
  6. package/dist/cluster-filter.d.ts +19 -25
  7. package/dist/cluster-filter.js +19 -25
  8. package/dist/colour-editor.d.ts +16 -36
  9. package/dist/colour-editor.js +16 -36
  10. package/dist/context.d.ts +4 -4
  11. package/dist/context.js +4 -4
  12. package/dist/count.d.ts +16 -15
  13. package/dist/count.js +16 -15
  14. package/dist/events.d.ts +63 -68
  15. package/dist/explorer.d.ts +76 -119
  16. package/dist/explorer.js +76 -121
  17. package/dist/field-card.d.ts +24 -56
  18. package/dist/field-card.js +24 -56
  19. package/dist/filter-panel.d.ts +31 -45
  20. package/dist/filter-panel.js +31 -45
  21. package/dist/filter.d.ts +20 -28
  22. package/dist/filter.js +20 -28
  23. package/dist/hierarchy.d.ts +35 -36
  24. package/dist/hierarchy.js +35 -36
  25. package/dist/index.d.ts +5 -4
  26. package/dist/index.js +5 -4
  27. package/dist/item-card.d.ts +34 -55
  28. package/dist/item-card.js +34 -55
  29. package/dist/key-picker.d.ts +5 -5
  30. package/dist/key-picker.js +5 -5
  31. package/dist/layer-picker.d.ts +11 -9
  32. package/dist/layer-picker.js +11 -9
  33. package/dist/map.d.ts +134 -172
  34. package/dist/map.js +136 -188
  35. package/dist/mosaica-components.js +5599 -1594
  36. package/dist/mosaica-components.js.LICENSE.txt +80 -16
  37. package/dist/mosaica-components.js.sri +1 -1
  38. package/dist/mosaica-components.json +2 -2
  39. package/dist/parts.d.ts +3 -4
  40. package/dist/parts.js +3 -4
  41. package/dist/selection.d.ts +21 -27
  42. package/dist/selection.js +21 -27
  43. package/dist/states.d.ts +15 -20
  44. package/dist/status.d.ts +26 -38
  45. package/dist/status.js +26 -38
  46. package/dist/store-element.d.ts +8 -7
  47. package/dist/store-element.js +8 -7
  48. package/dist/tokens.d.ts +12 -13
  49. package/dist/tokens.js +12 -13
  50. package/dist/view-picker.d.ts +10 -6
  51. package/dist/view-picker.js +10 -6
  52. package/package.json +6 -6
package/dist/map.js CHANGED
@@ -56,37 +56,29 @@ const VIEW = new OrthographicView({ id: 'ortho', flipY: true });
56
56
  /** How many maps have been made, which numbers each one's ask for point columns. */
57
57
  let mapsMade = 0;
58
58
  /**
59
- * The map: the points, the density wash, the artifacts' outlines and labels, hover, pick and the
60
- * selection, drawn with deck.gl in an orthographic view. The refused, expired and empty states, and
61
- * a server that cannot be reached, did not answer or is too busy, are drawn over the canvas, so
62
- * none of them reads as an empty corpus. A refusal shows the server's reason under its words. The
63
- * toolbar switches between pan, box select and lasso select, and fits the camera to the items the
64
- * filters match; shift-drag in pan mode draws a box. A settled box or lasso becomes the store's
65
- * selection, a filter every count narrows to; a tag on its top-left corner gives the count matched
66
- * inside it and a button that clears it.
59
+ * Use the map on its own when you lay out your own panels around it. It draws one view's points,
60
+ * density and annotation layers. When the viewer picks a point or draws a region, the map records
61
+ * it in the store, so the other elements on the page follow.
67
62
  *
68
- * The map owns the camera and tells the store where it is looking on every move. When it is given
69
- * a store, and when the store switches to a view with another extent, it opens framed on the items
70
- * the store's filters match, as the Fit button frames them ({@link MosaicaMap.fit}). It sends the
71
- * store no camera until then, so no points are fetched for a camera it is about to leave. A camera
72
- * the user or the host moves first is kept, and a later change of filter leaves the camera where
73
- * it is. Density is asked for once the camera has rested for 200 ms, as counts by cell over the
74
- * view and a margin round it, with coarser counts reaching further for a zoom out, and the last
75
- * counts are drawn at their own positions until the next land. Keys, with the map focused: the
76
- * arrow keys pan, `+` and `-` zoom, and Escape cancels a shape being drawn, else
77
- * clears the selected region, else drops the picked point or artifact and its ring. A click on
78
- * empty map drops them too; a selected region stays. A press hides
79
- * the hover tooltip until the pointer is released, and the point whose record is selected, which
80
- * its item card shows, has no tooltip. The canvas is one tab stop, after the toolbar
81
- * and before the content of the other corners: it carries `role="application"`, the `tabindex`
82
- * the host set on the map, else 0, and the host's `aria-label` where the host set one, else one
83
- * naming the keys. A `tabindex` the host sets moves to the canvas, leaving -1 on the map, so the
84
- * map is never a second stop. `focus()` focuses the canvas.
63
+ * The map takes its store from its `store` property or from an enclosing `<mosaica-store>`. It can
64
+ * also build its own from `viewer-url` and `token` or `authorise`.
85
65
  *
86
- * The host element is `display: block`; its height comes from `--mosaica-map-height`. A map that
87
- * is disconnected and not reconnected releases its GPU resources a quarter of a second later.
66
+ * When the map first gets a store, it frames the items the filters match unless the camera has
67
+ * already been moved. It frames them again when the view switches to one with a different extent,
68
+ * but a change of filter leaves the camera where it is.
88
69
  *
89
- * @summary The map canvas.
70
+ * A box or lasso drawn with the toolbar becomes the store's selected region, which narrows the map
71
+ * and every count to the items inside it. Shift-drag draws a box without changing tool. With the
72
+ * map focused, the arrow keys pan and `+` and `-` zoom. Escape cancels a shape being drawn, or
73
+ * clears the region when there is no shape, or drops the picked item when there is neither.
74
+ *
75
+ * When the map cannot draw the view, it says why over the canvas.
76
+ *
77
+ * The canvas is a single tab stop, and it takes any `tabindex` or `aria-label` you set on the map.
78
+ * Without an `aria-label`, the canvas is labelled with its keys, "map: arrow keys pan, + and -
79
+ * zoom", so that someone using a screen reader knows how to move it.
80
+ *
81
+ * @summary An interactive map with no panels around it.
90
82
  * @tagname mosaica-map
91
83
  * @category Elements
92
84
  * @slot top-left - Content in the top-left corner, below the toolbar when it is there.
@@ -102,42 +94,39 @@ let mapsMade = 0;
102
94
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-itemopen']>} mosaica-itemopen - The selected
103
95
  * item's record arrived, however the item was selected.
104
96
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-miss']>} mosaica-miss - A click found no point
105
- * and no artifact. The map has dropped the selection, as {@link MosaicaMap.clearPick} does.
97
+ * and no artifact. The map has already dropped the picked item.
106
98
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-hover']>} mosaica-hover - The pointer moved onto
107
99
  * or over a point.
108
100
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-artifactopen']>} mosaica-artifactopen - An
109
- * artifact was opened and its drill-down arrived.
101
+ * artifact was opened and its details arrived.
110
102
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-selectchange']>} mosaica-selectchange - A
111
103
  * selection was drawn or cleared (`status` `loading` or `cleared`), and again when its counts
112
104
  * arrive.
113
105
  * @fires {CustomEvent<MosaicaEventDetails['mosaica-layerchange']>} mosaica-layerchange - The
114
106
  * `layers` attribute changed.
115
107
  * @csspart canvas - The deck.gl canvas's container.
116
- * @csspart overlay - The state drawn over the canvas when refused, expired or empty, when the
117
- * server cannot be reached, when it did not answer, and when it is too busy. Where the
118
- * viewer can see no item in the view at all, it says so in place of Nothing in view.
108
+ * @csspart overlay - The message over the canvas when the view is refused, expired or empty, or the
109
+ * server cannot be reached, did not answer or is too busy. If the viewer may see no item in the
110
+ * view at all, it says so instead of "Nothing in view".
119
111
  * @csspart state - The state line inside the overlay, with `data-state`, and `data-visible="none"`
120
- * where the viewer can see no item in the view.
121
- * @csspart retry - The Retry button in the overlay, when the view was refused or the server did
122
- * not answer or is too busy.
112
+ * if the viewer may see no item in the view.
113
+ * @csspart retry - The Retry button in the overlay, after a refusal, no answer or a busy server.
123
114
  * @csspart refusal - The words "View refused", or "Server busy", inside the overlay, with
124
115
  * `data-code` set to the refusal's code.
125
116
  * @csspart reason - The server's reason for a refusal, as it sent it, on a line under "View
126
117
  * refused".
127
118
  * @csspart controls - The toolbar.
128
- * @csspart region-tag - The drawn region's tag on its top-left corner: how many items match inside
129
- * it, or outside it for its complement, and a button that clears the selection.
119
+ * @csspart region-tag - The tag on the selected region's top-left corner, with how many items
120
+ * match inside it (or outside it, for its complement) and a button that clears it.
130
121
  * @csspart tooltip - The hover tooltip.
131
- * @csspart density-key - The key to density's colours, items per cell from 0 to the largest count
132
- * drawn with the count at the scale's midpoint, in the bottom-left corner while density is drawn
133
- * in a ramp or without the points.
134
- * @csspart note - Why no basemap is drawn under this view, in the bottom-right corner: the value
135
- * given does not fit it, or the basemap did not load.
122
+ * @csspart density-key - The key to density's colours in items per cell, in the bottom-left corner.
123
+ * Shown while density is drawn in a colour ramp or without the points.
124
+ * @csspart note - Why no basemap is drawn under this view, in the bottom-right corner.
136
125
  * @csspart attribution - The tile server's credit, in the bottom-right corner while tiles are drawn.
137
126
  * @cssprop --mosaica-map-height - The map's height.
138
127
  * @cssprop --mosaica-map-bg - The canvas's background, behind the points and any basemap.
139
- * @cssprop --mosaica-map-inset-left - Extra space between the top-left corner's content and the
140
- * map's left edge, for a panel floated over the map's left side. Defaults to 0.
128
+ * @cssprop --mosaica-map-inset-left - Extra space to the left of the top-left corner's content, to
129
+ * clear a panel you float over the map's left side. Defaults to 0.
141
130
  */
142
131
  let MosaicaMap = (() => {
143
132
  let _classSuper = MosaicaElement;
@@ -150,12 +139,6 @@ let MosaicaMap = (() => {
150
139
  let _budget_decorators;
151
140
  let _budget_initializers = [];
152
141
  let _budget_extraInitializers = [];
153
- let _budgetMin_decorators;
154
- let _budgetMin_initializers = [];
155
- let _budgetMin_extraInitializers = [];
156
- let _budgetMax_decorators;
157
- let _budgetMax_initializers = [];
158
- let _budgetMax_extraInitializers = [];
159
142
  let _clusterBudget_decorators;
160
143
  let _clusterBudget_initializers = [];
161
144
  let _clusterBudget_extraInitializers = [];
@@ -264,8 +247,6 @@ let MosaicaMap = (() => {
264
247
  converter: { fromAttribute: (v) => (v ? v.split(/[\s,]+/).filter(Boolean) : []), toAttribute: (v) => v.join(' ') }
265
248
  })];
266
249
  _budget_decorators = [property({ type: Number })];
267
- _budgetMin_decorators = [property({ type: Number, attribute: 'budget-min' })];
268
- _budgetMax_decorators = [property({ type: Number, attribute: 'budget-max' })];
269
250
  _clusterBudget_decorators = [property({ type: Number, attribute: 'cluster-budget' })];
270
251
  _tooltipFields_decorators = [property({ attribute: 'tooltip-fields' })];
271
252
  _titleField_decorators = [property({ attribute: 'title-field' })];
@@ -302,8 +283,6 @@ let MosaicaMap = (() => {
302
283
  __esDecorate(this, null, _colourBy_decorators, { kind: "accessor", name: "colourBy", static: false, private: false, access: { has: obj => "colourBy" in obj, get: obj => obj.colourBy, set: (obj, value) => { obj.colourBy = value; } }, metadata: _metadata }, _colourBy_initializers, _colourBy_extraInitializers);
303
284
  __esDecorate(this, null, _layers_decorators, { kind: "accessor", name: "layers", static: false, private: false, access: { has: obj => "layers" in obj, get: obj => obj.layers, set: (obj, value) => { obj.layers = value; } }, metadata: _metadata }, _layers_initializers, _layers_extraInitializers);
304
285
  __esDecorate(this, null, _budget_decorators, { kind: "accessor", name: "budget", static: false, private: false, access: { has: obj => "budget" in obj, get: obj => obj.budget, set: (obj, value) => { obj.budget = value; } }, metadata: _metadata }, _budget_initializers, _budget_extraInitializers);
305
- __esDecorate(this, null, _budgetMin_decorators, { kind: "accessor", name: "budgetMin", static: false, private: false, access: { has: obj => "budgetMin" in obj, get: obj => obj.budgetMin, set: (obj, value) => { obj.budgetMin = value; } }, metadata: _metadata }, _budgetMin_initializers, _budgetMin_extraInitializers);
306
- __esDecorate(this, null, _budgetMax_decorators, { kind: "accessor", name: "budgetMax", static: false, private: false, access: { has: obj => "budgetMax" in obj, get: obj => obj.budgetMax, set: (obj, value) => { obj.budgetMax = value; } }, metadata: _metadata }, _budgetMax_initializers, _budgetMax_extraInitializers);
307
286
  __esDecorate(this, null, _clusterBudget_decorators, { kind: "accessor", name: "clusterBudget", static: false, private: false, access: { has: obj => "clusterBudget" in obj, get: obj => obj.clusterBudget, set: (obj, value) => { obj.clusterBudget = value; } }, metadata: _metadata }, _clusterBudget_initializers, _clusterBudget_extraInitializers);
308
287
  __esDecorate(this, null, _tooltipFields_decorators, { kind: "accessor", name: "tooltipFields", static: false, private: false, access: { has: obj => "tooltipFields" in obj, get: obj => obj.tooltipFields, set: (obj, value) => { obj.tooltipFields = value; } }, metadata: _metadata }, _tooltipFields_initializers, _tooltipFields_extraInitializers);
309
288
  __esDecorate(this, null, _titleField_decorators, { kind: "accessor", name: "titleField", static: false, private: false, access: { has: obj => "titleField" in obj, get: obj => obj.titleField, set: (obj, value) => { obj.titleField = value; } }, metadata: _metadata }, _titleField_initializers, _titleField_extraInitializers);
@@ -550,51 +529,41 @@ let MosaicaMap = (() => {
550
529
  canBuildOwn = true;
551
530
  #colourBy_accessor_storage = __runInitializers(this, _colourBy_initializers, '');
552
531
  /**
553
- * What the points are coloured by: a declared column that is rendered, `cluster:<layer>` for a
554
- * layer that can colour, or `none` for one colour. Unset, the store's choice stands.
532
+ * What colours the points: a rendered column (one sent with the points), `cluster:<layer>` for a
533
+ * layer that can colour, or `none` for a single colour. Unset, the store's choice stands.
555
534
  */
556
535
  get colourBy() { return this.#colourBy_accessor_storage; }
557
536
  set colourBy(value) { this.#colourBy_accessor_storage = value; }
558
537
  #layers_accessor_storage = (__runInitializers(this, _colourBy_extraInitializers), __runInitializers(this, _layers_initializers, null));
559
538
  /**
560
- * The annotation layers to draw, space- or comma-separated; each is drawn with the layers it
539
+ * The annotation layers to draw, separated by spaces or commas. Each also draws the layers it
561
540
  * depends on. Unset, the store's choice stands.
562
541
  */
563
542
  get layers() { return this.#layers_accessor_storage; }
564
543
  set layers(value) { this.#layers_accessor_storage = value; }
565
544
  #budget_accessor_storage = (__runInitializers(this, _layers_extraInitializers), __runInitializers(this, _budget_initializers, 0));
566
- /** How many marks to aim for on screen. `0` leaves the store's budget, which starts at 250000. */
545
+ /** How many marks to aim for on screen. `0` keeps the store's budget, which starts at 250000. */
567
546
  get budget() { return this.#budget_accessor_storage; }
568
547
  set budget(value) { this.#budget_accessor_storage = value; }
569
- #budgetMin_accessor_storage = (__runInitializers(this, _budget_extraInitializers), __runInitializers(this, _budgetMin_initializers, 1_000));
570
- /** The fewest marks a control for `budget` offers. The map sets no budget from it. */
571
- get budgetMin() { return this.#budgetMin_accessor_storage; }
572
- set budgetMin(value) { this.#budgetMin_accessor_storage = value; }
573
- #budgetMax_accessor_storage = (__runInitializers(this, _budgetMin_extraInitializers), __runInitializers(this, _budgetMax_initializers, 2_000_000));
574
- /** The most marks a control for `budget` offers. The map sets no budget from it. */
575
- get budgetMax() { return this.#budgetMax_accessor_storage; }
576
- set budgetMax(value) { this.#budgetMax_accessor_storage = value; }
577
- #clusterBudget_accessor_storage = (__runInitializers(this, _budgetMax_extraInitializers), __runInitializers(this, _clusterBudget_initializers, 0));
548
+ #clusterBudget_accessor_storage = (__runInitializers(this, _budget_extraInitializers), __runInitializers(this, _clusterBudget_initializers, 0));
578
549
  /**
579
- * The most clusters a `nested` or `dag` layer is cut to (`Store.setClusterBudget`). `0` at first
580
- * leaves the store's; `0` after a budget was set clears it, to the finest cut.
550
+ * The most clusters a `nested` or `dag` layer is cut to (`Store.setClusterBudget`). `0` keeps the
551
+ * store's setting; setting `0` after another value removes the limit, giving the finest cut.
581
552
  */
582
553
  get clusterBudget() { return this.#clusterBudget_accessor_storage; }
583
554
  set clusterBudget(value) { this.#clusterBudget_accessor_storage = value; }
584
555
  #tooltipFields_accessor_storage = (__runInitializers(this, _clusterBudget_extraInitializers), __runInitializers(this, _tooltipFields_initializers, ''));
585
556
  /**
586
- * Columns shown beneath a hovered point's title, space- or comma-separated. The map asks the
587
- * store for them with `setPointColumns`. Only a rendered column's value is in the marks; another
588
- * shows nothing.
557
+ * The columns the hover tooltip shows under the point's title, separated by spaces or commas.
558
+ * Only rendered columns arrive with the points, so another column shows nothing.
589
559
  */
590
560
  get tooltipFields() { return this.#tooltipFields_accessor_storage; }
591
561
  set tooltipFields(value) { this.#tooltipFields_accessor_storage = value; }
592
562
  #titleField_accessor_storage = (__runInitializers(this, _tooltipFields_extraInitializers), __runInitializers(this, _titleField_initializers, ''));
593
563
  /**
594
- * The field a hovered point is titled by, read from the marks where they carry it (the map asks
595
- * the store for a rendered one with `setPointColumns`), else from the item's record once the
596
- * pointer has rested on it for 140 ms. Unset, the title is the point's
597
- * `mosaica_id`.
564
+ * The field that titles a point in the hover tooltip. A rendered column shows at once; any other
565
+ * field is read from the item's record once the pointer rests on the point. Unset, the title is
566
+ * the point's `mosaica_id`.
598
567
  */
599
568
  get titleField() { return this.#titleField_accessor_storage; }
600
569
  set titleField(value) { this.#titleField_accessor_storage = value; }
@@ -604,50 +573,39 @@ let MosaicaMap = (() => {
604
573
  set mode(value) { this.#mode_accessor_storage = value; }
605
574
  #palette_accessor_storage = (__runInitializers(this, _mode_extraInitializers), __runInitializers(this, _palette_initializers, ''));
606
575
  /**
607
- * The palette clusters are coloured from under colour by cluster: `okabe-ito`, `tableau10`,
608
- * `tableau20` or `kelly`, set on the store (`Store.setPalette`). Each cluster's colour is the
609
- * palette's colour at the slot the server gives it. Unset, the store's palette stands, which is
610
- * Tableau 10 until one is chosen.
576
+ * The palette clusters are coloured from when the points are coloured by a layer: `okabe-ito`,
577
+ * `tableau10`, `tableau20` or `kelly`. It is set on the store (`Store.setPalette`). Unset, the
578
+ * store's palette stands, which starts as `tableau10`.
611
579
  */
612
580
  get palette() { return this.#palette_accessor_storage; }
613
581
  set palette(value) { this.#palette_accessor_storage = value; }
614
582
  #clusterLevel_accessor_storage = (__runInitializers(this, _palette_extraInitializers), __runInitializers(this, _clusterLevel_initializers, null));
615
583
  /**
616
- * The level of a `stacked` or `tiered` layer to colour, name and outline clusters at. Unset, the
617
- * layer's top (coarsest) level. A `nested` or `dag` layer draws the cut served.
584
+ * The level of a `stacked` or `tiered` layer at which clusters are coloured, labelled and
585
+ * outlined. Unset, the coarsest level. A `nested` or `dag` layer ignores it.
618
586
  */
619
587
  get clusterLevel() { return this.#clusterLevel_accessor_storage; }
620
588
  set clusterLevel(value) { this.#clusterLevel_accessor_storage = value; }
621
589
  #basemap_accessor_storage = (__runInitializers(this, _clusterLevel_extraInitializers), __runInitializers(this, _basemap_initializers, null));
622
590
  /**
623
- * What is drawn under the points: `world` (the server's world outline: land, coastlines and
624
- * country borders), `none`, `{tiles, attribution}` (a tile server's URL template, with `{z}`,
625
- * `{x}` and `{y}`, and its credit, shown in the bottom-right corner), `{image, bounds}` (one
626
- * image over `[x0, y0, x1, y1]` in the view's coordinates, degrees on a geographic view, or over
627
- * the whole frame), a mapping from view id to one of those, or a deck.gl layer the host built in
628
- * the map's 512-unit world. The attribute takes `world` and `none`. Unset, or for a view a
629
- * mapping leaves out, `world` on a view with a map projection and nothing on one without.
630
- *
631
- * An object with a `tiles` or `image` key is one value, and takes only the keys its form names;
632
- * any other object is a mapping. A mapping's keys are view ids as `meta.views` lists them, so a
633
- * view named `tiles` or `image` cannot be named in one; a key that names no view this viewer may
634
- * reach is ignored, and every value must be one of the forms.
635
- *
636
- * The world outline needs a projection and tiles need the view's `tileScheme`. A value that does
637
- * not fit the view it was given on, or that a mapping names for a view, is refused over the map
638
- * with what to write instead; one value that does not fit a view switched to later draws nothing
639
- * there, and a note in the bottom-right corner says why. The points are drawn either way. The
640
- * code that draws a basemap is loaded the first time one is drawn.
591
+ * What is drawn under the points. `world` is the server's outline of land, coastlines and country
592
+ * borders, and needs a view with a map projection. `{tiles, attribution}` is a tile server's URL
593
+ * template with `{z}`, `{x}` and `{y}` and the credit to show, and needs a view with a
594
+ * `tileScheme`. `{image, bounds}` is one image over `[x0, y0, x1, y1]` in the view's coordinates
595
+ * (degrees on a geographic view), or over the whole frame without `bounds`. You can also pass
596
+ * `none`, a deck.gl layer you built in the map's 512-unit world, or an object mapping view ids to
597
+ * any of these for a different basemap per view. The attribute takes only `world` and `none`.
598
+ * Unset, a view with a map projection gets `world` and any other view gets nothing. A value that
599
+ * does not fit the view is shown as an error over the map; one that stops fitting after a switch
600
+ * of view draws nothing, and a note says why. The points are drawn either way.
641
601
  */
642
602
  get basemap() { return this.#basemap_accessor_storage; }
643
603
  set basemap(value) { this.#basemap_accessor_storage = value; }
644
604
  #ground_accessor_storage = (__runInitializers(this, _basemap_extraInitializers), __runInitializers(this, _ground_initializers, ''));
645
605
  /**
646
- * The ground the map draws on, `light` or `dark`, where it differs from the page's, such as a
647
- * light basemap under a dark page. The labels and the density colours follow it, and the
648
- * toolbar and panels follow the page. Unset, the scheme the elements render in: the one the
649
- * host's `color-scheme` names, the system preference where it names both, and light where it
650
- * names neither.
606
+ * Whether the map's background is `light` or `dark`, for when it differs from the page's, such as
607
+ * a light basemap on a dark page. Labels and density colours follow it; the toolbar and panels
608
+ * follow the page. Unset, it follows the page's `color-scheme`.
651
609
  */
652
610
  get ground() { return this.#ground_accessor_storage; }
653
611
  set ground(value) { this.#ground_accessor_storage = value; }
@@ -657,35 +615,33 @@ let MosaicaMap = (() => {
657
615
  set noPoints(value) { this.#noPoints_accessor_storage = value; }
658
616
  #pointOpacity_accessor_storage = (__runInitializers(this, _noPoints_extraInitializers), __runInitializers(this, _pointOpacity_initializers, null));
659
617
  /**
660
- * A fixed point alpha from 0.1 to 1. Unset, points are more transparent the more of them are
661
- * drawn, so a dense region reads as a density.
618
+ * A fixed point opacity from 0.1 to 1. Unset, points get more transparent the more of them are
619
+ * drawn.
662
620
  */
663
621
  get pointOpacity() { return this.#pointOpacity_accessor_storage; }
664
622
  set pointOpacity(value) { this.#pointOpacity_accessor_storage = value; }
665
623
  #density_accessor_storage = (__runInitializers(this, _pointOpacity_extraInitializers), __runInitializers(this, _density_initializers, 'none'));
666
624
  /**
667
- * How density is drawn under the points, from exact counts by cell (`POST /v1/aggregate`) and
668
- * never from the points, which are a sample: `none`, `smooth` (a soft wash), `hex` (hexagons),
669
- * `grid` (square cells) or `contours` (lines of equal density). It counts the highlighted items
670
- * under a highlight, the matched items under a filter or selection, else the visible items.
625
+ * How density is drawn under the points: `none`, `smooth` (a soft wash), `hex` (hexagons),
626
+ * `grid` (square cells) or `contours` (lines of equal density). Density is counted by the server
627
+ * over every matching item, so it covers more than the sampled points drawn. It counts the
628
+ * highlighted items if there is a highlight, otherwise the items the filters and selection match.
671
629
  */
672
630
  get density() { return this.#density_accessor_storage; }
673
631
  set density(value) { this.#density_accessor_storage = value; }
674
632
  #densityResolution_accessor_storage = (__runInitializers(this, _density_extraInitializers), __runInitializers(this, _densityResolution_initializers, DEFAULT_DENSITY_CELL_PX));
675
633
  /**
676
- * How large density's cells are on screen, in CSS pixels: 32, 24, 16, 12, 8, 6 or 4, and any
677
- * other size is taken as the nearest of them. The cells asked for are those of the depth nearest
678
- * that size at the current zoom. Where that depth's cells over the area asked for are more than
679
- * the server's `selection.maxAggregateCells`, the finest size that fits is drawn instead;
680
- * {@link MosaicaMap.densityStops} says which sizes fit.
634
+ * The size of density's cells on screen, in CSS pixels: 32, 24, 16, 12, 8, 6 or 4. Other values
635
+ * are rounded to the nearest of these. If the server's `selection.maxAggregateCells` does not
636
+ * allow that many cells, the finest size that fits is drawn; `densityStops()` says
637
+ * which sizes fit.
681
638
  */
682
639
  get densityResolution() { return this.#densityResolution_accessor_storage; }
683
640
  set densityResolution(value) { this.#densityResolution_accessor_storage = value; }
684
641
  #densityColours_accessor_storage = (__runInitializers(this, _densityResolution_extraInitializers), __runInitializers(this, _densityColours_initializers, ''));
685
642
  /**
686
643
  * The colours density is drawn in: `warm-grey`, `viridis`, `cividis`, `magma` or `greys`. Unset,
687
- * the smooth wash under the points is warm grey and every other density is Viridis. While density
688
- * is drawn in a ramp, or without the points, a key to the colours sits in the bottom-left corner.
644
+ * a `smooth` wash under the points is warm grey and anything else is `viridis`.
689
645
  */
690
646
  get densityColours() { return this.#densityColours_accessor_storage; }
691
647
  set densityColours(value) { this.#densityColours_accessor_storage = value; }
@@ -695,34 +651,29 @@ let MosaicaMap = (() => {
695
651
  set densityStrength(value) { this.#densityStrength_accessor_storage = value; }
696
652
  #densityScale_accessor_storage = (__runInitializers(this, _densityStrength_extraInitializers), __runInitializers(this, _densityScale_initializers, DEFAULT_DENSITY_SCALE));
697
653
  /**
698
- * How a cell's count is placed between no items and the largest count drawn, which picks its
699
- * colour: `linear`, in proportion to the count, or `log`, in proportion to `log(1 + count)`,
700
- * which spreads counts that span several orders of magnitude. Log is the default because counts
701
- * are skewed on most maps, and under linear only the densest few cells stand out from the rest.
702
- * The largest count is that of the densest cell in the area counted, which is the view and a
703
- * margin around it; the contours take it among the cells they merge to, and a hexagon is
704
- * coloured by the densest cell under it. Any other value is taken as `log`.
654
+ * How a cell's count maps to a colour, from zero to the densest cell in and around the view:
655
+ * `linear`, or `log` on `log(1 + count)`. `log` is the default because counts are skewed on most
656
+ * maps, and on a linear scale only the densest few cells stand out. Any other value is taken as
657
+ * `log`.
705
658
  */
706
659
  get densityScale() { return this.#densityScale_accessor_storage; }
707
660
  set densityScale(value) { this.#densityScale_accessor_storage = value; }
708
661
  #categoryPalette_accessor_storage = (__runInitializers(this, _densityScale_extraInitializers), __runInitializers(this, _categoryPalette_initializers, ''));
709
662
  /**
710
- * The palette a category column's values are coloured from: `tableau10`, `okabe-ito`, `set2` or
711
- * `dark2`. Unset, the choice made in the explorer's Colour section stands, Tableau 10 until one
712
- * is made.
663
+ * The palette for colouring by a category column: `tableau10`, `okabe-ito`, `set2` or `dark2`.
664
+ * Unset, the current choice stands, which starts as `tableau10`.
713
665
  */
714
666
  get categoryPalette() { return this.#categoryPalette_accessor_storage; }
715
667
  set categoryPalette(value) { this.#categoryPalette_accessor_storage = value; }
716
668
  #ramp_accessor_storage = (__runInitializers(this, _categoryPalette_extraInitializers), __runInitializers(this, _ramp_initializers, ''));
717
669
  /**
718
- * The ramp a number column's values are coloured on: `viridis`, `cividis`, `magma`, `greys` or
719
- * `red-blue`. Unset, the choice made in the explorer's Colour section stands, Viridis until one
720
- * is made.
670
+ * The colour ramp for colouring by a number column: `viridis`, `cividis`, `magma`, `greys` or
671
+ * `red-blue`. Unset, the current choice stands, which starts as `viridis`.
721
672
  */
722
673
  get ramp() { return this.#ramp_accessor_storage; }
723
674
  set ramp(value) { this.#ramp_accessor_storage = value; }
724
675
  #rampScale_accessor_storage = (__runInitializers(this, _ramp_extraInitializers), __runInitializers(this, _rampScale_initializers, ''));
725
- /** How numbers are placed on the ramp, `linear` or `log`. Unset, the Colour section's choice stands. */
676
+ /** How numbers are placed on the ramp, `linear` or `log`. Unset, the current choice stands. */
726
677
  get rampScale() { return this.#rampScale_accessor_storage; }
727
678
  set rampScale(value) { this.#rampScale_accessor_storage = value; }
728
679
  #rampReverse_accessor_storage = (__runInitializers(this, _rampScale_extraInitializers), __runInitializers(this, _rampReverse_initializers, false));
@@ -731,21 +682,19 @@ let MosaicaMap = (() => {
731
682
  set rampReverse(value) { this.#rampReverse_accessor_storage = value; }
732
683
  #valueColours_accessor_storage = (__runInitializers(this, _rampReverse_extraInitializers), __runInitializers(this, _valueColours_initializers, null));
733
684
  /**
734
- * Colours for single category values, per column, per category key, as `#rrggbb`, such as
735
- * `{field: {'cs.CV': '#f28e2b'}}`. Setting it replaces every value colour chosen before,
736
- * including those chosen on a field card; a host restores a viewer's saved choices this way,
737
- * having kept them from `mosaica-valuecolour`. Unset, the choices made on the cards stand.
685
+ * Colours for individual category values, by column and category key, as `#rrggbb`, such as
686
+ * `{field: {'cs.CV': '#f28e2b'}}`. Setting it replaces every value colour chosen before, including
687
+ * those chosen on a field card. Use it to restore choices you saved from `mosaica-valuecolour`.
738
688
  */
739
689
  get valueColours() { return this.#valueColours_accessor_storage; }
740
690
  set valueColours(value) { this.#valueColours_accessor_storage = value; }
741
691
  #clusterColours_accessor_storage = (__runInitializers(this, _valueColours_extraInitializers), __runInitializers(this, _clusterColours_initializers, null));
742
692
  /**
743
- * Colours for single clusters, per layer, per `mosaica_id` as a decimal string, as `#rrggbb`, such
744
- * as `{topics: {'4021': '#f28e2b'}}`, set on the store in place of their palette colours
693
+ * Colours for individual clusters, by layer and `mosaica_id` (as a decimal string), as `#rrggbb`,
694
+ * such as `{topics: {'4021': '#f28e2b'}}`. They replace the palette colours
745
695
  * (`Store.setArtifactColours`). Setting it replaces every cluster colour chosen before, including
746
- * those chosen on a field card or in Edit colours; a host restores a viewer's saved choices this
747
- * way, having kept them from `mosaica-clustercolour`. An entry that is not a `mosaica_id` and a
748
- * `#rrggbb` colour is skipped. Unset, the choices made on the cards stand.
696
+ * those chosen on a field card or in Edit colours. Use it to restore choices you saved from
697
+ * `mosaica-clustercolour`. Invalid entries are skipped.
749
698
  */
750
699
  get clusterColours() { return this.#clusterColours_accessor_storage; }
751
700
  set clusterColours(value) { this.#clusterColours_accessor_storage = value; }
@@ -761,39 +710,40 @@ let MosaicaMap = (() => {
761
710
  set measure(value) { this.#measure_accessor_storage = value; }
762
711
  #radius_accessor_storage = (__runInitializers(this, _measure_extraInitializers), __runInitializers(this, _radius_initializers, null));
763
712
  /**
764
- * A fixed point radius in pixels. Unset, points are sized by how many are drawn and by the zoom.
765
- * Under `size-by`, the size column sizes the points in its place.
713
+ * A fixed point radius in pixels. Unset, the radius depends on how many points are drawn and on
714
+ * the zoom. Ignored while `size-by` names a column.
766
715
  */
767
716
  get radius() { return this.#radius_accessor_storage; }
768
717
  set radius(value) { this.#radius_accessor_storage = value; }
769
718
  #sizeBy_accessor_storage = (__runInitializers(this, _radius_extraInitializers), __runInitializers(this, _sizeBy_initializers, ''));
770
719
  /**
771
- * What the points are sized by: a declared number column that is rendered, or `none` for one
772
- * size. Each point's value is placed between `size-min` and `size-max` on `size-scale`, against
773
- * the range of the values drawn, or under rank a sample of them; a point with no value, NaN or an
774
- * infinity draws as a ring, at `size-min` or 3 px, whichever is larger. The column arrives with
775
- * the points, so choosing one sends no request. Unset, the store's choice stands.
720
+ * The rendered number column that sizes the points, or `none` for a single size. Each value is
721
+ * placed between `size-min` and `size-max` on `size-scale`, against the range of the values
722
+ * drawn. A point with no value, NaN or an infinity is drawn as a ring. Unset, the store's choice
723
+ * stands.
776
724
  */
777
725
  get sizeBy() { return this.#sizeBy_accessor_storage; }
778
726
  set sizeBy(value) { this.#sizeBy_accessor_storage = value; }
779
727
  #sizeMin_accessor_storage = (__runInitializers(this, _sizeBy_extraInitializers), __runInitializers(this, _sizeMin_initializers, null));
780
728
  /**
781
- * The radius in pixels of the smallest value under `size-by`. A value that is not a finite number
782
- * above zero is ignored. Unset, the choice made in the explorer stands, 2 until one is made.
729
+ * The radius in pixels of the smallest value under `size-by`. A value that is not above zero is
730
+ * ignored. Unset, the
731
+ * current choice stands, which starts at 2.
783
732
  */
784
733
  get sizeMin() { return this.#sizeMin_accessor_storage; }
785
734
  set sizeMin(value) { this.#sizeMin_accessor_storage = value; }
786
735
  #sizeMax_accessor_storage = (__runInitializers(this, _sizeMin_extraInitializers), __runInitializers(this, _sizeMax_initializers, null));
787
736
  /**
788
- * The radius in pixels of the largest value under `size-by`. A value that is not a finite number
789
- * above zero is ignored. Unset, the choice made in the explorer stands, 9 until one is made.
737
+ * The radius in pixels of the largest value under `size-by`. A value that is not above zero is
738
+ * ignored. Unset, the
739
+ * current choice stands, which starts at 9.
790
740
  */
791
741
  get sizeMax() { return this.#sizeMax_accessor_storage; }
792
742
  set sizeMax(value) { this.#sizeMax_accessor_storage = value; }
793
743
  #sizeScale_accessor_storage = (__runInitializers(this, _sizeMax_extraInitializers), __runInitializers(this, _sizeScale_initializers, ''));
794
744
  /**
795
745
  * How values are placed between the two sizes: `linear`, `log`, or `rank` among a sample of the
796
- * values drawn. Unset, the choice made in the explorer stands, linear until one is made.
746
+ * values drawn. Unset, the current choice stands, which starts as `linear`.
797
747
  */
798
748
  get sizeScale() { return this.#sizeScale_accessor_storage; }
799
749
  set sizeScale(value) { this.#sizeScale_accessor_storage = value; }
@@ -803,8 +753,9 @@ let MosaicaMap = (() => {
803
753
  set noControls(value) { this.#noControls_accessor_storage = value; }
804
754
  #controlsCorner_accessor_storage = (__runInitializers(this, _noControls_extraInitializers), __runInitializers(this, _controlsCorner_initializers, 'top-left'));
805
755
  /**
806
- * Which corner the toolbar sits in: `top-left`, `top-right`, `bottom-left` or `bottom-right`. In
807
- * a top corner the corner's slotted content is below the toolbar; in a bottom corner, above it.
756
+ * The corner the toolbar sits in: `top-left`, `top-right`, `bottom-left` or `bottom-right`.
757
+ * Content in the same corner's slot sits below the toolbar in a top corner, and above it in a
758
+ * bottom corner.
808
759
  */
809
760
  get controlsCorner() { return this.#controlsCorner_accessor_storage; }
810
761
  set controlsCorner(value) { this.#controlsCorner_accessor_storage = value; }
@@ -825,15 +776,15 @@ let MosaicaMap = (() => {
825
776
  get dragPolygon() { return this.#dragPolygon_accessor_storage; }
826
777
  set dragPolygon(value) { this.#dragPolygon_accessor_storage = value; }
827
778
  /**
828
- * What the last click found where it found no item: `{kind: 'miss'}`, or a broken pick, a fault
829
- * in the layer, with its details. `null` after a hit. `<mosaica-item-card>`'s `pick` takes it.
779
+ * What the last click found if it found no item: `{kind: 'miss'}`, or `{kind: 'broken', ...}`
780
+ * with details of a fault in the layer. `null` after a hit. Pass it to `<mosaica-item-card>`'s
781
+ * `pick`.
830
782
  */
831
783
  lastPick = (__runInitializers(this, _dragPolygon_extraInitializers), null);
832
784
  /**
833
- * What the last click picked and where: an item or an artifact, by `mosaicaId`, and the world
834
- * position the card for it points at, the picked point's own or, for an artifact, where the click
835
- * landed. `null` before a pick, after a miss and after a switch of view. `<mosaica-explorer>`
836
- * places its callout from it through {@link MosaicaMap.screenOf}.
785
+ * What the last click picked, an item or an artifact, and where in world coordinates: the point's
786
+ * position, or where the click landed on an artifact. `null` before a pick, after a miss and after
787
+ * a switch of view. Pass `world` to `screenOf()` to place a card beside it.
837
788
  */
838
789
  pickedAt = null;
839
790
  /** The map's probe, one object mutated in place, for instruments and tests. @internal */
@@ -1081,9 +1032,8 @@ let MosaicaMap = (() => {
1081
1032
  this.densityCounter?.set({ on: this.density !== 'none', cellPx: this.densityResolution });
1082
1033
  }
1083
1034
  /**
1084
- * The resolution stops at the camera as it stands: each cell size, the depth it asks for, and
1085
- * whether that depth's cells over the area asked for fit the server's
1086
- * `selection.maxAggregateCells`. Every stop is enabled before `meta` has arrived.
1035
+ * The density cell sizes `density-resolution` offers at the current camera, each with whether the
1036
+ * server's `selection.maxAggregateCells` allows it. Every size is allowed before `meta` has loaded.
1087
1037
  */
1088
1038
  densityStops() {
1089
1039
  return this.densityCounter?.stops() ?? [];
@@ -1336,7 +1286,7 @@ let MosaicaMap = (() => {
1336
1286
  }
1337
1287
  return { layer, layersOn: a.layers, coverage: a.coverage, servedIds: rows.map((x) => idString(x.mosaicaId)), sample, coloured };
1338
1288
  }
1339
- /** Dispose of the store this map built, as on every element, and release its GPU resources now. */
1289
+ /** Dispose of the store this map built and release its GPU resources now. */
1340
1290
  dispose() {
1341
1291
  this.densityCounter?.dispose();
1342
1292
  this.densityCounter = null;
@@ -1617,9 +1567,8 @@ let MosaicaMap = (() => {
1617
1567
  super.focus(options);
1618
1568
  }
1619
1569
  /**
1620
- * Drop the selection: forget the last pick and the ring drawn round the picked point, and clear
1621
- * the store's selection, which closes the card it opened. A click on empty map and Escape call
1622
- * it. A selected region stays.
1570
+ * Drop the picked item or artifact and the ring around it, and clear the store's selection, which
1571
+ * closes its card. A click on an empty part of the map does the same. A selected region stays.
1623
1572
  */
1624
1573
  clearPick() {
1625
1574
  this.lastPick = null;
@@ -1828,13 +1777,13 @@ let MosaicaMap = (() => {
1828
1777
  const s = this.resolvedStore;
1829
1778
  return drawnLevel(s?.get('meta') ?? null, s?.get('artifacts') ?? null, s?.get('legend').colourBy, this.clusterLevel ?? undefined);
1830
1779
  }
1831
- /** The ground the map draws on now: `ground` where it is set, else the page's colour scheme. */
1780
+ /** Whether the map is drawn on a light or dark background now: `ground` if set, else the page's scheme. */
1832
1781
  get drawnGround() {
1833
1782
  return this.scheme();
1834
1783
  }
1835
1784
  /**
1836
- * A world position in the map's pixels, from its top-left corner, under the camera as it stands.
1837
- * A position off the map falls outside `[0, width] × [0, height]`.
1785
+ * Convert a world position to pixels from the map's top-left corner, under the current camera. A
1786
+ * position off the map falls outside `[0, width] × [0, height]`.
1838
1787
  */
1839
1788
  screenOf(world) {
1840
1789
  // The orthographic camera, y down: world units scale by 2^zoom about the target at the centre.
@@ -1843,7 +1792,7 @@ let MosaicaMap = (() => {
1843
1792
  const [tx, ty] = this.viewState.target;
1844
1793
  return [(world[0] - tx) * scale + width / 2, (world[1] - ty) * scale + height / 2];
1845
1794
  }
1846
- /** The camera's zoom: 0 when the 512-unit world fills 512 px, +1 per doubling. */
1795
+ /** The camera's zoom: 0 when the 512-unit world is 512 pixels wide, and 1 more per doubling. */
1847
1796
  get zoom() {
1848
1797
  return this.viewState.zoom;
1849
1798
  }
@@ -1852,11 +1801,10 @@ let MosaicaMap = (() => {
1852
1801
  /** Whether the map frames the matches when it is next connected: it left the page with a framing pending. */
1853
1802
  frameOnConnect = false;
1854
1803
  /**
1855
- * Frame the items the store's filters and selected region match: the box {@link frameMatches}
1856
- * gives, which holds every one of them, fitted to 92% of the map along the side that limits it.
1857
- * Where nothing matches, or the server refuses the count, the whole extent is fitted instead.
1858
- * The camera moves once the count lands, unless it is moved before then. A map off the page
1859
- * frames once it is back on it. Resolves when the camera has moved or the framing was cancelled.
1804
+ * Move the camera to frame every item the filters and selected region match, filling 92% of the
1805
+ * map. If nothing matches, or the server refuses, it frames the whole extent. The camera moves
1806
+ * when the server answers, unless it is moved first. Resolves when the camera has moved or
1807
+ * the move was cancelled.
1860
1808
  */
1861
1809
  async fit() {
1862
1810
  const s = this.resolvedStore;
@@ -1881,10 +1829,7 @@ let MosaicaMap = (() => {
1881
1829
  this.framing = null;
1882
1830
  this.frameOnConnect = false;
1883
1831
  }
1884
- /**
1885
- * Centre the camera on a data coordinate at the current zoom. Returns false before `meta`, when
1886
- * there is no frame to convert against.
1887
- */
1832
+ /** Centre the camera on a point in data coordinates, keeping the zoom. Returns false before `meta` has loaded. */
1888
1833
  lookAt(x, y) {
1889
1834
  const q = this.resolvedStore?.frame();
1890
1835
  if (!q)
@@ -1893,7 +1838,10 @@ let MosaicaMap = (() => {
1893
1838
  this.setViewState({ target: [wx, wy, 0] });
1894
1839
  return true;
1895
1840
  }
1896
- /** Fit a served artifact's box into the map. Returns false where the store holds no box for it. */
1841
+ /**
1842
+ * Fit the camera to an artifact's bounding box. Returns false if the artifact is not among those
1843
+ * currently drawn (`artifacts.served`) or has no box.
1844
+ */
1897
1845
  fitTo(artifactId) {
1898
1846
  const extent = this.resolvedStore?.extentOf(artifactId);
1899
1847
  if (!extent)
@@ -1901,11 +1849,11 @@ let MosaicaMap = (() => {
1901
1849
  return this.fitBbox(extent);
1902
1850
  }
1903
1851
  /**
1904
- * Fit a box `[x0, y0, x1, y1]` in data coordinates, the space `mosaica-viewchange` reports, into
1905
- * the map. The camera keeps the canvas's aspect, so the box shown contains the one asked for,
1906
- * and the next `mosaica-viewchange` reports the box shown. `fill` is the share of the map the
1907
- * box takes along the side that limits it, 2^-0.3 (about 81%) unless given; at 1 a box
1908
- * `mosaica-viewchange` reported is fitted back to the same camera. Returns false before `meta`.
1852
+ * Fit the camera to a box `[x0, y0, x1, y1]` in data coordinates, as `mosaica-viewchange`
1853
+ * reports them. The canvas keeps its aspect ratio, so the area shown contains the box. `fill` is
1854
+ * the share of the map the box fills along its tighter side, about 81% by default; pass `1` to
1855
+ * restore a camera from a box `mosaica-viewchange` reported. Returns false before `meta` has
1856
+ * loaded.
1909
1857
  */
1910
1858
  fitBbox(extent, fill = 2 ** -0.3) {
1911
1859
  const q = this.resolvedStore?.frame();