@flowmap.gl/data 8.0.0-alpha.13 → 8.0.0-alpha.17
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/FlowmapSelectors.d.ts +21 -21
- package/dist/FlowmapSelectors.d.ts.map +1 -1
- package/dist/FlowmapSelectors.js +55 -31
- package/dist/cluster/cluster.d.ts +6 -5
- package/dist/cluster/cluster.d.ts.map +1 -1
- package/dist/cluster/cluster.js +11 -9
- package/dist/getViewStateForLocations.d.ts +1 -1
- package/dist/getViewStateForLocations.d.ts.map +1 -1
- package/dist/getViewStateForLocations.js +16 -5
- package/dist/provider/FlowmapDataProvider.d.ts.map +1 -1
- package/dist/provider/FlowmapDataProvider.js +6 -6
- package/dist/provider/LocalFlowmapDataProvider.d.ts.map +1 -1
- package/dist/provider/LocalFlowmapDataProvider.js +2 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/package.json +13 -16
- package/src/FlowmapSelectors.ts +78 -59
- package/src/cluster/cluster.ts +23 -20
- package/src/getViewStateForLocations.ts +17 -7
- package/src/provider/FlowmapDataProvider.ts +4 -5
- package/src/provider/LocalFlowmapDataProvider.ts +1 -0
- package/src/types.ts +5 -5
- package/dist-es5/FlowmapAggregateAccessors.d.ts +0 -16
- package/dist-es5/FlowmapAggregateAccessors.d.ts.map +0 -1
- package/dist-es5/FlowmapAggregateAccessors.js +0 -57
- package/dist-es5/FlowmapSelectors.d.ts +0 -188
- package/dist-es5/FlowmapSelectors.d.ts.map +0 -1
- package/dist-es5/FlowmapSelectors.js +0 -1507
- package/dist-es5/FlowmapState.d.ts +0 -27
- package/dist-es5/FlowmapState.d.ts.map +0 -1
- package/dist-es5/FlowmapState.js +0 -3
- package/dist-es5/cluster/ClusterIndex.d.ts +0 -42
- package/dist-es5/cluster/ClusterIndex.d.ts.map +0 -1
- package/dist-es5/cluster/ClusterIndex.js +0 -297
- package/dist-es5/cluster/cluster.d.ts +0 -31
- package/dist-es5/cluster/cluster.d.ts.map +0 -1
- package/dist-es5/cluster/cluster.js +0 -266
- package/dist-es5/colors.d.ts +0 -103
- package/dist-es5/colors.d.ts.map +0 -1
- package/dist-es5/colors.js +0 -510
- package/dist-es5/getViewStateForLocations.d.ts +0 -23
- package/dist-es5/getViewStateForLocations.d.ts.map +0 -1
- package/dist-es5/getViewStateForLocations.js +0 -64
- package/dist-es5/index.d.ts +0 -11
- package/dist-es5/index.d.ts.map +0 -1
- package/dist-es5/index.js +0 -28
- package/dist-es5/provider/FlowmapDataProvider.d.ts +0 -16
- package/dist-es5/provider/FlowmapDataProvider.d.ts.map +0 -1
- package/dist-es5/provider/FlowmapDataProvider.js +0 -22
- package/dist-es5/provider/LocalFlowmapDataProvider.d.ts +0 -20
- package/dist-es5/provider/LocalFlowmapDataProvider.d.ts.map +0 -1
- package/dist-es5/provider/LocalFlowmapDataProvider.js +0 -154
- package/dist-es5/time.d.ts +0 -24
- package/dist-es5/time.d.ts.map +0 -1
- package/dist-es5/time.js +0 -168
- package/dist-es5/types.d.ts +0 -118
- package/dist-es5/types.d.ts.map +0 -1
- package/dist-es5/types.js +0 -29
- package/dist-es5/util.d.ts +0 -5
- package/dist-es5/util.d.ts.map +0 -1
- package/dist-es5/util.js +0 -14
- package/tsconfig.es5.json +0 -11
package/src/FlowmapSelectors.ts
CHANGED
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import {WebMercatorViewport} from '@math.gl/web-mercator';
|
|
20
|
-
import {ascending, descending, extent, min} from 'd3-array';
|
|
21
|
-
import {nest} from 'd3-collection';
|
|
20
|
+
import {ascending, rollup, descending, extent, min} from 'd3-array';
|
|
22
21
|
import {ScaleLinear, scaleLinear, scaleSqrt} from 'd3-scale';
|
|
23
22
|
import KDBush from 'kdbush';
|
|
24
23
|
import {
|
|
@@ -158,25 +157,34 @@ export default class FlowmapSelectors<L, F> {
|
|
|
158
157
|
},
|
|
159
158
|
);
|
|
160
159
|
|
|
161
|
-
getLocations: Selector<L, F, L
|
|
160
|
+
getLocations: Selector<L, F, Iterable<L> | undefined> = createSelector(
|
|
162
161
|
this.getFetchedLocations,
|
|
163
162
|
this.getInvalidLocationIds,
|
|
164
163
|
(locations, invalidIds) => {
|
|
165
164
|
if (!locations) return undefined;
|
|
166
165
|
if (!invalidIds || invalidIds.length === 0) return locations;
|
|
167
166
|
const invalid = new Set(invalidIds);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
const filtered: L[] = [];
|
|
168
|
+
for (const location of locations) {
|
|
169
|
+
const id = this.accessors.getLocationId(location);
|
|
170
|
+
if (!invalid.has(id)) {
|
|
171
|
+
filtered.push(location);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return filtered;
|
|
171
175
|
},
|
|
172
176
|
);
|
|
173
177
|
|
|
174
178
|
getLocationIds: Selector<L, F, Set<string> | undefined> = createSelector(
|
|
175
179
|
this.getLocations,
|
|
176
|
-
(locations) =>
|
|
177
|
-
locations
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
(locations) => {
|
|
181
|
+
if (!locations) return undefined;
|
|
182
|
+
const ids = new Set<string>();
|
|
183
|
+
for (const id of locations) {
|
|
184
|
+
ids.add(this.accessors.getLocationId(id));
|
|
185
|
+
}
|
|
186
|
+
return ids;
|
|
187
|
+
},
|
|
180
188
|
);
|
|
181
189
|
|
|
182
190
|
getSelectedLocationsSet: Selector<L, F, Set<string> | undefined> =
|
|
@@ -187,18 +195,20 @@ export default class FlowmapSelectors<L, F> {
|
|
|
187
195
|
getSortedFlowsForKnownLocations: Selector<L, F, F[] | undefined> =
|
|
188
196
|
createSelector(this.getFetchedFlows, this.getLocationIds, (flows, ids) => {
|
|
189
197
|
if (!ids || !flows) return undefined;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
),
|
|
201
|
-
|
|
198
|
+
const filtered = [];
|
|
199
|
+
for (const flow of flows) {
|
|
200
|
+
const srcId = this.accessors.getFlowOriginId(flow);
|
|
201
|
+
const dstId = this.accessors.getFlowDestId(flow);
|
|
202
|
+
if (ids.has(srcId) && ids.has(dstId)) {
|
|
203
|
+
filtered.push(flow);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return filtered.sort((a: F, b: F) =>
|
|
207
|
+
descending(
|
|
208
|
+
Math.abs(this.accessors.getFlowMagnitude(a)),
|
|
209
|
+
Math.abs(this.accessors.getFlowMagnitude(b)),
|
|
210
|
+
),
|
|
211
|
+
);
|
|
202
212
|
});
|
|
203
213
|
|
|
204
214
|
getActualTimeExtent: Selector<L, F, [Date, Date] | undefined> =
|
|
@@ -271,30 +281,36 @@ export default class FlowmapSelectors<L, F> {
|
|
|
271
281
|
},
|
|
272
282
|
);
|
|
273
283
|
|
|
274
|
-
getLocationsHavingFlows: Selector<L, F, L
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
getLocationsHavingFlows: Selector<L, F, Iterable<L> | undefined> =
|
|
285
|
+
createSelector(
|
|
286
|
+
this.getSortedFlowsForKnownLocations,
|
|
287
|
+
this.getLocations,
|
|
288
|
+
(flows, locations) => {
|
|
289
|
+
if (!locations || !flows) return locations;
|
|
290
|
+
const withFlows = new Set();
|
|
291
|
+
for (const flow of flows) {
|
|
292
|
+
withFlows.add(this.accessors.getFlowOriginId(flow));
|
|
293
|
+
withFlows.add(this.accessors.getFlowDestId(flow));
|
|
294
|
+
}
|
|
295
|
+
const filtered = [];
|
|
296
|
+
for (const location of locations) {
|
|
297
|
+
if (withFlows.has(this.accessors.getLocationId(location))) {
|
|
298
|
+
filtered.push(location);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return filtered;
|
|
302
|
+
},
|
|
303
|
+
);
|
|
289
304
|
|
|
290
305
|
getLocationsById: Selector<L, F, Map<string, L> | undefined> = createSelector(
|
|
291
306
|
this.getLocationsHavingFlows,
|
|
292
307
|
(locations) => {
|
|
293
308
|
if (!locations) return undefined;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
.
|
|
297
|
-
|
|
309
|
+
const locationsById = new Map<string, L>();
|
|
310
|
+
for (const location of locations) {
|
|
311
|
+
locationsById.set(this.accessors.getLocationId(location), location);
|
|
312
|
+
}
|
|
313
|
+
return locationsById;
|
|
298
314
|
},
|
|
299
315
|
);
|
|
300
316
|
|
|
@@ -438,7 +454,7 @@ export default class FlowmapSelectors<L, F> {
|
|
|
438
454
|
clusterIndex,
|
|
439
455
|
) => {
|
|
440
456
|
if (!locations) return undefined;
|
|
441
|
-
let result: (L | Cluster)[] = locations;
|
|
457
|
+
let result: (L | Cluster)[] = Array.from(locations);
|
|
442
458
|
// if (clusteringEnabled) {
|
|
443
459
|
// if (clusterIndex) {
|
|
444
460
|
// const zoomItems = clusterIndex.getClusterNodesFor(clusterZoom);
|
|
@@ -448,7 +464,7 @@ export default class FlowmapSelectors<L, F> {
|
|
|
448
464
|
// }
|
|
449
465
|
// }
|
|
450
466
|
|
|
451
|
-
if (
|
|
467
|
+
if (clusterIndex && selectedLocations) {
|
|
452
468
|
const toAppend = [];
|
|
453
469
|
for (const id of selectedLocations) {
|
|
454
470
|
const cluster = clusterIndex.getClusterById(id);
|
|
@@ -475,11 +491,12 @@ export default class FlowmapSelectors<L, F> {
|
|
|
475
491
|
getDiffMode: Selector<L, F, boolean> = createSelector(
|
|
476
492
|
this.getFetchedFlows,
|
|
477
493
|
(flows) => {
|
|
478
|
-
if (
|
|
479
|
-
flows
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
494
|
+
if (flows) {
|
|
495
|
+
for (const f of flows) {
|
|
496
|
+
if (this.accessors.getFlowMagnitude(f) < 0) {
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
483
500
|
}
|
|
484
501
|
return false;
|
|
485
502
|
},
|
|
@@ -512,8 +529,8 @@ export default class FlowmapSelectors<L, F> {
|
|
|
512
529
|
(ids, flows, flowsForKnownLocations) => {
|
|
513
530
|
if (!ids || !flows) return undefined;
|
|
514
531
|
if (
|
|
515
|
-
flowsForKnownLocations
|
|
516
|
-
flows.length === flowsForKnownLocations.length
|
|
532
|
+
flowsForKnownLocations
|
|
533
|
+
// && flows.length === flowsForKnownLocations.length
|
|
517
534
|
)
|
|
518
535
|
return undefined;
|
|
519
536
|
const missing = new Set<string>();
|
|
@@ -656,7 +673,7 @@ export default class FlowmapSelectors<L, F> {
|
|
|
656
673
|
},
|
|
657
674
|
);
|
|
658
675
|
|
|
659
|
-
getLocationsForZoom: Selector<L, F, L
|
|
676
|
+
getLocationsForZoom: Selector<L, F, Iterable<L> | ClusterNode[] | undefined> =
|
|
660
677
|
createSelector(
|
|
661
678
|
this.getClusteringEnabled,
|
|
662
679
|
this.getLocationsHavingFlows,
|
|
@@ -1403,10 +1420,9 @@ function aggregateFlows<F>(
|
|
|
1403
1420
|
flowAccessors: FlowAccessors<F>,
|
|
1404
1421
|
): AggregateFlow[] {
|
|
1405
1422
|
// Sum up flows with same origin, dest
|
|
1406
|
-
const byOriginDest =
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
.rollup((ff: F[]) => {
|
|
1423
|
+
const byOriginDest = rollup(
|
|
1424
|
+
flows,
|
|
1425
|
+
(ff: F[]) => {
|
|
1410
1426
|
const origin = flowAccessors.getFlowOriginId(ff[0]);
|
|
1411
1427
|
const dest = flowAccessors.getFlowDestId(ff[0]);
|
|
1412
1428
|
// const color = ff[0].color;
|
|
@@ -1425,11 +1441,14 @@ function aggregateFlows<F>(
|
|
|
1425
1441
|
};
|
|
1426
1442
|
// if (color) rv.color = color;
|
|
1427
1443
|
return rv;
|
|
1428
|
-
}
|
|
1429
|
-
.
|
|
1444
|
+
},
|
|
1445
|
+
flowAccessors.getFlowOriginId,
|
|
1446
|
+
flowAccessors.getFlowDestId,
|
|
1447
|
+
);
|
|
1448
|
+
|
|
1430
1449
|
const rv: AggregateFlow[] = [];
|
|
1431
|
-
for (const
|
|
1432
|
-
for (const
|
|
1450
|
+
for (const values of byOriginDest.values()) {
|
|
1451
|
+
for (const value of values.values()) {
|
|
1433
1452
|
rv.push(value);
|
|
1434
1453
|
}
|
|
1435
1454
|
}
|
package/src/cluster/cluster.ts
CHANGED
|
@@ -69,8 +69,9 @@ interface BasePoint {
|
|
|
69
69
|
parentId: number; // parent cluster id
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
interface LeafPoint extends BasePoint {
|
|
72
|
+
interface LeafPoint<L> extends BasePoint {
|
|
73
73
|
index: number; // index of the source feature in the original input array,
|
|
74
|
+
location: L;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
interface ClusterPoint extends BasePoint {
|
|
@@ -78,14 +79,14 @@ interface ClusterPoint extends BasePoint {
|
|
|
78
79
|
numPoints: number;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
type Point = LeafPoint | ClusterPoint;
|
|
82
|
+
type Point<L> = LeafPoint<L> | ClusterPoint;
|
|
82
83
|
|
|
83
|
-
export function isLeafPoint(p: Point): p is LeafPoint {
|
|
84
|
-
const {index} = p as LeafPoint
|
|
84
|
+
export function isLeafPoint<L>(p: Point<L>): p is LeafPoint<L> {
|
|
85
|
+
const {index} = p as LeafPoint<L>;
|
|
85
86
|
return index != null;
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
export function isClusterPoint(p: Point): p is ClusterPoint {
|
|
89
|
+
export function isClusterPoint<L>(p: Point<L>): p is ClusterPoint {
|
|
89
90
|
const {id} = p as ClusterPoint;
|
|
90
91
|
return id != null;
|
|
91
92
|
}
|
|
@@ -93,7 +94,7 @@ export function isClusterPoint(p: Point): p is ClusterPoint {
|
|
|
93
94
|
type ZoomLevelKDBush = any;
|
|
94
95
|
|
|
95
96
|
export function clusterLocations<L>(
|
|
96
|
-
locations: L
|
|
97
|
+
locations: Iterable<L>,
|
|
97
98
|
locationAccessors: LocationAccessors<L>,
|
|
98
99
|
getLocationWeight: LocationWeightGetter,
|
|
99
100
|
options?: Partial<Options>,
|
|
@@ -108,18 +109,21 @@ export function clusterLocations<L>(
|
|
|
108
109
|
const trees = new Array<ZoomLevelKDBush>(maxZoom + 1);
|
|
109
110
|
|
|
110
111
|
// generate a cluster object for each point and index input points into a KD-tree
|
|
111
|
-
let clusters = new Array<Point
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
112
|
+
let clusters = new Array<Point<L>>();
|
|
113
|
+
let i = 0;
|
|
114
|
+
for (const location of locations) {
|
|
115
|
+
const x = getLocationLon(location);
|
|
116
|
+
const y = getLocationLat(location);
|
|
115
117
|
clusters.push({
|
|
116
118
|
x: lngX(x), // projected point coordinates
|
|
117
119
|
y: latY(y),
|
|
118
|
-
weight: getLocationWeight(getLocationId(
|
|
120
|
+
weight: getLocationWeight(getLocationId(location)),
|
|
119
121
|
zoom: Infinity, // the last zoom the point was processed at
|
|
120
122
|
index: i, // index of the source feature in the original input array,
|
|
121
123
|
parentId: -1, // parent cluster id
|
|
124
|
+
location,
|
|
122
125
|
});
|
|
126
|
+
i++;
|
|
123
127
|
}
|
|
124
128
|
trees[maxZoom + 1] = new KDBush(clusters, getX, getY, nodeSize, Float32Array);
|
|
125
129
|
|
|
@@ -148,11 +152,11 @@ export function clusterLocations<L>(
|
|
|
148
152
|
let childrenByParent: Map<number, string[]> | undefined;
|
|
149
153
|
const tree = trees[zoom];
|
|
150
154
|
if (zoom < maxAvailZoom) {
|
|
151
|
-
childrenByParent = rollup<Point
|
|
155
|
+
childrenByParent = rollup<Point<L>, string[], number>(
|
|
152
156
|
trees[zoom + 1].points,
|
|
153
157
|
(points: any[]) =>
|
|
154
158
|
points.map((p: any) =>
|
|
155
|
-
p.id ? makeClusterId(p.id) : getLocationId(
|
|
159
|
+
p.id ? makeClusterId(p.id) : getLocationId(p.location),
|
|
156
160
|
),
|
|
157
161
|
(point: any) => point.parentId,
|
|
158
162
|
);
|
|
@@ -160,9 +164,8 @@ export function clusterLocations<L>(
|
|
|
160
164
|
|
|
161
165
|
const nodes: ClusterNode[] = [];
|
|
162
166
|
for (const point of tree.points) {
|
|
163
|
-
const {x, y, numPoints} = point;
|
|
167
|
+
const {x, y, numPoints, location} = point;
|
|
164
168
|
if (isLeafPoint(point)) {
|
|
165
|
-
const location = locations[point.index];
|
|
166
169
|
nodes.push({
|
|
167
170
|
id: getLocationId(location),
|
|
168
171
|
zoom,
|
|
@@ -211,13 +214,13 @@ function createCluster(
|
|
|
211
214
|
};
|
|
212
215
|
}
|
|
213
216
|
|
|
214
|
-
function cluster(
|
|
215
|
-
points: Point[],
|
|
217
|
+
function cluster<L>(
|
|
218
|
+
points: Point<L>[],
|
|
216
219
|
zoom: number,
|
|
217
220
|
tree: ZoomLevelKDBush,
|
|
218
221
|
options: Options,
|
|
219
222
|
) {
|
|
220
|
-
const clusters: Point[] = [];
|
|
223
|
+
const clusters: Point<L>[] = [];
|
|
221
224
|
const {radius, extent} = options;
|
|
222
225
|
const r = radius / (extent * Math.pow(2, zoom));
|
|
223
226
|
|
|
@@ -293,10 +296,10 @@ function latY(lat: number) {
|
|
|
293
296
|
return y < 0 ? 0 : y > 1 ? 1 : y;
|
|
294
297
|
}
|
|
295
298
|
|
|
296
|
-
function getX(p: Point) {
|
|
299
|
+
function getX<L>(p: Point<L>) {
|
|
297
300
|
return p.x;
|
|
298
301
|
}
|
|
299
302
|
|
|
300
|
-
function getY(p: Point) {
|
|
303
|
+
function getY<L>(p: Point<L>) {
|
|
301
304
|
return p.y;
|
|
302
305
|
}
|
|
@@ -50,19 +50,29 @@ export function getViewStateForFeatures(
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export function getViewStateForLocations(
|
|
54
|
-
locations:
|
|
55
|
-
getLocationCoords: (location:
|
|
53
|
+
export function getViewStateForLocations<L>(
|
|
54
|
+
locations: Iterable<L>,
|
|
55
|
+
getLocationCoords: (location: L) => [number, number],
|
|
56
56
|
size: [number, number],
|
|
57
57
|
opts?: GetViewStateOptions,
|
|
58
58
|
): ViewState & {width: number; height: number} {
|
|
59
|
+
const asGeometry = (location: L) => ({
|
|
60
|
+
type: 'Point',
|
|
61
|
+
coordinates: getLocationCoords(location),
|
|
62
|
+
});
|
|
63
|
+
let geometries;
|
|
64
|
+
if (Array.isArray(locations)) {
|
|
65
|
+
geometries = locations.map(asGeometry);
|
|
66
|
+
} else {
|
|
67
|
+
geometries = [];
|
|
68
|
+
for (const location of locations) {
|
|
69
|
+
geometries.push(asGeometry(location));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
59
72
|
return getViewStateForFeatures(
|
|
60
73
|
{
|
|
61
74
|
type: 'GeometryCollection',
|
|
62
|
-
geometries
|
|
63
|
-
type: 'Point',
|
|
64
|
-
coordinates: getLocationCoords(location),
|
|
65
|
-
})),
|
|
75
|
+
geometries,
|
|
66
76
|
} as any,
|
|
67
77
|
size,
|
|
68
78
|
opts,
|
|
@@ -42,11 +42,10 @@ export function isFlowmapData<L, F>(
|
|
|
42
42
|
data: Record<string, any>,
|
|
43
43
|
): data is FlowmapData<L, F> {
|
|
44
44
|
return (
|
|
45
|
-
data &&
|
|
46
|
-
|
|
47
|
-
data.
|
|
48
|
-
Array.isArray(data.
|
|
49
|
-
Array.isArray(data.flows)
|
|
45
|
+
data && data.locations && data.flows
|
|
46
|
+
// TODO: test that they are iterable
|
|
47
|
+
// Array.isArray(data.locations) &&
|
|
48
|
+
// Array.isArray(data.flows)
|
|
50
49
|
);
|
|
51
50
|
}
|
|
52
51
|
|
|
@@ -53,6 +53,7 @@ export default class LocalFlowmapDataProvider<L, F>
|
|
|
53
53
|
return flows?.[idx];
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// TODO: this is unreliable, should replace by unqiue ID
|
|
56
57
|
async getLocationByIndex(idx: number): Promise<L | ClusterNode | undefined> {
|
|
57
58
|
if (!this.flowmapState || !this.flowmapData) {
|
|
58
59
|
return undefined;
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type FlowmapData<L, F> = {
|
|
2
|
-
locations: L
|
|
3
|
-
flows: F
|
|
2
|
+
locations: Iterable<L> | undefined;
|
|
3
|
+
flows: Iterable<F> | undefined;
|
|
4
4
|
};
|
|
5
5
|
|
|
6
6
|
export interface ViewState {
|
|
@@ -115,9 +115,9 @@ export function isAggregateFlow(
|
|
|
115
115
|
): flow is AggregateFlow {
|
|
116
116
|
return (
|
|
117
117
|
flow &&
|
|
118
|
-
flow.origin !== undefined &&
|
|
119
|
-
flow.dest !== undefined &&
|
|
120
|
-
flow.count !== undefined &&
|
|
118
|
+
// flow.origin !== undefined &&
|
|
119
|
+
// flow.dest !== undefined &&
|
|
120
|
+
// flow.count !== undefined &&
|
|
121
121
|
(flow.aggregate ? true : false)
|
|
122
122
|
);
|
|
123
123
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { AggregateFlow, ClusterNode, FlowmapDataAccessors } from './types';
|
|
2
|
-
export default class FlowmapAggregateAccessors<L, F> {
|
|
3
|
-
private accessors;
|
|
4
|
-
constructor(accessors: FlowmapDataAccessors<L, F>);
|
|
5
|
-
setAccessors(accessors: FlowmapDataAccessors<L, F>): void;
|
|
6
|
-
getFlowmapDataAccessors(): FlowmapDataAccessors<L, F>;
|
|
7
|
-
getLocationId: (location: L | ClusterNode) => string;
|
|
8
|
-
getLocationName: (location: L | ClusterNode) => string;
|
|
9
|
-
getLocationLat: (location: L | ClusterNode) => number;
|
|
10
|
-
getLocationLon: (location: L | ClusterNode) => number;
|
|
11
|
-
getFlowOriginId: (f: F | AggregateFlow) => string;
|
|
12
|
-
getFlowDestId: (f: F | AggregateFlow) => string;
|
|
13
|
-
getFlowMagnitude: (f: F | AggregateFlow) => number;
|
|
14
|
-
getFlowTime: (f: F) => Date | undefined;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=FlowmapAggregateAccessors.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FlowmapAggregateAccessors.d.ts","sourceRoot":"","sources":["../src/FlowmapAggregateAccessors.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,WAAW,EACX,oBAAoB,EAIrB,MAAM,SAAS,CAAC;AAEjB,MAAM,CAAC,OAAO,OAAO,yBAAyB,CAAC,CAAC,EAAE,CAAC;IACjD,OAAO,CAAC,SAAS,CAA6B;gBAClC,SAAS,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC;IAIjD,YAAY,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC;IAIlD,uBAAuB;IAIvB,aAAa,aAAc,CAAC,GAAG,WAAW,KAAG,MAAM,CAGN;IAE7C,eAAe,aAAc,CAAC,GAAG,WAAW,KAAG,MAAM,CAGJ;IAMjD,cAAc,aAAc,CAAC,GAAG,WAAW,KAAG,MAAM,CAGN;IAE9C,cAAc,aAAc,CAAC,GAAG,WAAW,KAAG,MAAM,CAGN;IAE9C,eAAe,MAAO,CAAC,GAAG,aAAa,YAErC;IAEF,aAAa,MAAO,CAAC,GAAG,aAAa,YAEnC;IAEF,gBAAgB,MAAO,CAAC,GAAG,aAAa,YAEtC;IAGF,WAAW,MAAO,CAAC,sBAGjB;CACH"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var types_1 = require("./types");
|
|
4
|
-
var FlowmapAggregateAccessors = /** @class */ (function () {
|
|
5
|
-
function FlowmapAggregateAccessors(accessors) {
|
|
6
|
-
var _this = this;
|
|
7
|
-
this.getLocationId = function (location) {
|
|
8
|
-
return (0, types_1.isLocationClusterNode)(location)
|
|
9
|
-
? location.id
|
|
10
|
-
: _this.accessors.getLocationId(location);
|
|
11
|
-
};
|
|
12
|
-
this.getLocationName = function (location) {
|
|
13
|
-
var _a;
|
|
14
|
-
return (_a = ((0, types_1.isLocationClusterNode)(location) && (0, types_1.isCluster)(location)
|
|
15
|
-
? location.name
|
|
16
|
-
: undefined)) !== null && _a !== void 0 ? _a : _this.getLocationId(location);
|
|
17
|
-
};
|
|
18
|
-
// ? location.name // TODO getLocationName for locations and clusters
|
|
19
|
-
// : this.accessors.getLocationName
|
|
20
|
-
// ? this.accessors.getLocationName(location)
|
|
21
|
-
// : this.getLocationId(location);
|
|
22
|
-
this.getLocationLat = function (location) {
|
|
23
|
-
return (0, types_1.isLocationClusterNode)(location)
|
|
24
|
-
? location.lat
|
|
25
|
-
: _this.accessors.getLocationLat(location);
|
|
26
|
-
};
|
|
27
|
-
this.getLocationLon = function (location) {
|
|
28
|
-
return (0, types_1.isLocationClusterNode)(location)
|
|
29
|
-
? location.lon
|
|
30
|
-
: _this.accessors.getLocationLon(location);
|
|
31
|
-
};
|
|
32
|
-
this.getFlowOriginId = function (f) {
|
|
33
|
-
return (0, types_1.isAggregateFlow)(f) ? f.origin : _this.accessors.getFlowOriginId(f);
|
|
34
|
-
};
|
|
35
|
-
this.getFlowDestId = function (f) {
|
|
36
|
-
return (0, types_1.isAggregateFlow)(f) ? f.dest : _this.accessors.getFlowDestId(f);
|
|
37
|
-
};
|
|
38
|
-
this.getFlowMagnitude = function (f) {
|
|
39
|
-
return (0, types_1.isAggregateFlow)(f) ? f.count : _this.accessors.getFlowMagnitude(f);
|
|
40
|
-
};
|
|
41
|
-
// Note: Aggregate flows have no time
|
|
42
|
-
this.getFlowTime = function (f) {
|
|
43
|
-
var getFlowTime = _this.accessors.getFlowTime;
|
|
44
|
-
return getFlowTime ? getFlowTime(f) : undefined;
|
|
45
|
-
};
|
|
46
|
-
this.accessors = accessors;
|
|
47
|
-
}
|
|
48
|
-
FlowmapAggregateAccessors.prototype.setAccessors = function (accessors) {
|
|
49
|
-
this.accessors = accessors;
|
|
50
|
-
};
|
|
51
|
-
FlowmapAggregateAccessors.prototype.getFlowmapDataAccessors = function () {
|
|
52
|
-
return this.accessors;
|
|
53
|
-
};
|
|
54
|
-
return FlowmapAggregateAccessors;
|
|
55
|
-
}());
|
|
56
|
-
exports.default = FlowmapAggregateAccessors;
|
|
57
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd21hcEFnZ3JlZ2F0ZUFjY2Vzc29ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9GbG93bWFwQWdncmVnYXRlQWNjZXNzb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBT2lCO0FBRWpCO0lBRUUsbUNBQVksU0FBcUM7UUFBakQsaUJBRUM7UUFVRCxrQkFBYSxHQUFHLFVBQUMsUUFBeUI7WUFDeEMsT0FBQSxJQUFBLDZCQUFxQixFQUFDLFFBQVEsQ0FBQztnQkFDN0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUNiLENBQUMsQ0FBQyxLQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7UUFGMUMsQ0FFMEMsQ0FBQztRQUU3QyxvQkFBZSxHQUFHLFVBQUMsUUFBeUI7O1lBQzFDLE9BQUEsTUFBQSxDQUFDLElBQUEsNkJBQXFCLEVBQUMsUUFBUSxDQUFDLElBQUksSUFBQSxpQkFBUyxFQUFDLFFBQVEsQ0FBQztnQkFDckQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJO2dCQUNmLENBQUMsQ0FBQyxTQUFTLENBQUMsbUNBQUksS0FBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtTQUFBLENBQUM7UUFDakQscUVBQXFFO1FBQ3JFLG1DQUFtQztRQUNuQyw2Q0FBNkM7UUFDN0Msa0NBQWtDO1FBRWxDLG1CQUFjLEdBQUcsVUFBQyxRQUF5QjtZQUN6QyxPQUFBLElBQUEsNkJBQXFCLEVBQUMsUUFBUSxDQUFDO2dCQUM3QixDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUc7Z0JBQ2QsQ0FBQyxDQUFDLEtBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQztRQUYzQyxDQUUyQyxDQUFDO1FBRTlDLG1CQUFjLEdBQUcsVUFBQyxRQUF5QjtZQUN6QyxPQUFBLElBQUEsNkJBQXFCLEVBQUMsUUFBUSxDQUFDO2dCQUM3QixDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUc7Z0JBQ2QsQ0FBQyxDQUFDLEtBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQztRQUYzQyxDQUUyQyxDQUFDO1FBRTlDLG9CQUFlLEdBQUcsVUFBQyxDQUFvQjtZQUNyQyxPQUFPLElBQUEsdUJBQWUsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDO1FBRUYsa0JBQWEsR0FBRyxVQUFDLENBQW9CO1lBQ25DLE9BQU8sSUFBQSx1QkFBZSxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2RSxDQUFDLENBQUM7UUFFRixxQkFBZ0IsR0FBRyxVQUFDLENBQW9CO1lBQ3RDLE9BQU8sSUFBQSx1QkFBZSxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLENBQUMsQ0FBQztRQUVGLHFDQUFxQztRQUNyQyxnQkFBVyxHQUFHLFVBQUMsQ0FBSTtZQUNWLElBQUEsV0FBVyxHQUFJLEtBQUksQ0FBQyxTQUFTLFlBQWxCLENBQW1CO1lBQ3JDLE9BQU8sV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNsRCxDQUFDLENBQUM7UUFuREEsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDN0IsQ0FBQztJQUVELGdEQUFZLEdBQVosVUFBYSxTQUFxQztRQUNoRCxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUM3QixDQUFDO0lBRUQsMkRBQXVCLEdBQXZCO1FBQ0UsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUEyQ0gsZ0NBQUM7QUFBRCxDQUFDLEFBdkRELElBdURDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWdncmVnYXRlRmxvdyxcbiAgQ2x1c3Rlck5vZGUsXG4gIEZsb3dtYXBEYXRhQWNjZXNzb3JzLFxuICBpc0FnZ3JlZ2F0ZUZsb3csXG4gIGlzQ2x1c3RlcixcbiAgaXNMb2NhdGlvbkNsdXN0ZXJOb2RlLFxufSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmxvd21hcEFnZ3JlZ2F0ZUFjY2Vzc29yczxMLCBGPiB7XG4gIHByaXZhdGUgYWNjZXNzb3JzOiBGbG93bWFwRGF0YUFjY2Vzc29yczxMLCBGPjtcbiAgY29uc3RydWN0b3IoYWNjZXNzb3JzOiBGbG93bWFwRGF0YUFjY2Vzc29yczxMLCBGPikge1xuICAgIHRoaXMuYWNjZXNzb3JzID0gYWNjZXNzb3JzO1xuICB9XG5cbiAgc2V0QWNjZXNzb3JzKGFjY2Vzc29yczogRmxvd21hcERhdGFBY2Nlc3NvcnM8TCwgRj4pIHtcbiAgICB0aGlzLmFjY2Vzc29ycyA9IGFjY2Vzc29ycztcbiAgfVxuXG4gIGdldEZsb3dtYXBEYXRhQWNjZXNzb3JzKCkge1xuICAgIHJldHVybiB0aGlzLmFjY2Vzc29ycztcbiAgfVxuXG4gIGdldExvY2F0aW9uSWQgPSAobG9jYXRpb246IEwgfCBDbHVzdGVyTm9kZSk6IHN0cmluZyA9PlxuICAgIGlzTG9jYXRpb25DbHVzdGVyTm9kZShsb2NhdGlvbilcbiAgICAgID8gbG9jYXRpb24uaWRcbiAgICAgIDogdGhpcy5hY2Nlc3NvcnMuZ2V0TG9jYXRpb25JZChsb2NhdGlvbik7XG5cbiAgZ2V0TG9jYXRpb25OYW1lID0gKGxvY2F0aW9uOiBMIHwgQ2x1c3Rlck5vZGUpOiBzdHJpbmcgPT5cbiAgICAoaXNMb2NhdGlvbkNsdXN0ZXJOb2RlKGxvY2F0aW9uKSAmJiBpc0NsdXN0ZXIobG9jYXRpb24pXG4gICAgICA/IGxvY2F0aW9uLm5hbWVcbiAgICAgIDogdW5kZWZpbmVkKSA/PyB0aGlzLmdldExvY2F0aW9uSWQobG9jYXRpb24pO1xuICAvLyA/IGxvY2F0aW9uLm5hbWUgLy8gVE9ETyBnZXRMb2NhdGlvbk5hbWUgZm9yIGxvY2F0aW9ucyBhbmQgY2x1c3RlcnNcbiAgLy8gOiB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbk5hbWVcbiAgLy8gPyB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbk5hbWUobG9jYXRpb24pXG4gIC8vIDogdGhpcy5nZXRMb2NhdGlvbklkKGxvY2F0aW9uKTtcblxuICBnZXRMb2NhdGlvbkxhdCA9IChsb2NhdGlvbjogTCB8IENsdXN0ZXJOb2RlKTogbnVtYmVyID0+XG4gICAgaXNMb2NhdGlvbkNsdXN0ZXJOb2RlKGxvY2F0aW9uKVxuICAgICAgPyBsb2NhdGlvbi5sYXRcbiAgICAgIDogdGhpcy5hY2Nlc3NvcnMuZ2V0TG9jYXRpb25MYXQobG9jYXRpb24pO1xuXG4gIGdldExvY2F0aW9uTG9uID0gKGxvY2F0aW9uOiBMIHwgQ2x1c3Rlck5vZGUpOiBudW1iZXIgPT5cbiAgICBpc0xvY2F0aW9uQ2x1c3Rlck5vZGUobG9jYXRpb24pXG4gICAgICA/IGxvY2F0aW9uLmxvblxuICAgICAgOiB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbkxvbihsb2NhdGlvbik7XG5cbiAgZ2V0Rmxvd09yaWdpbklkID0gKGY6IEYgfCBBZ2dyZWdhdGVGbG93KSA9PiB7XG4gICAgcmV0dXJuIGlzQWdncmVnYXRlRmxvdyhmKSA/IGYub3JpZ2luIDogdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGYpO1xuICB9O1xuXG4gIGdldEZsb3dEZXN0SWQgPSAoZjogRiB8IEFnZ3JlZ2F0ZUZsb3cpID0+IHtcbiAgICByZXR1cm4gaXNBZ2dyZWdhdGVGbG93KGYpID8gZi5kZXN0IDogdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmKTtcbiAgfTtcblxuICBnZXRGbG93TWFnbml0dWRlID0gKGY6IEYgfCBBZ2dyZWdhdGVGbG93KSA9PiB7XG4gICAgcmV0dXJuIGlzQWdncmVnYXRlRmxvdyhmKSA/IGYuY291bnQgOiB0aGlzLmFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGYpO1xuICB9O1xuXG4gIC8vIE5vdGU6IEFnZ3JlZ2F0ZSBmbG93cyBoYXZlIG5vIHRpbWVcbiAgZ2V0Rmxvd1RpbWUgPSAoZjogRikgPT4ge1xuICAgIGNvbnN0IHtnZXRGbG93VGltZX0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICByZXR1cm4gZ2V0Rmxvd1RpbWUgPyBnZXRGbG93VGltZShmKSA6IHVuZGVmaW5lZDtcbiAgfTtcbn1cbiJdfQ==
|