@carto/kepler.gl 0.0.71-alpha.1 → 0.0.71-alpha.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.
Files changed (36) hide show
  1. package/dist/components/common/item-selector/accessor.js +2 -2
  2. package/dist/components/common/item-selector/dropdown-list.js +10 -8
  3. package/dist/components/common/item-selector/item-selector.js +2 -2
  4. package/dist/components/side-panel/layer-panel/color-range-selector.js +43 -8
  5. package/dist/components/side-panel/layer-panel/color-selector.js +7 -1
  6. package/dist/components/side-panel/layer-panel/hex-column-config.js +84 -0
  7. package/dist/components/side-panel/layer-panel/layer-configurator.js +40 -34
  8. package/dist/components/side-panel/layer-panel/vis-config-by-field-selector.js +2 -4
  9. package/dist/constants/color-ranges.js +12 -2
  10. package/dist/constants/default-settings.js +7 -10
  11. package/dist/layers/base-layer.js +110 -24
  12. package/dist/layers/point-layer/point-layer.js +2 -3
  13. package/dist/localization/en.js +5 -2
  14. package/dist/reducers/vis-state-merger.js +16 -2
  15. package/dist/schemas/vis-state-schema.js +2 -2
  16. package/dist/utils/table-utils/kepler-table.js +1 -2
  17. package/package.json +4 -4
  18. package/src/components/common/item-selector/accessor.js +1 -1
  19. package/src/components/common/item-selector/dropdown-list.js +24 -15
  20. package/src/components/common/item-selector/item-selector.js +1 -1
  21. package/src/components/side-panel/layer-panel/color-range-selector.js +37 -8
  22. package/src/components/side-panel/layer-panel/color-selector.js +7 -0
  23. package/src/components/side-panel/layer-panel/hex-column-config.js +40 -0
  24. package/src/components/side-panel/layer-panel/layer-configurator.js +59 -34
  25. package/src/components/side-panel/layer-panel/vis-config-by-field-selector.js +0 -2
  26. package/src/constants/color-ranges.js +9 -0
  27. package/src/constants/default-settings.js +7 -9
  28. package/src/layers/base-layer.js +92 -23
  29. package/src/layers/layer-factory.d.ts +1 -0
  30. package/src/layers/point-layer/point-layer.js +1 -1
  31. package/src/localization/en.js +4 -1
  32. package/src/reducers/vis-state-merger.js +13 -1
  33. package/src/schemas/vis-state-schema.js +1 -1
  34. package/src/utils/table-utils/kepler-table.js +0 -1
  35. package/dist/utils/custom-scale.js +0 -30
  36. package/src/utils/custom-scale.js +0 -22
@@ -41,12 +41,13 @@ import TextLabelPanelFactory from './text-label-panel';
41
41
 
42
42
  import {capitalizeFirstLetter} from 'utils/utils';
43
43
 
44
- import {CHANNEL_SCALES, CHANNEL_SCALE_SUPPORTED_FIELDS, SCALE_TYPES} from 'constants/default-settings';
44
+ import {CHANNEL_SCALES, CHANNEL_SCALE_SUPPORTED_FIELDS} from 'constants/default-settings';
45
45
  import {LAYER_TYPES} from 'layers/types';
46
46
  import {injectIntl} from 'react-intl';
47
47
  import ColorDimensionScaleSelectorFactory from './color-dimension-scale-selector';
48
48
  import ColorSelectorFactory from './color-selector';
49
49
  import LayerAggregationResolutionFactory from './layer-aggregation-resolution';
50
+ import {hexColorCustomPalette} from 'constants/color-ranges';
50
51
 
51
52
  const StyledLayerConfigurator = styled.div.attrs({
52
53
  className: 'layer-panel__config'
@@ -172,6 +173,8 @@ export default function LayerConfiguratorFactory(
172
173
  channel={layer.visualChannels.color}
173
174
  {...layerChannelConfigProps}
174
175
  />
176
+ </ConfigGroupCollapsibleContent>
177
+ <ConfigGroupCollapsibleContent>
175
178
  <VisConfigSlider {...layer.visConfigSettings.opacity} {...visConfiguratorProps} />
176
179
  </ConfigGroupCollapsibleContent>
177
180
  </LayerConfigGroup>
@@ -185,7 +188,11 @@ export default function LayerConfiguratorFactory(
185
188
  disabled={Boolean(layer.config.visConfig.customMarkers)}
186
189
  >
187
190
  {layer.config.strokeColorField ? (
188
- <LayerColorRangeSelector {...visConfiguratorProps} property="strokeColorRange" />
191
+ <LayerColorRangeSelector
192
+ {...visConfiguratorProps}
193
+ property="strokeColorRange"
194
+ field="strokeColorField"
195
+ />
189
196
  ) : (
190
197
  <LayerColorSelector
191
198
  {...visConfiguratorProps}
@@ -701,7 +708,11 @@ export default function LayerConfiguratorFactory(
701
708
  collapsible
702
709
  >
703
710
  {layer.config.strokeColorField ? (
704
- <LayerColorRangeSelector {...visConfiguratorProps} property="strokeColorRange" />
711
+ <LayerColorRangeSelector
712
+ {...visConfiguratorProps}
713
+ property="strokeColorRange"
714
+ field="strokeColorField"
715
+ />
705
716
  ) : (
706
717
  <LayerColorSelector
707
718
  {...visConfiguratorProps}
@@ -884,7 +895,11 @@ export default function LayerConfiguratorFactory(
884
895
  collapsible
885
896
  >
886
897
  {layer.config.strokeColorField ? (
887
- <LayerColorRangeSelector {...visConfiguratorProps} property="strokeColorRange" />
898
+ <LayerColorRangeSelector
899
+ {...visConfiguratorProps}
900
+ property="strokeColorRange"
901
+ field="strokeColorField"
902
+ />
888
903
  ) : (
889
904
  <LayerColorSelector
890
905
  {...visConfiguratorProps}
@@ -963,7 +978,6 @@ export default function LayerConfiguratorFactory(
963
978
  const layerConfiguratorProps = getLayerConfiguratorProps(this.props);
964
979
  const layerChannelConfigProps = getLayerChannelConfigProps(this.props);
965
980
  const dataset = getLayerDataset(datasets, layer);
966
- // TODO
967
981
  const renderTemplate = layer.type && `_render${capitalizeFirstLetter(layer.type)}LayerConfig`;
968
982
 
969
983
  return (
@@ -1049,13 +1063,14 @@ LayerColorSelectorFactory.deps = [ColorSelectorFactory];
1049
1063
  export function LayerColorSelectorFactory(ColorSelector) {
1050
1064
  class LayerColorSelector extends Component {
1051
1065
  render() {
1052
- const {layer, onChange, selectedColor, property = 'color', setColorUI} = this.props;
1066
+ const {layer, onChange, selectedColor, property = 'color', setColorUI, fields} = this.props;
1053
1067
  return (
1054
1068
  <SidePanelSection>
1055
1069
  <PanelLabel>
1056
1070
  <FormattedMessage id="layer.color" />
1057
1071
  </PanelLabel>
1058
1072
  <ColorSelector
1073
+ fields={fields}
1059
1074
  colorSets={[
1060
1075
  {
1061
1076
  selectedColor: selectedColor || layer.config.color,
@@ -1077,13 +1092,22 @@ ArcLayerColorSelectorFactory.deps = [ColorSelectorFactory];
1077
1092
  export function ArcLayerColorSelectorFactory(ColorSelector) {
1078
1093
  class ArcLayerColorSelector extends Component {
1079
1094
  render() {
1080
- const {layer, onChangeConfig, onChangeVisConfig, property = 'color', setColorUI} = this.props;
1095
+ const {
1096
+ layer,
1097
+ onChangeConfig,
1098
+ onChangeVisConfig,
1099
+ property = 'color',
1100
+ setColorUI,
1101
+ fields
1102
+ } = this.props;
1103
+
1081
1104
  return (
1082
1105
  <SidePanelSection>
1083
1106
  <PanelLabel>
1084
1107
  <FormattedMessage id="layer.colorRange" />
1085
1108
  </PanelLabel>
1086
1109
  <ColorSelector
1110
+ fields={fields}
1087
1111
  colorSets={[
1088
1112
  {
1089
1113
  selectedColor: layer.config.color,
@@ -1114,42 +1138,43 @@ export function LayerColorRangeSelectorFactory(ColorSelector) {
1114
1138
  layer,
1115
1139
  onChange,
1116
1140
  property = 'colorRange',
1117
- scaleProperty = 'colorScale',
1118
- domain = 'colorDomain',
1119
- setColorUI
1141
+ field = 'colorField',
1142
+ setColorUI,
1143
+ fields
1120
1144
  } = this.props;
1121
-
1122
- const colorSets = [
1123
- {
1124
- selectedColor: layer.config.visConfig[property],
1125
- isRange: true,
1126
- setColor: colorRange => {
1127
- const {colorMap} = layer.config.visConfig[property];
1128
- const colorRangeUpdated = colorMap
1129
- ? layer.updateColorMap(property, colorMap, colorRange)
1130
- : colorRange;
1131
- onChange({[property]: colorRangeUpdated});
1132
- }
1133
- }
1134
- ];
1135
-
1136
- const scale = layer.config[scaleProperty];
1137
- // TODO
1138
- if (scale === SCALE_TYPES.hexColor) {
1139
- colorSets[0].selectedColor = {
1140
- colors: layer.config[domain]
1141
- };
1142
- }
1143
-
1144
1145
  return (
1145
1146
  <SidePanelSection>
1146
1147
  <PanelLabel>
1147
1148
  <FormattedMessage id="layer.colorRange" />
1148
1149
  </PanelLabel>
1149
1150
  <ColorSelector
1150
- colorSets={colorSets}
1151
+ fields={fields}
1152
+ colorSets={[
1153
+ {
1154
+ selectedColor: layer.config.visConfig[property],
1155
+ isRange: true,
1156
+ setColor: colorRange => {
1157
+ const {colorMap} = layer.config.visConfig[property];
1158
+ const colorRangeUpdated = colorMap
1159
+ ? layer.updateColorMap(property, colorMap, colorRange)
1160
+ : colorRange;
1161
+ onChange({[property]: colorRangeUpdated});
1162
+ }
1163
+ }
1164
+ ]}
1151
1165
  colorUI={layer.config.colorUI[property]}
1152
1166
  setColorUI={newConfig => setColorUI(property, newConfig)}
1167
+ onSelectHexColorColumn={colorColumn => {
1168
+ layer.updateLayerConfig({
1169
+ [field]: {
1170
+ ...layer.config[field],
1171
+ colorColumn: colorColumn?.name,
1172
+ colorColumnIdx: colorColumn?.fieldIdx
1173
+ }
1174
+ });
1175
+
1176
+ onChange({[property]: hexColorCustomPalette});
1177
+ }}
1153
1178
  />
1154
1179
  </SidePanelSection>
1155
1180
  );
@@ -144,14 +144,12 @@ function VisConfigByFieldSelectorFactory(InfoHelper, FieldSelector, ColorDimensi
144
144
  defaultMessage={label}
145
145
  />
146
146
  }
147
- layerId={this.props.id}
148
147
  scaleType={this.props.scaleType}
149
148
  options={scaleOptions}
150
149
  domain={domain}
151
150
  range={range}
152
151
  onSelect={this.props.updateScale}
153
152
  onSetCustomPalette={this.props.updateCustomPalette}
154
- fields={this.props.fields}
155
153
  />
156
154
  </div>
157
155
  )}
@@ -61,3 +61,12 @@ export const DEFAULT_COLOR_RANGE = colorRanges.find(({name}) => name === 'Global
61
61
  category: 'Uber',
62
62
  colors: ['#5A1846', '#900C3F', '#C70039', '#E3611C', '#F1920E', '#FFC300']
63
63
  };
64
+
65
+ export const hexColor = 'hexColor';
66
+ export const hexColorCustomPalette = {
67
+ name: hexColor,
68
+ type: hexColor,
69
+ colors: [],
70
+ category: 'CARTO',
71
+ hexColor: true
72
+ };
@@ -45,7 +45,6 @@ import {
45
45
  import {getHTMLMapModeTileUrl} from 'utils/utils';
46
46
  import {TOOLTIP_FORMAT_TYPES} from './tooltip';
47
47
  import {LAYER_TYPES} from 'layers/types';
48
- import {scaleHexColor} from 'utils/custom-scale';
49
48
 
50
49
  export const ACTION_PREFIX = '@@kepler.gl/';
51
50
  export const CLOUDFRONT = 'https://d1a3f4spazzrp4.cloudfront.net/kepler.gl';
@@ -311,9 +310,7 @@ export const SCALE_TYPES = keyMirror({
311
310
  point: null,
312
311
  custom: null,
313
312
  // UI-only type, resolving as custom
314
- logarithmic: null,
315
- // Scale for HexColor column initiative
316
- hexColor: null
313
+ logarithmic: null
317
314
  });
318
315
 
319
316
  export const SCALE_FUNC = {
@@ -324,8 +321,7 @@ export const SCALE_FUNC = {
324
321
  [SCALE_TYPES.sqrt]: scaleSqrt,
325
322
  [SCALE_TYPES.log]: scaleLog,
326
323
  [SCALE_TYPES.point]: scalePoint,
327
- [SCALE_TYPES.custom]: scaleThreshold,
328
- [SCALE_TYPES.hexColor]: scaleHexColor
324
+ [SCALE_TYPES.custom]: scaleThreshold
329
325
  };
330
326
 
331
327
  export const ALL_FIELD_TYPES = keyMirror({
@@ -439,7 +435,8 @@ export const CHANNEL_SCALES = keyMirror({
439
435
  size: null,
440
436
  customMarker: null,
441
437
  colorAggr: null,
442
- sizeAggr: null
438
+ sizeAggr: null,
439
+ identity: null
443
440
  });
444
441
 
445
442
  export const AGGREGATION_TYPES = {
@@ -557,10 +554,11 @@ export const linearFieldAggrScaleFunctions = {
557
554
  };
558
555
 
559
556
  export const ordinalFieldScaleFunctions = {
560
- [CHANNEL_SCALES.color]: [SCALE_TYPES.ordinal, SCALE_TYPES.hexColor],
557
+ [CHANNEL_SCALES.color]: [SCALE_TYPES.ordinal],
561
558
  [CHANNEL_SCALES.radius]: [SCALE_TYPES.point],
562
559
  [CHANNEL_SCALES.size]: [SCALE_TYPES.point],
563
- [CHANNEL_SCALES.customMarker]: [SCALE_TYPES.ordinal]
560
+ [CHANNEL_SCALES.customMarker]: [SCALE_TYPES.ordinal],
561
+ [CHANNEL_SCALES.identity]: []
564
562
  };
565
563
 
566
564
  export const ordinalFieldAggrScaleFunctions = {
@@ -21,7 +21,7 @@
21
21
  import {console as Console} from 'global/window';
22
22
  import keymirror from 'keymirror';
23
23
  import {CollisionFilterExtension, DataFilterExtension} from '@deck.gl/extensions';
24
- import {COORDINATE_SYSTEM} from '@deck.gl/core';
24
+ import {COORDINATE_SYSTEM, Layer as DeckLayer} from '@deck.gl/core';
25
25
  import {_PointLabelLayer as PointLabelLayer} from '@deck.gl/carto';
26
26
  import DefaultLayerIcon from './default-layer-icon';
27
27
  import {diffUpdateTriggers} from './layer-update';
@@ -38,7 +38,7 @@ import {
38
38
  UNKNOWN_COLOR,
39
39
  ZOOM_LEVEL_LIMITS
40
40
  } from 'constants/default-settings';
41
- import {COLOR_RANGES} from 'constants/color-ranges';
41
+ import {COLOR_RANGES, hexColor} from 'constants/color-ranges';
42
42
  import {DataVizColors} from 'constants/custom-color-ranges';
43
43
  import {
44
44
  LAYER_VIS_CONFIGS,
@@ -76,6 +76,7 @@ const collisionFilterExtension = new CollisionFilterExtension();
76
76
 
77
77
  const defaultDataAccessor = dc => d => d;
78
78
  const defaultGetFieldValue = (field, d) => field.valueAccessor(d);
79
+ const scaleIdentity = v => v;
79
80
 
80
81
  export const OVERLAY_TYPE = keymirror({
81
82
  deckgl: null,
@@ -99,7 +100,6 @@ export const colorMaker = generateColor();
99
100
  class Layer {
100
101
  constructor(props = {}) {
101
102
  this.id = props.id || generateHashId(LAYER_ID_LENGTH);
102
-
103
103
  // meta
104
104
  this.meta = {};
105
105
 
@@ -608,8 +608,9 @@ class Layer {
608
608
  };
609
609
 
610
610
  this.updateLayerConfig({colorUI});
611
- // if colorUI[prop] is colorRange
612
- const isColorRange = visConfig[prop] && visConfig[prop].colors;
611
+ // if colorUI[prop] is colorRange. If type is hexColor then it's also a range
612
+ const isColorRange =
613
+ visConfig[prop] && (visConfig[prop].colors || visConfig[prop].type === hexColor);
613
614
 
614
615
  if (isColorRange) {
615
616
  this.updateColorUIByColorRange(newConfig, prop);
@@ -662,8 +663,9 @@ class Layer {
662
663
  colorRangeConfig: {
663
664
  ...colorUI[prop].colorRangeConfig,
664
665
  type: visConfig[prop].type,
665
- steps: visConfig[prop].colors.length,
666
- reversed: Boolean(visConfig[prop].reversed)
666
+ steps: visConfig[prop].colors?.length,
667
+ reversed: Boolean(visConfig[prop].reversed),
668
+ hexColumn: this.isColoredByColorColumn(prop)
667
669
  }
668
670
  }
669
671
  }
@@ -731,6 +733,12 @@ class Layer {
731
733
  updateCategoryColorMap(colorMap, domain, colorRange) {
732
734
  const colors = colorRange.colors;
733
735
  const assignedCategories = [];
736
+ if (colorRange.type === hexColor) {
737
+ return {
738
+ ...colorRange,
739
+ colorMap: []
740
+ };
741
+ }
734
742
  const newColorMap = colorMap.slice(0, colors.length).map((cMap, index) => {
735
743
  assignedCategories.push(cMap[0]);
736
744
  return [cMap[0], colors[index]];
@@ -820,7 +828,11 @@ class Layer {
820
828
  }
821
829
 
822
830
  getColorScale(colorScale, colorDomain, colorRange) {
823
- if (Array.isArray(colorRange.colorMap)) {
831
+ if (colorRange.type === hexColor) {
832
+ return (_, color) => {
833
+ return hexToRgb(color);
834
+ };
835
+ } else if (Array.isArray(colorRange.colorMap)) {
824
836
  const cMap = new Map();
825
837
  colorRange.colorMap.forEach(([k, v]) => {
826
838
  cMap.set(k, typeof v === 'string' ? hexToRgb(v) : v);
@@ -901,7 +913,9 @@ class Layer {
901
913
  const aggregationValue = this.config.visConfig[aggregation];
902
914
 
903
915
  const scaleFunction =
904
- channelScaleType === CHANNEL_SCALES.color
916
+ channelScaleType === CHANNEL_SCALES.identity
917
+ ? scaleIdentity
918
+ : channelScaleType === CHANNEL_SCALES.color
905
919
  ? this.getColorScale(...args)
906
920
  : channelScaleType === CHANNEL_SCALES.customMarker
907
921
  ? this.getCustomMarkersScale(
@@ -912,10 +926,12 @@ class Layer {
912
926
 
913
927
  attributeAccessors[accessor] = d =>
914
928
  this.getEncodedChannelValue({
929
+ channel,
930
+ dataContainer,
915
931
  scale: scaleFunction,
916
932
  data: dataAccessor(dataContainer)(d),
917
933
  field: fieldConfig,
918
- aggregation: aggregationValue,
934
+ _aggregation: aggregationValue,
919
935
  nullValue
920
936
  });
921
937
  } else if (typeof getAttributeValue === 'function') {
@@ -934,7 +950,7 @@ class Layer {
934
950
  }
935
951
 
936
952
  getVisChannelScale(scale, domain, range, fixed) {
937
- if (scale === SCALE_TYPES.ordinal || scale === SCALE_TYPES.hexColor) {
953
+ if (scale === SCALE_TYPES.ordinal) {
938
954
  // @ts-ignore d3-scale type
939
955
  return SCALE_FUNC[scale]()
940
956
  .domain(domain.slice(0, range.length))
@@ -988,16 +1004,34 @@ class Layer {
988
1004
  }
989
1005
 
990
1006
  getEncodedChannelValue({
1007
+ channel,
991
1008
  scale,
992
1009
  data,
993
1010
  field,
1011
+ dataContainer,
994
1012
  // In builder we overwrite the getValue function and we use the _aggregation parameter in spatial index layers as the QuadkeyLayer.
995
- aggregation,
1013
+ _aggregation,
996
1014
  nullValue = NO_VALUE_COLOR,
997
1015
  getValue = defaultGetFieldValue
998
1016
  }) {
1017
+ let colorColumnValue;
999
1018
  const {type} = field;
1000
1019
  const value = getValue(field, data);
1020
+ const channelConfig = this.config.visConfig[this.visualChannels[channel].range];
1021
+ const channelField = this.config[this.visualChannels[channel].field];
1022
+
1023
+ if (channelConfig.type === hexColor) {
1024
+ const columnField = {
1025
+ id: channelField.colorColumn,
1026
+ name: channelField.colorColumn,
1027
+ fieldIdx: channelField.colorColumnIdx,
1028
+ valueAccessor: d => {
1029
+ return dataContainer.valueAt(d.index, channelField.colorColumnIdx);
1030
+ }
1031
+ };
1032
+
1033
+ colorColumnValue = getValue(columnField, data);
1034
+ }
1001
1035
 
1002
1036
  if (!notNullorUndefined(value)) {
1003
1037
  return nullValue;
@@ -1007,9 +1041,9 @@ class Layer {
1007
1041
  if (type === ALL_FIELD_TYPES.timestamp) {
1008
1042
  // shouldn't need to convert here
1009
1043
  // scale Function should take care of it
1010
- attributeValue = scale(new Date(value));
1044
+ attributeValue = scale(new Date(value), colorColumnValue);
1011
1045
  } else {
1012
- attributeValue = scale(value);
1046
+ attributeValue = scale(value, colorColumnValue);
1013
1047
  }
1014
1048
 
1015
1049
  if (!notNullorUndefined(attributeValue)) {
@@ -1043,13 +1077,14 @@ class Layer {
1043
1077
  if (!this.config.dataId) {
1044
1078
  return {};
1045
1079
  }
1046
- const layerDataset = datasets[this.config.dataId];
1047
- const {dataContainer} = layerDataset;
1080
+ const dataset = this.getDataset(datasets);
1081
+ const {dataContainer} = dataset;
1048
1082
 
1049
- this.updateVisualChannelFields(layerDataset);
1083
+ this.updateVisualChannelFields(dataset);
1084
+ this.updateHexColorDomain(dataset);
1050
1085
 
1051
1086
  const getPosition = this.getPositionAccessor(dataContainer);
1052
- const dataUpdateTriggers = this.getDataUpdateTriggers(layerDataset);
1087
+ const dataUpdateTriggers = this.getDataUpdateTriggers(dataset);
1053
1088
  const triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
1054
1089
 
1055
1090
  if (triggerChanged.getMeta) {
@@ -1062,7 +1097,7 @@ class Layer {
1062
1097
  // same data
1063
1098
  data = oldLayerData.data;
1064
1099
  } else {
1065
- data = this.calculateDataAttribute(layerDataset, getPosition);
1100
+ data = this.calculateDataAttribute(dataset, getPosition);
1066
1101
  }
1067
1102
 
1068
1103
  return {data, triggerChanged};
@@ -1074,12 +1109,20 @@ class Layer {
1074
1109
  * @param {Object} dataset
1075
1110
  */
1076
1111
  updateVisualChannelFields(dataset) {
1077
- for (const {field} of Object.values(this.visualChannels)) {
1112
+ for (const {field, range} of Object.values(this.visualChannels)) {
1078
1113
  const oldField = this.config[field];
1114
+ const isUsingHexColorCode = this.config.visConfig[range].hexColor
1079
1115
  if (!oldField) {
1080
1116
  return;
1081
1117
  }
1082
- const newDataSetField = dataset.fields.find(fd => fd.name === oldField.name) || null;
1118
+ let newDataSetField = dataset.fields.find(fd => fd.name === oldField.name) || null;
1119
+ if (isUsingHexColorCode) {
1120
+ newDataSetField = {
1121
+ ...newDataSetField,
1122
+ colorColumn: newDataSetField.colorColumn || oldField.colorColumn,
1123
+ colorColumnIdx: newDataSetField.colorColumnIdx || oldField.colorColumnIdx
1124
+ };
1125
+ }
1083
1126
  this.updateLayerConfig({[field]: newDataSetField});
1084
1127
  }
1085
1128
  }
@@ -1100,12 +1143,12 @@ class Layer {
1100
1143
  Object.values(this.visualChannels).forEach(channel => {
1101
1144
  const {scale} = channel;
1102
1145
  const scaleType = this.config[scale];
1146
+
1103
1147
  // ordinal domain is based on dataContainer, if only filter changed
1104
1148
  // no need to update ordinal domain
1105
1149
  if (!newFilter || scaleType !== SCALE_TYPES.ordinal) {
1106
1150
  const {domain} = channel;
1107
1151
  const updatedDomain = this.calculateLayerDomain(table, channel);
1108
- console.log(this.name, updatedDomain, domain);
1109
1152
  this.updateLayerConfig({[domain]: updatedDomain});
1110
1153
  }
1111
1154
  });
@@ -1222,6 +1265,24 @@ class Layer {
1222
1265
  return dataset.getColumnLayerDomain(dataSetField, scaleType) || defaultDomain;
1223
1266
  }
1224
1267
 
1268
+ updateHexColorDomain(dataset) {
1269
+ if (!dataset) {
1270
+ return this;
1271
+ }
1272
+ Object.values(this.visualChannels).forEach(channel => {
1273
+ const channelConfig = this.config.visConfig[channel.range];
1274
+ const field = this.config[channel.field];
1275
+
1276
+ if (channelConfig?.type === hexColor) {
1277
+ const dataSetField = dataset.fields.find(f => f.name === field.colorColumn);
1278
+ const colors = dataset.getColumnLayerDomain(dataSetField, SCALE_TYPES.ordinal);
1279
+ this.updateLayerVisConfig({[channel.range]: {...channelConfig, colors}});
1280
+ }
1281
+ });
1282
+
1283
+ return this;
1284
+ }
1285
+
1225
1286
  hasHoveredObject(objectInfo) {
1226
1287
  return this.isLayerHovered(objectInfo) && objectInfo.object ? objectInfo.object : null;
1227
1288
  }
@@ -1250,6 +1311,7 @@ class Layer {
1250
1311
  if (!radiusChannel || this.config[radiusChannel.field]) {
1251
1312
  return 1;
1252
1313
  }
1314
+
1253
1315
  return this.config.visConfig.radius;
1254
1316
  }
1255
1317
 
@@ -1312,7 +1374,7 @@ class Layer {
1312
1374
  {getPosition, getRadius, radiusScale, updateTriggers, sharedProps},
1313
1375
  renderOpts
1314
1376
  ) {
1315
- const {data} = renderOpts;
1377
+ const {data, mapState} = renderOpts;
1316
1378
  const {textLabel, visibilityByZoom} = this.config;
1317
1379
  const extensions = [...sharedProps.extensions, collisionFilterExtension];
1318
1380
 
@@ -1431,6 +1493,13 @@ class Layer {
1431
1493
  // implemented in subclasses
1432
1494
  return () => null;
1433
1495
  }
1496
+
1497
+ isColoredByColorColumn(range) {
1498
+ const field = Object.values(this.visualChannels)?.find(value => value.range === range)?.field;
1499
+ if (field) {
1500
+ return this.config[field].colorColumn;
1501
+ }
1502
+ }
1434
1503
  }
1435
1504
 
1436
1505
  export default Layer;
@@ -31,6 +31,7 @@ export type ColorUI = {
31
31
  steps: number;
32
32
  reversed: boolean;
33
33
  custom: boolean;
34
+ hexColumn: boolean;
34
35
  };
35
36
  };
36
37
 
@@ -238,7 +238,7 @@ export default class PointLayer extends Layer {
238
238
  formatLayerData(datasets, oldLayerData) {
239
239
  const {textLabel} = this.config;
240
240
  const {gpuFilter, dataContainer} = datasets[this.config.dataId];
241
- const {data, triggerChanged} = this.updateData(datasets, oldLayerData);
241
+ const {data} = this.updateData(datasets, oldLayerData);
242
242
  const getPosition = this.getPositionAccessor(dataContainer);
243
243
 
244
244
  // get all distinct characters in the text labels
@@ -448,7 +448,10 @@ export default {
448
448
  customPalette: 'Custom Palette',
449
449
  steps: 'steps',
450
450
  type: 'type',
451
- reversed: 'reversed'
451
+ reversed: 'reversed',
452
+ hexColumn: {
453
+ field: 'Color field'
454
+ }
452
455
  },
453
456
  customPalette: {
454
457
  apply: 'Apply',
@@ -423,6 +423,7 @@ export function validateSavedTextLabel(fields, [layerTextLabel], savedTextLabel)
423
423
  export function validateSavedVisualChannels(fields, newLayer, savedLayer) {
424
424
  Object.values(newLayer.visualChannels).forEach(({field, scale, key}) => {
425
425
  let foundField;
426
+ const colorFieldProps = {};
426
427
  if (savedLayer.config) {
427
428
  if (savedLayer.config[field]) {
428
429
  foundField = fields.find(
@@ -430,8 +431,19 @@ export function validateSavedVisualChannels(fields, newLayer, savedLayer) {
430
431
  );
431
432
  }
432
433
 
434
+ if (savedLayer.config[field]?.colorColumn) {
435
+ const colorColumnField = fields.find(
436
+ fd => savedLayer.config && fd.name === savedLayer.config[field].colorColumn
437
+ );
438
+
439
+ if (colorColumnField) {
440
+ colorFieldProps.colorColumn = colorColumnField.name;
441
+ colorFieldProps.colorColumnIdx = colorColumnField.fieldIdx;
442
+ }
443
+ }
444
+
433
445
  const foundChannel = {
434
- ...(foundField ? {[field]: foundField} : {}),
446
+ ...(foundField ? {[field]: {...foundField, ...colorFieldProps}} : {}),
435
447
  ...(savedLayer.config[scale] ? {[scale]: savedLayer.config[scale]} : {})
436
448
  };
437
449
  if (Object.keys(foundChannel).length) {
@@ -340,7 +340,7 @@ class VisualChannelSchemaV1 extends Schema {
340
340
  (accu, key) => ({
341
341
  ...accu,
342
342
  [visualChannels[key].field]: layer.config[visualChannels[key].field]
343
- ? pick(layer.config[visualChannels[key].field], ['name', 'type'])
343
+ ? pick(layer.config[visualChannels[key].field], ['name', 'type', 'colorColumn'])
344
344
  : null,
345
345
  [visualChannels[key].scale]: layer.config[visualChannels[key].scale]
346
346
  }),
@@ -324,7 +324,6 @@ class KeplerTable {
324
324
  switch (scaleType) {
325
325
  case SCALE_TYPES.ordinal:
326
326
  case SCALE_TYPES.point:
327
- case SCALE_TYPES.hexColor:
328
327
  // do not recalculate ordinal domain based on filtered data
329
328
  // don't need to update ordinal domain every time
330
329
  return getOrdinalDomain(dataContainer, valueAccessor);
@@ -1,30 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.scaleHexColor = scaleHexColor;
7
-
8
- var _colorUtils = require("./color-utils");
9
-
10
- function scaleHexColor() {
11
- var unknown;
12
-
13
- function scale(x) {
14
- return x === null ? unknown : (0, _colorUtils.hexToRgb)(x);
15
- }
16
-
17
- scale.invert = scale;
18
- scale.domain = scale.range = scaleHexColor;
19
-
20
- scale.unknown = function (u) {
21
- if (u) {
22
- unknown = u;
23
- }
24
-
25
- return scale;
26
- };
27
-
28
- return scale;
29
- }
30
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9jdXN0b20tc2NhbGUuanMiXSwibmFtZXMiOlsic2NhbGVIZXhDb2xvciIsInVua25vd24iLCJzY2FsZSIsIngiLCJpbnZlcnQiLCJkb21haW4iLCJyYW5nZSIsInUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFTyxTQUFTQSxhQUFULEdBQXlCO0FBQzlCLE1BQUlDLE9BQUo7O0FBQ0EsV0FBU0MsS0FBVCxDQUFlQyxDQUFmLEVBQWtCO0FBQ2hCLFdBQU9BLENBQUMsS0FBSyxJQUFOLEdBQWFGLE9BQWIsR0FBdUIsMEJBQVNFLENBQVQsQ0FBOUI7QUFDRDs7QUFFREQsRUFBQUEsS0FBSyxDQUFDRSxNQUFOLEdBQWVGLEtBQWY7QUFFQUEsRUFBQUEsS0FBSyxDQUFDRyxNQUFOLEdBQWVILEtBQUssQ0FBQ0ksS0FBTixHQUFjTixhQUE3Qjs7QUFFQUUsRUFBQUEsS0FBSyxDQUFDRCxPQUFOLEdBQWdCLFVBQUFNLENBQUMsRUFBSTtBQUNuQixRQUFJQSxDQUFKLEVBQU87QUFDTE4sTUFBQUEsT0FBTyxHQUFHTSxDQUFWO0FBQ0Q7O0FBRUQsV0FBT0wsS0FBUDtBQUNELEdBTkQ7O0FBUUEsU0FBT0EsS0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtoZXhUb1JnYn0gZnJvbSAnLi9jb2xvci11dGlscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZUhleENvbG9yKCkge1xuICBsZXQgdW5rbm93bjtcbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHJldHVybiB4ID09PSBudWxsID8gdW5rbm93biA6IGhleFRvUmdiKHgpO1xuICB9XG5cbiAgc2NhbGUuaW52ZXJ0ID0gc2NhbGU7XG5cbiAgc2NhbGUuZG9tYWluID0gc2NhbGUucmFuZ2UgPSBzY2FsZUhleENvbG9yO1xuXG4gIHNjYWxlLnVua25vd24gPSB1ID0+IHtcbiAgICBpZiAodSkge1xuICAgICAgdW5rbm93biA9IHU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjYWxlO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cbiJdfQ==
@@ -1,22 +0,0 @@
1
- import {hexToRgb} from './color-utils';
2
-
3
- export function scaleHexColor() {
4
- let unknown;
5
- function scale(x) {
6
- return x === null ? unknown : hexToRgb(x);
7
- }
8
-
9
- scale.invert = scale;
10
-
11
- scale.domain = scale.range = scaleHexColor;
12
-
13
- scale.unknown = u => {
14
- if (u) {
15
- unknown = u;
16
- }
17
-
18
- return scale;
19
- };
20
-
21
- return scale;
22
- }