canvas-globe 1.1.1 → 1.3.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.
- package/CHANGELOG.md +44 -0
- package/README.md +113 -5
- package/THIRD_PARTY_NOTICES.md +1 -0
- package/codemeta.json +1 -1
- package/custom-elements.json +2 -2
- package/dist/canvas-globe.umd.js +331 -8
- package/package.json +34 -2
- package/src/charts.js +458 -0
- package/src/controls.js +187 -0
- package/src/data/places.js +5 -0
- package/src/fx/effects/ambient.js +355 -0
- package/src/fx/effects/data.js +438 -0
- package/src/fx/effects/entrances.js +111 -0
- package/src/fx/effects/interaction.js +850 -0
- package/src/fx/effects/scene.js +571 -0
- package/src/fx/effects/transitions.js +209 -0
- package/src/fx/index.js +52 -0
- package/src/fx/pointer.js +94 -0
- package/src/fx/runtime.js +161 -0
- package/src/geo-globe.js +261 -8
- package/src/geo.js +70 -0
- package/src/places.js +97 -0
- package/src/recipes.js +188 -0
- package/src/version.js +1 -1
- package/types/charts.d.ts +82 -0
- package/types/controls.d.ts +54 -0
- package/types/element.d.ts +3 -3
- package/types/fx-interaction.d.ts +16 -0
- package/types/fx.d.ts +313 -0
- package/types/index.d.ts +94 -7
- package/types/jsr-element.d.ts +3 -3
- package/types/places.d.ts +43 -0
- package/types/recipes.d.ts +54 -0
package/types/index.d.ts
CHANGED
|
@@ -32,6 +32,20 @@ export interface ClusterMarker {
|
|
|
32
32
|
lon: number;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/** Synthetic marker produced by the `hexBins` density layer. */
|
|
36
|
+
export interface HexBinMarker {
|
|
37
|
+
hexBin: true;
|
|
38
|
+
/** Number of source markers in the cell. */
|
|
39
|
+
markerCount: number;
|
|
40
|
+
/** Number of source markers in the cell. */
|
|
41
|
+
count: number;
|
|
42
|
+
/** Sum of source marker `count` values, with missing values treated as 1. */
|
|
43
|
+
value: number;
|
|
44
|
+
markers: Marker[];
|
|
45
|
+
lat: number;
|
|
46
|
+
lon: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
export type Coordinate = { lat: number; lon: number } | [lon: number, lat: number];
|
|
36
50
|
|
|
37
51
|
export interface Arc {
|
|
@@ -178,7 +192,7 @@ export interface Handle {
|
|
|
178
192
|
stop(): void;
|
|
179
193
|
}
|
|
180
194
|
|
|
181
|
-
export interface StoryStep extends Partial<GeoGlobeOptions> {
|
|
195
|
+
export interface StoryStep extends Omit<Partial<GeoGlobeOptions>, "center" | "zoom"> {
|
|
182
196
|
/** Scroll progress, 0-1. */
|
|
183
197
|
at: number;
|
|
184
198
|
center?: [lon: number, lat: number];
|
|
@@ -193,6 +207,31 @@ export interface HeatmapOptions {
|
|
|
193
207
|
color?: string;
|
|
194
208
|
}
|
|
195
209
|
|
|
210
|
+
export interface HexBinOptions {
|
|
211
|
+
/** Hexagon radius in screen pixels. Default 18. */
|
|
212
|
+
radius?: number;
|
|
213
|
+
/** Ignore cells below this count or summed value. Default 1. */
|
|
214
|
+
minValue?: number;
|
|
215
|
+
/** Colour cells by summed marker values or marker count. Default "sum". */
|
|
216
|
+
value?: "sum" | "count";
|
|
217
|
+
/** Single base colour used when `colorRange` is omitted. */
|
|
218
|
+
color?: string;
|
|
219
|
+
/** Low-to-high colour ramp. */
|
|
220
|
+
colorRange?: string[];
|
|
221
|
+
/** Fill opacity, 0-1. Default 0.82. */
|
|
222
|
+
opacity?: number;
|
|
223
|
+
stroke?: string;
|
|
224
|
+
/** Cell outline width in px. Default 0.8. */
|
|
225
|
+
strokeWidth?: number;
|
|
226
|
+
/** Gap inside each cell in px. Default 1.5. */
|
|
227
|
+
padding?: number;
|
|
228
|
+
/** Draw the selected count/value inside each cell. Default false. */
|
|
229
|
+
showCount?: boolean;
|
|
230
|
+
labelColor?: string;
|
|
231
|
+
/** Hide individual markers beneath the bins. Default true. */
|
|
232
|
+
hideMarkers?: boolean;
|
|
233
|
+
}
|
|
234
|
+
|
|
196
235
|
export interface SpikeOptions {
|
|
197
236
|
/** Tallest spike as a fraction of the globe radius. Default 0.28. */
|
|
198
237
|
height?: number;
|
|
@@ -378,7 +417,7 @@ export interface RenderMarkerContext {
|
|
|
378
417
|
globe: GeoGlobe;
|
|
379
418
|
}
|
|
380
419
|
|
|
381
|
-
export type TooltipKind = "marker" | "cluster" | "country";
|
|
420
|
+
export type TooltipKind = "marker" | "cluster" | "hex-bin" | "country";
|
|
382
421
|
|
|
383
422
|
export interface GeoGlobeOptions {
|
|
384
423
|
/** Commercial license key supplied after purchase. */
|
|
@@ -387,8 +426,6 @@ export interface GeoGlobeOptions {
|
|
|
387
426
|
mode?: "globe" | "map";
|
|
388
427
|
/** Flat-map projection. Default "equirectangular". */
|
|
389
428
|
projection?: MapProjection;
|
|
390
|
-
/** Built-in theme name or a partial theme object. Default "atlas". */
|
|
391
|
-
theme?: ThemeName | Partial<Theme>;
|
|
392
429
|
/** Named bundle of theme + render style, applied under your own options. */
|
|
393
430
|
preset?: PresetName;
|
|
394
431
|
/** Theme name, a partial theme, "auto" for the OS colour scheme, or "css"
|
|
@@ -428,6 +465,8 @@ export interface GeoGlobeOptions {
|
|
|
428
465
|
transparentBackground?: boolean;
|
|
429
466
|
/** Additive density blobs instead of, or under, markers. */
|
|
430
467
|
heatmap?: boolean | HeatmapOptions;
|
|
468
|
+
/** Screen-space hexagonal aggregation for dense marker datasets. */
|
|
469
|
+
hexBins?: boolean | HexBinOptions;
|
|
431
470
|
/** Bars standing off the surface, scaled by each marker's `count`. */
|
|
432
471
|
spikes?: boolean | SpikeOptions;
|
|
433
472
|
/** Text labels with collision avoidance. */
|
|
@@ -496,16 +535,42 @@ export interface GeoGlobeOptions {
|
|
|
496
535
|
/** Frame cap. Default 30. */
|
|
497
536
|
fps?: number;
|
|
498
537
|
/** Built-in tooltip. `true` uses the default text, or pass a formatter. */
|
|
499
|
-
tooltip?: boolean | ((target: Marker | ClusterMarker | CountryShape, kind: TooltipKind) => string);
|
|
538
|
+
tooltip?: boolean | ((target: Marker | ClusterMarker | HexBinMarker | CountryShape, kind: TooltipKind) => string);
|
|
500
539
|
/** Honour `prefers-reduced-motion`. Default true. */
|
|
501
540
|
respectReducedMotion?: boolean;
|
|
502
541
|
/** Accessible name for the canvas. */
|
|
503
542
|
ariaLabel?: string;
|
|
504
|
-
onHover?: (marker: Marker | ClusterMarker | null, position: { x: number; y: number } | null) => void;
|
|
505
|
-
onClick?: (marker: Marker | ClusterMarker, position: { x: number; y: number }) => void;
|
|
543
|
+
onHover?: (marker: Marker | ClusterMarker | HexBinMarker | null, position: { x: number; y: number } | null) => void;
|
|
544
|
+
onClick?: (marker: Marker | ClusterMarker | HexBinMarker, position: { x: number; y: number }) => void;
|
|
506
545
|
onCountryHover?: (country: CountryShape | null, position: { x: number; y: number } | null) => void;
|
|
507
546
|
onCountryClick?: (country: CountryShape, position: { x: number; y: number }) => void;
|
|
508
547
|
onRender?: (instance: GeoGlobe) => void;
|
|
548
|
+
/** Effects installed when the globe is created. */
|
|
549
|
+
effects?: GlobeEffect[];
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/** Where an effect paints relative to the globe itself. */
|
|
553
|
+
export type EffectStage = "beneath" | "above" | "post";
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* An effect derives its whole appearance from `t` (0→1), which is why
|
|
557
|
+
* `renderFrame()` can reproduce any frame exactly.
|
|
558
|
+
*/
|
|
559
|
+
export interface GlobeEffect<S = any> {
|
|
560
|
+
name?: string;
|
|
561
|
+
/** Default "above". */
|
|
562
|
+
stage?: EffectStage;
|
|
563
|
+
/** Paint order within a stage. Lower paints first. Default 0. */
|
|
564
|
+
z?: number;
|
|
565
|
+
/** Milliseconds for one cycle. Default 1000. */
|
|
566
|
+
duration?: number;
|
|
567
|
+
/** Milliseconds held at the end before looping. Default 0. */
|
|
568
|
+
hold?: number;
|
|
569
|
+
/** Default true. */
|
|
570
|
+
loop?: boolean;
|
|
571
|
+
setup?(globe: GeoGlobe): S;
|
|
572
|
+
frame(ctx: CanvasRenderingContext2D, globe: GeoGlobe, t: number, state: S): void;
|
|
573
|
+
dispose?(state: S, globe: GeoGlobe): void;
|
|
509
574
|
}
|
|
510
575
|
|
|
511
576
|
export interface FlyToOptions {
|
|
@@ -593,6 +658,28 @@ export declare class GeoGlobe {
|
|
|
593
658
|
countryAt(x: number, y: number): CountryShape | null;
|
|
594
659
|
/** Marks the next frame as needing a redraw. */
|
|
595
660
|
invalidate(): this;
|
|
661
|
+
|
|
662
|
+
/** Pointer position in canvas pixels and the coordinate beneath it. */
|
|
663
|
+
readonly pointer: { x: number; y: number; lon: number; lat: number; over: boolean };
|
|
664
|
+
/** Effects currently installed, in paint order. */
|
|
665
|
+
readonly effects: GlobeEffect[];
|
|
666
|
+
use(effect: GlobeEffect): this;
|
|
667
|
+
remove(effect: GlobeEffect | string): this;
|
|
668
|
+
clearEffects(): this;
|
|
669
|
+
/** Pins the effect clock so a frame can be reproduced. */
|
|
670
|
+
seek(ms: number): this;
|
|
671
|
+
/** Releases the clock back to wall time. */
|
|
672
|
+
play(): this;
|
|
673
|
+
/** Draws the frame belonging at `ms` on the effect clock. */
|
|
674
|
+
renderFrame(ms: number): this;
|
|
675
|
+
/** Traces a country outline into a path using the current projection. */
|
|
676
|
+
tracePath(
|
|
677
|
+
shape: CountryShape | { coordinates: unknown },
|
|
678
|
+
ctx?: CanvasRenderingContext2D,
|
|
679
|
+
transform?: (coord: [number, number]) => [number, number],
|
|
680
|
+
): this;
|
|
681
|
+
/** Land sample points as `[lon, lat]` pairs. */
|
|
682
|
+
landPoints(spacing?: number): [number, number][];
|
|
596
683
|
resize(): this;
|
|
597
684
|
render(): this;
|
|
598
685
|
snapshot(type?: string, quality?: number): string;
|
package/types/jsr-element.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Arc, CountryShape, GeoGlobe, GeoGlobeOptions, Marker, ClusterMarker, FlyToOptions } from "./index.js";
|
|
1
|
+
import type { Arc, CountryShape, GeoGlobe, GeoGlobeOptions, Marker, ClusterMarker, HexBinMarker, FlyToOptions } from "./index.js";
|
|
2
2
|
|
|
3
3
|
export interface GeoGlobeEventMap {
|
|
4
|
-
"geo-hover": CustomEvent<{ marker: Marker | ClusterMarker | null; pos: { x: number; y: number } | null }>;
|
|
5
|
-
"geo-click": CustomEvent<{ marker: Marker | ClusterMarker; pos: { x: number; y: number } }>;
|
|
4
|
+
"geo-hover": CustomEvent<{ marker: Marker | ClusterMarker | HexBinMarker | null; pos: { x: number; y: number } | null }>;
|
|
5
|
+
"geo-click": CustomEvent<{ marker: Marker | ClusterMarker | HexBinMarker; pos: { x: number; y: number } }>;
|
|
6
6
|
"geo-country-hover": CustomEvent<{ country: CountryShape | null; pos: { x: number; y: number } | null }>;
|
|
7
7
|
"geo-country-click": CustomEvent<{ country: CountryShape; pos: { x: number; y: number } }>;
|
|
8
8
|
"geo-render": CustomEvent<{ globe: GeoGlobe }>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** A place from the bundled Natural Earth table. */
|
|
2
|
+
export interface Place {
|
|
3
|
+
name: string;
|
|
4
|
+
/** Accent-folded, lowercase name used for matching. */
|
|
5
|
+
key: string;
|
|
6
|
+
lon: number;
|
|
7
|
+
lat: number;
|
|
8
|
+
/** ISO 3166-1 alpha-2 country code. */
|
|
9
|
+
country: string;
|
|
10
|
+
/** Admin-1 name, present only where it disambiguates a repeated name. */
|
|
11
|
+
region: string;
|
|
12
|
+
population: number;
|
|
13
|
+
/** `"Springfield, Illinois, US"` - ready to show in a results list. */
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Lowercases and strips accents, so "São Paulo" answers to "sao paulo". */
|
|
18
|
+
export declare function fold(value: string): string;
|
|
19
|
+
|
|
20
|
+
/** Places matching `query`, prefix matches first, then by population. */
|
|
21
|
+
export declare function searchPlaces(
|
|
22
|
+
query: string,
|
|
23
|
+
options?: {
|
|
24
|
+
limit?: number;
|
|
25
|
+
country?: string;
|
|
26
|
+
/** Also match names that contain the query, not just start with it. */
|
|
27
|
+
contains?: boolean;
|
|
28
|
+
}
|
|
29
|
+
): Place[];
|
|
30
|
+
|
|
31
|
+
/** Coordinate for an exact-ish name, matching the shape of `geocode()`. */
|
|
32
|
+
export declare function placePoint(
|
|
33
|
+
name: string,
|
|
34
|
+
options?: { country?: string }
|
|
35
|
+
): { lon: number; lat: number } | null;
|
|
36
|
+
|
|
37
|
+
/** Ready-made resolver for `searchAndFly({ source })`. */
|
|
38
|
+
export declare function placeSource(
|
|
39
|
+
options?: { limit?: number; country?: string; contains?: boolean }
|
|
40
|
+
): (query: string) => Place[];
|
|
41
|
+
|
|
42
|
+
/** How many places the bundled table holds. */
|
|
43
|
+
export declare function placeCount(): number;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { GeoGlobe, GlobeOptions, Coordinate } from "./index";
|
|
2
|
+
import type { GlobeEffect } from "./fx";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A complete look: options, effects, and optionally a call into the
|
|
6
|
+
* imperative API. Plain data, so it can be read and pulled apart.
|
|
7
|
+
*/
|
|
8
|
+
export interface GlobeRecipe {
|
|
9
|
+
name: string;
|
|
10
|
+
options?: Partial<GlobeOptions>;
|
|
11
|
+
effects?: GlobeEffect[];
|
|
12
|
+
/** Runs after the options and effects are applied. Returns a teardown. */
|
|
13
|
+
start?: (globe: GeoGlobe) => (() => void) | void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Applies a recipe and returns a function that undoes it. */
|
|
17
|
+
export declare function applyRecipe(globe: GeoGlobe, recipe: GlobeRecipe): () => void;
|
|
18
|
+
|
|
19
|
+
export declare function devPlatformGlobe(options?: {
|
|
20
|
+
hub?: Coordinate;
|
|
21
|
+
spokes?: number;
|
|
22
|
+
}): GlobeRecipe;
|
|
23
|
+
|
|
24
|
+
export declare function keynoteGlobe(options?: {
|
|
25
|
+
hub?: Coordinate;
|
|
26
|
+
countries?: number;
|
|
27
|
+
caption?: string;
|
|
28
|
+
}): GlobeRecipe;
|
|
29
|
+
|
|
30
|
+
export declare function satelliteOrbits(options?: {
|
|
31
|
+
count?: number;
|
|
32
|
+
preset?: string;
|
|
33
|
+
rotateSpeed?: number;
|
|
34
|
+
}): GlobeRecipe;
|
|
35
|
+
|
|
36
|
+
export declare function growthOverTime(options?: {
|
|
37
|
+
duration?: number;
|
|
38
|
+
loop?: boolean;
|
|
39
|
+
preset?: string;
|
|
40
|
+
}): GlobeRecipe;
|
|
41
|
+
|
|
42
|
+
export declare function celebrationBurst(options?: {
|
|
43
|
+
at?: Coordinate;
|
|
44
|
+
label?: string;
|
|
45
|
+
emoji?: string;
|
|
46
|
+
every?: number;
|
|
47
|
+
burst?: number;
|
|
48
|
+
}): GlobeRecipe;
|
|
49
|
+
|
|
50
|
+
export declare function cityTour(options?: {
|
|
51
|
+
stops?: Coordinate[];
|
|
52
|
+
dwell?: number;
|
|
53
|
+
zoom?: number;
|
|
54
|
+
}): GlobeRecipe;
|