@carto/kepler.gl 0.0.65-alpha.labels → 0.0.65-alpha.labels.10
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/components/side-panel/layer-panel/layer-config-group.js +3 -3
- package/dist/components/side-panel/layer-panel/text-label-panel.js +67 -81
- package/dist/constants/default-settings.js +2 -2
- package/dist/layers/base-layer.js +112 -224
- package/dist/layers/layer-factory.js +19 -23
- package/dist/layers/layer-text-label.js +9 -32
- package/dist/layers/point-layer/point-layer.js +5 -7
- package/dist/localization/en.js +3 -3
- package/dist/reducers/vis-state-updaters.js +16 -8
- package/package.json +9 -8
- package/src/.index.js.swp +0 -0
- package/src/components/side-panel/layer-panel/layer-config-group.js +2 -2
- package/src/components/side-panel/layer-panel/text-label-panel.js +0 -10
- package/src/layers/base-layer.js +78 -145
- package/src/layers/layer-factory.js +8 -1
- package/src/layers/layer-text-label.js +11 -48
- package/src/layers/point-layer/point-layer.js +6 -14
- package/src/localization/en.js +2 -2
- package/src/reducers/vis-state-updaters.js +13 -10
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.65-alpha.labels",
|
|
5
|
+
"version": "0.0.65-alpha.labels.10",
|
|
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",
|
|
@@ -238,13 +238,14 @@
|
|
|
238
238
|
"tough-cookie": "4.0.0"
|
|
239
239
|
},
|
|
240
240
|
"peerDependencies": {
|
|
241
|
-
"@deck.gl/aggregation-layers": "^8.
|
|
242
|
-
"@deck.gl/
|
|
243
|
-
"@deck.gl/
|
|
244
|
-
"@deck.gl/
|
|
245
|
-
"@deck.gl/layers": "^8.
|
|
246
|
-
"@deck.gl/
|
|
247
|
-
"@deck.gl/
|
|
241
|
+
"@deck.gl/aggregation-layers": "^8.9.5",
|
|
242
|
+
"@deck.gl/carto": "^8.9.5",
|
|
243
|
+
"@deck.gl/core": "^8.9.5",
|
|
244
|
+
"@deck.gl/extensions": "^8.9.5",
|
|
245
|
+
"@deck.gl/geo-layers": "^8.9.5",
|
|
246
|
+
"@deck.gl/layers": "^8.9.5",
|
|
247
|
+
"@deck.gl/mesh-layers": "^8.9.5",
|
|
248
|
+
"@deck.gl/react": "^8.9.5",
|
|
248
249
|
"@loaders.gl/core": "^3.1.5",
|
|
249
250
|
"@loaders.gl/csv": "^3.1.5",
|
|
250
251
|
"@loaders.gl/gltf": "^3.1.5",
|
|
Binary file
|
|
@@ -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: 650px;
|
|
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: 650px;
|
|
66
66
|
}
|
|
67
67
|
.layer-config-group__content {
|
|
68
68
|
.layer-config-group__content__collapsible {
|
|
@@ -69,16 +69,6 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
|
|
|
69
69
|
const currentFields = textLabel.map(tl => tl.field && tl.field.name).filter(d => d);
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
// Switch only works with group/property set to customMarkers???
|
|
73
|
-
/* <LayerConfigGroup
|
|
74
|
-
type="boolean"
|
|
75
|
-
disabled={undefined}
|
|
76
|
-
layer={layer}
|
|
77
|
-
group="labels"
|
|
78
|
-
property="labelsEnabled"
|
|
79
|
-
label="panel.text.label"
|
|
80
|
-
collapsible
|
|
81
|
-
>*/
|
|
82
72
|
<LayerConfigGroup label={'panel.text.label'} collapsible>
|
|
83
73
|
<ConfigGroupCollapsibleHeader>
|
|
84
74
|
<FieldSelector
|
package/src/layers/base-layer.js
CHANGED
|
@@ -22,53 +22,7 @@ import {console as Console} from 'global/window';
|
|
|
22
22
|
import keymirror from 'keymirror';
|
|
23
23
|
import {CollisionFilterExtension, DataFilterExtension} from '@deck.gl/extensions';
|
|
24
24
|
import {COORDINATE_SYSTEM, Layer as DeckLayer} from '@deck.gl/core';
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
// TODO remove prior to release
|
|
28
|
-
const SHOW_TEXT_BORDER = false;
|
|
29
|
-
|
|
30
|
-
const [LEFT, TOP, RIGHT, BOTTOM] = [0, 1, 2, 3];
|
|
31
|
-
class EnhancedTextLayer extends TextLayer {
|
|
32
|
-
filterSubLayer({layer, renderPass}) {
|
|
33
|
-
const background = layer.id.includes('background');
|
|
34
|
-
if (renderPass === 'collision') {
|
|
35
|
-
return background; // Only draw background layer in collision pass
|
|
36
|
-
} else {
|
|
37
|
-
return !background || (SHOW_TEXT_BORDER && this.props.getBorderWidth); // Do not draw background layer in other passes
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Workaround until https://github.com/visgl/deck.gl/pull/7513 is released
|
|
43
|
-
DeckLayer.defaultProps.getFilterValue = {type: 'accessor', value: 0};
|
|
44
|
-
|
|
45
|
-
// Workaround until https://github.com/visgl/deck.gl/pull/7507 is released
|
|
46
|
-
function deepEqual(a, b) {
|
|
47
|
-
if (a === b) {
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
if (!a || !b) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
for (const key in a) {
|
|
54
|
-
const aValue = a[key];
|
|
55
|
-
const bValue = b[key];
|
|
56
|
-
const equals = aValue === bValue || deepEqual(aValue, bValue);
|
|
57
|
-
if (!equals) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
DeckLayer.defaultProps.loadOptions = {
|
|
65
|
-
type: 'object',
|
|
66
|
-
value: {},
|
|
67
|
-
optional: true,
|
|
68
|
-
compare: true,
|
|
69
|
-
equal: deepEqual
|
|
70
|
-
};
|
|
71
|
-
|
|
25
|
+
import {_PointLabelLayer as PointLabelLayer} from '@deck.gl/carto';
|
|
72
26
|
import DefaultLayerIcon from './default-layer-icon';
|
|
73
27
|
import {diffUpdateTriggers} from './layer-update';
|
|
74
28
|
|
|
@@ -1357,110 +1311,89 @@ class Layer {
|
|
|
1357
1311
|
};
|
|
1358
1312
|
}
|
|
1359
1313
|
|
|
1360
|
-
renderTextLabelLayer(
|
|
1314
|
+
renderTextLabelLayer(
|
|
1315
|
+
{getPosition, getRadius, radiusScale, updateTriggers, sharedProps},
|
|
1316
|
+
renderOpts
|
|
1317
|
+
) {
|
|
1361
1318
|
const {data, mapState} = renderOpts;
|
|
1362
1319
|
const {textLabel, visibilityByZoom} = this.config;
|
|
1363
|
-
// const extensions = [...sharedProps.extensions];
|
|
1364
1320
|
const extensions = [...sharedProps.extensions, collisionFilterExtension];
|
|
1365
1321
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
const mainLabel = textLabel[0];
|
|
1370
|
-
const {alignment, anchor, size} = mainLabel;
|
|
1371
|
-
// Heuristics to avoid label overlap (should we base this on the text length?)
|
|
1372
|
-
const paddingX = 12 * size;
|
|
1373
|
-
const paddingY = 3 * size;
|
|
1374
|
-
const backgroundPadding = [0, 0, 0, 0];
|
|
1375
|
-
if (alignment === 'top') {
|
|
1376
|
-
backgroundPadding[TOP] = paddingY;
|
|
1377
|
-
} else if (alignment === 'bottom') {
|
|
1378
|
-
backgroundPadding[BOTTOM] = paddingY;
|
|
1379
|
-
} else {
|
|
1380
|
-
backgroundPadding[TOP] = 0.5 * paddingY;
|
|
1381
|
-
backgroundPadding[BOTTOM] = 0.5 * paddingY;
|
|
1382
|
-
}
|
|
1383
|
-
if (anchor === 'start') {
|
|
1384
|
-
backgroundPadding[LEFT] = paddingX;
|
|
1385
|
-
} else if (anchor === 'end') {
|
|
1386
|
-
backgroundPadding[RIGHT] = paddingX;
|
|
1387
|
-
} else {
|
|
1388
|
-
backgroundPadding[LEFT] = 0.5 * paddingX;
|
|
1389
|
-
backgroundPadding[RIGHT] = 0.5 * paddingX;
|
|
1390
|
-
}
|
|
1322
|
+
if (!data || !data.textLabels || !data.textLabels[0] || !data.textLabels[0].getText) {
|
|
1323
|
+
return [];
|
|
1324
|
+
}
|
|
1391
1325
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1326
|
+
const [mainLabel, secondaryLabel] = textLabel;
|
|
1327
|
+
const {
|
|
1328
|
+
alignment,
|
|
1329
|
+
anchor,
|
|
1330
|
+
color: getColor,
|
|
1331
|
+
field: mainField,
|
|
1332
|
+
outlineColor,
|
|
1333
|
+
size: sizeScale
|
|
1334
|
+
} = mainLabel;
|
|
1335
|
+
const {
|
|
1336
|
+
color: getSecondaryColor,
|
|
1337
|
+
field: secondaryField,
|
|
1338
|
+
outlineColor: secondaryOutlineColor,
|
|
1339
|
+
size: secondarySizeScale
|
|
1340
|
+
} = secondaryLabel || {};
|
|
1341
|
+
|
|
1342
|
+
return [
|
|
1343
|
+
new PointLabelLayer({
|
|
1344
|
+
...sharedProps,
|
|
1345
|
+
|
|
1346
|
+
// Recreate layer when labels change otherwise rendering breaks
|
|
1347
|
+
// TODO could be more efficient with updateTriggers?
|
|
1348
|
+
id: `${this.id}-${mainField?.name}-${secondaryField?.name}-label`,
|
|
1349
|
+
data: data.data,
|
|
1350
|
+
visibilityByZoom,
|
|
1351
|
+
extensions,
|
|
1352
|
+
|
|
1353
|
+
characterSet: 'auto',
|
|
1354
|
+
collisionEnabled: true,
|
|
1355
|
+
collisionGroup: `${this.id}-labels`,
|
|
1356
|
+
|
|
1357
|
+
getText: data.textLabels[0].getText,
|
|
1358
|
+
getColor,
|
|
1359
|
+
sizeScale,
|
|
1360
|
+
outlineColor,
|
|
1361
|
+
|
|
1362
|
+
...(secondaryField && {
|
|
1363
|
+
getSecondaryText: data.textLabels[1].getText,
|
|
1364
|
+
getSecondaryColor,
|
|
1365
|
+
secondarySizeScale,
|
|
1366
|
+
secondaryOutlineColor
|
|
1367
|
+
}),
|
|
1397
1368
|
|
|
1398
|
-
//
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
// DEBUG
|
|
1428
|
-
...(SHOW_TEXT_BORDER && {
|
|
1429
|
-
getBorderColor: [255, 0, 0, 80],
|
|
1430
|
-
getBackgroundColor: [0, 0, 0, 0],
|
|
1431
|
-
getBorderWidth: 1
|
|
1432
|
-
}),
|
|
1433
|
-
|
|
1434
|
-
getColor: textLabel[i].color,
|
|
1435
|
-
fontFamily: 'Inter, sans',
|
|
1436
|
-
fontSettings: {sdf: true},
|
|
1437
|
-
fontWeight: 500,
|
|
1438
|
-
outlineColor: textLabel[i].outlineColor,
|
|
1439
|
-
outlineWidth: 4, // 1 seems to be thinner than 1px in CSS
|
|
1440
|
-
parameters: {
|
|
1441
|
-
// text will always show on top of all layers
|
|
1442
|
-
depthTest: false
|
|
1443
|
-
},
|
|
1444
|
-
|
|
1445
|
-
getFilterValue: data.getFilterValue,
|
|
1446
|
-
updateTriggers: {
|
|
1447
|
-
...updateTriggers,
|
|
1448
|
-
getText: textLabel[i].field?.name,
|
|
1449
|
-
getPixelOffset: {
|
|
1450
|
-
...updateTriggers.getPixelOffset,
|
|
1451
|
-
...updateTriggers.getRadius,
|
|
1452
|
-
anchor: mainLabel.anchor,
|
|
1453
|
-
alignment: mainLabel.alignment
|
|
1454
|
-
},
|
|
1455
|
-
getTextAnchor: mainLabel.anchor,
|
|
1456
|
-
getAlignmentBaseline: mainLabel.alignment,
|
|
1457
|
-
getColor: textLabel[i].color
|
|
1458
|
-
}
|
|
1459
|
-
})
|
|
1460
|
-
);
|
|
1461
|
-
}
|
|
1462
|
-
return accu;
|
|
1463
|
-
}, []);
|
|
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
|
+
];
|
|
1464
1397
|
}
|
|
1465
1398
|
|
|
1466
1399
|
/**
|
|
@@ -45,13 +45,20 @@ export {DEFAULT_COLOR_RANGE};
|
|
|
45
45
|
export const DEFAULT_TEXT_LABEL = {
|
|
46
46
|
field: null,
|
|
47
47
|
color: [44, 48, 50],
|
|
48
|
-
outlineColor: [
|
|
48
|
+
outlineColor: [255, 255, 255],
|
|
49
49
|
size: 12,
|
|
50
50
|
offset: [0, 0],
|
|
51
51
|
anchor: 'start',
|
|
52
52
|
alignment: 'center'
|
|
53
53
|
};
|
|
54
54
|
|
|
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
|
+
|
|
55
62
|
/** @type {import('./layer-factory').ColorRange} */
|
|
56
63
|
export const DEFAULT_CUSTOM_PALETTE = {
|
|
57
64
|
name: 'color.customPalette',
|
|
@@ -21,31 +21,25 @@
|
|
|
21
21
|
import {notNullorUndefined} from 'utils/data-utils';
|
|
22
22
|
import uniq from 'lodash.uniq';
|
|
23
23
|
|
|
24
|
-
export const defaultPadding = 20;
|
|
25
|
-
|
|
26
24
|
export function getTextOffsetByRadius(radiusScale, getRadius) {
|
|
27
25
|
return textLabel => {
|
|
28
26
|
const xMult = textLabel.anchor === 'middle' ? 0 : textLabel.anchor === 'start' ? 1 : -1;
|
|
29
27
|
const yMult = textLabel.alignment === 'center' ? 0 : textLabel.alignment === 'bottom' ? 1 : -1;
|
|
30
28
|
|
|
31
|
-
const sizeOffset =
|
|
32
|
-
textLabel.alignment === 'center'
|
|
33
|
-
? 0
|
|
34
|
-
: textLabel.alignment === 'bottom'
|
|
35
|
-
? textLabel.size
|
|
36
|
-
: textLabel.size;
|
|
29
|
+
const sizeOffset = Math.abs(yMult * textLabel.size);
|
|
37
30
|
|
|
38
|
-
const
|
|
39
|
-
const
|
|
31
|
+
const xPadding = textLabel.size / 4; // Padding based on font size (font size / 4)
|
|
32
|
+
const yPadding = textLabel.size;
|
|
33
|
+
const radiusPadding = 1 + 1 / 4; // Padding based on point radius (radius/ 4)
|
|
40
34
|
|
|
41
35
|
return typeof getRadius === 'function'
|
|
42
36
|
? d => [
|
|
43
|
-
xMult * (getRadius(d) * radiusScale *
|
|
44
|
-
yMult * (getRadius(d) * radiusScale *
|
|
37
|
+
xMult * (getRadius(d) * radiusScale * radiusPadding + xPadding),
|
|
38
|
+
yMult * (getRadius(d) * radiusScale * radiusPadding + yPadding)
|
|
45
39
|
]
|
|
46
40
|
: [
|
|
47
|
-
xMult * (getRadius * radiusScale *
|
|
48
|
-
yMult * (getRadius * radiusScale *
|
|
41
|
+
xMult * (getRadius * radiusScale * radiusPadding + xPadding),
|
|
42
|
+
yMult * (getRadius * radiusScale * radiusPadding + yPadding)
|
|
49
43
|
];
|
|
50
44
|
};
|
|
51
45
|
}
|
|
@@ -55,40 +49,9 @@ export const textLabelAccessor = textLabel => dc => d => {
|
|
|
55
49
|
return notNullorUndefined(val) ? String(val) : '';
|
|
56
50
|
};
|
|
57
51
|
|
|
58
|
-
export const formatTextLabelData = ({
|
|
59
|
-
textLabel,
|
|
60
|
-
triggerChanged,
|
|
61
|
-
oldLayerData,
|
|
62
|
-
data,
|
|
63
|
-
dataContainer
|
|
64
|
-
}) => {
|
|
52
|
+
export const formatTextLabelData = ({textLabel, dataContainer}) => {
|
|
65
53
|
return textLabel.map((tl, i) => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
getText: null,
|
|
70
|
-
characterSet: []
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const getText = textLabelAccessor(tl)(dataContainer);
|
|
75
|
-
let characterSet;
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
!triggerChanged[`getLabelCharacterSet-${i}`] &&
|
|
79
|
-
oldLayerData &&
|
|
80
|
-
oldLayerData.textLabels &&
|
|
81
|
-
oldLayerData.textLabels[i]
|
|
82
|
-
) {
|
|
83
|
-
characterSet = oldLayerData.textLabels[i].characterSet;
|
|
84
|
-
} else {
|
|
85
|
-
const allLabels = tl.field ? data.map(getText) : [];
|
|
86
|
-
characterSet = uniq(allLabels.join(''));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
characterSet,
|
|
91
|
-
getText
|
|
92
|
-
};
|
|
54
|
+
const getText = tl.field ? textLabelAccessor(tl)(dataContainer) : null;
|
|
55
|
+
return {getText};
|
|
93
56
|
});
|
|
94
57
|
};
|
|
@@ -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 {
|
|
32
|
+
import {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),
|
|
@@ -243,13 +243,7 @@ export default class PointLayer extends Layer {
|
|
|
243
243
|
const getPosition = this.getPositionAccessor(dataContainer);
|
|
244
244
|
|
|
245
245
|
// get all distinct characters in the text labels
|
|
246
|
-
const textLabels = formatTextLabelData({
|
|
247
|
-
textLabel,
|
|
248
|
-
triggerChanged,
|
|
249
|
-
oldLayerData,
|
|
250
|
-
data,
|
|
251
|
-
dataContainer
|
|
252
|
-
});
|
|
246
|
+
const textLabels = formatTextLabelData({textLabel, dataContainer});
|
|
253
247
|
|
|
254
248
|
const accessors = this.getAttributeAccessors({dataContainer});
|
|
255
249
|
|
|
@@ -285,11 +279,6 @@ export default class PointLayer extends Layer {
|
|
|
285
279
|
|
|
286
280
|
const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
|
|
287
281
|
const brushingProps = this.getBrushingExtensionProps(interactionConfig);
|
|
288
|
-
const getPixelOffset = getTextOffsetByRadius(
|
|
289
|
-
// TODO remove this scaling by half here and elsewhere
|
|
290
|
-
customMarkers ? radiusScale / 2 : radiusScale,
|
|
291
|
-
data.getRadius
|
|
292
|
-
);
|
|
293
282
|
const extensions = [...defaultLayerProps.extensions, brushingExtension];
|
|
294
283
|
|
|
295
284
|
const updateTriggers = {
|
|
@@ -302,6 +291,7 @@ export default class PointLayer extends Layer {
|
|
|
302
291
|
getFilterValue: data.getFilterValue,
|
|
303
292
|
extensions,
|
|
304
293
|
filterRange: defaultLayerProps.filterRange,
|
|
294
|
+
maskId: defaultLayerProps.maskId,
|
|
305
295
|
visible: defaultLayerProps.visible,
|
|
306
296
|
...brushingProps
|
|
307
297
|
};
|
|
@@ -311,7 +301,9 @@ export default class PointLayer extends Layer {
|
|
|
311
301
|
{
|
|
312
302
|
getPosition: data.getPosition,
|
|
313
303
|
sharedProps,
|
|
314
|
-
|
|
304
|
+
// TODO remove this scaling by half here and elsewhere
|
|
305
|
+
radiusScale: customMarkers ? radiusScale / 2 : radiusScale,
|
|
306
|
+
getRadius: data.getRadius,
|
|
315
307
|
updateTriggers
|
|
316
308
|
},
|
|
317
309
|
opts
|
package/src/localization/en.js
CHANGED
|
@@ -72,10 +72,10 @@ export default {
|
|
|
72
72
|
secondaryLabel: 'Secondary Label',
|
|
73
73
|
fontSize: 'Font size',
|
|
74
74
|
fontColor: 'Font color',
|
|
75
|
-
outlineColor: 'Outline
|
|
75
|
+
outlineColor: 'Outline color',
|
|
76
76
|
textAnchor: 'Text anchor',
|
|
77
77
|
alignment: 'Alignment',
|
|
78
|
-
addMoreLabel: 'Add
|
|
78
|
+
addMoreLabel: 'Add secondary label'
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
sidebar: {
|
|
@@ -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} from 'layers/layer-factory';
|
|
79
|
+
import {DEFAULT_TEXT_LABEL, DEFAULT_SECONDARY_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,16 +315,19 @@ 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;
|
|
319
318
|
|
|
320
319
|
// add
|
|
321
|
-
newTextLabel =
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
320
|
+
newTextLabel = newTextLabel.filter(tl => tl.field);
|
|
321
|
+
const defaultLabel = newTextLabel.length ? DEFAULT_SECONDARY_TEXT_LABEL : DEFAULT_TEXT_LABEL;
|
|
322
|
+
newTextLabel = [...newTextLabel, ...addFields.map(af => ({...defaultLabel, field: af}))];
|
|
323
|
+
|
|
324
|
+
// limit to 2 labels (overwrite 2nd label with 3rd)
|
|
325
|
+
if (newTextLabel.length > 2) {
|
|
326
|
+
newTextLabel = [newTextLabel[0], newTextLabel[2]];
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// default
|
|
330
|
+
newTextLabel = !newTextLabel.length ? [DEFAULT_TEXT_LABEL] : newTextLabel;
|
|
328
331
|
|
|
329
332
|
return newTextLabel;
|
|
330
333
|
}
|
|
@@ -359,7 +362,7 @@ export function layerTextLabelChangeUpdater(state, action) {
|
|
|
359
362
|
let newTextLabel = textLabel.slice();
|
|
360
363
|
if (!textLabel[idx] && idx === textLabel.length) {
|
|
361
364
|
// if idx is set to length, add empty text label
|
|
362
|
-
newTextLabel = [...textLabel, DEFAULT_TEXT_LABEL];
|
|
365
|
+
newTextLabel = [...textLabel, idx === 0 ? DEFAULT_TEXT_LABEL : DEFAULT_SECONDARY_TEXT_LABEL];
|
|
363
366
|
}
|
|
364
367
|
|
|
365
368
|
if (idx === 'all' && prop === 'fields') {
|