@d3-maps/core 0.2.0 → 0.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/dist/index.css +1 -0
- package/dist/index.d.ts +184 -100
- package/dist/index.iife.js +1 -1
- package/dist/index.js +47 -51
- package/package.json +2 -1
package/dist/index.css
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,55 @@
|
|
|
1
|
-
import { GeoPath, GeoProjection } from "d3-geo";
|
|
1
|
+
import { ExtendedFeature, ExtendedFeatureCollection, GeoGeometryObjects, GeoPath, GeoPermissibleObjects, GeoProjection } from "d3-geo";
|
|
2
|
+
import { mesh } from "topojson-client";
|
|
2
3
|
import { D3ZoomEvent, D3ZoomEvent as D3ZoomEvent$1, ZoomBehavior, ZoomBehavior as ZoomBehavior$1, ZoomTransform, ZoomTransform as ZoomTransform$1 } from "d3-zoom";
|
|
3
4
|
|
|
5
|
+
//#region src/lib/mapObject.d.ts
|
|
6
|
+
type MapObject = GeoGeometryObjects | ExtendedFeature;
|
|
7
|
+
type MapObjectFocusEventType = 'focus' | 'blur';
|
|
8
|
+
type MapObjectMouseEventType = 'mouseenter' | 'mouseleave' | 'mousedown' | 'mouseup';
|
|
9
|
+
type MapObjectEventType = MapObjectFocusEventType | MapObjectMouseEventType;
|
|
10
|
+
type MapObjectEvent<E> = E extends MapObjectFocusEventType ? FocusEvent : MouseEvent;
|
|
11
|
+
/**
|
|
12
|
+
* Supported interaction states for map objects.
|
|
13
|
+
*/
|
|
14
|
+
declare const mapObjectState: readonly ["default", "hover", "active"];
|
|
15
|
+
type MapObjectState = typeof mapObjectState[number];
|
|
16
|
+
type MapObjectStyles<TStyle> = Partial<Record<MapObjectState, TStyle>>;
|
|
17
|
+
/**
|
|
18
|
+
* Maps DOM event names to interaction state updates.
|
|
19
|
+
*/
|
|
20
|
+
declare function getObjectStateUpdate(event: MapObjectEventType): MapObjectState;
|
|
21
|
+
/**
|
|
22
|
+
* Resolves a style value for the current state (falls back to `default`).
|
|
23
|
+
*/
|
|
24
|
+
declare function resolveObjectStyle<TStyle>(state: MapObjectState, styles?: MapObjectStyles<TStyle>): TStyle | undefined;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/lib/feature.d.ts
|
|
27
|
+
/**
|
|
28
|
+
* A GeoJSON Feature used by d3-maps.
|
|
29
|
+
*
|
|
30
|
+
* This type allows extra top-level fields to be attached in `dataTransformer` (e.g. choropleth colors).
|
|
31
|
+
*/
|
|
32
|
+
type MapFeature = (ExtendedFeature & Record<string, unknown>) | ExtendedFeature;
|
|
33
|
+
/**
|
|
34
|
+
* Shared props contract for a single rendered feature.
|
|
35
|
+
*/
|
|
36
|
+
interface MapFeatureProps<TStyle = unknown> {
|
|
37
|
+
data: MapFeature;
|
|
38
|
+
styles?: MapObjectStyles<TStyle>;
|
|
39
|
+
fill?: string;
|
|
40
|
+
stroke?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolves a stable key for a feature.
|
|
44
|
+
*
|
|
45
|
+
* Checks:
|
|
46
|
+
* 1) `feature[idKey]`
|
|
47
|
+
* 2) `feature.properties[idKey]`
|
|
48
|
+
* 3) fallback to the list index
|
|
49
|
+
*/
|
|
50
|
+
declare function getFeatureKey(feature: MapFeature, idKey: string | undefined, index: number): string | number;
|
|
51
|
+
//#endregion
|
|
4
52
|
//#region ../../node_modules/.pnpm/@types+geojson@7946.0.16/node_modules/@types/geojson/index.d.ts
|
|
5
|
-
|
|
6
53
|
/**
|
|
7
54
|
* The valid values for the "type" property of GeoJSON geometry objects.
|
|
8
55
|
* https://tools.ietf.org/html/rfc7946#section-1.4
|
|
@@ -183,53 +230,6 @@ interface FeatureCollection<G extends Geometry | null = Geometry, P$1 = GeoJsonP
|
|
|
183
230
|
features: Array<Feature<G, P$1>>;
|
|
184
231
|
}
|
|
185
232
|
//#endregion
|
|
186
|
-
//#region src/lib/mapObject.d.ts
|
|
187
|
-
type MapObject = Point$1 | Feature;
|
|
188
|
-
type MapObjectFocusEventType = 'focus' | 'blur';
|
|
189
|
-
type MapObjectMouseEventType = 'mouseenter' | 'mouseleave' | 'mousedown' | 'mouseup';
|
|
190
|
-
type MapObjectEventType = MapObjectFocusEventType | MapObjectMouseEventType;
|
|
191
|
-
type MapObjectEvent<E> = E extends MapObjectFocusEventType ? FocusEvent : MouseEvent;
|
|
192
|
-
/**
|
|
193
|
-
* Supported interaction states for map objects.
|
|
194
|
-
*/
|
|
195
|
-
declare const mapObjectState: readonly ["default", "hover", "active"];
|
|
196
|
-
type MapObjectState = typeof mapObjectState[number];
|
|
197
|
-
type MapObjectStyles<TStyle> = Partial<Record<MapObjectState, TStyle>>;
|
|
198
|
-
/**
|
|
199
|
-
* Maps DOM event names to interaction state updates.
|
|
200
|
-
*/
|
|
201
|
-
declare function getObjectStateUpdate(event: MapObjectEventType): MapObjectState;
|
|
202
|
-
/**
|
|
203
|
-
* Resolves a style value for the current state (falls back to `default`).
|
|
204
|
-
*/
|
|
205
|
-
declare function resolveObjectStyle<TStyle>(state: MapObjectState, styles?: MapObjectStyles<TStyle>): TStyle | undefined;
|
|
206
|
-
//#endregion
|
|
207
|
-
//#region src/lib/feature.d.ts
|
|
208
|
-
/**
|
|
209
|
-
* A GeoJSON Feature used by d3-maps.
|
|
210
|
-
*
|
|
211
|
-
* This type allows extra top-level fields to be attached in `dataTransformer` (e.g. choropleth colors).
|
|
212
|
-
*/
|
|
213
|
-
type MapFeature = (Feature & Record<string, unknown>) | Feature;
|
|
214
|
-
/**
|
|
215
|
-
* Shared props contract for a single rendered feature.
|
|
216
|
-
*/
|
|
217
|
-
interface MapFeatureProps<TStyle = unknown> {
|
|
218
|
-
data: MapFeature;
|
|
219
|
-
styles?: MapObjectStyles<TStyle>;
|
|
220
|
-
fill?: string;
|
|
221
|
-
stroke?: string;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Resolves a stable key for a feature.
|
|
225
|
-
*
|
|
226
|
-
* Checks:
|
|
227
|
-
* 1) `feature[idKey]`
|
|
228
|
-
* 2) `feature.properties[idKey]`
|
|
229
|
-
* 3) fallback to the list index
|
|
230
|
-
*/
|
|
231
|
-
declare function getFeatureKey(feature: MapFeature, idKey: string | undefined, index: number): string | number;
|
|
232
|
-
//#endregion
|
|
233
233
|
//#region ../../node_modules/.pnpm/@types+topojson-specification@1.0.5/node_modules/@types/topojson-specification/index.d.ts
|
|
234
234
|
// ---------------------------------------------------------------
|
|
235
235
|
// TopoJSON Format Specification
|
|
@@ -316,19 +316,120 @@ interface NullObject extends GeometryObjectA {
|
|
|
316
316
|
type: null;
|
|
317
317
|
}
|
|
318
318
|
//#endregion
|
|
319
|
+
//#region src/lib/utils.d.ts
|
|
320
|
+
declare function isString(value: unknown): value is string;
|
|
321
|
+
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
322
|
+
declare const isNullish: (value: unknown) => value is null | undefined;
|
|
323
|
+
declare const isNumber: (value: unknown) => value is number;
|
|
324
|
+
declare function isStringOrNumber(value: unknown): value is string | number;
|
|
325
|
+
declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
|
|
326
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
327
|
+
declare function makeTransform(x: number, y: number, k?: number): string;
|
|
328
|
+
type AnyFn = (...args: any) => any;
|
|
329
|
+
/**
|
|
330
|
+
* Extracts a union of parameter tuples from a (possibly overloaded) function type.
|
|
331
|
+
*
|
|
332
|
+
* TypeScript's built-in `Parameters<F>` only captures the *last* overload, which breaks typing
|
|
333
|
+
* for overloaded getter/setter APIs (common in d3), where the setter overload might not be last.
|
|
334
|
+
*
|
|
335
|
+
* Notes:
|
|
336
|
+
* - This helper supports up to 5 overload signatures (adjust if needed).
|
|
337
|
+
* - Getter overloads like `(): T` are filtered out later via `Exclude<..., []>` when we build
|
|
338
|
+
* setter-only config types.
|
|
339
|
+
*/
|
|
340
|
+
type OverloadedArgs<F> = F extends {
|
|
341
|
+
(...a: infer A1): any;
|
|
342
|
+
(...a: infer A2): any;
|
|
343
|
+
(...a: infer A3): any;
|
|
344
|
+
(...a: infer A4): any;
|
|
345
|
+
(...a: infer A5): any;
|
|
346
|
+
} ? A1 | A2 | A3 | A4 | A5 : F extends {
|
|
347
|
+
(...a: infer A1): any;
|
|
348
|
+
(...a: infer A2): any;
|
|
349
|
+
(...a: infer A3): any;
|
|
350
|
+
(...a: infer A4): any;
|
|
351
|
+
} ? A1 | A2 | A3 | A4 : F extends {
|
|
352
|
+
(...a: infer A1): any;
|
|
353
|
+
(...a: infer A2): any;
|
|
354
|
+
(...a: infer A3): any;
|
|
355
|
+
} ? A1 | A2 | A3 : F extends {
|
|
356
|
+
(...a: infer A1): any;
|
|
357
|
+
(...a: infer A2): any;
|
|
358
|
+
} ? A1 | A2 : F extends ((...a: infer A1) => any) ? A1 : never;
|
|
359
|
+
/**
|
|
360
|
+
* Removes 0-arg overloads (getters), leaving only setter-style overload argument tuples.
|
|
361
|
+
*/
|
|
362
|
+
type SetterArgs<F> = Exclude<OverloadedArgs<F>, []>;
|
|
363
|
+
/**
|
|
364
|
+
* True if the function has at least one overload that accepts arguments (i.e. a setter overload).
|
|
365
|
+
*/
|
|
366
|
+
type HasArgs<F> = [SetterArgs<F>] extends [never] ? false : true;
|
|
367
|
+
type OwnKeys<T> = T extends AnyFn ? Exclude<keyof T, keyof CallableFunction> : keyof T;
|
|
368
|
+
/**
|
|
369
|
+
* Converts method parameters to modifiers values
|
|
370
|
+
* - single non-array arg: `arg` | `[arg]`
|
|
371
|
+
* - multiple args/single array wrapped with array
|
|
372
|
+
*/
|
|
373
|
+
type ModifierArgs<P$1 extends unknown[]> = P$1 extends [infer Only] ? Only extends readonly unknown[] ? [Only] : Only | [Only] : P$1;
|
|
374
|
+
/**
|
|
375
|
+
* Maps methods with args to modifiers
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* type X = {
|
|
379
|
+
* a: string; // not a function - will be ignored
|
|
380
|
+
* b(): void; // has no arguments - will be ignored
|
|
381
|
+
* c(x: number): void;
|
|
382
|
+
* d(x: number, y: string): void;
|
|
383
|
+
* e(xs: string[]): void;
|
|
384
|
+
* }
|
|
385
|
+
*
|
|
386
|
+
* type R = MethodsToModifiers<X>
|
|
387
|
+
* {
|
|
388
|
+
* c: number | [number];
|
|
389
|
+
* d: [number, string];
|
|
390
|
+
* e: [string[]]; // forced wrapper (arg is array)
|
|
391
|
+
* }
|
|
392
|
+
*/
|
|
393
|
+
type MethodsToModifiers<T extends object> = { [K in OwnKeys<T> as Extract<T[K], AnyFn> extends never ? never : HasArgs<Extract<T[K], AnyFn>> extends true ? K : never]?: ModifierArgs<Extract<SetterArgs<Extract<T[K], AnyFn>>, unknown[]>> };
|
|
394
|
+
/**
|
|
395
|
+
* Invokes `target` methods with arguments from `modifiers`.
|
|
396
|
+
*
|
|
397
|
+
* modifiers: `{ [methodName]: args[] | arg }`
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* class X {
|
|
401
|
+
* a(x: number) {}
|
|
402
|
+
* b(x: number, y: string) {}
|
|
403
|
+
* c(x: string[]) {}
|
|
404
|
+
* d() {}
|
|
405
|
+
* e = 'foo'
|
|
406
|
+
* }
|
|
407
|
+
*
|
|
408
|
+
* applyModifiers(new X(), {
|
|
409
|
+
* a: 1, // ok (single arg as-is)
|
|
410
|
+
* a: [1], // ok (single arg wrapped)
|
|
411
|
+
* b: [1, 'foo'], // ok (tuple for 2 args)
|
|
412
|
+
* c: [['foo', 'bar']], // ok (array-arg must be wrapped)
|
|
413
|
+
* c: ['foo', 'bar'], // error (single array-arg must be wrapped into array)
|
|
414
|
+
* d: [], // error (d has no args, excluded)
|
|
415
|
+
* e: 'foo' // error (e is not a function, excluded)
|
|
416
|
+
* })
|
|
417
|
+
*/
|
|
418
|
+
declare function applyModifiers<T extends object>(target: T, modifiers?: MethodsToModifiers<T>): void;
|
|
419
|
+
//#endregion
|
|
319
420
|
//#region src/lib/map.d.ts
|
|
320
|
-
type
|
|
421
|
+
type MapMesh = ReturnType<typeof mesh>;
|
|
422
|
+
type MapData = ExtendedFeatureCollection | Topology;
|
|
321
423
|
type DataTransformer = (features: MapFeature[]) => MapFeature[];
|
|
322
424
|
/**
|
|
323
|
-
*
|
|
425
|
+
* Extra projection method calls to apply before rendering.
|
|
324
426
|
*
|
|
325
|
-
*
|
|
427
|
+
* Use projection method names as keys and method arguments as values.
|
|
428
|
+
* Example: `{ center: [[0, 20]], rotate: [[0, 0, 0]], scale: 160 }`
|
|
429
|
+
*
|
|
430
|
+
* @see https://d3js.org/d3-geo/projection
|
|
326
431
|
*/
|
|
327
|
-
interface ProjectionConfig {
|
|
328
|
-
center?: [number, number];
|
|
329
|
-
rotate?: [number, number, number];
|
|
330
|
-
scale?: number;
|
|
331
|
-
}
|
|
432
|
+
interface ProjectionConfig extends Omit<MethodsToModifiers<GeoProjection>, 'invert' | 'stream'> {}
|
|
332
433
|
/**
|
|
333
434
|
* Input configuration for creating a map context.
|
|
334
435
|
*
|
|
@@ -344,6 +445,9 @@ interface MapConfig {
|
|
|
344
445
|
* Example: `geoEqualEarth`.
|
|
345
446
|
*/
|
|
346
447
|
projection?: () => GeoProjection;
|
|
448
|
+
/**
|
|
449
|
+
* Projection method arguments passed to the created projection
|
|
450
|
+
*/
|
|
347
451
|
projectionConfig?: ProjectionConfig;
|
|
348
452
|
/**
|
|
349
453
|
* TopoJSON or GeoJSON input.
|
|
@@ -366,9 +470,9 @@ interface MapContext {
|
|
|
366
470
|
height: number;
|
|
367
471
|
projection?: GeoProjection;
|
|
368
472
|
features: MapFeature[];
|
|
369
|
-
mesh?:
|
|
473
|
+
mesh?: MapMesh;
|
|
370
474
|
path: GeoPath;
|
|
371
|
-
renderPath: (feature:
|
|
475
|
+
renderPath: (feature: MapFeature) => ReturnType<GeoPath>;
|
|
372
476
|
renderMesh: () => ReturnType<GeoPath>;
|
|
373
477
|
}
|
|
374
478
|
/**
|
|
@@ -385,7 +489,7 @@ declare function makeProjection({
|
|
|
385
489
|
height: number;
|
|
386
490
|
config?: ProjectionConfig;
|
|
387
491
|
projection: () => GeoProjection;
|
|
388
|
-
geoJson?:
|
|
492
|
+
geoJson?: GeoPermissibleObjects;
|
|
389
493
|
}): GeoProjection;
|
|
390
494
|
/**
|
|
391
495
|
* Normalizes input map data to GeoJSON features.
|
|
@@ -393,12 +497,12 @@ declare function makeProjection({
|
|
|
393
497
|
* - TopoJSON is converted via `topojson-client`.
|
|
394
498
|
* - If provided, `dataTransformer` is applied to the feature array.
|
|
395
499
|
*/
|
|
396
|
-
declare function makeFeatures(geoData: MapData, dataTransformer?: DataTransformer): [features: MapFeature[], geoJson:
|
|
500
|
+
declare function makeFeatures(geoData: MapData, dataTransformer?: DataTransformer): [features: MapFeature[], geoJson: ExtendedFeatureCollection];
|
|
397
501
|
declare const makePathFn: (mapProjection: GeoProjection) => GeoPath;
|
|
398
502
|
/**
|
|
399
503
|
* Returns a TopoJSON mesh when topology data is provided.
|
|
400
504
|
*/
|
|
401
|
-
declare function makeMesh(geoData: MapData):
|
|
505
|
+
declare function makeMesh(geoData: MapData): MapMesh | undefined;
|
|
402
506
|
/**
|
|
403
507
|
* Creates a full {@link MapContext} from a {@link MapConfig}.
|
|
404
508
|
*/
|
|
@@ -433,40 +537,24 @@ interface MapMarkerProps<TStyle = unknown> {
|
|
|
433
537
|
*/
|
|
434
538
|
declare function getMarkerTransform(context: MapContext | undefined, coordinates: MapMarkerCoordinates, fallback?: string): string;
|
|
435
539
|
//#endregion
|
|
436
|
-
//#region src/lib/utils.d.ts
|
|
437
|
-
declare function isString(value: unknown): value is string;
|
|
438
|
-
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
439
|
-
declare const isNullish: (value: unknown) => value is null | undefined;
|
|
440
|
-
declare const isNumber: (value: unknown) => value is number;
|
|
441
|
-
declare function isStringOrNumber(value: unknown): value is string | number;
|
|
442
|
-
declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
|
|
443
|
-
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
444
|
-
declare function get<T>(url: string): Promise<T>;
|
|
445
|
-
declare function makeTransform(x: number, y: number, k?: number): string;
|
|
446
|
-
//#endregion
|
|
447
540
|
//#region src/lib/zoom.d.ts
|
|
448
541
|
type Extent = [[number, number], [number, number]];
|
|
449
|
-
interface
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
type ZoomBehaviorSingleArg<TElement extends Element, TDatum, TMethod extends ZoomBehaviorMethodName<TElement, TDatum>> = ZoomBehaviorMethodArgs<TElement, TDatum, TMethod> extends [infer TArg] ? TArg : never;
|
|
461
|
-
type ZoomModifierValue<TElement extends Element, TDatum, TMethod extends ZoomBehaviorMethodName<TElement, TDatum>> = ZoomBehaviorMethodArgs<TElement, TDatum, TMethod> | ZoomBehaviorSingleArg<TElement, TDatum, TMethod>;
|
|
462
|
-
type ZoomModifiers<TElement extends Element = SVGSVGElement, TDatum = unknown> = Partial<{ [K in ZoomBehaviorMethodName<TElement, TDatum>]: ZoomModifierValue<TElement, TDatum, K> }>;
|
|
463
|
-
interface ZoomProps<TElement extends Element = SVGSVGElement, TDatum = unknown> {
|
|
542
|
+
interface DefaultZoomBehavior extends ZoomBehavior$1<SVGSVGElement, unknown> {}
|
|
543
|
+
/**
|
|
544
|
+
* Extra zoom method calls to apply before rendering.
|
|
545
|
+
*
|
|
546
|
+
* Use zoom method names as keys and method arguments as values.
|
|
547
|
+
* Example: `{ scaleExtent: [[2, 9]], translateExtent: [[[0, 0], [10, 10]]] }`
|
|
548
|
+
*
|
|
549
|
+
* @see https://d3js.org/d3-zoom
|
|
550
|
+
*/
|
|
551
|
+
interface ZoomModifiers extends MethodsToModifiers<DefaultZoomBehavior> {}
|
|
552
|
+
interface ZoomProps {
|
|
464
553
|
center?: [number, number];
|
|
465
554
|
zoom?: number;
|
|
466
555
|
minZoom?: number;
|
|
467
556
|
maxZoom?: number;
|
|
468
|
-
|
|
469
|
-
modifiers?: ZoomModifiers<TElement, TDatum>;
|
|
557
|
+
config?: ZoomModifiers;
|
|
470
558
|
}
|
|
471
559
|
interface ZoomEvent extends D3ZoomEvent$1<SVGSVGElement, unknown> {}
|
|
472
560
|
interface ZoomEvents {
|
|
@@ -474,7 +562,7 @@ interface ZoomEvents {
|
|
|
474
562
|
onZoom?: (event: ZoomEvent) => void;
|
|
475
563
|
onZoomEnd?: (event: ZoomEvent) => void;
|
|
476
564
|
}
|
|
477
|
-
interface ZoomBehaviorOptions
|
|
565
|
+
interface ZoomBehaviorOptions extends ZoomProps, ZoomEvents {}
|
|
478
566
|
type ZoomScaleSource = number | ZoomTransform$1 | {
|
|
479
567
|
transform: ZoomTransform$1;
|
|
480
568
|
};
|
|
@@ -484,24 +572,20 @@ declare const ZOOM_DEFAULTS: {
|
|
|
484
572
|
zoom: number;
|
|
485
573
|
minZoom: number;
|
|
486
574
|
maxZoom: number;
|
|
487
|
-
extent: Extent;
|
|
488
575
|
};
|
|
489
576
|
interface ApplyZoomOptions {
|
|
490
577
|
element: ZoomTargetElement | null | undefined;
|
|
491
|
-
behavior:
|
|
578
|
+
behavior: DefaultZoomBehavior;
|
|
492
579
|
center?: [number, number];
|
|
493
580
|
zoom?: number;
|
|
494
581
|
}
|
|
495
582
|
interface SetupZoomOptions extends ApplyZoomOptions {}
|
|
496
|
-
declare function
|
|
497
|
-
declare function
|
|
498
|
-
declare function
|
|
499
|
-
declare function createZoomBehavior<TElement extends Element = SVGSVGElement, TDatum = unknown>(context?: MapContext, options?: ZoomBehaviorOptions<TElement, TDatum>): ZoomBehavior$1<TElement, TDatum>;
|
|
500
|
-
declare function attachZoomBehavior(element: ZoomTargetElement | null | undefined, behavior: ZoomBehavior$1<SVGSVGElement, unknown>): void;
|
|
501
|
-
declare function applyZoomBehaviorTransform(element: ZoomTargetElement | null | undefined, behavior: ZoomBehavior$1<SVGSVGElement, unknown>, transform: ZoomTransform$1): void;
|
|
583
|
+
declare function createZoomBehavior(context?: MapContext, options?: ZoomBehaviorOptions): DefaultZoomBehavior;
|
|
584
|
+
declare function attachZoomBehavior(element: ZoomTargetElement | null | undefined, behavior: DefaultZoomBehavior): void;
|
|
585
|
+
declare function applyZoomBehaviorTransform(element: ZoomTargetElement | null | undefined, behavior: DefaultZoomBehavior, transform: ZoomTransform$1): void;
|
|
502
586
|
declare function applyZoomTransform(options: ApplyZoomOptions): void;
|
|
503
587
|
declare function setupZoom(options: SetupZoomOptions): void;
|
|
504
588
|
declare function getZoomScale(source: ZoomScaleSource): number;
|
|
505
589
|
declare function getInverseZoomScale(source: ZoomScaleSource, fallback?: number): number;
|
|
506
590
|
//#endregion
|
|
507
|
-
export { ApplyZoomOptions, type D3ZoomEvent, DataTransformer, Extent, MapConfig, MapContext, MapData, MapFeature, MapFeatureProps, MapMarkerCoordinates, MapMarkerProps, MapObject, MapObjectEvent, MapObjectEventType, MapObjectFocusEventType, MapObjectMouseEventType, MapObjectState, MapObjectStyles,
|
|
591
|
+
export { AnyFn, ApplyZoomOptions, type D3ZoomEvent, DataTransformer, DefaultZoomBehavior, Extent, HasArgs, MapConfig, MapContext, MapData, MapFeature, MapFeatureProps, MapMarkerCoordinates, MapMarkerProps, MapMesh, MapObject, MapObjectEvent, MapObjectEventType, MapObjectFocusEventType, MapObjectMouseEventType, MapObjectState, MapObjectStyles, MethodsToModifiers, ModifierArgs, OverloadedArgs, OwnKeys, ProjectionConfig, SetterArgs, SetupZoomOptions, ZOOM_DEFAULTS, type ZoomBehavior, ZoomBehaviorOptions, ZoomEvent, ZoomEvents, ZoomModifiers, ZoomProps, ZoomScaleSource, ZoomTargetElement, type ZoomTransform, applyModifiers, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior, getFeatureKey, getInverseZoomScale, getMarkerTransform, getObjectStateUpdate, getTopoObject, getZoomScale, isDefined, isFunction, isNullish, isNumber, isPlainObject, isString, isStringOrNumber, isTopology, makeFeatures, makeMapContext, makeMesh, makePathFn, makeProjection, makeTransform, mapObjectState, resolveObjectStyle, setupZoom };
|
package/dist/index.iife.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(e,t,n,r,i){function a(e){return typeof e==`string`}function o(e){return e!==`undefined`}let s=e=>e==null,c=e=>Number.isFinite(e);function l(e){return a(e)||c(e)}function u(e){return typeof e==`function`}function d(e){if(Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}
|
|
1
|
+
(function(e,t,n,r,i){function a(e){return typeof e==`string`}function o(e){return e!==`undefined`}let s=e=>e==null,c=e=>Number.isFinite(e);function l(e){return a(e)||c(e)}function u(e){return typeof e==`function`}function d(e){if(Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function f(e,t,n){return`translate(${e}, ${t}) scale(${n??1})`}function p(e,t){if(t)for(let n of Object.keys(t)){let r=t[n];if(!o(r))continue;let i=e[n];if(!u(i))continue;let a=Array.isArray(r)?r:[r];i.apply(e,a)}}function m(e,t=`id`,n){let r=e[t];if(l(r))return r;let i=e.properties?.[t];return l(i)?i:n}function h({width:e,height:t,config:n,projection:r,geoJson:i}){let a=r();return i?n?.fitSize||a.fitSize([e,t],i):n?.translate||a.translate([e/2,t/2]),p(a,n),a}function g(e,t){let r;if(b(e)){let t=(0,n.feature)(e,x(e));r=t.type===`FeatureCollection`?t:{type:`FeatureCollection`,features:[t]}}else r=e;return[t?t(r.features):r.features,r]}let _=e=>(0,t.geoPath)().projection(e);function v(e){if(b(e))return(0,n.mesh)(e,x(e))}function y({width:e=600,height:n,aspectRatio:r=16/9,data:i,dataTransformer:a,projection:o=t.geoEqualEarth,projectionConfig:s}){let[c,l]=g(i,a),u=v(i),d=n||e/r,f=h({width:e,height:d,projection:o,config:s,geoJson:l}),p=_(f);return{width:e,height:d,projection:f,features:c,mesh:u,path:p,renderPath:e=>p(e),renderMesh:()=>u?p(u):null}}function b(e){return e?.type===`Topology`}function x(e){let t=Object.keys(e.objects)[0];return e.objects[t]}let S=[`default`,`hover`,`active`];function C(e){switch(e){case`focus`:case`mouseenter`:case`mouseup`:return`hover`;case`blur`:case`mouseleave`:return`default`;case`mousedown`:return`active`;default:return`default`}}function w(e,t){return t?.[e]??t?.default}function T(e,t,n=`translate(0, 0)`){let r=e?.projection;if(!r)return n;let i=r(t);return i?f(...i):n}let E={center:[0,0],zoom:1,minZoom:1,maxZoom:8};function D(e,t={}){let n=(0,i.zoom)(),r=t.minZoom??E.minZoom,a=t.maxZoom??E.maxZoom,o=[[0,0],[e?.width??0,e?.height??0]];return n.scaleExtent([r,a]).translateExtent(o),t.onZoomStart&&n.on(`start`,t.onZoomStart),t.onZoom&&n.on(`zoom`,t.onZoom),t.onZoomEnd&&n.on(`end`,t.onZoomEnd),p(n,t.config),n}function O(e,t){let n=F(e);n&&(0,r.select)(n).call(t)}function k(e,t,n){let i=F(e);i&&(0,r.select)(i).call(t.transform,n)}function A(e){let t=e.center??E.center,n=e.zoom??E.zoom;k(e.element,e.behavior,i.zoomIdentity.translate(...t).scale(n))}function j(e){O(e.element,e.behavior),A(e)}function M(e){return c(e)?e:P(e)?e.k:e?.transform?.k??1}function N(e,t=1){let n=M(e);return!c(n)||n===0?t:1/n}function P(e){return!!(e&&c(e.k)&&c(e.x)&&c(e.y))}function F(e){return e?e instanceof SVGSVGElement?e:e.closest(`svg`):null}e.ZOOM_DEFAULTS=E,e.applyModifiers=p,e.applyZoomBehaviorTransform=k,e.applyZoomTransform=A,e.attachZoomBehavior=O,e.createZoomBehavior=D,e.getFeatureKey=m,e.getInverseZoomScale=N,e.getMarkerTransform=T,e.getObjectStateUpdate=C,e.getTopoObject=x,e.getZoomScale=M,e.isDefined=o,e.isFunction=u,e.isNullish=s,e.isNumber=c,e.isPlainObject=d,e.isString=a,e.isStringOrNumber=l,e.isTopology=b,e.makeFeatures=g,e.makeMapContext=y,e.makeMesh=v,e.makePathFn=_,e.makeProjection=h,e.makeTransform=f,e.mapObjectState=S,e.resolveObjectStyle=w,e.setupZoom=j})(this.D3Maps=this.D3Maps||{},d3,topojson,d3,d3);
|
package/dist/index.js
CHANGED
|
@@ -23,12 +23,44 @@ function isPlainObject(value) {
|
|
|
23
23
|
const prototype = Object.getPrototypeOf(value);
|
|
24
24
|
return prototype === null || prototype === Object.prototype;
|
|
25
25
|
}
|
|
26
|
-
async function get(url) {
|
|
27
|
-
return (await fetch(url)).json();
|
|
28
|
-
}
|
|
29
26
|
function makeTransform(x, y, k) {
|
|
30
27
|
return `translate(${x}, ${y}) scale(${k ?? 1})`;
|
|
31
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Invokes `target` methods with arguments from `modifiers`.
|
|
31
|
+
*
|
|
32
|
+
* modifiers: `{ [methodName]: args[] | arg }`
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* class X {
|
|
36
|
+
* a(x: number) {}
|
|
37
|
+
* b(x: number, y: string) {}
|
|
38
|
+
* c(x: string[]) {}
|
|
39
|
+
* d() {}
|
|
40
|
+
* e = 'foo'
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* applyModifiers(new X(), {
|
|
44
|
+
* a: 1, // ok (single arg as-is)
|
|
45
|
+
* a: [1], // ok (single arg wrapped)
|
|
46
|
+
* b: [1, 'foo'], // ok (tuple for 2 args)
|
|
47
|
+
* c: [['foo', 'bar']], // ok (array-arg must be wrapped)
|
|
48
|
+
* c: ['foo', 'bar'], // error (single array-arg must be wrapped into array)
|
|
49
|
+
* d: [], // error (d has no args, excluded)
|
|
50
|
+
* e: 'foo' // error (e is not a function, excluded)
|
|
51
|
+
* })
|
|
52
|
+
*/
|
|
53
|
+
function applyModifiers(target, modifiers) {
|
|
54
|
+
if (!modifiers) return;
|
|
55
|
+
for (const methodName of Object.keys(modifiers)) {
|
|
56
|
+
const methodArgs = modifiers[methodName];
|
|
57
|
+
if (!isDefined(methodArgs)) continue;
|
|
58
|
+
const fn = target[methodName];
|
|
59
|
+
if (!isFunction(fn)) continue;
|
|
60
|
+
const normalizedArgs = Array.isArray(methodArgs) ? methodArgs : [methodArgs];
|
|
61
|
+
fn.apply(target, normalizedArgs);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
32
64
|
|
|
33
65
|
//#endregion
|
|
34
66
|
//#region src/lib/feature.ts
|
|
@@ -55,21 +87,10 @@ function getFeatureKey(feature$1, idKey = "id", index) {
|
|
|
55
87
|
*/
|
|
56
88
|
function makeProjection({ width, height, config, projection, geoJson }) {
|
|
57
89
|
const mapProjection = projection();
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (config?.rotate) {
|
|
63
|
-
const [rx, ry, rz] = config.rotate;
|
|
64
|
-
if (isNumber(rx) && isNumber(ry)) mapProjection.rotate([
|
|
65
|
-
rx,
|
|
66
|
-
ry,
|
|
67
|
-
isNumber(rz) ? rz : 0
|
|
68
|
-
]);
|
|
69
|
-
}
|
|
70
|
-
if (config && isNumber(config.scale)) mapProjection.scale(config.scale);
|
|
71
|
-
if (geoJson) mapProjection.fitSize([width, height], geoJson);
|
|
72
|
-
else mapProjection.translate([width / 2, height / 2]);
|
|
90
|
+
if (!geoJson) {
|
|
91
|
+
if (!config?.translate) mapProjection.translate([width / 2, height / 2]);
|
|
92
|
+
} else if (!config?.fitSize) mapProjection.fitSize([width, height], geoJson);
|
|
93
|
+
applyModifiers(mapProjection, config);
|
|
73
94
|
return mapProjection;
|
|
74
95
|
}
|
|
75
96
|
/**
|
|
@@ -186,33 +207,18 @@ const ZOOM_DEFAULTS = {
|
|
|
186
207
|
center: [0, 0],
|
|
187
208
|
zoom: 1,
|
|
188
209
|
minZoom: 1,
|
|
189
|
-
maxZoom: 8
|
|
190
|
-
extent: [[0, 0], [0, 0]]
|
|
210
|
+
maxZoom: 8
|
|
191
211
|
};
|
|
192
|
-
function getDefaultTranslateExtent(context) {
|
|
193
|
-
return [[0, 0], [context?.width ?? 0, context?.height ?? 0]];
|
|
194
|
-
}
|
|
195
|
-
function createZoomTransform(center, zoomLevel) {
|
|
196
|
-
return zoomIdentity.translate(...center).scale(zoomLevel);
|
|
197
|
-
}
|
|
198
|
-
function createZoomConfig(options) {
|
|
199
|
-
return {
|
|
200
|
-
scaleExtent: [options.minZoom ?? ZOOM_DEFAULTS.minZoom, options.maxZoom ?? ZOOM_DEFAULTS.maxZoom],
|
|
201
|
-
translateExtent: options.translateExtent ?? ZOOM_DEFAULTS.extent
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
212
|
function createZoomBehavior(context, options = {}) {
|
|
205
213
|
const behavior = zoom();
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
});
|
|
211
|
-
behavior.scaleExtent(config.scaleExtent).translateExtent(config.translateExtent);
|
|
214
|
+
const minZoom = options.minZoom ?? ZOOM_DEFAULTS.minZoom;
|
|
215
|
+
const maxZoom = options.maxZoom ?? ZOOM_DEFAULTS.maxZoom;
|
|
216
|
+
const translateExtent = [[0, 0], [context?.width ?? 0, context?.height ?? 0]];
|
|
217
|
+
behavior.scaleExtent([minZoom, maxZoom]).translateExtent(translateExtent);
|
|
212
218
|
if (options.onZoomStart) behavior.on("start", options.onZoomStart);
|
|
213
219
|
if (options.onZoom) behavior.on("zoom", options.onZoom);
|
|
214
220
|
if (options.onZoomEnd) behavior.on("end", options.onZoomEnd);
|
|
215
|
-
|
|
221
|
+
applyModifiers(behavior, options.config);
|
|
216
222
|
return behavior;
|
|
217
223
|
}
|
|
218
224
|
function attachZoomBehavior(element, behavior) {
|
|
@@ -228,7 +234,7 @@ function applyZoomBehaviorTransform(element, behavior, transform) {
|
|
|
228
234
|
function applyZoomTransform(options) {
|
|
229
235
|
const center = options.center ?? ZOOM_DEFAULTS.center;
|
|
230
236
|
const zoom$1 = options.zoom ?? ZOOM_DEFAULTS.zoom;
|
|
231
|
-
applyZoomBehaviorTransform(options.element, options.behavior,
|
|
237
|
+
applyZoomBehaviorTransform(options.element, options.behavior, zoomIdentity.translate(...center).scale(zoom$1));
|
|
232
238
|
}
|
|
233
239
|
function setupZoom(options) {
|
|
234
240
|
attachZoomBehavior(options.element, options.behavior);
|
|
@@ -247,16 +253,6 @@ function getInverseZoomScale(source, fallback = 1) {
|
|
|
247
253
|
function isZoomTransform(value) {
|
|
248
254
|
return Boolean(value && isNumber(value.k) && isNumber(value.x) && isNumber(value.y));
|
|
249
255
|
}
|
|
250
|
-
function applyZoomModifiers(behavior, modifiers) {
|
|
251
|
-
if (!modifiers) return;
|
|
252
|
-
for (const [methodName, methodArgs] of Object.entries(modifiers)) {
|
|
253
|
-
if (!methodName || methodArgs === void 0) continue;
|
|
254
|
-
const modifier = behavior[methodName];
|
|
255
|
-
if (typeof modifier !== "function") continue;
|
|
256
|
-
const normalizedArgs = Array.isArray(methodArgs) ? methodArgs : [methodArgs];
|
|
257
|
-
modifier.apply(behavior, normalizedArgs);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
256
|
function getSvgElement(element) {
|
|
261
257
|
if (!element) return null;
|
|
262
258
|
if (element instanceof SVGSVGElement) return element;
|
|
@@ -264,4 +260,4 @@ function getSvgElement(element) {
|
|
|
264
260
|
}
|
|
265
261
|
|
|
266
262
|
//#endregion
|
|
267
|
-
export { ZOOM_DEFAULTS, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior,
|
|
263
|
+
export { ZOOM_DEFAULTS, applyModifiers, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior, getFeatureKey, getInverseZoomScale, getMarkerTransform, getObjectStateUpdate, getTopoObject, getZoomScale, isDefined, isFunction, isNullish, isNumber, isPlainObject, isString, isStringOrNumber, isTopology, makeFeatures, makeMapContext, makeMesh, makePathFn, makeProjection, makeTransform, mapObjectState, resolveObjectStyle, setupZoom };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d3-maps/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Framework-agnostic core utilities for building reactive D3 maps",
|
|
7
7
|
"author": "Georgii Bukharov <souljorje@gmail.com>",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"typecheck": "tsc --noEmit",
|
|
55
|
+
"typecheck:test": "tsc -p tsconfig.test.json --noEmit",
|
|
55
56
|
"build": "pnpm run typecheck && tsdown",
|
|
56
57
|
"dev": "tsdown --watch",
|
|
57
58
|
"test": "vitest run",
|