@deck.gl/carto 9.4.0-beta.1 → 9.4.0-beta.4
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/api/types.d.ts +1 -11
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cartoPropertiesTile-worker.js +1 -1
- package/dist/cartoRasterTile-worker.js +1 -1
- package/dist/cartoSpatialTile-worker.js +1 -1
- package/dist/cartoVectorTile-worker.js +1 -1
- package/dist/index.cjs +175 -19247
- package/dist/index.cjs.map +3 -3
- package/dist/layers/schema/carto-properties-tile-loader.js +1 -1
- package/dist/layers/schema/carto-raster-tile-loader.js +1 -1
- package/dist/layers/schema/carto-spatial-tile-loader.js +1 -1
- package/dist/layers/schema/carto-vector-tile-loader.js +1 -1
- package/dist.min.js +2 -2
- package/package.json +10 -10
- package/src/api/types.ts +1 -13
- package/dist/api/layer-map.d.ts +0 -57
- package/dist/api/layer-map.d.ts.map +0 -1
- package/dist/api/layer-map.js +0 -385
- package/dist/api/layer-map.js.map +0 -1
- package/dist/api/parse-map.d.ts +0 -32
- package/dist/api/parse-map.d.ts.map +0 -1
- package/dist/api/parse-map.js +0 -260
- package/dist/api/parse-map.js.map +0 -1
- package/src/api/layer-map.ts +0 -498
- package/src/api/parse-map.ts +0 -372
package/src/api/layer-map.ts
DELETED
|
@@ -1,498 +0,0 @@
|
|
|
1
|
-
// deck.gl
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Copyright (c) vis.gl contributors
|
|
4
|
-
|
|
5
|
-
import {deviation, extent, groupSort, median, variance} from 'd3-array';
|
|
6
|
-
import {rgb} from 'd3-color';
|
|
7
|
-
import {
|
|
8
|
-
scaleLinear,
|
|
9
|
-
scaleOrdinal,
|
|
10
|
-
scaleLog,
|
|
11
|
-
scalePoint,
|
|
12
|
-
scaleQuantile,
|
|
13
|
-
scaleQuantize,
|
|
14
|
-
scaleSqrt,
|
|
15
|
-
scaleThreshold
|
|
16
|
-
} from 'd3-scale';
|
|
17
|
-
import {format as d3Format} from 'd3-format';
|
|
18
|
-
import moment from 'moment-timezone';
|
|
19
|
-
|
|
20
|
-
import {Accessor, Layer, _ConstructorOf as ConstructorOf} from '@deck.gl/core';
|
|
21
|
-
import {GridLayer, HeatmapLayer, HexagonLayer} from '@deck.gl/aggregation-layers';
|
|
22
|
-
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
23
|
-
import {H3HexagonLayer} from '@deck.gl/geo-layers';
|
|
24
|
-
|
|
25
|
-
import ClusterTileLayer from '../layers/cluster-tile-layer';
|
|
26
|
-
import H3TileLayer from '../layers/h3-tile-layer';
|
|
27
|
-
import QuadbinTileLayer from '../layers/quadbin-tile-layer';
|
|
28
|
-
import RasterTileLayer from '../layers/raster-tile-layer';
|
|
29
|
-
import VectorTileLayer from '../layers/vector-tile-layer';
|
|
30
|
-
import {assert, createBinaryProxy, scaleIdentity} from '../utils';
|
|
31
|
-
import {
|
|
32
|
-
CustomMarkersRange,
|
|
33
|
-
MapDataset,
|
|
34
|
-
MapTextSubLayerConfig,
|
|
35
|
-
VisConfig,
|
|
36
|
-
VisualChannelField,
|
|
37
|
-
VisualChannels
|
|
38
|
-
} from './types';
|
|
39
|
-
import HeatmapTileLayer from '../layers/heatmap-tile-layer';
|
|
40
|
-
|
|
41
|
-
const SCALE_FUNCS = {
|
|
42
|
-
linear: scaleLinear,
|
|
43
|
-
ordinal: scaleOrdinal,
|
|
44
|
-
log: scaleLog,
|
|
45
|
-
point: scalePoint,
|
|
46
|
-
quantile: scaleQuantile,
|
|
47
|
-
quantize: scaleQuantize,
|
|
48
|
-
sqrt: scaleSqrt,
|
|
49
|
-
custom: scaleThreshold,
|
|
50
|
-
identity: scaleIdentity
|
|
51
|
-
};
|
|
52
|
-
export type SCALE_TYPE = keyof typeof SCALE_FUNCS;
|
|
53
|
-
|
|
54
|
-
type TileLayerType =
|
|
55
|
-
| 'clusterTile'
|
|
56
|
-
| 'h3'
|
|
57
|
-
| 'heatmapTile'
|
|
58
|
-
| 'mvt'
|
|
59
|
-
| 'quadbin'
|
|
60
|
-
| 'raster'
|
|
61
|
-
| 'tileset';
|
|
62
|
-
type DocumentLayerType = 'geojson' | 'grid' | 'heatmap' | 'hexagon' | 'hexagonId' | 'point';
|
|
63
|
-
type LayerType = TileLayerType | DocumentLayerType;
|
|
64
|
-
|
|
65
|
-
function identity<T>(v: T): T {
|
|
66
|
-
return v;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const UNKNOWN_COLOR = '#868d91';
|
|
70
|
-
|
|
71
|
-
export const AGGREGATION = {
|
|
72
|
-
average: 'MEAN',
|
|
73
|
-
maximum: 'MAX',
|
|
74
|
-
minimum: 'MIN',
|
|
75
|
-
sum: 'SUM'
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const OPACITY_MAP = {
|
|
79
|
-
getFillColor: 'opacity',
|
|
80
|
-
getLineColor: 'strokeOpacity',
|
|
81
|
-
getTextColor: 'opacity'
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const AGGREGATION_FUNC = {
|
|
85
|
-
'count unique': (values, accessor) => groupSort(values, v => v.length, accessor).length,
|
|
86
|
-
median,
|
|
87
|
-
// Unfortunately mode() is only available in d3-array@3+ which is ESM only
|
|
88
|
-
mode: (values, accessor) => groupSort(values, v => v.length, accessor).pop(),
|
|
89
|
-
stddev: deviation,
|
|
90
|
-
variance
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const TILE_LAYER_TYPE_TO_LAYER: Record<TileLayerType, ConstructorOf<Layer>> = {
|
|
94
|
-
clusterTile: ClusterTileLayer,
|
|
95
|
-
h3: H3TileLayer,
|
|
96
|
-
heatmapTile: HeatmapTileLayer,
|
|
97
|
-
mvt: VectorTileLayer,
|
|
98
|
-
quadbin: QuadbinTileLayer,
|
|
99
|
-
raster: RasterTileLayer,
|
|
100
|
-
tileset: VectorTileLayer
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const hexToRGBA = c => {
|
|
104
|
-
const {r, g, b, opacity} = rgb(c);
|
|
105
|
-
return [r, g, b, 255 * opacity];
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// Kepler prop value -> Deck.gl prop value
|
|
109
|
-
// Supports nested definitions, and function transforms:
|
|
110
|
-
// {keplerProp: 'deckProp'} is equivalent to:
|
|
111
|
-
// {keplerProp: x => ({deckProp: x})}
|
|
112
|
-
const sharedPropMap = {
|
|
113
|
-
// Apply the value of Kepler `color` prop to the deck `getFillColor` prop
|
|
114
|
-
color: 'getFillColor',
|
|
115
|
-
isVisible: 'visible',
|
|
116
|
-
label: 'cartoLabel',
|
|
117
|
-
textLabel: {
|
|
118
|
-
alignment: 'getTextAlignmentBaseline',
|
|
119
|
-
anchor: 'getTextAnchor',
|
|
120
|
-
// Apply the value of Kepler `textLabel.color` prop to the deck `getTextColor` prop
|
|
121
|
-
color: 'getTextColor',
|
|
122
|
-
size: 'getTextSize'
|
|
123
|
-
},
|
|
124
|
-
visConfig: {
|
|
125
|
-
enable3d: 'extruded',
|
|
126
|
-
elevationScale: 'elevationScale',
|
|
127
|
-
filled: 'filled',
|
|
128
|
-
strokeColor: 'getLineColor',
|
|
129
|
-
stroked: 'stroked',
|
|
130
|
-
thickness: 'getLineWidth',
|
|
131
|
-
radius: 'getPointRadius',
|
|
132
|
-
wireframe: 'wireframe'
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const customMarkersPropsMap = {
|
|
137
|
-
color: 'getIconColor',
|
|
138
|
-
visConfig: {
|
|
139
|
-
radius: 'getIconSize'
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const heatmapTilePropsMap = {
|
|
144
|
-
visConfig: {
|
|
145
|
-
colorRange: x => ({colorRange: x.colors.map(hexToRGBA)}),
|
|
146
|
-
radius: 'radiusPixels'
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const aggregationVisConfig = {
|
|
151
|
-
colorAggregation: x => ({colorAggregation: AGGREGATION[x] || AGGREGATION.sum}),
|
|
152
|
-
colorRange: x => ({colorRange: x.colors.map(hexToRGBA)}),
|
|
153
|
-
coverage: 'coverage',
|
|
154
|
-
elevationPercentile: ['elevationLowerPercentile', 'elevationUpperPercentile'],
|
|
155
|
-
percentile: ['lowerPercentile', 'upperPercentile']
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const defaultProps = {
|
|
159
|
-
lineMiterLimit: 2,
|
|
160
|
-
lineWidthUnits: 'pixels',
|
|
161
|
-
pointRadiusUnits: 'pixels',
|
|
162
|
-
rounded: true,
|
|
163
|
-
wrapLongitude: false
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
function mergePropMaps(a: Record<string, any> = {}, b: Record<string, any> = {}) {
|
|
167
|
-
return {...a, ...b, visConfig: {...a.visConfig, ...b.visConfig}};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function getLayer(
|
|
171
|
-
type: LayerType,
|
|
172
|
-
config: MapTextSubLayerConfig,
|
|
173
|
-
dataset: MapDataset
|
|
174
|
-
): {Layer: ConstructorOf<Layer>; propMap: any; defaultProps: any} {
|
|
175
|
-
let basePropMap: any = sharedPropMap;
|
|
176
|
-
|
|
177
|
-
if (config.visConfig?.customMarkers) {
|
|
178
|
-
basePropMap = mergePropMaps(basePropMap, customMarkersPropsMap);
|
|
179
|
-
}
|
|
180
|
-
if (type === 'heatmapTile') {
|
|
181
|
-
basePropMap = mergePropMaps(basePropMap, heatmapTilePropsMap);
|
|
182
|
-
}
|
|
183
|
-
if (TILE_LAYER_TYPE_TO_LAYER[type]) {
|
|
184
|
-
return getTileLayer(dataset, basePropMap, type);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const geoColumn = dataset?.geoColumn;
|
|
188
|
-
const getPosition = d => d[geoColumn].coordinates;
|
|
189
|
-
|
|
190
|
-
const hexagonId = config.columns?.hex_id;
|
|
191
|
-
|
|
192
|
-
const layerTypeDefs: Record<
|
|
193
|
-
DocumentLayerType,
|
|
194
|
-
{Layer: ConstructorOf<Layer>; propMap?: any; defaultProps?: any}
|
|
195
|
-
> = {
|
|
196
|
-
point: {
|
|
197
|
-
Layer: GeoJsonLayer,
|
|
198
|
-
propMap: {
|
|
199
|
-
columns: {
|
|
200
|
-
altitude: x => ({parameters: {depthWriteEnabled: Boolean(x)}})
|
|
201
|
-
},
|
|
202
|
-
visConfig: {outline: 'stroked'}
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
geojson: {
|
|
206
|
-
Layer: GeoJsonLayer
|
|
207
|
-
},
|
|
208
|
-
grid: {
|
|
209
|
-
Layer: GridLayer,
|
|
210
|
-
propMap: {visConfig: {...aggregationVisConfig, worldUnitSize: x => ({cellSize: 1000 * x})}},
|
|
211
|
-
defaultProps: {getPosition}
|
|
212
|
-
},
|
|
213
|
-
heatmap: {
|
|
214
|
-
Layer: HeatmapLayer,
|
|
215
|
-
propMap: {visConfig: {...aggregationVisConfig, radius: 'radiusPixels'}},
|
|
216
|
-
defaultProps: {getPosition}
|
|
217
|
-
},
|
|
218
|
-
hexagon: {
|
|
219
|
-
Layer: HexagonLayer,
|
|
220
|
-
propMap: {visConfig: {...aggregationVisConfig, worldUnitSize: x => ({radius: 1000 * x})}},
|
|
221
|
-
defaultProps: {getPosition}
|
|
222
|
-
},
|
|
223
|
-
hexagonId: {
|
|
224
|
-
Layer: H3HexagonLayer,
|
|
225
|
-
propMap: {visConfig: {coverage: 'coverage'}},
|
|
226
|
-
defaultProps: {getHexagon: d => d[hexagonId], stroked: false}
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
const layer = layerTypeDefs[type];
|
|
231
|
-
|
|
232
|
-
assert(layer, `Unsupported layer type: ${type}`);
|
|
233
|
-
return {
|
|
234
|
-
...layer,
|
|
235
|
-
propMap: mergePropMaps(basePropMap, layer.propMap),
|
|
236
|
-
defaultProps: {...defaultProps, ...layer.defaultProps}
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function getTileLayer(dataset: MapDataset, basePropMap, type: LayerType) {
|
|
241
|
-
const {aggregationExp, aggregationResLevel} = dataset;
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
Layer: TILE_LAYER_TYPE_TO_LAYER[type] || VectorTileLayer,
|
|
245
|
-
propMap: basePropMap,
|
|
246
|
-
defaultProps: {
|
|
247
|
-
...defaultProps,
|
|
248
|
-
...(aggregationExp && {aggregationExp}),
|
|
249
|
-
...(aggregationResLevel && {aggregationResLevel}),
|
|
250
|
-
uniqueIdProperty: 'geoid'
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function domainFromAttribute(attribute, scaleType: SCALE_TYPE, scaleLength: number) {
|
|
256
|
-
if (scaleType === 'ordinal' || scaleType === 'point') {
|
|
257
|
-
return attribute.categories.map(c => c.category).filter(c => c !== undefined && c !== null);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (scaleType === 'quantile' && attribute.quantiles) {
|
|
261
|
-
return attribute.quantiles.global
|
|
262
|
-
? attribute.quantiles.global[scaleLength]
|
|
263
|
-
: attribute.quantiles[scaleLength];
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
let {min} = attribute;
|
|
267
|
-
if (scaleType === 'log' && min === 0) {
|
|
268
|
-
min = 1e-5;
|
|
269
|
-
}
|
|
270
|
-
return [min, attribute.max];
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function domainFromValues(values, scaleType: SCALE_TYPE) {
|
|
274
|
-
if (scaleType === 'ordinal' || scaleType === 'point') {
|
|
275
|
-
return groupSort(
|
|
276
|
-
values,
|
|
277
|
-
g => -g.length,
|
|
278
|
-
d => d
|
|
279
|
-
);
|
|
280
|
-
} else if (scaleType === 'quantile') {
|
|
281
|
-
return values.sort((a, b) => a - b);
|
|
282
|
-
} else if (scaleType === 'log') {
|
|
283
|
-
const [d0, d1] = extent(values as number[]);
|
|
284
|
-
return [d0 === 0 ? 1e-5 : d0, d1];
|
|
285
|
-
}
|
|
286
|
-
return extent(values);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function calculateDomain(data, name, scaleType, scaleLength?) {
|
|
290
|
-
if (data.tilestats) {
|
|
291
|
-
// Tileset data type
|
|
292
|
-
const {attributes} = data.tilestats.layers[0];
|
|
293
|
-
const attribute = attributes.find(a => a.attribute === name);
|
|
294
|
-
return domainFromAttribute(attribute, scaleType, scaleLength);
|
|
295
|
-
} else if (data.features) {
|
|
296
|
-
// GeoJSON data type
|
|
297
|
-
const values = data.features.map(({properties}) => properties[name]);
|
|
298
|
-
return domainFromValues(values, scaleType);
|
|
299
|
-
} else if (Array.isArray(data) && data[0][name] !== undefined) {
|
|
300
|
-
// JSON data type
|
|
301
|
-
const values = data.map(properties => properties[name]);
|
|
302
|
-
return domainFromValues(values, scaleType);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return [0, 1];
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function normalizeAccessor(accessor, data) {
|
|
309
|
-
if (data.features || data.tilestats) {
|
|
310
|
-
return (object, info) => {
|
|
311
|
-
if (object) {
|
|
312
|
-
return accessor(object.properties || object.__source.object.properties);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const {data, index} = info;
|
|
316
|
-
const proxy = createBinaryProxy(data, index);
|
|
317
|
-
return accessor(proxy);
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
return accessor;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
export function opacityToAlpha(opacity?: number) {
|
|
324
|
-
return opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function getAccessorKeys(name: string, aggregation?: string | undefined): string[] {
|
|
328
|
-
let keys = [name];
|
|
329
|
-
if (aggregation) {
|
|
330
|
-
// Snowflake will capitalized the keys, need to check lower and upper case version
|
|
331
|
-
keys = keys.concat([aggregation, aggregation.toUpperCase()].map(a => `${name}_${a}`));
|
|
332
|
-
}
|
|
333
|
-
return keys;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function findAccessorKey(keys: string[], properties): string[] {
|
|
337
|
-
for (const key of keys) {
|
|
338
|
-
if (key in properties) {
|
|
339
|
-
return [key];
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
throw new Error(`Could not find property for any accessor key: ${keys}`);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
export function getColorValueAccessor({name}, colorAggregation, data: any) {
|
|
347
|
-
const aggregator = AGGREGATION_FUNC[colorAggregation];
|
|
348
|
-
const accessor = values => aggregator(values, p => p[name]);
|
|
349
|
-
return normalizeAccessor(accessor, data);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
export function getColorAccessor(
|
|
353
|
-
{name, colorColumn}: VisualChannelField,
|
|
354
|
-
scaleType: SCALE_TYPE,
|
|
355
|
-
{aggregation, range},
|
|
356
|
-
opacity: number | undefined,
|
|
357
|
-
data: any
|
|
358
|
-
) {
|
|
359
|
-
const scale = calculateLayerScale(colorColumn || name, scaleType, range, data);
|
|
360
|
-
const alpha = opacityToAlpha(opacity);
|
|
361
|
-
|
|
362
|
-
let accessorKeys = getAccessorKeys(name, aggregation);
|
|
363
|
-
const accessor = properties => {
|
|
364
|
-
if (!(accessorKeys[0] in properties)) {
|
|
365
|
-
accessorKeys = findAccessorKey(accessorKeys, properties);
|
|
366
|
-
}
|
|
367
|
-
const propertyValue = properties[accessorKeys[0]];
|
|
368
|
-
const {r, g, b} = rgb(scale(propertyValue));
|
|
369
|
-
return [r, g, b, propertyValue === null ? 0 : alpha];
|
|
370
|
-
};
|
|
371
|
-
return normalizeAccessor(accessor, data);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function calculateLayerScale(name, scaleType, range, data) {
|
|
375
|
-
const scale = SCALE_FUNCS[scaleType]();
|
|
376
|
-
let domain: (string | number)[] = [];
|
|
377
|
-
let scaleColor: string[] = [];
|
|
378
|
-
|
|
379
|
-
if (scaleType !== 'identity') {
|
|
380
|
-
const {colorMap, colors} = range;
|
|
381
|
-
|
|
382
|
-
if (Array.isArray(colorMap)) {
|
|
383
|
-
colorMap.forEach(([value, color]) => {
|
|
384
|
-
domain.push(value);
|
|
385
|
-
scaleColor.push(color);
|
|
386
|
-
});
|
|
387
|
-
} else {
|
|
388
|
-
domain = calculateDomain(data, name, scaleType, colors.length);
|
|
389
|
-
scaleColor = colors;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (scaleType === 'ordinal') {
|
|
393
|
-
domain = domain.slice(0, scaleColor.length);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
scale.domain(domain);
|
|
398
|
-
scale.range(scaleColor);
|
|
399
|
-
scale.unknown(UNKNOWN_COLOR);
|
|
400
|
-
|
|
401
|
-
return scale;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const FALLBACK_ICON =
|
|
405
|
-
'data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNTAiLz4NCjwvc3ZnPg==';
|
|
406
|
-
|
|
407
|
-
export function getIconUrlAccessor(
|
|
408
|
-
field: VisualChannelField | null | undefined,
|
|
409
|
-
range: CustomMarkersRange | null | undefined,
|
|
410
|
-
{fallbackUrl, maxIconSize, useMaskedIcons},
|
|
411
|
-
data: any
|
|
412
|
-
) {
|
|
413
|
-
const urlToUnpackedIcon = (url: string) => ({
|
|
414
|
-
id: `${url}@@${maxIconSize}`,
|
|
415
|
-
url,
|
|
416
|
-
width: maxIconSize,
|
|
417
|
-
height: maxIconSize,
|
|
418
|
-
mask: useMaskedIcons
|
|
419
|
-
});
|
|
420
|
-
let unknownValue = fallbackUrl || FALLBACK_ICON;
|
|
421
|
-
|
|
422
|
-
if (range?.othersMarker) {
|
|
423
|
-
unknownValue = range.othersMarker;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const unknownIcon = urlToUnpackedIcon(unknownValue);
|
|
427
|
-
if (!range || !field) {
|
|
428
|
-
return () => unknownIcon;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
const mapping: Record<string, any> = {};
|
|
432
|
-
for (const {value, markerUrl} of range.markerMap) {
|
|
433
|
-
if (markerUrl) {
|
|
434
|
-
mapping[value] = urlToUnpackedIcon(markerUrl);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const accessor = properties => {
|
|
439
|
-
const propertyValue = properties[field.name];
|
|
440
|
-
return mapping[propertyValue] || unknownIcon;
|
|
441
|
-
};
|
|
442
|
-
return normalizeAccessor(accessor, data);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
export function getMaxMarkerSize(visConfig: VisConfig, visualChannels: VisualChannels): number {
|
|
446
|
-
const {radiusRange, radius} = visConfig;
|
|
447
|
-
const {radiusField, sizeField} = visualChannels;
|
|
448
|
-
const field = radiusField || sizeField;
|
|
449
|
-
return Math.ceil(radiusRange && field ? radiusRange[1] : radius);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
export function negateAccessor<T>(accessor: Accessor<T, number>): Accessor<T, number> {
|
|
453
|
-
return typeof accessor === 'function' ? (d, i) => -accessor(d, i) : -accessor;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
export function getSizeAccessor(
|
|
457
|
-
{name},
|
|
458
|
-
scaleType: SCALE_TYPE | undefined,
|
|
459
|
-
aggregation,
|
|
460
|
-
range: Iterable<Range> | undefined,
|
|
461
|
-
data: any
|
|
462
|
-
) {
|
|
463
|
-
const scale = scaleType ? SCALE_FUNCS[scaleType as any]() : identity;
|
|
464
|
-
if (scaleType) {
|
|
465
|
-
if (aggregation !== 'count') {
|
|
466
|
-
scale.domain(calculateDomain(data, name, scaleType));
|
|
467
|
-
}
|
|
468
|
-
scale.range(range);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
let accessorKeys = getAccessorKeys(name, aggregation);
|
|
472
|
-
const accessor = properties => {
|
|
473
|
-
if (!(accessorKeys[0] in properties)) {
|
|
474
|
-
accessorKeys = findAccessorKey(accessorKeys, properties);
|
|
475
|
-
}
|
|
476
|
-
const propertyValue = properties[accessorKeys[0]];
|
|
477
|
-
return scale(propertyValue);
|
|
478
|
-
};
|
|
479
|
-
return normalizeAccessor(accessor, data);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const FORMATS: Record<string, (value: any) => string> = {
|
|
483
|
-
date: s => moment.utc(s).format('MM/DD/YY HH:mm:ssa'),
|
|
484
|
-
integer: d3Format('i'),
|
|
485
|
-
float: d3Format('.5f'),
|
|
486
|
-
timestamp: s => moment.utc(s).format('X'),
|
|
487
|
-
default: String
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
export function getTextAccessor({name, type}: VisualChannelField, data) {
|
|
491
|
-
const format = FORMATS[type] || FORMATS.default;
|
|
492
|
-
const accessor = properties => {
|
|
493
|
-
return format(properties[name]);
|
|
494
|
-
};
|
|
495
|
-
return normalizeAccessor(accessor, data);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export {domainFromValues as _domainFromValues};
|