@carto/kepler.gl 0.0.71-alpha.1 → 0.0.71-alpha.3
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/common/item-selector/accessor.js +2 -2
- package/dist/components/common/item-selector/dropdown-list.js +10 -8
- package/dist/components/common/item-selector/item-selector.js +2 -2
- package/dist/components/side-panel/layer-panel/color-range-selector.js +43 -8
- package/dist/components/side-panel/layer-panel/color-selector.js +7 -1
- package/dist/components/side-panel/layer-panel/hex-column-config.js +84 -0
- package/dist/components/side-panel/layer-panel/layer-configurator.js +45 -34
- package/dist/components/side-panel/layer-panel/vis-config-by-field-selector.js +2 -4
- package/dist/constants/color-ranges.js +12 -2
- package/dist/constants/default-settings.js +8 -8
- package/dist/layers/base-layer.js +111 -25
- package/dist/layers/point-layer/point-layer.js +2 -3
- package/dist/localization/en.js +5 -2
- package/dist/reducers/vis-state-merger.js +16 -2
- package/dist/schemas/vis-state-schema.js +2 -2
- package/dist/utils/custom-scales.js +28 -0
- package/dist/utils/table-utils/kepler-table.js +1 -2
- package/package.json +3 -3
- package/src/components/common/item-selector/accessor.js +1 -1
- package/src/components/common/item-selector/dropdown-list.js +24 -15
- package/src/components/common/item-selector/item-selector.js +1 -1
- package/src/components/side-panel/layer-panel/color-range-selector.js +37 -8
- package/src/components/side-panel/layer-panel/color-selector.js +7 -0
- package/src/components/side-panel/layer-panel/hex-column-config.js +40 -0
- package/src/components/side-panel/layer-panel/layer-configurator.js +68 -34
- package/src/components/side-panel/layer-panel/vis-config-by-field-selector.js +0 -2
- package/src/constants/color-ranges.js +9 -0
- package/src/constants/default-settings.js +8 -7
- package/src/layers/base-layer.js +93 -24
- package/src/layers/layer-factory.d.ts +1 -0
- package/src/layers/point-layer/point-layer.js +1 -1
- package/src/localization/en.js +4 -1
- package/src/reducers/vis-state-merger.js +13 -1
- package/src/schemas/vis-state-schema.js +1 -1
- package/src/utils/{custom-scale.js → custom-scales.js} +3 -5
- package/src/utils/table-utils/kepler-table.js +0 -1
- package/dist/utils/custom-scale.js +0 -30
|
@@ -41,12 +41,17 @@ import TextLabelPanelFactory from './text-label-panel';
|
|
|
41
41
|
|
|
42
42
|
import {capitalizeFirstLetter} from 'utils/utils';
|
|
43
43
|
|
|
44
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
CHANNEL_SCALES,
|
|
46
|
+
CHANNEL_SCALE_SUPPORTED_FIELDS,
|
|
47
|
+
SCALE_TYPES
|
|
48
|
+
} from 'constants/default-settings';
|
|
45
49
|
import {LAYER_TYPES} from 'layers/types';
|
|
46
50
|
import {injectIntl} from 'react-intl';
|
|
47
51
|
import ColorDimensionScaleSelectorFactory from './color-dimension-scale-selector';
|
|
48
52
|
import ColorSelectorFactory from './color-selector';
|
|
49
53
|
import LayerAggregationResolutionFactory from './layer-aggregation-resolution';
|
|
54
|
+
import {hexColorCustomPalette} from 'constants/color-ranges';
|
|
50
55
|
|
|
51
56
|
const StyledLayerConfigurator = styled.div.attrs({
|
|
52
57
|
className: 'layer-panel__config'
|
|
@@ -172,6 +177,8 @@ export default function LayerConfiguratorFactory(
|
|
|
172
177
|
channel={layer.visualChannels.color}
|
|
173
178
|
{...layerChannelConfigProps}
|
|
174
179
|
/>
|
|
180
|
+
</ConfigGroupCollapsibleContent>
|
|
181
|
+
<ConfigGroupCollapsibleContent>
|
|
175
182
|
<VisConfigSlider {...layer.visConfigSettings.opacity} {...visConfiguratorProps} />
|
|
176
183
|
</ConfigGroupCollapsibleContent>
|
|
177
184
|
</LayerConfigGroup>
|
|
@@ -185,7 +192,11 @@ export default function LayerConfiguratorFactory(
|
|
|
185
192
|
disabled={Boolean(layer.config.visConfig.customMarkers)}
|
|
186
193
|
>
|
|
187
194
|
{layer.config.strokeColorField ? (
|
|
188
|
-
<LayerColorRangeSelector
|
|
195
|
+
<LayerColorRangeSelector
|
|
196
|
+
{...visConfiguratorProps}
|
|
197
|
+
property="strokeColorRange"
|
|
198
|
+
field="strokeColorField"
|
|
199
|
+
/>
|
|
189
200
|
) : (
|
|
190
201
|
<LayerColorSelector
|
|
191
202
|
{...visConfiguratorProps}
|
|
@@ -701,7 +712,11 @@ export default function LayerConfiguratorFactory(
|
|
|
701
712
|
collapsible
|
|
702
713
|
>
|
|
703
714
|
{layer.config.strokeColorField ? (
|
|
704
|
-
<LayerColorRangeSelector
|
|
715
|
+
<LayerColorRangeSelector
|
|
716
|
+
{...visConfiguratorProps}
|
|
717
|
+
property="strokeColorRange"
|
|
718
|
+
field="strokeColorField"
|
|
719
|
+
/>
|
|
705
720
|
) : (
|
|
706
721
|
<LayerColorSelector
|
|
707
722
|
{...visConfiguratorProps}
|
|
@@ -884,7 +899,11 @@ export default function LayerConfiguratorFactory(
|
|
|
884
899
|
collapsible
|
|
885
900
|
>
|
|
886
901
|
{layer.config.strokeColorField ? (
|
|
887
|
-
<LayerColorRangeSelector
|
|
902
|
+
<LayerColorRangeSelector
|
|
903
|
+
{...visConfiguratorProps}
|
|
904
|
+
property="strokeColorRange"
|
|
905
|
+
field="strokeColorField"
|
|
906
|
+
/>
|
|
888
907
|
) : (
|
|
889
908
|
<LayerColorSelector
|
|
890
909
|
{...visConfiguratorProps}
|
|
@@ -963,7 +982,6 @@ export default function LayerConfiguratorFactory(
|
|
|
963
982
|
const layerConfiguratorProps = getLayerConfiguratorProps(this.props);
|
|
964
983
|
const layerChannelConfigProps = getLayerChannelConfigProps(this.props);
|
|
965
984
|
const dataset = getLayerDataset(datasets, layer);
|
|
966
|
-
// TODO
|
|
967
985
|
const renderTemplate = layer.type && `_render${capitalizeFirstLetter(layer.type)}LayerConfig`;
|
|
968
986
|
|
|
969
987
|
return (
|
|
@@ -1049,13 +1067,14 @@ LayerColorSelectorFactory.deps = [ColorSelectorFactory];
|
|
|
1049
1067
|
export function LayerColorSelectorFactory(ColorSelector) {
|
|
1050
1068
|
class LayerColorSelector extends Component {
|
|
1051
1069
|
render() {
|
|
1052
|
-
const {layer, onChange, selectedColor, property = 'color', setColorUI} = this.props;
|
|
1070
|
+
const {layer, onChange, selectedColor, property = 'color', setColorUI, fields} = this.props;
|
|
1053
1071
|
return (
|
|
1054
1072
|
<SidePanelSection>
|
|
1055
1073
|
<PanelLabel>
|
|
1056
1074
|
<FormattedMessage id="layer.color" />
|
|
1057
1075
|
</PanelLabel>
|
|
1058
1076
|
<ColorSelector
|
|
1077
|
+
fields={fields}
|
|
1059
1078
|
colorSets={[
|
|
1060
1079
|
{
|
|
1061
1080
|
selectedColor: selectedColor || layer.config.color,
|
|
@@ -1077,13 +1096,22 @@ ArcLayerColorSelectorFactory.deps = [ColorSelectorFactory];
|
|
|
1077
1096
|
export function ArcLayerColorSelectorFactory(ColorSelector) {
|
|
1078
1097
|
class ArcLayerColorSelector extends Component {
|
|
1079
1098
|
render() {
|
|
1080
|
-
const {
|
|
1099
|
+
const {
|
|
1100
|
+
layer,
|
|
1101
|
+
onChangeConfig,
|
|
1102
|
+
onChangeVisConfig,
|
|
1103
|
+
property = 'color',
|
|
1104
|
+
setColorUI,
|
|
1105
|
+
fields
|
|
1106
|
+
} = this.props;
|
|
1107
|
+
|
|
1081
1108
|
return (
|
|
1082
1109
|
<SidePanelSection>
|
|
1083
1110
|
<PanelLabel>
|
|
1084
1111
|
<FormattedMessage id="layer.colorRange" />
|
|
1085
1112
|
</PanelLabel>
|
|
1086
1113
|
<ColorSelector
|
|
1114
|
+
fields={fields}
|
|
1087
1115
|
colorSets={[
|
|
1088
1116
|
{
|
|
1089
1117
|
selectedColor: layer.config.color,
|
|
@@ -1114,42 +1142,48 @@ export function LayerColorRangeSelectorFactory(ColorSelector) {
|
|
|
1114
1142
|
layer,
|
|
1115
1143
|
onChange,
|
|
1116
1144
|
property = 'colorRange',
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
setColorUI
|
|
1145
|
+
field = 'colorField',
|
|
1146
|
+
scale = 'colorScale',
|
|
1147
|
+
setColorUI,
|
|
1148
|
+
fields
|
|
1120
1149
|
} = 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
1150
|
return (
|
|
1145
1151
|
<SidePanelSection>
|
|
1146
1152
|
<PanelLabel>
|
|
1147
1153
|
<FormattedMessage id="layer.colorRange" />
|
|
1148
1154
|
</PanelLabel>
|
|
1149
1155
|
<ColorSelector
|
|
1150
|
-
|
|
1156
|
+
fields={fields}
|
|
1157
|
+
colorSets={[
|
|
1158
|
+
{
|
|
1159
|
+
selectedColor: layer.config.visConfig[property],
|
|
1160
|
+
isRange: true,
|
|
1161
|
+
setColor: colorRange => {
|
|
1162
|
+
layer.updateLayerConfig({
|
|
1163
|
+
[scale]: SCALE_TYPES.ordinal
|
|
1164
|
+
});
|
|
1165
|
+
const {colorMap} = layer.config.visConfig[property];
|
|
1166
|
+
const colorRangeUpdated = colorMap
|
|
1167
|
+
? layer.updateColorMap(property, colorMap, colorRange)
|
|
1168
|
+
: colorRange;
|
|
1169
|
+
onChange({[property]: colorRangeUpdated});
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
]}
|
|
1151
1173
|
colorUI={layer.config.colorUI[property]}
|
|
1152
1174
|
setColorUI={newConfig => setColorUI(property, newConfig)}
|
|
1175
|
+
onSelectHexColorColumn={colorColumn => {
|
|
1176
|
+
layer.updateLayerConfig({
|
|
1177
|
+
[field]: {
|
|
1178
|
+
...layer.config[field],
|
|
1179
|
+
colorColumn: colorColumn?.name,
|
|
1180
|
+
colorColumnIdx: colorColumn?.fieldIdx
|
|
1181
|
+
},
|
|
1182
|
+
[scale]: SCALE_TYPES.identity
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
onChange({[property]: hexColorCustomPalette});
|
|
1186
|
+
}}
|
|
1153
1187
|
/>
|
|
1154
1188
|
</SidePanelSection>
|
|
1155
1189
|
);
|
|
@@ -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,7 @@ 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 {
|
|
48
|
+
import {scaleIdentity} from 'utils/custom-scales';
|
|
49
49
|
|
|
50
50
|
export const ACTION_PREFIX = '@@kepler.gl/';
|
|
51
51
|
export const CLOUDFRONT = 'https://d1a3f4spazzrp4.cloudfront.net/kepler.gl';
|
|
@@ -312,8 +312,7 @@ export const SCALE_TYPES = keyMirror({
|
|
|
312
312
|
custom: null,
|
|
313
313
|
// UI-only type, resolving as custom
|
|
314
314
|
logarithmic: null,
|
|
315
|
-
|
|
316
|
-
hexColor: null
|
|
315
|
+
identity: null
|
|
317
316
|
});
|
|
318
317
|
|
|
319
318
|
export const SCALE_FUNC = {
|
|
@@ -325,7 +324,7 @@ export const SCALE_FUNC = {
|
|
|
325
324
|
[SCALE_TYPES.log]: scaleLog,
|
|
326
325
|
[SCALE_TYPES.point]: scalePoint,
|
|
327
326
|
[SCALE_TYPES.custom]: scaleThreshold,
|
|
328
|
-
[SCALE_TYPES.
|
|
327
|
+
[SCALE_TYPES.identity]: scaleIdentity
|
|
329
328
|
};
|
|
330
329
|
|
|
331
330
|
export const ALL_FIELD_TYPES = keyMirror({
|
|
@@ -439,7 +438,8 @@ export const CHANNEL_SCALES = keyMirror({
|
|
|
439
438
|
size: null,
|
|
440
439
|
customMarker: null,
|
|
441
440
|
colorAggr: null,
|
|
442
|
-
sizeAggr: null
|
|
441
|
+
sizeAggr: null,
|
|
442
|
+
identity: null
|
|
443
443
|
});
|
|
444
444
|
|
|
445
445
|
export const AGGREGATION_TYPES = {
|
|
@@ -557,10 +557,11 @@ export const linearFieldAggrScaleFunctions = {
|
|
|
557
557
|
};
|
|
558
558
|
|
|
559
559
|
export const ordinalFieldScaleFunctions = {
|
|
560
|
-
[CHANNEL_SCALES.color]: [SCALE_TYPES.ordinal
|
|
560
|
+
[CHANNEL_SCALES.color]: [SCALE_TYPES.ordinal],
|
|
561
561
|
[CHANNEL_SCALES.radius]: [SCALE_TYPES.point],
|
|
562
562
|
[CHANNEL_SCALES.size]: [SCALE_TYPES.point],
|
|
563
|
-
[CHANNEL_SCALES.customMarker]: [SCALE_TYPES.ordinal]
|
|
563
|
+
[CHANNEL_SCALES.customMarker]: [SCALE_TYPES.ordinal],
|
|
564
|
+
[CHANNEL_SCALES.identity]: []
|
|
564
565
|
};
|
|
565
566
|
|
|
566
567
|
export const ordinalFieldAggrScaleFunctions = {
|
package/src/layers/base-layer.js
CHANGED
|
@@ -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 =
|
|
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
|
|
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 (
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
1047
|
-
const {dataContainer} =
|
|
1080
|
+
const dataset = this.getDataset(datasets);
|
|
1081
|
+
const {dataContainer} = dataset;
|
|
1048
1082
|
|
|
1049
|
-
this.updateVisualChannelFields(
|
|
1083
|
+
this.updateVisualChannelFields(dataset);
|
|
1084
|
+
this.updateHexColorDomain(dataset);
|
|
1050
1085
|
|
|
1051
1086
|
const getPosition = this.getPositionAccessor(dataContainer);
|
|
1052
|
-
const dataUpdateTriggers = this.getDataUpdateTriggers(
|
|
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(
|
|
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
|
-
|
|
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
|
});
|
|
@@ -1152,7 +1195,7 @@ class Layer {
|
|
|
1152
1195
|
validateScale(channel) {
|
|
1153
1196
|
const visualChannel = this.visualChannels[channel];
|
|
1154
1197
|
const {scale} = visualChannel;
|
|
1155
|
-
if (!scale) {
|
|
1198
|
+
if (!scale || this.config[scale] === SCALE_TYPES.identity) {
|
|
1156
1199
|
// visualChannel doesn't have scale
|
|
1157
1200
|
return;
|
|
1158
1201
|
}
|
|
@@ -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;
|
|
@@ -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
|
|
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
|
package/src/localization/en.js
CHANGED
|
@@ -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
|
}),
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export function scaleHexColor() {
|
|
1
|
+
export function scaleIdentity() {
|
|
4
2
|
let unknown;
|
|
5
3
|
function scale(x) {
|
|
6
|
-
return x === null ? unknown :
|
|
4
|
+
return x === null ? unknown : x;
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
scale.invert = scale;
|
|
10
8
|
|
|
11
|
-
scale.domain = scale.range =
|
|
9
|
+
scale.domain = scale.range = scaleIdentity;
|
|
12
10
|
|
|
13
11
|
scale.unknown = u => {
|
|
14
12
|
if (u) {
|
|
@@ -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);
|