@carto/kepler.gl 0.0.65-alpha.labels.9 → 0.0.66
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/README.md +651 -42
- package/dist/components/side-panel/layer-panel/layer-config-group.js +3 -3
- package/dist/components/side-panel/layer-panel/layer-configurator.js +1 -2
- package/dist/components/side-panel/layer-panel/text-label-panel.js +7 -15
- package/dist/constants/default-settings.js +2 -2
- package/dist/index.js +2 -12
- package/dist/layers/base-layer.js +77 -73
- package/dist/layers/layer-factory.js +26 -38
- package/dist/layers/layer-text-label.js +31 -11
- package/dist/layers/point-layer/point-layer.js +10 -10
- package/dist/localization/en.js +3 -6
- package/dist/processors/data-processor.js +4 -1
- package/dist/reducers/vis-state-updaters.js +8 -16
- package/package.json +1 -5
- package/src/components/side-panel/layer-panel/layer-config-group.js +2 -2
- package/src/components/side-panel/layer-panel/layer-configurator.js +0 -1
- package/src/components/side-panel/layer-panel/text-label-panel.js +26 -45
- package/src/index.js +0 -3
- package/src/layers/base-layer.js +75 -83
- package/src/layers/layer-factory.js +4 -27
- package/src/layers/layer-text-label.js +47 -11
- package/src/layers/point-layer/point-layer.js +11 -8
- package/src/localization/en.js +2 -5
- package/src/processors/data-processor.js +4 -1
- package/src/reducers/vis-state-updaters.js +10 -13
- package/CHANGELOG.md +0 -899
- package/dist/deckgl-layers/point-label-layer/point-label-layer.js +0 -281
- package/src/components/side-panel/layer-panel/.layer-config-group.js.swp +0 -0
- package/src/components/side-panel/layer-panel/.text-label-panel.js.swp +0 -0
- package/src/deckgl-layers/point-label-layer/point-label-layer.js +0 -216
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@carto/kepler.gl",
|
|
3
3
|
"author": "CARTO",
|
|
4
4
|
"homepage": "https://github.com/CartoDB/carto-kepler#readme",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.66",
|
|
6
6
|
"description": "kepler.gl is a webgl based application to visualize large scale location data in the browser",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"main": "dist/index.js",
|
|
@@ -270,10 +270,6 @@
|
|
|
270
270
|
"engines": {
|
|
271
271
|
"node": ">=12.0.0"
|
|
272
272
|
},
|
|
273
|
-
"maintainers": [
|
|
274
|
-
"Shan He <heshan0131@gmail.com>",
|
|
275
|
-
"Giuseppe Macri <gmacri@uber.com>"
|
|
276
|
-
],
|
|
277
273
|
"volta": {
|
|
278
274
|
"node": "12.19.0"
|
|
279
275
|
}
|
|
@@ -40,7 +40,7 @@ export const ConfigGroupCollapsibleContent = styled.div.attrs({
|
|
|
40
40
|
overflow: visible;
|
|
41
41
|
transition: max-height 0.3s ease-out;
|
|
42
42
|
height: max-content;
|
|
43
|
-
max-height:
|
|
43
|
+
max-height: 600px;
|
|
44
44
|
`;
|
|
45
45
|
|
|
46
46
|
export const ConfigGroupCollapsibleHeader = styled.div.attrs({
|
|
@@ -62,7 +62,7 @@ export const StyledLayerConfigGroup = styled.div`
|
|
|
62
62
|
&.collapsed {
|
|
63
63
|
.layer-config-group__header__collapsible {
|
|
64
64
|
overflow: visible;
|
|
65
|
-
max-height:
|
|
65
|
+
max-height: 600px;
|
|
66
66
|
}
|
|
67
67
|
.layer-config-group__content {
|
|
68
68
|
.layer-config-group__content__collapsible {
|
|
@@ -246,7 +246,6 @@ export default function LayerConfiguratorFactory(
|
|
|
246
246
|
{/* text label */}
|
|
247
247
|
<TextLabelPanel
|
|
248
248
|
fields={visConfiguratorProps.fields}
|
|
249
|
-
layer={layer}
|
|
250
249
|
updateLayerTextLabel={this.props.updateLayerTextLabel}
|
|
251
250
|
textLabel={layer.config.textLabel}
|
|
252
251
|
colorPalette={visConfiguratorProps.colorPalette}
|
|
@@ -65,9 +65,8 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
render() {
|
|
68
|
-
const {
|
|
68
|
+
const {updateLayerTextLabel, textLabel, fields, AddButton} = this.props;
|
|
69
69
|
const currentFields = textLabel.map(tl => tl.field && tl.field.name).filter(d => d);
|
|
70
|
-
|
|
71
70
|
return (
|
|
72
71
|
<LayerConfigGroup label={'panel.text.label'} collapsible>
|
|
73
72
|
<ConfigGroupCollapsibleHeader>
|
|
@@ -81,11 +80,11 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
|
|
|
81
80
|
<ConfigGroupCollapsibleContent>
|
|
82
81
|
{textLabel.map((tl, idx) => (
|
|
83
82
|
<div
|
|
84
|
-
key={
|
|
83
|
+
key={tl.field ? tl.field.name : `null-${idx}`}
|
|
85
84
|
className="side-panel-section-group"
|
|
86
85
|
>
|
|
87
86
|
<PanelLabel>
|
|
88
|
-
<FormattedMessage id={
|
|
87
|
+
<FormattedMessage id={'panel.text.labelWithId'} values={{labelId: idx + 1}} />
|
|
89
88
|
</PanelLabel>
|
|
90
89
|
<SidePanelSection>
|
|
91
90
|
<FieldSelector
|
|
@@ -121,51 +120,33 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
|
|
|
121
120
|
/>
|
|
122
121
|
</SidePanelSection>
|
|
123
122
|
<SidePanelSection>
|
|
124
|
-
<
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
<SpaceBetweenFlexbox>
|
|
124
|
+
<SBFlexboxItem>
|
|
125
|
+
<PanelLabel>
|
|
126
|
+
<FormattedMessage id="panel.text.textAnchor" />
|
|
127
|
+
</PanelLabel>
|
|
128
|
+
<ItemSelector
|
|
129
|
+
{...LAYER_TEXT_CONFIGS.textAnchor}
|
|
130
|
+
selectedItems={tl.anchor}
|
|
131
|
+
onChange={val => updateLayerTextLabel(idx, 'anchor', val)}
|
|
132
|
+
/>
|
|
133
|
+
</SBFlexboxItem>
|
|
134
|
+
<SBFlexboxItem>
|
|
135
|
+
<PanelLabel>
|
|
136
|
+
<FormattedMessage id="panel.text.alignment" />
|
|
137
|
+
</PanelLabel>
|
|
138
|
+
<ItemSelector
|
|
139
|
+
{...LAYER_TEXT_CONFIGS.textAlignment}
|
|
140
|
+
selectedItems={tl.alignment}
|
|
141
|
+
onChange={val => updateLayerTextLabel(idx, 'alignment', val)}
|
|
142
|
+
/>
|
|
143
|
+
</SBFlexboxItem>
|
|
144
|
+
</SpaceBetweenFlexbox>
|
|
135
145
|
</SidePanelSection>
|
|
136
|
-
{idx === 0 && (
|
|
137
|
-
<SidePanelSection>
|
|
138
|
-
<SpaceBetweenFlexbox>
|
|
139
|
-
<SBFlexboxItem>
|
|
140
|
-
<PanelLabel>
|
|
141
|
-
<FormattedMessage id="panel.text.textAnchor" />
|
|
142
|
-
</PanelLabel>
|
|
143
|
-
<ItemSelector
|
|
144
|
-
{...LAYER_TEXT_CONFIGS.textAnchor}
|
|
145
|
-
selectedItems={tl.anchor}
|
|
146
|
-
onChange={val => updateLayerTextLabel(idx, 'anchor', val)}
|
|
147
|
-
/>
|
|
148
|
-
</SBFlexboxItem>
|
|
149
|
-
<SBFlexboxItem>
|
|
150
|
-
<PanelLabel>
|
|
151
|
-
<FormattedMessage id="panel.text.alignment" />
|
|
152
|
-
</PanelLabel>
|
|
153
|
-
<ItemSelector
|
|
154
|
-
{...LAYER_TEXT_CONFIGS.textAlignment}
|
|
155
|
-
selectedItems={tl.alignment}
|
|
156
|
-
onChange={val => updateLayerTextLabel(idx, 'alignment', val)}
|
|
157
|
-
/>
|
|
158
|
-
</SBFlexboxItem>
|
|
159
|
-
</SpaceBetweenFlexbox>
|
|
160
|
-
</SidePanelSection>
|
|
161
|
-
)}
|
|
162
146
|
</div>
|
|
163
147
|
))}
|
|
164
148
|
<SidePanelSection>
|
|
165
|
-
<AddButton
|
|
166
|
-
disabled={textLabel.length >= 2}
|
|
167
|
-
onClick={val => updateLayerTextLabel(textLabel.length)}
|
|
168
|
-
/>
|
|
149
|
+
<AddButton onClick={val => updateLayerTextLabel(textLabel.length)} />
|
|
169
150
|
</SidePanelSection>
|
|
170
151
|
</ConfigGroupCollapsibleContent>
|
|
171
152
|
</LayerConfigGroup>
|
package/src/index.js
CHANGED
package/src/layers/base-layer.js
CHANGED
|
@@ -20,9 +20,40 @@
|
|
|
20
20
|
|
|
21
21
|
import {console as Console} from 'global/window';
|
|
22
22
|
import keymirror from 'keymirror';
|
|
23
|
-
import {
|
|
23
|
+
import {DataFilterExtension} from '@deck.gl/extensions';
|
|
24
24
|
import {COORDINATE_SYSTEM, Layer as DeckLayer} from '@deck.gl/core';
|
|
25
|
-
import {
|
|
25
|
+
import {TextLayer} from '@deck.gl/layers';
|
|
26
|
+
|
|
27
|
+
// Workaround until https://github.com/visgl/deck.gl/pull/7513 is released
|
|
28
|
+
DeckLayer.defaultProps.getFilterValue = {type: 'accessor', value: 0};
|
|
29
|
+
|
|
30
|
+
// Workaround until https://github.com/visgl/deck.gl/pull/7507 is released
|
|
31
|
+
function deepEqual(a, b) {
|
|
32
|
+
if (a === b) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (!a || !b) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
for (const key in a) {
|
|
39
|
+
const aValue = a[key];
|
|
40
|
+
const bValue = b[key];
|
|
41
|
+
const equals = aValue === bValue || deepEqual(aValue, bValue);
|
|
42
|
+
if (!equals) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
DeckLayer.defaultProps.loadOptions = {
|
|
50
|
+
type: 'object',
|
|
51
|
+
value: {},
|
|
52
|
+
optional: true,
|
|
53
|
+
compare: true,
|
|
54
|
+
equal: deepEqual
|
|
55
|
+
};
|
|
56
|
+
|
|
26
57
|
import DefaultLayerIcon from './default-layer-icon';
|
|
27
58
|
import {diffUpdateTriggers} from './layer-update';
|
|
28
59
|
|
|
@@ -72,7 +103,6 @@ const FALLBACK_ICON =
|
|
|
72
103
|
const MAX_SAMPLE_SIZE = 5000;
|
|
73
104
|
const defaultDomain = [0, 1];
|
|
74
105
|
const dataFilterExtension = new DataFilterExtension({filterSize: MAX_GPU_FILTERS});
|
|
75
|
-
const collisionFilterExtension = new CollisionFilterExtension();
|
|
76
106
|
|
|
77
107
|
const defaultDataAccessor = dc => d => d;
|
|
78
108
|
const defaultGetFieldValue = (field, d) => field.valueAccessor(d);
|
|
@@ -1311,89 +1341,51 @@ class Layer {
|
|
|
1311
1341
|
};
|
|
1312
1342
|
}
|
|
1313
1343
|
|
|
1314
|
-
renderTextLabelLayer(
|
|
1315
|
-
{getPosition, getRadius, radiusScale, updateTriggers, sharedProps},
|
|
1316
|
-
renderOpts
|
|
1317
|
-
) {
|
|
1344
|
+
renderTextLabelLayer({getPosition, getPixelOffset, updateTriggers, sharedProps}, renderOpts) {
|
|
1318
1345
|
const {data, mapState} = renderOpts;
|
|
1319
1346
|
const {textLabel, visibilityByZoom} = this.config;
|
|
1320
|
-
const extensions = [...sharedProps.extensions, collisionFilterExtension];
|
|
1321
|
-
|
|
1322
|
-
if (!data || !data.textLabels || !data.textLabels[0] || !data.textLabels[0].getText) {
|
|
1323
|
-
return [];
|
|
1324
|
-
}
|
|
1325
1347
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
}),
|
|
1368
|
-
|
|
1369
|
-
// Position
|
|
1370
|
-
getPosition,
|
|
1371
|
-
getRadius,
|
|
1372
|
-
radiusScale,
|
|
1373
|
-
getTextAnchor: anchor,
|
|
1374
|
-
getAlignmentBaseline: alignment,
|
|
1375
|
-
|
|
1376
|
-
// Style
|
|
1377
|
-
fontFamily: 'Inter, sans',
|
|
1378
|
-
fontSettings: {sdf: true},
|
|
1379
|
-
fontWeight: 500,
|
|
1380
|
-
outlineWidth: 4,
|
|
1381
|
-
parameters: {
|
|
1382
|
-
// text will always show on top of all layers
|
|
1383
|
-
depthTest: false
|
|
1384
|
-
},
|
|
1385
|
-
|
|
1386
|
-
getFilterValue: data.getFilterValue,
|
|
1387
|
-
updateTriggers: {
|
|
1388
|
-
...updateTriggers,
|
|
1389
|
-
getText: mainField?.name,
|
|
1390
|
-
getColor: mainField?.color,
|
|
1391
|
-
getTextAnchor: mainLabel.anchor,
|
|
1392
|
-
getAlignmentBaseline: mainLabel.alignment,
|
|
1393
|
-
getSecondaryText: secondaryField?.name
|
|
1394
|
-
}
|
|
1395
|
-
})
|
|
1396
|
-
];
|
|
1348
|
+
return data.textLabels.reduce((accu, d, i) => {
|
|
1349
|
+
if (d.getText) {
|
|
1350
|
+
accu.push(
|
|
1351
|
+
new TextLayer({
|
|
1352
|
+
...sharedProps,
|
|
1353
|
+
id: `${this.id}-label-${textLabel[i].field?.name}`,
|
|
1354
|
+
data: data.data,
|
|
1355
|
+
visibilityByZoom,
|
|
1356
|
+
getText: d.getText,
|
|
1357
|
+
getPosition,
|
|
1358
|
+
characterSet: d.characterSet,
|
|
1359
|
+
getPixelOffset: getPixelOffset(textLabel[i]),
|
|
1360
|
+
getSize: 1,
|
|
1361
|
+
sizeScale: textLabel[i].size,
|
|
1362
|
+
getTextAnchor: textLabel[i].anchor,
|
|
1363
|
+
getAlignmentBaseline: textLabel[i].alignment,
|
|
1364
|
+
getColor: textLabel[i].color,
|
|
1365
|
+
parameters: {
|
|
1366
|
+
// text will always show on top of all layers
|
|
1367
|
+
depthTest: false
|
|
1368
|
+
},
|
|
1369
|
+
|
|
1370
|
+
getFilterValue: data.getFilterValue,
|
|
1371
|
+
updateTriggers: {
|
|
1372
|
+
...updateTriggers,
|
|
1373
|
+
getText: textLabel[i].field?.name,
|
|
1374
|
+
getPixelOffset: {
|
|
1375
|
+
...updateTriggers.getPixelOffset,
|
|
1376
|
+
...updateTriggers.getRadius,
|
|
1377
|
+
anchor: textLabel[i].anchor,
|
|
1378
|
+
alignment: textLabel[i].alignment
|
|
1379
|
+
},
|
|
1380
|
+
getTextAnchor: textLabel[i].anchor,
|
|
1381
|
+
getAlignmentBaseline: textLabel[i].alignment,
|
|
1382
|
+
getColor: textLabel[i].color
|
|
1383
|
+
}
|
|
1384
|
+
})
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
return accu;
|
|
1388
|
+
}, []);
|
|
1397
1389
|
}
|
|
1398
1390
|
|
|
1399
1391
|
/**
|
|
@@ -27,7 +27,6 @@ export const PROPERTY_GROUPS = keyMirror({
|
|
|
27
27
|
color: null,
|
|
28
28
|
stroke: null,
|
|
29
29
|
customMarkers: null,
|
|
30
|
-
labels: null,
|
|
31
30
|
radius: null,
|
|
32
31
|
height: null,
|
|
33
32
|
angle: null,
|
|
@@ -44,21 +43,13 @@ export {DEFAULT_COLOR_RANGE};
|
|
|
44
43
|
/** @type {import('./layer-factory').LayerTextLabel} */
|
|
45
44
|
export const DEFAULT_TEXT_LABEL = {
|
|
46
45
|
field: null,
|
|
47
|
-
color: [
|
|
48
|
-
|
|
49
|
-
size: 12,
|
|
46
|
+
color: [255, 255, 255],
|
|
47
|
+
size: 18,
|
|
50
48
|
offset: [0, 0],
|
|
51
49
|
anchor: 'start',
|
|
52
50
|
alignment: 'center'
|
|
53
51
|
};
|
|
54
52
|
|
|
55
|
-
/** @type {import('./layer-factory').LayerTextLabel} */
|
|
56
|
-
export const DEFAULT_SECONDARY_TEXT_LABEL = {
|
|
57
|
-
...DEFAULT_TEXT_LABEL,
|
|
58
|
-
color: [128, 130, 132],
|
|
59
|
-
size: 10
|
|
60
|
-
};
|
|
61
|
-
|
|
62
53
|
/** @type {import('./layer-factory').ColorRange} */
|
|
63
54
|
export const DEFAULT_CUSTOM_PALETTE = {
|
|
64
55
|
name: 'color.customPalette',
|
|
@@ -396,13 +387,6 @@ export const LAYER_VIS_CONFIGS = {
|
|
|
396
387
|
group: PROPERTY_GROUPS.display,
|
|
397
388
|
property: 'filled'
|
|
398
389
|
},
|
|
399
|
-
labels: {
|
|
400
|
-
type: 'boolean',
|
|
401
|
-
label: 'layerVisConfigs.labels',
|
|
402
|
-
defaultValue: false,
|
|
403
|
-
group: PROPERTY_GROUPS.labels,
|
|
404
|
-
property: 'labels'
|
|
405
|
-
},
|
|
406
390
|
extruded: {
|
|
407
391
|
type: 'boolean',
|
|
408
392
|
defaultValue: false,
|
|
@@ -446,13 +430,6 @@ export const LAYER_VIS_CONFIGS = {
|
|
|
446
430
|
group: PROPERTY_GROUPS.customMarkers,
|
|
447
431
|
property: 'customMarkers'
|
|
448
432
|
},
|
|
449
|
-
labelsEnabled: {
|
|
450
|
-
type: 'boolean',
|
|
451
|
-
defaultValue: true,
|
|
452
|
-
label: 'layerVisConfigs.labelsEnabled',
|
|
453
|
-
group: PROPERTY_GROUPS.labels,
|
|
454
|
-
property: 'labelsEnabled'
|
|
455
|
-
},
|
|
456
433
|
customMarkersUrl: {
|
|
457
434
|
type: 'text',
|
|
458
435
|
defaultValue: '',
|
|
@@ -473,8 +450,8 @@ export const LAYER_VIS_CONFIGS = {
|
|
|
473
450
|
export const LAYER_TEXT_CONFIGS = {
|
|
474
451
|
fontSize: {
|
|
475
452
|
type: 'number',
|
|
476
|
-
range: [
|
|
477
|
-
value0:
|
|
453
|
+
range: [1, 100],
|
|
454
|
+
value0: 1,
|
|
478
455
|
step: 1,
|
|
479
456
|
isRanged: false,
|
|
480
457
|
label: 'Font size',
|
|
@@ -21,25 +21,30 @@
|
|
|
21
21
|
import {notNullorUndefined} from 'utils/data-utils';
|
|
22
22
|
import uniq from 'lodash.uniq';
|
|
23
23
|
|
|
24
|
+
export const defaultPadding = 20;
|
|
25
|
+
|
|
24
26
|
export function getTextOffsetByRadius(radiusScale, getRadius) {
|
|
25
27
|
return textLabel => {
|
|
26
28
|
const xMult = textLabel.anchor === 'middle' ? 0 : textLabel.anchor === 'start' ? 1 : -1;
|
|
27
29
|
const yMult = textLabel.alignment === 'center' ? 0 : textLabel.alignment === 'bottom' ? 1 : -1;
|
|
28
30
|
|
|
29
|
-
const sizeOffset =
|
|
31
|
+
const sizeOffset =
|
|
32
|
+
textLabel.alignment === 'center'
|
|
33
|
+
? 0
|
|
34
|
+
: textLabel.alignment === 'bottom'
|
|
35
|
+
? textLabel.size
|
|
36
|
+
: textLabel.size;
|
|
30
37
|
|
|
31
|
-
const
|
|
32
|
-
const yPadding = textLabel.size;
|
|
33
|
-
const radiusPadding = 1 + 1 / 4; // Padding based on point radius (radius/ 4)
|
|
38
|
+
const padding = defaultPadding;
|
|
34
39
|
|
|
35
40
|
return typeof getRadius === 'function'
|
|
36
41
|
? d => [
|
|
37
|
-
xMult * (getRadius(d) * radiusScale
|
|
38
|
-
yMult * (getRadius(d) * radiusScale
|
|
42
|
+
xMult * (getRadius(d) * radiusScale + padding),
|
|
43
|
+
yMult * (getRadius(d) * radiusScale + padding + sizeOffset)
|
|
39
44
|
]
|
|
40
45
|
: [
|
|
41
|
-
xMult * (getRadius * radiusScale
|
|
42
|
-
yMult * (getRadius * radiusScale
|
|
46
|
+
xMult * (getRadius * radiusScale + padding),
|
|
47
|
+
yMult * (getRadius * radiusScale + padding + sizeOffset)
|
|
43
48
|
];
|
|
44
49
|
};
|
|
45
50
|
}
|
|
@@ -49,9 +54,40 @@ export const textLabelAccessor = textLabel => dc => d => {
|
|
|
49
54
|
return notNullorUndefined(val) ? String(val) : '';
|
|
50
55
|
};
|
|
51
56
|
|
|
52
|
-
export const formatTextLabelData = ({
|
|
57
|
+
export const formatTextLabelData = ({
|
|
58
|
+
textLabel,
|
|
59
|
+
triggerChanged,
|
|
60
|
+
oldLayerData,
|
|
61
|
+
data,
|
|
62
|
+
dataContainer
|
|
63
|
+
}) => {
|
|
53
64
|
return textLabel.map((tl, i) => {
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
if (!tl.field) {
|
|
66
|
+
// if no field selected,
|
|
67
|
+
return {
|
|
68
|
+
getText: null,
|
|
69
|
+
characterSet: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const getText = textLabelAccessor(tl)(dataContainer);
|
|
74
|
+
let characterSet;
|
|
75
|
+
|
|
76
|
+
if (
|
|
77
|
+
!triggerChanged[`getLabelCharacterSet-${i}`] &&
|
|
78
|
+
oldLayerData &&
|
|
79
|
+
oldLayerData.textLabels &&
|
|
80
|
+
oldLayerData.textLabels[i]
|
|
81
|
+
) {
|
|
82
|
+
characterSet = oldLayerData.textLabels[i].characterSet;
|
|
83
|
+
} else {
|
|
84
|
+
const allLabels = tl.field ? data.map(getText) : [];
|
|
85
|
+
characterSet = uniq(allLabels.join(''));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
characterSet,
|
|
90
|
+
getText
|
|
91
|
+
};
|
|
56
92
|
});
|
|
57
93
|
};
|
|
@@ -29,7 +29,7 @@ import {findDefaultColorField} from 'utils/dataset-utils';
|
|
|
29
29
|
import PointLayerIcon from './point-layer-icon';
|
|
30
30
|
import {DEFAULT_LAYER_COLOR, CHANNEL_SCALES, UNKNOWN_COLOR} from 'constants/default-settings';
|
|
31
31
|
|
|
32
|
-
import {formatTextLabelData} from '../layer-text-label';
|
|
32
|
+
import {getTextOffsetByRadius, formatTextLabelData} from '../layer-text-label';
|
|
33
33
|
|
|
34
34
|
export const pointPosAccessor = ({lat, lng, altitude}) => dc => d => [
|
|
35
35
|
dc.valueAt(d.index, lng.fieldIdx),
|
|
@@ -47,7 +47,6 @@ export const pointVisConfigs = {
|
|
|
47
47
|
customMarkers: 'customMarkers',
|
|
48
48
|
customMarkersUrl: 'customMarkersUrl',
|
|
49
49
|
customMarkersRange: 'customMarkersRange',
|
|
50
|
-
labelsEnabled: 'labelsEnabled',
|
|
51
50
|
opacity: 'opacity',
|
|
52
51
|
outline: 'outline',
|
|
53
52
|
thickness: 'thickness',
|
|
@@ -243,7 +242,13 @@ export default class PointLayer extends Layer {
|
|
|
243
242
|
const getPosition = this.getPositionAccessor(dataContainer);
|
|
244
243
|
|
|
245
244
|
// get all distinct characters in the text labels
|
|
246
|
-
const textLabels = formatTextLabelData({
|
|
245
|
+
const textLabels = formatTextLabelData({
|
|
246
|
+
textLabel,
|
|
247
|
+
triggerChanged,
|
|
248
|
+
oldLayerData,
|
|
249
|
+
data,
|
|
250
|
+
dataContainer
|
|
251
|
+
});
|
|
247
252
|
|
|
248
253
|
const accessors = this.getAttributeAccessors({dataContainer});
|
|
249
254
|
|
|
@@ -273,12 +278,12 @@ export default class PointLayer extends Layer {
|
|
|
273
278
|
// eslint-disable-next-line complexity, max-statements
|
|
274
279
|
renderLayer(opts) {
|
|
275
280
|
const {data, gpuFilter, objectHovered, interactionConfig} = opts;
|
|
276
|
-
const {customMarkers, customMarkersUrl, customMarkersRange} = this.config.visConfig;
|
|
277
281
|
|
|
278
282
|
const radiusScale = this.getRadiusScale();
|
|
279
283
|
|
|
280
284
|
const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
|
|
281
285
|
const brushingProps = this.getBrushingExtensionProps(interactionConfig);
|
|
286
|
+
const getPixelOffset = getTextOffsetByRadius(radiusScale, data.getRadius);
|
|
282
287
|
const extensions = [...defaultLayerProps.extensions, brushingExtension];
|
|
283
288
|
|
|
284
289
|
const updateTriggers = {
|
|
@@ -291,7 +296,6 @@ export default class PointLayer extends Layer {
|
|
|
291
296
|
getFilterValue: data.getFilterValue,
|
|
292
297
|
extensions,
|
|
293
298
|
filterRange: defaultLayerProps.filterRange,
|
|
294
|
-
maskId: defaultLayerProps.maskId,
|
|
295
299
|
visible: defaultLayerProps.visible,
|
|
296
300
|
...brushingProps
|
|
297
301
|
};
|
|
@@ -301,9 +305,7 @@ export default class PointLayer extends Layer {
|
|
|
301
305
|
{
|
|
302
306
|
getPosition: data.getPosition,
|
|
303
307
|
sharedProps,
|
|
304
|
-
|
|
305
|
-
radiusScale: customMarkers ? radiusScale / 2 : radiusScale,
|
|
306
|
-
getRadius: data.getRadius,
|
|
308
|
+
getPixelOffset,
|
|
307
309
|
updateTriggers
|
|
308
310
|
},
|
|
309
311
|
opts
|
|
@@ -317,6 +319,7 @@ export default class PointLayer extends Layer {
|
|
|
317
319
|
};
|
|
318
320
|
|
|
319
321
|
const customMarkersField = this.config.customMarkersField;
|
|
322
|
+
const {customMarkers, customMarkersUrl, customMarkersRange} = this.config.visConfig;
|
|
320
323
|
const customMarkersConfigured =
|
|
321
324
|
customMarkers && Boolean(customMarkersUrl || (customMarkersField && customMarkersRange));
|
|
322
325
|
const customMarkersMisConfigured = customMarkers && !customMarkersConfigured;
|
package/src/localization/en.js
CHANGED
|
@@ -68,14 +68,12 @@ export default {
|
|
|
68
68
|
panel: {
|
|
69
69
|
text: {
|
|
70
70
|
label: 'label',
|
|
71
|
-
|
|
72
|
-
secondaryLabel: 'Secondary Label',
|
|
71
|
+
labelWithId: 'Label {labelId}',
|
|
73
72
|
fontSize: 'Font size',
|
|
74
73
|
fontColor: 'Font color',
|
|
75
|
-
outlineColor: 'Outline color',
|
|
76
74
|
textAnchor: 'Text anchor',
|
|
77
75
|
alignment: 'Alignment',
|
|
78
|
-
addMoreLabel: 'Add
|
|
76
|
+
addMoreLabel: 'Add More Label'
|
|
79
77
|
}
|
|
80
78
|
},
|
|
81
79
|
sidebar: {
|
|
@@ -159,7 +157,6 @@ export default {
|
|
|
159
157
|
highPrecisionRenderingDescription: 'High precision will result in slower performance',
|
|
160
158
|
height: 'Height',
|
|
161
159
|
heightDescription: 'Click button at top right of the map to switch to 3d view',
|
|
162
|
-
labels: 'Labels',
|
|
163
160
|
fill: 'Fill',
|
|
164
161
|
enablePolygonHeight: 'Enable Polygon Height',
|
|
165
162
|
showWireframe: 'Show Wireframe',
|
|
@@ -288,7 +288,10 @@ export function getFieldsFromData(data, fieldOrder) {
|
|
|
288
288
|
// add a check for epoch timestamp
|
|
289
289
|
const metadata = Analyzer.computeColMeta(
|
|
290
290
|
data,
|
|
291
|
-
[
|
|
291
|
+
[
|
|
292
|
+
{regex: /.*geojson|all_points/g, dataType: 'GEOMETRY'},
|
|
293
|
+
{regex: /.*census/g, dataType: 'STRING'}
|
|
294
|
+
],
|
|
292
295
|
{ignoredDataTypes: IGNORE_DATA_TYPES}
|
|
293
296
|
);
|
|
294
297
|
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
} from 'utils/split-map-utils';
|
|
77
77
|
|
|
78
78
|
import {Layer, LayerClasses, LAYER_ID_LENGTH} from 'layers';
|
|
79
|
-
import {DEFAULT_TEXT_LABEL
|
|
79
|
+
import {DEFAULT_TEXT_LABEL} from 'layers/layer-factory';
|
|
80
80
|
import {EDITOR_MODES, SORT_ORDER, FILTER_TYPES} from 'constants/default-settings';
|
|
81
81
|
import {pick_, merge_, swap_} from './composer-helpers';
|
|
82
82
|
import {processFileContent} from 'actions/vis-state-actions';
|
|
@@ -315,19 +315,16 @@ function addOrRemoveTextLabels(newFields, textLabel) {
|
|
|
315
315
|
|
|
316
316
|
// delete
|
|
317
317
|
newTextLabel = newTextLabel.filter(tl => tl.field && !deleteFields.includes(tl.field.name));
|
|
318
|
+
newTextLabel = !newTextLabel.length ? [DEFAULT_TEXT_LABEL] : newTextLabel;
|
|
318
319
|
|
|
319
320
|
// add
|
|
320
|
-
newTextLabel =
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// default
|
|
330
|
-
newTextLabel = !newTextLabel.length ? [DEFAULT_TEXT_LABEL] : newTextLabel;
|
|
321
|
+
newTextLabel = [
|
|
322
|
+
...newTextLabel.filter(tl => tl.field),
|
|
323
|
+
...addFields.map(af => ({
|
|
324
|
+
...DEFAULT_TEXT_LABEL,
|
|
325
|
+
field: af
|
|
326
|
+
}))
|
|
327
|
+
];
|
|
331
328
|
|
|
332
329
|
return newTextLabel;
|
|
333
330
|
}
|
|
@@ -362,7 +359,7 @@ export function layerTextLabelChangeUpdater(state, action) {
|
|
|
362
359
|
let newTextLabel = textLabel.slice();
|
|
363
360
|
if (!textLabel[idx] && idx === textLabel.length) {
|
|
364
361
|
// if idx is set to length, add empty text label
|
|
365
|
-
newTextLabel = [...textLabel,
|
|
362
|
+
newTextLabel = [...textLabel, DEFAULT_TEXT_LABEL];
|
|
366
363
|
}
|
|
367
364
|
|
|
368
365
|
if (idx === 'all' && prop === 'fields') {
|