@carto/kepler.gl 0.0.64 → 0.0.65-alpha.labels.2

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.
@@ -65,9 +65,20 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
65
65
  };
66
66
 
67
67
  render() {
68
- const {updateLayerTextLabel, textLabel, fields, AddButton} = this.props;
68
+ const {layer, updateLayerTextLabel, textLabel, fields, AddButton} = this.props;
69
69
  const currentFields = textLabel.map(tl => tl.field && tl.field.name).filter(d => d);
70
+
70
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
+ >*/
71
82
  <LayerConfigGroup label={'panel.text.label'} collapsible>
72
83
  <ConfigGroupCollapsibleHeader>
73
84
  <FieldSelector
@@ -80,11 +91,11 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
80
91
  <ConfigGroupCollapsibleContent>
81
92
  {textLabel.map((tl, idx) => (
82
93
  <div
83
- key={tl.field ? tl.field.name : `null-${idx}`}
94
+ key={`${tl.field ? tl.field.name : 'null'}-${idx}`}
84
95
  className="side-panel-section-group"
85
96
  >
86
97
  <PanelLabel>
87
- <FormattedMessage id={'panel.text.labelWithId'} values={{labelId: idx + 1}} />
98
+ <FormattedMessage id={`panel.text.${idx === 0 ? 'main' : 'secondary'}Label`} />
88
99
  </PanelLabel>
89
100
  <SidePanelSection>
90
101
  <FieldSelector
@@ -120,33 +131,51 @@ function TextLabelPanelFactory(RangeSlider, LayerConfigGroup, FieldSelector, Col
120
131
  />
121
132
  </SidePanelSection>
122
133
  <SidePanelSection>
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>
134
+ <PanelLabel>
135
+ <FormattedMessage id="panel.text.outlineColor" />
136
+ </PanelLabel>
137
+ <ColorSelector
138
+ colorSets={[
139
+ {
140
+ selectedColor: tl.outlineColor,
141
+ setColor: v => updateLayerTextLabel(idx, 'outlineColor', v)
142
+ }
143
+ ]}
144
+ />
145
145
  </SidePanelSection>
146
+ {idx === 0 && (
147
+ <SidePanelSection>
148
+ <SpaceBetweenFlexbox>
149
+ <SBFlexboxItem>
150
+ <PanelLabel>
151
+ <FormattedMessage id="panel.text.textAnchor" />
152
+ </PanelLabel>
153
+ <ItemSelector
154
+ {...LAYER_TEXT_CONFIGS.textAnchor}
155
+ selectedItems={tl.anchor}
156
+ onChange={val => updateLayerTextLabel(idx, 'anchor', val)}
157
+ />
158
+ </SBFlexboxItem>
159
+ <SBFlexboxItem>
160
+ <PanelLabel>
161
+ <FormattedMessage id="panel.text.alignment" />
162
+ </PanelLabel>
163
+ <ItemSelector
164
+ {...LAYER_TEXT_CONFIGS.textAlignment}
165
+ selectedItems={tl.alignment}
166
+ onChange={val => updateLayerTextLabel(idx, 'alignment', val)}
167
+ />
168
+ </SBFlexboxItem>
169
+ </SpaceBetweenFlexbox>
170
+ </SidePanelSection>
171
+ )}
146
172
  </div>
147
173
  ))}
148
174
  <SidePanelSection>
149
- <AddButton onClick={val => updateLayerTextLabel(textLabel.length)} />
175
+ <AddButton
176
+ disabled={textLabel.length >= 2}
177
+ onClick={val => updateLayerTextLabel(textLabel.length)}
178
+ />
150
179
  </SidePanelSection>
151
180
  </ConfigGroupCollapsibleContent>
152
181
  </LayerConfigGroup>
@@ -0,0 +1,174 @@
1
+ import {CompositeLayer} from '@deck.gl/core';
2
+ import {TextLayer} from '@deck.gl/layers';
3
+
4
+ // TODO remove prior to release
5
+ const SHOW_TEXT_BORDER = false;
6
+
7
+ const [LEFT, TOP, RIGHT, BOTTOM] = [0, 1, 2, 3];
8
+ class EnhancedTextLayer extends TextLayer {
9
+ filterSubLayer({layer, renderPass}) {
10
+ const background = layer.id.includes('primary-background');
11
+ if (renderPass === 'collision') {
12
+ return background; // Only draw primary background layer in collision pass
13
+ } else {
14
+ return !background || (SHOW_TEXT_BORDER && this.props.getBorderWidth); // Do not draw background layer in other passes
15
+ }
16
+ }
17
+ }
18
+
19
+ // TODO fix in deck.gl
20
+ TextLayer.defaultProps.fontSettings = {type: 'object', value: {}, optional: true, compare: 2};
21
+
22
+ const defaultProps = {
23
+ ...TextLayer.defaultProps,
24
+ getRadius: {type: 'accessor', value: 1},
25
+ radiusScale: {type: 'number', min: 0, value: 1}
26
+ };
27
+
28
+ export class PointLabelLayer extends CompositeLayer {
29
+ static defaultProps = defaultProps;
30
+
31
+ calculatePixelOffset(secondary) {
32
+ const {
33
+ getTextAnchor: anchor,
34
+ getAlignmentBaseline: alignment,
35
+ getRadius,
36
+ radiusScale,
37
+ sizeScale
38
+ } = this.props;
39
+ const xMult = anchor === 'middle' ? 0 : anchor === 'start' ? 1 : -1;
40
+ const yMult = alignment === 'center' ? 0 : alignment === 'bottom' ? 1 : -1;
41
+
42
+ // Place secondary label under main label (spacing 1 / 3 main label font size)
43
+ const yOffset = secondary ? (1 + 1 / 3) * sizeScale : 0;
44
+ const xPadding = sizeScale / 4; // Padding based on font size (font size / 4)
45
+ const yPadding = sizeScale;
46
+ const radiusPadding = 1 + 1 / 4; // Padding based on point radius (radius/ 4)
47
+
48
+ return typeof getRadius === 'function'
49
+ ? d => {
50
+ const r = (d ? getRadius(d) : 1) * radiusScale * radiusPadding;
51
+ return [xMult * (r + xPadding), yMult * (r + yPadding) + yOffset];
52
+ }
53
+ : [
54
+ xMult * (getRadius * radiusScale * radiusPadding + xPadding),
55
+ yMult * (getRadius * radiusScale * radiusPadding + yPadding) + yOffset
56
+ ];
57
+ }
58
+
59
+ calculateBackgroundPadding(getPixelOffset) {
60
+ // Alignment based only on first label
61
+ const {alignment, anchor, sizeScale} = this.props;
62
+
63
+ // Heuristics to avoid label overlap (should we base this on the text length?)
64
+ const paddingX = 12 * sizeScale;
65
+ const paddingY = 3 * sizeScale;
66
+ const backgroundPadding = [0, 0, 0, 0];
67
+ if (alignment === 'top') {
68
+ backgroundPadding[TOP] = paddingY;
69
+ } else if (alignment === 'bottom') {
70
+ backgroundPadding[BOTTOM] = paddingY;
71
+ } else {
72
+ backgroundPadding[TOP] = 0.5 * paddingY;
73
+ backgroundPadding[BOTTOM] = 0.5 * paddingY;
74
+ }
75
+ if (anchor === 'start') {
76
+ backgroundPadding[LEFT] = paddingX;
77
+ } else if (anchor === 'end') {
78
+ backgroundPadding[RIGHT] = paddingX;
79
+ } else {
80
+ backgroundPadding[LEFT] = 0.5 * paddingX;
81
+ backgroundPadding[RIGHT] = 0.5 * paddingX;
82
+ }
83
+
84
+ // For getRadius function, invoke without data, as there is no backgroundPadding accessor
85
+ const pixelOffset = Array.isArray(getPixelOffset) ? getPixelOffset : getPixelOffset();
86
+ backgroundPadding[LEFT] += pixelOffset[0];
87
+ backgroundPadding[RIGHT] -= pixelOffset[0];
88
+ backgroundPadding[TOP] += pixelOffset[1];
89
+ backgroundPadding[BOTTOM] -= pixelOffset[1];
90
+
91
+ return backgroundPadding;
92
+ }
93
+
94
+ renderTextLayer(id, props) {
95
+ const {
96
+ data,
97
+
98
+ fontFamily,
99
+ fontSettings,
100
+ fontWeight,
101
+ outlineColor,
102
+ outlineWidth,
103
+ sizeScale,
104
+
105
+ getAlignmentBaseline,
106
+ getColor,
107
+ getPosition,
108
+ getTextAnchor,
109
+
110
+ updateTriggers
111
+ } = this.props;
112
+
113
+ return new EnhancedTextLayer(
114
+ this.getSubLayerProps({
115
+ id,
116
+ data: data,
117
+
118
+ fontFamily,
119
+ fontSettings,
120
+ fontWeight,
121
+ outlineColor,
122
+ outlineWidth,
123
+ sizeScale,
124
+
125
+ getAlignmentBaseline,
126
+ getColor,
127
+ getPosition,
128
+ getTextAnchor,
129
+
130
+ updateTriggers
131
+ }),
132
+ {
133
+ getSize: 1
134
+ },
135
+ // DEBUG
136
+ SHOW_TEXT_BORDER
137
+ ? {getBackgroundColor: [0, 0, 0, 0], getBorderColor: [255, 0, 0, 80], getBorderWidth: 1}
138
+ : {},
139
+ props
140
+ );
141
+ }
142
+
143
+ renderLayers() {
144
+ const {
145
+ getText,
146
+ getSecondaryColor,
147
+ getSecondaryText,
148
+ secondaryOutlineColor,
149
+ secondarySizeScale
150
+ } = this.props;
151
+ const getPixelOffset = this.calculatePixelOffset();
152
+ const backgroundPadding = this.calculateBackgroundPadding(getPixelOffset);
153
+ const out = [
154
+ this.renderTextLayer('primary', {
155
+ backgroundPadding,
156
+ getText,
157
+ getPixelOffset,
158
+ background: true // Only use background for primary label for faster collisions
159
+ }),
160
+ getSecondaryText &&
161
+ this.renderTextLayer('secondary', {
162
+ getText: getSecondaryText,
163
+ getPixelOffset: this.calculatePixelOffset(true),
164
+
165
+ // Optional overrides
166
+ ...(getSecondaryColor && {getColor: getSecondaryColor}),
167
+ ...(secondarySizeScale && {sizeScale: secondarySizeScale}),
168
+ ...(secondaryOutlineColor && {outlineColor: secondaryOutlineColor})
169
+ })
170
+ ];
171
+
172
+ return out;
173
+ }
174
+ }
package/src/index.js CHANGED
@@ -39,6 +39,9 @@ export * from './components';
39
39
  // Layers
40
40
  export * from './layers';
41
41
 
42
+ // label layer (move to deck.gl/carto?)
43
+ export {PointLabelLayer} from './deckgl-layers/point-label-layer/point-label-layer';
44
+
42
45
  // Styles
43
46
  export * from './styles';
44
47
 
@@ -20,9 +20,9 @@
20
20
 
21
21
  import {console as Console} from 'global/window';
22
22
  import keymirror from 'keymirror';
23
- import {DataFilterExtension} from '@deck.gl/extensions';
23
+ import {CollisionFilterExtension, DataFilterExtension} from '@deck.gl/extensions';
24
24
  import {COORDINATE_SYSTEM, Layer as DeckLayer} from '@deck.gl/core';
25
- import {TextLayer} from '@deck.gl/layers';
25
+ import {PointLabelLayer} from '../deckgl-layers/point-label-layer/point-label-layer';
26
26
 
27
27
  // Workaround until https://github.com/visgl/deck.gl/pull/7513 is released
28
28
  DeckLayer.defaultProps.getFilterValue = {type: 'accessor', value: 0};
@@ -103,6 +103,7 @@ const FALLBACK_ICON =
103
103
  const MAX_SAMPLE_SIZE = 5000;
104
104
  const defaultDomain = [0, 1];
105
105
  const dataFilterExtension = new DataFilterExtension({filterSize: MAX_GPU_FILTERS});
106
+ const collisionFilterExtension = new CollisionFilterExtension();
106
107
 
107
108
  const defaultDataAccessor = dc => d => d;
108
109
  const defaultGetFieldValue = (field, d) => field.valueAccessor(d);
@@ -1341,51 +1342,87 @@ class Layer {
1341
1342
  };
1342
1343
  }
1343
1344
 
1344
- renderTextLabelLayer({getPosition, getPixelOffset, updateTriggers, sharedProps}, renderOpts) {
1345
+ renderTextLabelLayer(
1346
+ {getPosition, getRadius, radiusScale, updateTriggers, sharedProps},
1347
+ renderOpts
1348
+ ) {
1345
1349
  const {data, mapState} = renderOpts;
1346
1350
  const {textLabel, visibilityByZoom} = this.config;
1351
+ // const extensions = [...sharedProps.extensions];
1352
+ const extensions = [...sharedProps.extensions, collisionFilterExtension];
1347
1353
 
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
- }, []);
1354
+ if (!data || !data.textLabels || !data.textLabels[0] || !data.textLabels[0].getText) {
1355
+ return null;
1356
+ }
1357
+
1358
+ // TODO other labels
1359
+ const i = 0;
1360
+
1361
+ const [mainLabel, secondaryLabel] = textLabel;
1362
+ const {alignment, anchor, color: getColor, outlineColor, size: sizeScale} = mainLabel;
1363
+ const {
1364
+ color: getSecondaryColor,
1365
+ outlineColor: secondaryOutlineColor,
1366
+ size: secondarySizeScale
1367
+ } = secondaryLabel || {};
1368
+
1369
+ return [
1370
+ new PointLabelLayer({
1371
+ ...sharedProps,
1372
+ id: `${this.id}-label`,
1373
+ data: data.data,
1374
+ visibilityByZoom,
1375
+ characterSet: 'auto',
1376
+
1377
+ extensions,
1378
+ collisionEnabled: true,
1379
+ collisionGroup: `${this.id}-labels`,
1380
+
1381
+ getText: data.textLabels[0].getText,
1382
+ getColor,
1383
+ sizeScale,
1384
+ outlineColor,
1385
+
1386
+ ...(secondaryLabel && {
1387
+ getSecondaryText: data.textLabels[1].getText,
1388
+ getSecondaryColor,
1389
+ secondarySizeScale,
1390
+ secondaryOutlineColor
1391
+ }),
1392
+
1393
+ // Position
1394
+ getPosition,
1395
+ getRadius,
1396
+ radiusScale,
1397
+ getTextAnchor: anchor,
1398
+ getAlignmentBaseline: alignment,
1399
+
1400
+ // Style
1401
+ fontFamily: 'Inter, sans',
1402
+ fontSettings: {sdf: true},
1403
+ fontWeight: 500,
1404
+ outlineWidth: 4,
1405
+ parameters: {
1406
+ // text will always show on top of all layers
1407
+ depthTest: false
1408
+ },
1409
+
1410
+ getFilterValue: data.getFilterValue,
1411
+ updateTriggers: {
1412
+ ...updateTriggers,
1413
+ getText: textLabel[i].field?.name,
1414
+ getPixelOffset: {
1415
+ ...updateTriggers.getPixelOffset,
1416
+ ...updateTriggers.getRadius,
1417
+ anchor: mainLabel.anchor,
1418
+ alignment: mainLabel.alignment
1419
+ },
1420
+ getTextAnchor: mainLabel.anchor,
1421
+ getAlignmentBaseline: mainLabel.alignment,
1422
+ getColor: textLabel[i].color
1423
+ }
1424
+ })
1425
+ ];
1389
1426
  }
1390
1427
 
1391
1428
  /**
@@ -27,6 +27,7 @@ export const PROPERTY_GROUPS = keyMirror({
27
27
  color: null,
28
28
  stroke: null,
29
29
  customMarkers: null,
30
+ labels: null,
30
31
  radius: null,
31
32
  height: null,
32
33
  angle: null,
@@ -43,8 +44,9 @@ export {DEFAULT_COLOR_RANGE};
43
44
  /** @type {import('./layer-factory').LayerTextLabel} */
44
45
  export const DEFAULT_TEXT_LABEL = {
45
46
  field: null,
46
- color: [255, 255, 255],
47
- size: 18,
47
+ color: [44, 48, 50],
48
+ outlineColor: [255, 255, 255],
49
+ size: 12,
48
50
  offset: [0, 0],
49
51
  anchor: 'start',
50
52
  alignment: 'center'
@@ -387,6 +389,13 @@ export const LAYER_VIS_CONFIGS = {
387
389
  group: PROPERTY_GROUPS.display,
388
390
  property: 'filled'
389
391
  },
392
+ labels: {
393
+ type: 'boolean',
394
+ label: 'layerVisConfigs.labels',
395
+ defaultValue: false,
396
+ group: PROPERTY_GROUPS.labels,
397
+ property: 'labels'
398
+ },
390
399
  extruded: {
391
400
  type: 'boolean',
392
401
  defaultValue: false,
@@ -430,6 +439,13 @@ export const LAYER_VIS_CONFIGS = {
430
439
  group: PROPERTY_GROUPS.customMarkers,
431
440
  property: 'customMarkers'
432
441
  },
442
+ labelsEnabled: {
443
+ type: 'boolean',
444
+ defaultValue: true,
445
+ label: 'layerVisConfigs.labelsEnabled',
446
+ group: PROPERTY_GROUPS.labels,
447
+ property: 'labelsEnabled'
448
+ },
433
449
  customMarkersUrl: {
434
450
  type: 'text',
435
451
  defaultValue: '',
@@ -450,8 +466,8 @@ export const LAYER_VIS_CONFIGS = {
450
466
  export const LAYER_TEXT_CONFIGS = {
451
467
  fontSize: {
452
468
  type: 'number',
453
- range: [1, 100],
454
- value0: 1,
469
+ range: [6, 32],
470
+ value0: 6,
455
471
  step: 1,
456
472
  isRanged: false,
457
473
  label: 'Font size',
@@ -21,30 +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 padding = defaultPadding;
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)
39
34
 
40
35
  return typeof getRadius === 'function'
41
36
  ? d => [
42
- xMult * (getRadius(d) * radiusScale + padding),
43
- yMult * (getRadius(d) * radiusScale + padding + sizeOffset)
37
+ xMult * (getRadius(d) * radiusScale * radiusPadding + xPadding),
38
+ yMult * (getRadius(d) * radiusScale * radiusPadding + yPadding)
44
39
  ]
45
40
  : [
46
- xMult * (getRadius * radiusScale + padding),
47
- yMult * (getRadius * radiusScale + padding + sizeOffset)
41
+ xMult * (getRadius * radiusScale * radiusPadding + xPadding),
42
+ yMult * (getRadius * radiusScale * radiusPadding + yPadding)
48
43
  ];
49
44
  };
50
45
  }
@@ -54,40 +49,9 @@ export const textLabelAccessor = textLabel => dc => d => {
54
49
  return notNullorUndefined(val) ? String(val) : '';
55
50
  };
56
51
 
57
- export const formatTextLabelData = ({
58
- textLabel,
59
- triggerChanged,
60
- oldLayerData,
61
- data,
62
- dataContainer
63
- }) => {
52
+ export const formatTextLabelData = ({textLabel, dataContainer}) => {
64
53
  return textLabel.map((tl, i) => {
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
- };
54
+ const getText = tl.field ? textLabelAccessor(tl)(dataContainer) : null;
55
+ return {getText};
92
56
  });
93
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 {getTextOffsetByRadius, formatTextLabelData} from '../layer-text-label';
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),
@@ -47,6 +47,7 @@ export const pointVisConfigs = {
47
47
  customMarkers: 'customMarkers',
48
48
  customMarkersUrl: 'customMarkersUrl',
49
49
  customMarkersRange: 'customMarkersRange',
50
+ labelsEnabled: 'labelsEnabled',
50
51
  opacity: 'opacity',
51
52
  outline: 'outline',
52
53
  thickness: 'thickness',
@@ -242,13 +243,7 @@ export default class PointLayer extends Layer {
242
243
  const getPosition = this.getPositionAccessor(dataContainer);
243
244
 
244
245
  // get all distinct characters in the text labels
245
- const textLabels = formatTextLabelData({
246
- textLabel,
247
- triggerChanged,
248
- oldLayerData,
249
- data,
250
- dataContainer
251
- });
246
+ const textLabels = formatTextLabelData({textLabel, dataContainer});
252
247
 
253
248
  const accessors = this.getAttributeAccessors({dataContainer});
254
249
 
@@ -278,12 +273,12 @@ export default class PointLayer extends Layer {
278
273
  // eslint-disable-next-line complexity, max-statements
279
274
  renderLayer(opts) {
280
275
  const {data, gpuFilter, objectHovered, interactionConfig} = opts;
276
+ const {customMarkers, customMarkersUrl, customMarkersRange} = this.config.visConfig;
281
277
 
282
278
  const radiusScale = this.getRadiusScale();
283
279
 
284
280
  const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
285
281
  const brushingProps = this.getBrushingExtensionProps(interactionConfig);
286
- const getPixelOffset = getTextOffsetByRadius(radiusScale, data.getRadius);
287
282
  const extensions = [...defaultLayerProps.extensions, brushingExtension];
288
283
 
289
284
  const updateTriggers = {
@@ -305,7 +300,9 @@ export default class PointLayer extends Layer {
305
300
  {
306
301
  getPosition: data.getPosition,
307
302
  sharedProps,
308
- getPixelOffset,
303
+ // TODO remove this scaling by half here and elsewhere
304
+ radiusScale: customMarkers ? radiusScale / 2 : radiusScale,
305
+ getRadius: data.getRadius,
309
306
  updateTriggers
310
307
  },
311
308
  opts
@@ -319,7 +316,6 @@ export default class PointLayer extends Layer {
319
316
  };
320
317
 
321
318
  const customMarkersField = this.config.customMarkersField;
322
- const {customMarkers, customMarkersUrl, customMarkersRange} = this.config.visConfig;
323
319
  const customMarkersConfigured =
324
320
  customMarkers && Boolean(customMarkersUrl || (customMarkersField && customMarkersRange));
325
321
  const customMarkersMisConfigured = customMarkers && !customMarkersConfigured;
@@ -68,9 +68,11 @@ export default {
68
68
  panel: {
69
69
  text: {
70
70
  label: 'label',
71
- labelWithId: 'Label {labelId}',
71
+ mainLabel: 'Main Label',
72
+ secondaryLabel: 'Secondary Label',
72
73
  fontSize: 'Font size',
73
74
  fontColor: 'Font color',
75
+ outlineColor: 'Outline Color',
74
76
  textAnchor: 'Text anchor',
75
77
  alignment: 'Alignment',
76
78
  addMoreLabel: 'Add More Label'
@@ -157,6 +159,7 @@ export default {
157
159
  highPrecisionRenderingDescription: 'High precision will result in slower performance',
158
160
  height: 'Height',
159
161
  heightDescription: 'Click button at top right of the map to switch to 3d view',
162
+ labels: 'Labels',
160
163
  fill: 'Fill',
161
164
  enablePolygonHeight: 'Enable Polygon Height',
162
165
  showWireframe: 'Show Wireframe',
@@ -288,10 +288,7 @@ export function getFieldsFromData(data, fieldOrder) {
288
288
  // add a check for epoch timestamp
289
289
  const metadata = Analyzer.computeColMeta(
290
290
  data,
291
- [
292
- {regex: /.*geojson|all_points/g, dataType: 'GEOMETRY'},
293
- {regex: /.*census/g, dataType: 'STRING'}
294
- ],
291
+ [{regex: /.*geojson|all_points/g, dataType: 'GEOMETRY'}],
295
292
  {ignoredDataTypes: IGNORE_DATA_TYPES}
296
293
  );
297
294