@d3-maps/core 0.1.1-next.0 → 0.2.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.d.ts +11 -5
- package/dist/index.iife.js +1 -1
- package/dist/index.js +26 -15
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -366,8 +366,10 @@ interface MapContext {
|
|
|
366
366
|
height: number;
|
|
367
367
|
projection?: GeoProjection;
|
|
368
368
|
features: MapFeature[];
|
|
369
|
+
mesh?: MultiLineString$1;
|
|
369
370
|
path: GeoPath;
|
|
370
371
|
renderPath: (feature: Feature) => ReturnType<GeoPath>;
|
|
372
|
+
renderMesh: () => ReturnType<GeoPath>;
|
|
371
373
|
}
|
|
372
374
|
/**
|
|
373
375
|
* Creates a configured projection and fits it to the provided GeoJSON (if present).
|
|
@@ -393,6 +395,10 @@ declare function makeProjection({
|
|
|
393
395
|
*/
|
|
394
396
|
declare function makeFeatures(geoData: MapData, dataTransformer?: DataTransformer): [features: MapFeature[], geoJson: FeatureCollection];
|
|
395
397
|
declare const makePathFn: (mapProjection: GeoProjection) => GeoPath;
|
|
398
|
+
/**
|
|
399
|
+
* Returns a TopoJSON mesh when topology data is provided.
|
|
400
|
+
*/
|
|
401
|
+
declare function makeMesh(geoData: MapData): MultiLineString$1 | undefined;
|
|
396
402
|
/**
|
|
397
403
|
* Creates a full {@link MapContext} from a {@link MapConfig}.
|
|
398
404
|
*/
|
|
@@ -409,6 +415,7 @@ declare function makeMapContext({
|
|
|
409
415
|
* Type guard for TopoJSON topology inputs.
|
|
410
416
|
*/
|
|
411
417
|
declare function isTopology(data: MapData): data is Topology;
|
|
418
|
+
declare function getTopoObject(geoData: Topology): GeometryObject;
|
|
412
419
|
//#endregion
|
|
413
420
|
//#region src/lib/marker.d.ts
|
|
414
421
|
type MapMarkerCoordinates = [number, number];
|
|
@@ -431,11 +438,11 @@ declare function isString(value: unknown): value is string;
|
|
|
431
438
|
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
432
439
|
declare const isNullish: (value: unknown) => value is null | undefined;
|
|
433
440
|
declare const isNumber: (value: unknown) => value is number;
|
|
434
|
-
declare
|
|
441
|
+
declare function isStringOrNumber(value: unknown): value is string | number;
|
|
435
442
|
declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
|
|
436
443
|
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
437
444
|
declare function get<T>(url: string): Promise<T>;
|
|
438
|
-
declare
|
|
445
|
+
declare function makeTransform(x: number, y: number, k?: number): string;
|
|
439
446
|
//#endregion
|
|
440
447
|
//#region src/lib/zoom.d.ts
|
|
441
448
|
type Extent = [[number, number], [number, number]];
|
|
@@ -448,8 +455,7 @@ interface ZoomConfig {
|
|
|
448
455
|
scaleExtent: [number, number];
|
|
449
456
|
translateExtent: Extent;
|
|
450
457
|
}
|
|
451
|
-
type
|
|
452
|
-
type ZoomBehaviorMethodName<TElement extends Element, TDatum> = Extract<{ [K in ZoomBehaviorOwnMethodName<TElement, TDatum>]: ZoomBehavior$1<TElement, TDatum>[K] extends ((...args: unknown[]) => unknown) ? K : never }[ZoomBehaviorOwnMethodName<TElement, TDatum>], string>;
|
|
458
|
+
type ZoomBehaviorMethodName<TElement extends Element, TDatum> = Extract<{ [K in keyof ZoomBehavior$1<TElement, TDatum>]: ZoomBehavior$1<TElement, TDatum>[K] extends ((...args: unknown[]) => unknown) ? K : never }[keyof ZoomBehavior$1<TElement, TDatum>], string>;
|
|
453
459
|
type ZoomBehaviorMethodArgs<TElement extends Element, TDatum, TMethod extends ZoomBehaviorMethodName<TElement, TDatum>> = ZoomBehavior$1<TElement, TDatum>[TMethod] extends ((...args: infer TArgs) => unknown) ? TArgs : never;
|
|
454
460
|
type ZoomBehaviorSingleArg<TElement extends Element, TDatum, TMethod extends ZoomBehaviorMethodName<TElement, TDatum>> = ZoomBehaviorMethodArgs<TElement, TDatum, TMethod> extends [infer TArg] ? TArg : never;
|
|
455
461
|
type ZoomModifierValue<TElement extends Element, TDatum, TMethod extends ZoomBehaviorMethodName<TElement, TDatum>> = ZoomBehaviorMethodArgs<TElement, TDatum, TMethod> | ZoomBehaviorSingleArg<TElement, TDatum, TMethod>;
|
|
@@ -498,4 +504,4 @@ declare function setupZoom(options: SetupZoomOptions): void;
|
|
|
498
504
|
declare function getZoomScale(source: ZoomScaleSource): number;
|
|
499
505
|
declare function getInverseZoomScale(source: ZoomScaleSource, fallback?: number): number;
|
|
500
506
|
//#endregion
|
|
501
|
-
export { ApplyZoomOptions, type D3ZoomEvent, DataTransformer, Extent, MapConfig, MapContext, MapData, MapFeature, MapFeatureProps, MapMarkerCoordinates, MapMarkerProps, MapObject, MapObjectEvent, MapObjectEventType, MapObjectFocusEventType, MapObjectMouseEventType, MapObjectState, MapObjectStyles, ProjectionConfig, SetupZoomOptions, ZOOM_DEFAULTS, type ZoomBehavior, ZoomBehaviorMethodArgs, ZoomBehaviorMethodName, ZoomBehaviorOptions,
|
|
507
|
+
export { ApplyZoomOptions, type D3ZoomEvent, DataTransformer, Extent, MapConfig, MapContext, MapData, MapFeature, MapFeatureProps, MapMarkerCoordinates, MapMarkerProps, MapObject, MapObjectEvent, MapObjectEventType, MapObjectFocusEventType, MapObjectMouseEventType, MapObjectState, MapObjectStyles, ProjectionConfig, SetupZoomOptions, ZOOM_DEFAULTS, type ZoomBehavior, ZoomBehaviorMethodArgs, ZoomBehaviorMethodName, ZoomBehaviorOptions, ZoomBehaviorSingleArg, ZoomConfig, ZoomConfigOptions, ZoomEvent, ZoomEvents, ZoomModifierValue, ZoomModifiers, ZoomProps, ZoomScaleSource, ZoomTargetElement, type ZoomTransform, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior, createZoomConfig, createZoomTransform, get, getDefaultTranslateExtent, 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)
|
|
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}async function f(e){return(await fetch(e)).json()}function p(e,t,n){return`translate(${e}, ${t}) scale(${n??1})`}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();if(n?.center){let[e,t]=n.center;c(e)&&c(t)&&a.center([e,t])}if(n?.rotate){let[e,t,r]=n.rotate;c(e)&&c(t)&&a.rotate([e,t,c(r)?r:0])}return n&&c(n.scale)&&a.scale(n.scale),i?a.fitSize([e,t],i):a.translate([e/2,t/2]),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?p(...i):n}let E={center:[0,0],zoom:1,minZoom:1,maxZoom:8,extent:[[0,0],[0,0]]};function D(e){return[[0,0],[e?.width??0,e?.height??0]]}function O(e,t){return i.zoomIdentity.translate(...e).scale(t)}function k(e){return{scaleExtent:[e.minZoom??E.minZoom,e.maxZoom??E.maxZoom],translateExtent:e.translateExtent??E.extent}}function A(e,t={}){let n=(0,i.zoom)(),r=k({minZoom:t.minZoom,maxZoom:t.maxZoom,translateExtent:t.translateExtent??D(e)});return n.scaleExtent(r.scaleExtent).translateExtent(r.translateExtent),t.onZoomStart&&n.on(`start`,t.onZoomStart),t.onZoom&&n.on(`zoom`,t.onZoom),t.onZoomEnd&&n.on(`end`,t.onZoomEnd),R(n,t.modifiers),n}function j(e,t){let n=z(e);n&&(0,r.select)(n).call(t)}function M(e,t,n){let i=z(e);i&&(0,r.select)(i).call(t.transform,n)}function N(e){let t=e.center??E.center,n=e.zoom??E.zoom;M(e.element,e.behavior,O(t,n))}function P(e){j(e.element,e.behavior),N(e)}function F(e){return c(e)?e:L(e)?e.k:e?.transform?.k??1}function I(e,t=1){let n=F(e);return!c(n)||n===0?t:1/n}function L(e){return!!(e&&c(e.k)&&c(e.x)&&c(e.y))}function R(e,t){if(t)for(let[n,r]of Object.entries(t)){if(!n||r===void 0)continue;let t=e[n];if(typeof t!=`function`)continue;let i=Array.isArray(r)?r:[r];t.apply(e,i)}}function z(e){return e?e instanceof SVGSVGElement?e:e.closest(`svg`):null}e.ZOOM_DEFAULTS=E,e.applyZoomBehaviorTransform=M,e.applyZoomTransform=N,e.attachZoomBehavior=j,e.createZoomBehavior=A,e.createZoomConfig=k,e.createZoomTransform=O,e.get=f,e.getDefaultTranslateExtent=D,e.getFeatureKey=m,e.getInverseZoomScale=I,e.getMarkerTransform=T,e.getObjectStateUpdate=C,e.getTopoObject=x,e.getZoomScale=F,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=p,e.mapObjectState=S,e.resolveObjectStyle=w,e.setupZoom=P})(this.D3Maps=this.D3Maps||{},d3,topojson,d3,d3);
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { geoEqualEarth, geoPath } from "d3-geo";
|
|
2
|
-
import { feature } from "topojson-client";
|
|
2
|
+
import { feature, mesh } from "topojson-client";
|
|
3
3
|
import { select } from "d3-selection";
|
|
4
4
|
import { zoom, zoomIdentity } from "d3-zoom";
|
|
5
5
|
|
|
@@ -12,7 +12,9 @@ function isDefined(value) {
|
|
|
12
12
|
}
|
|
13
13
|
const isNullish = (value) => value == null;
|
|
14
14
|
const isNumber = (value) => Number.isFinite(value);
|
|
15
|
-
|
|
15
|
+
function isStringOrNumber(value) {
|
|
16
|
+
return isString(value) || isNumber(value);
|
|
17
|
+
}
|
|
16
18
|
function isFunction(value) {
|
|
17
19
|
return typeof value === "function";
|
|
18
20
|
}
|
|
@@ -24,7 +26,9 @@ function isPlainObject(value) {
|
|
|
24
26
|
async function get(url) {
|
|
25
27
|
return (await fetch(url)).json();
|
|
26
28
|
}
|
|
27
|
-
|
|
29
|
+
function makeTransform(x, y, k) {
|
|
30
|
+
return `translate(${x}, ${y}) scale(${k ?? 1})`;
|
|
31
|
+
}
|
|
28
32
|
|
|
29
33
|
//#endregion
|
|
30
34
|
//#region src/lib/feature.ts
|
|
@@ -77,27 +81,28 @@ function makeProjection({ width, height, config, projection, geoJson }) {
|
|
|
77
81
|
function makeFeatures(geoData, dataTransformer) {
|
|
78
82
|
let geoJson;
|
|
79
83
|
if (isTopology(geoData)) {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
const topoObject = geoData.objects[objectKey];
|
|
83
|
-
const normalizedGeoJson = feature(geoData, topoObject);
|
|
84
|
-
geoJson = normalizedGeoJson.type === "FeatureCollection" ? normalizedGeoJson : {
|
|
85
|
-
type: "FeatureCollection",
|
|
86
|
-
features: [normalizedGeoJson]
|
|
87
|
-
};
|
|
88
|
-
} else geoJson = {
|
|
84
|
+
const normalizedGeoJson = feature(geoData, getTopoObject(geoData));
|
|
85
|
+
geoJson = normalizedGeoJson.type === "FeatureCollection" ? normalizedGeoJson : {
|
|
89
86
|
type: "FeatureCollection",
|
|
90
|
-
features: []
|
|
87
|
+
features: [normalizedGeoJson]
|
|
91
88
|
};
|
|
92
89
|
} else geoJson = geoData;
|
|
93
90
|
return [dataTransformer ? dataTransformer(geoJson.features) : geoJson.features, geoJson];
|
|
94
91
|
}
|
|
95
92
|
const makePathFn = (mapProjection) => geoPath().projection(mapProjection);
|
|
96
93
|
/**
|
|
94
|
+
* Returns a TopoJSON mesh when topology data is provided.
|
|
95
|
+
*/
|
|
96
|
+
function makeMesh(geoData) {
|
|
97
|
+
if (!isTopology(geoData)) return void 0;
|
|
98
|
+
return mesh(geoData, getTopoObject(geoData));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
97
101
|
* Creates a full {@link MapContext} from a {@link MapConfig}.
|
|
98
102
|
*/
|
|
99
103
|
function makeMapContext({ width = 600, height: passedHeight, aspectRatio = 16 / 9, data, dataTransformer, projection: providedProjection = geoEqualEarth, projectionConfig }) {
|
|
100
104
|
const [features, geoJson] = makeFeatures(data, dataTransformer);
|
|
105
|
+
const mapMesh = makeMesh(data);
|
|
101
106
|
const height = passedHeight || width / aspectRatio;
|
|
102
107
|
const projection = makeProjection({
|
|
103
108
|
width,
|
|
@@ -112,8 +117,10 @@ function makeMapContext({ width = 600, height: passedHeight, aspectRatio = 16 /
|
|
|
112
117
|
height,
|
|
113
118
|
projection,
|
|
114
119
|
features,
|
|
120
|
+
mesh: mapMesh,
|
|
115
121
|
path: pathFn,
|
|
116
|
-
renderPath: (feature$1) => pathFn(feature$1)
|
|
122
|
+
renderPath: (feature$1) => pathFn(feature$1),
|
|
123
|
+
renderMesh: () => mapMesh ? pathFn(mapMesh) : null
|
|
117
124
|
};
|
|
118
125
|
}
|
|
119
126
|
/**
|
|
@@ -122,6 +129,10 @@ function makeMapContext({ width = 600, height: passedHeight, aspectRatio = 16 /
|
|
|
122
129
|
function isTopology(data) {
|
|
123
130
|
return data?.type === "Topology";
|
|
124
131
|
}
|
|
132
|
+
function getTopoObject(geoData) {
|
|
133
|
+
const objectKey = Object.keys(geoData.objects)[0];
|
|
134
|
+
return geoData.objects[objectKey];
|
|
135
|
+
}
|
|
125
136
|
|
|
126
137
|
//#endregion
|
|
127
138
|
//#region src/lib/mapObject.ts
|
|
@@ -253,4 +264,4 @@ function getSvgElement(element) {
|
|
|
253
264
|
}
|
|
254
265
|
|
|
255
266
|
//#endregion
|
|
256
|
-
export { ZOOM_DEFAULTS, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior, createZoomConfig, createZoomTransform, get, getDefaultTranslateExtent, getFeatureKey, getInverseZoomScale, getMarkerTransform, getObjectStateUpdate, getZoomScale, isDefined, isFunction, isNullish, isNumber, isPlainObject, isString, isStringOrNumber, isTopology, makeFeatures, makeMapContext, makePathFn, makeProjection, makeTransform, mapObjectState, resolveObjectStyle, setupZoom };
|
|
267
|
+
export { ZOOM_DEFAULTS, applyZoomBehaviorTransform, applyZoomTransform, attachZoomBehavior, createZoomBehavior, createZoomConfig, createZoomTransform, get, getDefaultTranslateExtent, 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
|
-
"version": "0.1.1-next.0",
|
|
4
3
|
"type": "module",
|
|
4
|
+
"version": "0.2.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>",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@types/geojson": "^7946.0.16",
|
|
47
47
|
"@types/topojson-client": "^3.1.5",
|
|
48
48
|
"@types/topojson-specification": "^1.0.5",
|
|
49
|
-
"typescript": "^5.9.3",
|
|
50
49
|
"tsdown": "0.19.0",
|
|
50
|
+
"typescript": "^5.9.3",
|
|
51
51
|
"vitest": "^4.0.15"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|