@carto/kepler.gl 0.0.33-alpha1 → 0.0.34
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/index.js +25 -2
- package/dist/components/side-panel/layer-panel/color-dimension-scale-selector.js +45 -0
- package/dist/components/side-panel/layer-panel/layer-configurator.js +108 -33
- package/dist/components/side-panel/layer-panel/vis-config-by-field-selector.js +23 -5
- package/dist/constants/default-settings.js +12 -9
- package/dist/constants/index.js +7 -1
- package/dist/deckgl-layers/layer-utils/cpu-aggregator.js +12 -9
- package/dist/layers/aggregation-layer.js +23 -1
- package/dist/layers/base-layer.js +120 -6
- package/dist/layers/cluster-layer/cluster-layer.js +2 -1
- package/dist/layers/h3-hexagon-layer/h3-hexagon-layer.js +16 -14
- package/dist/utils/data-scale-utils.js +2 -2
- package/dist/utils/data-utils.js +19 -1
- package/package.json +1 -1
- package/src/components/index.js +5 -0
- package/src/components/side-panel/layer-panel/color-dimension-scale-selector.js +33 -0
- package/src/components/side-panel/layer-panel/layer-configurator.js +101 -23
- package/src/components/side-panel/layer-panel/vis-config-by-field-selector.js +31 -3
- package/src/constants/default-settings.js +21 -13
- package/src/constants/index.js +2 -1
- package/src/deckgl-layers/layer-utils/cpu-aggregator.js +25 -8
- package/src/layers/aggregation-layer.js +19 -1
- package/src/layers/base-layer.js +82 -8
- package/src/layers/cluster-layer/cluster-layer.js +1 -0
- package/src/layers/h3-hexagon-layer/h3-hexagon-layer.js +14 -17
- package/src/utils/data-scale-utils.js +2 -4
- package/src/utils/data-utils.d.ts +1 -0
- package/src/utils/data-utils.js +14 -0
- package/umd/keplergl.min.js +31 -31
- package/CHANGELOG.md +0 -711
|
@@ -40,8 +40,10 @@ import TextLabelPanelFactory from './text-label-panel';
|
|
|
40
40
|
|
|
41
41
|
import {capitalizeFirstLetter} from 'utils/utils';
|
|
42
42
|
|
|
43
|
-
import {CHANNEL_SCALE_SUPPORTED_FIELDS} from 'constants/default-settings';
|
|
43
|
+
import {CHANNEL_SCALES, CHANNEL_SCALE_SUPPORTED_FIELDS} from 'constants/default-settings';
|
|
44
44
|
import {LAYER_TYPES} from 'layers/types';
|
|
45
|
+
import {injectIntl} from 'react-intl';
|
|
46
|
+
import ColorDimensionScaleSelectorFactory from './color-dimension-scale-selector';
|
|
45
47
|
|
|
46
48
|
const StyledLayerConfigurator = styled.div.attrs({
|
|
47
49
|
className: 'layer-panel__config'
|
|
@@ -82,7 +84,8 @@ export const getVisConfiguratorProps = props => ({
|
|
|
82
84
|
export const getLayerChannelConfigProps = props => ({
|
|
83
85
|
layer: props.layer,
|
|
84
86
|
fields: getLayerFields(props.datasets, props.layer),
|
|
85
|
-
onChange: props.updateLayerVisualChannelConfig
|
|
87
|
+
onChange: props.updateLayerVisualChannelConfig,
|
|
88
|
+
onChangeVisConfig: props.updateLayerVisConfig
|
|
86
89
|
});
|
|
87
90
|
|
|
88
91
|
LayerConfiguratorFactory.deps = [
|
|
@@ -93,7 +96,8 @@ LayerConfiguratorFactory.deps = [
|
|
|
93
96
|
ChannelByValueSelectorFactory,
|
|
94
97
|
LayerColumnConfigFactory,
|
|
95
98
|
LayerTypeSelectorFactory,
|
|
96
|
-
VisConfigSwitchFactory
|
|
99
|
+
VisConfigSwitchFactory,
|
|
100
|
+
AggrScaleSelectorFactory
|
|
97
101
|
];
|
|
98
102
|
|
|
99
103
|
export default function LayerConfiguratorFactory(
|
|
@@ -104,7 +108,8 @@ export default function LayerConfiguratorFactory(
|
|
|
104
108
|
ChannelByValueSelector,
|
|
105
109
|
LayerColumnConfig,
|
|
106
110
|
LayerTypeSelector,
|
|
107
|
-
VisConfigSwitch
|
|
111
|
+
VisConfigSwitch,
|
|
112
|
+
AggrScaleSelector
|
|
108
113
|
) {
|
|
109
114
|
class LayerConfigurator extends Component {
|
|
110
115
|
static propTypes = {
|
|
@@ -240,7 +245,11 @@ export default function LayerConfiguratorFactory(
|
|
|
240
245
|
<LayerConfigGroup label={'layer.color'} collapsible>
|
|
241
246
|
<LayerColorRangeSelector {...visConfiguratorProps} />
|
|
242
247
|
<ConfigGroupCollapsibleContent>
|
|
243
|
-
<AggrScaleSelector
|
|
248
|
+
<AggrScaleSelector
|
|
249
|
+
{...layerConfiguratorProps}
|
|
250
|
+
channel={layer.visualChannels.color}
|
|
251
|
+
onChangeVisConfig={layerChannelConfigProps.onChangeVisConfig}
|
|
252
|
+
/>
|
|
244
253
|
<ChannelByValueSelector
|
|
245
254
|
channel={layer.visualChannels.color}
|
|
246
255
|
{...layerChannelConfigProps}
|
|
@@ -328,7 +337,11 @@ export default function LayerConfiguratorFactory(
|
|
|
328
337
|
<LayerConfigGroup label={'layer.color'} collapsible>
|
|
329
338
|
<LayerColorRangeSelector {...visConfiguratorProps} />
|
|
330
339
|
<ConfigGroupCollapsibleContent>
|
|
331
|
-
<AggrScaleSelector
|
|
340
|
+
<AggrScaleSelector
|
|
341
|
+
{...layerConfiguratorProps}
|
|
342
|
+
channel={layer.visualChannels.color}
|
|
343
|
+
onChangeVisConfig={layerChannelConfigProps.onChangeVisConfig}
|
|
344
|
+
/>
|
|
332
345
|
<ChannelByValueSelector
|
|
333
346
|
channel={layer.visualChannels.color}
|
|
334
347
|
{...layerChannelConfigProps}
|
|
@@ -382,6 +395,7 @@ export default function LayerConfiguratorFactory(
|
|
|
382
395
|
<AggrScaleSelector
|
|
383
396
|
{...layerConfiguratorProps}
|
|
384
397
|
channel={layer.visualChannels.size}
|
|
398
|
+
onChangeVisConfig={layerChannelConfigProps.onChangeVisConfig}
|
|
385
399
|
/>
|
|
386
400
|
<VisConfigSlider
|
|
387
401
|
{...layer.visConfigSettings.sizeRange}
|
|
@@ -1067,7 +1081,13 @@ export const LayerColorRangeSelector = ({layer, onChange, property = 'colorRange
|
|
|
1067
1081
|
{
|
|
1068
1082
|
selectedColor: layer.config.visConfig[property],
|
|
1069
1083
|
isRange: true,
|
|
1070
|
-
setColor: colorRange =>
|
|
1084
|
+
setColor: colorRange => {
|
|
1085
|
+
const {colorMap} = layer.config.visConfig[property];
|
|
1086
|
+
const colorRangeUpdated = colorMap
|
|
1087
|
+
? layer.updateColorMap(property, colorMap, colorRange)
|
|
1088
|
+
: colorRange;
|
|
1089
|
+
onChange({[property]: colorRangeUpdated});
|
|
1090
|
+
}
|
|
1071
1091
|
}
|
|
1072
1092
|
]}
|
|
1073
1093
|
colorUI={layer.config.colorUI[property]}
|
|
@@ -1078,7 +1098,15 @@ export const LayerColorRangeSelector = ({layer, onChange, property = 'colorRange
|
|
|
1078
1098
|
|
|
1079
1099
|
ChannelByValueSelectorFactory.deps = [VisConfigByFieldSelectorFactory];
|
|
1080
1100
|
export function ChannelByValueSelectorFactory(VisConfigByFieldSelector) {
|
|
1081
|
-
const ChannelByValueSelector = ({
|
|
1101
|
+
const ChannelByValueSelector = ({
|
|
1102
|
+
layer,
|
|
1103
|
+
channel,
|
|
1104
|
+
onChange,
|
|
1105
|
+
onChangeVisConfig,
|
|
1106
|
+
fields,
|
|
1107
|
+
description,
|
|
1108
|
+
isLoading
|
|
1109
|
+
}) => {
|
|
1082
1110
|
const {
|
|
1083
1111
|
channelScaleType,
|
|
1084
1112
|
domain,
|
|
@@ -1094,8 +1122,18 @@ export function ChannelByValueSelectorFactory(VisConfigByFieldSelector) {
|
|
|
1094
1122
|
supportedFieldTypes || CHANNEL_SCALE_SUPPORTED_FIELDS[channelScaleType];
|
|
1095
1123
|
const supportedFields = fields.filter(({type}) => channelSupportedFieldTypes.includes(type));
|
|
1096
1124
|
const scaleOptions = layer.getScaleOptions(channel.key);
|
|
1097
|
-
const
|
|
1125
|
+
const showScaleCustomizable =
|
|
1126
|
+
channelScaleType === CHANNEL_SCALES.color &&
|
|
1127
|
+
layer.config[scale] &&
|
|
1128
|
+
Boolean(layer.config[field]) &&
|
|
1129
|
+
scaleOptions.length > 0;
|
|
1130
|
+
const showScale =
|
|
1131
|
+
!showScaleCustomizable &&
|
|
1132
|
+
!layer.isAggregated &&
|
|
1133
|
+
layer.config[scale] &&
|
|
1134
|
+
scaleOptions.length > 1;
|
|
1098
1135
|
const defaultDescription = 'layerConfiguration.defaultDescription';
|
|
1136
|
+
const visRange = layer.config.visConfig[range];
|
|
1099
1137
|
|
|
1100
1138
|
return (
|
|
1101
1139
|
<VisConfigByFieldSelector
|
|
@@ -1107,13 +1145,20 @@ export function ChannelByValueSelectorFactory(VisConfigByFieldSelector) {
|
|
|
1107
1145
|
key={`${key}-channel-selector`}
|
|
1108
1146
|
property={property}
|
|
1109
1147
|
placeholder={defaultMeasure || 'placeholder.selectField'}
|
|
1110
|
-
range={
|
|
1148
|
+
range={visRange}
|
|
1111
1149
|
scaleOptions={scaleOptions}
|
|
1112
1150
|
scaleType={scale ? layer.config[scale] : null}
|
|
1113
1151
|
selectedField={layer.config[field]}
|
|
1114
1152
|
showScale={showScale}
|
|
1115
|
-
|
|
1153
|
+
showScaleCustomizable={showScaleCustomizable}
|
|
1154
|
+
updateField={val => {
|
|
1155
|
+
if (visRange.colorMap) {
|
|
1156
|
+
onChangeVisConfig({[range]: {...visRange, colorMap: undefined}});
|
|
1157
|
+
}
|
|
1158
|
+
onChange({[field]: val}, key);
|
|
1159
|
+
}}
|
|
1116
1160
|
updateScale={val => onChange({[scale]: val}, key)}
|
|
1161
|
+
updateCustomPalette={colorMap => onChangeVisConfig({[range]: {...visRange, colorMap}})}
|
|
1117
1162
|
isLoading={isLoading}
|
|
1118
1163
|
/>
|
|
1119
1164
|
);
|
|
@@ -1122,19 +1167,52 @@ export function ChannelByValueSelectorFactory(VisConfigByFieldSelector) {
|
|
|
1122
1167
|
return ChannelByValueSelector;
|
|
1123
1168
|
}
|
|
1124
1169
|
|
|
1125
|
-
|
|
1126
|
-
const {scale, key} = channel;
|
|
1127
|
-
const scaleOptions = layer.getScaleOptions(key);
|
|
1170
|
+
AggrScaleSelectorFactory.deps = [ColorDimensionScaleSelectorFactory];
|
|
1128
1171
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1172
|
+
function AggrScaleSelectorFactory(ColorDimensionScaleSelector) {
|
|
1173
|
+
class AggrScaleSelector extends Component {
|
|
1174
|
+
render() {
|
|
1175
|
+
const {channel, layer, onChange, onChangeVisConfig} = this.props;
|
|
1176
|
+
const {scale, key, channelScaleType, domain, range} = channel;
|
|
1177
|
+
const scaleOptions = layer.getScaleOptions(key);
|
|
1178
|
+
const visRange = layer.config.visConfig[range];
|
|
1179
|
+
const showScaleCustomizable =
|
|
1180
|
+
channelScaleType === CHANNEL_SCALES.colorAggr &&
|
|
1181
|
+
Array.isArray(scaleOptions) &&
|
|
1182
|
+
scaleOptions.length > 0;
|
|
1183
|
+
const showScale = Array.isArray(scaleOptions) && scaleOptions.length > 1;
|
|
1184
|
+
|
|
1185
|
+
if (showScaleCustomizable) {
|
|
1186
|
+
return (
|
|
1187
|
+
<SidePanelSection>
|
|
1188
|
+
<ColorDimensionScaleSelector
|
|
1189
|
+
label={`${key} Scale`}
|
|
1190
|
+
scaleType={layer.config[scale]}
|
|
1191
|
+
options={scaleOptions}
|
|
1192
|
+
domain={layer.config[domain]}
|
|
1193
|
+
range={visRange}
|
|
1194
|
+
onSelect={val => onChange({[scale]: val}, key)}
|
|
1195
|
+
onSetCustomPalette={colorMap => onChangeVisConfig({[range]: {...visRange, colorMap}})}
|
|
1196
|
+
/>
|
|
1197
|
+
</SidePanelSection>
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
if (showScale) {
|
|
1202
|
+
return (
|
|
1203
|
+
<DimensionScaleSelector
|
|
1204
|
+
label={`${key} Scale`}
|
|
1205
|
+
options={scaleOptions}
|
|
1206
|
+
scaleType={layer.config[scale]}
|
|
1207
|
+
onSelect={val => onChange({[scale]: val}, key)}
|
|
1208
|
+
/>
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
return null;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
return injectIntl(AggrScaleSelector);
|
|
1215
|
+
}
|
|
1138
1216
|
|
|
1139
1217
|
export const AggregationTypeSelector = ({layer, channel, onChange}) => {
|
|
1140
1218
|
const {field, aggregation, key} = channel;
|
|
@@ -27,9 +27,14 @@ import InfoHelperFacotry from 'components/common/info-helper';
|
|
|
27
27
|
import DimensionScaleSelector from './dimension-scale-selector';
|
|
28
28
|
import {camelize} from 'utils/utils';
|
|
29
29
|
import FieldSelectorFactory from '../../common/field-selector';
|
|
30
|
+
import ColorDimensionScaleSelectorFactory from './color-dimension-scale-selector';
|
|
30
31
|
|
|
31
|
-
VisConfigByFieldSelectorFactory.deps = [
|
|
32
|
-
|
|
32
|
+
VisConfigByFieldSelectorFactory.deps = [
|
|
33
|
+
InfoHelperFacotry,
|
|
34
|
+
FieldSelectorFactory,
|
|
35
|
+
ColorDimensionScaleSelectorFactory
|
|
36
|
+
];
|
|
37
|
+
function VisConfigByFieldSelectorFactory(InfoHelper, FieldSelector, ColorDimensionScaleSelector) {
|
|
33
38
|
class VisConfigByFieldSelector extends Component {
|
|
34
39
|
static propTypes = {
|
|
35
40
|
channel: PropTypes.string.isRequired,
|
|
@@ -37,8 +42,10 @@ function VisConfigByFieldSelectorFactory(InfoHelper, FieldSelector) {
|
|
|
37
42
|
id: PropTypes.string.isRequired,
|
|
38
43
|
property: PropTypes.string.isRequired,
|
|
39
44
|
showScale: PropTypes.bool.isRequired,
|
|
45
|
+
showScaleCustomizable: PropTypes.bool.isRequired,
|
|
40
46
|
updateField: PropTypes.func.isRequired,
|
|
41
47
|
updateScale: PropTypes.func.isRequired,
|
|
48
|
+
updateCustomPalette: PropTypes.func.isRequired,
|
|
42
49
|
|
|
43
50
|
// optional
|
|
44
51
|
scaleType: PropTypes.string,
|
|
@@ -57,11 +64,14 @@ function VisConfigByFieldSelectorFactory(InfoHelper, FieldSelector) {
|
|
|
57
64
|
const {
|
|
58
65
|
property,
|
|
59
66
|
showScale,
|
|
67
|
+
showScaleCustomizable,
|
|
60
68
|
selectedField,
|
|
61
69
|
description,
|
|
62
70
|
label,
|
|
63
71
|
intl,
|
|
64
|
-
scaleOptions = []
|
|
72
|
+
scaleOptions = [],
|
|
73
|
+
domain,
|
|
74
|
+
range
|
|
65
75
|
} = this.props;
|
|
66
76
|
|
|
67
77
|
return (
|
|
@@ -109,6 +119,24 @@ function VisConfigByFieldSelectorFactory(InfoHelper, FieldSelector) {
|
|
|
109
119
|
/>
|
|
110
120
|
) : null}
|
|
111
121
|
</div>
|
|
122
|
+
<div>
|
|
123
|
+
{showScaleCustomizable && !this.props.isLoading && (
|
|
124
|
+
<ColorDimensionScaleSelector
|
|
125
|
+
label={
|
|
126
|
+
<FormattedMessage
|
|
127
|
+
id={`scale.${camelize(`${property} scale`)}`}
|
|
128
|
+
defaultMessage={label}
|
|
129
|
+
/>
|
|
130
|
+
}
|
|
131
|
+
scaleType={this.props.scaleType}
|
|
132
|
+
options={scaleOptions}
|
|
133
|
+
domain={domain}
|
|
134
|
+
range={range}
|
|
135
|
+
onSelect={this.props.updateScale}
|
|
136
|
+
onSetCustomPalette={this.props.updateCustomPalette}
|
|
137
|
+
/>
|
|
138
|
+
)}
|
|
139
|
+
</div>
|
|
112
140
|
</SidePanelSection>
|
|
113
141
|
);
|
|
114
142
|
}
|
|
@@ -28,7 +28,8 @@ import {
|
|
|
28
28
|
scaleOrdinal,
|
|
29
29
|
scaleSqrt,
|
|
30
30
|
scaleLog,
|
|
31
|
-
scalePoint
|
|
31
|
+
scalePoint,
|
|
32
|
+
scaleThreshold
|
|
32
33
|
} from 'd3-scale';
|
|
33
34
|
import {
|
|
34
35
|
Layers,
|
|
@@ -306,7 +307,8 @@ export const SCALE_TYPES = keyMirror({
|
|
|
306
307
|
log: null,
|
|
307
308
|
|
|
308
309
|
// ordinal domain to linear range
|
|
309
|
-
point: null
|
|
310
|
+
point: null,
|
|
311
|
+
custom: null
|
|
310
312
|
});
|
|
311
313
|
|
|
312
314
|
export const SCALE_FUNC = {
|
|
@@ -316,7 +318,8 @@ export const SCALE_FUNC = {
|
|
|
316
318
|
[SCALE_TYPES.ordinal]: scaleOrdinal,
|
|
317
319
|
[SCALE_TYPES.sqrt]: scaleSqrt,
|
|
318
320
|
[SCALE_TYPES.log]: scaleLog,
|
|
319
|
-
[SCALE_TYPES.point]: scalePoint
|
|
321
|
+
[SCALE_TYPES.point]: scalePoint,
|
|
322
|
+
[SCALE_TYPES.custom]: scaleThreshold
|
|
320
323
|
};
|
|
321
324
|
|
|
322
325
|
export const ALL_FIELD_TYPES = keyMirror({
|
|
@@ -449,20 +452,20 @@ export const AGGREGATION_TYPES = {
|
|
|
449
452
|
};
|
|
450
453
|
|
|
451
454
|
export const linearFieldScaleFunctions = {
|
|
452
|
-
[CHANNEL_SCALES.color]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
455
|
+
[CHANNEL_SCALES.color]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
453
456
|
[CHANNEL_SCALES.radius]: [SCALE_TYPES.sqrt],
|
|
454
457
|
[CHANNEL_SCALES.size]: [SCALE_TYPES.linear, SCALE_TYPES.sqrt, SCALE_TYPES.log]
|
|
455
458
|
};
|
|
456
459
|
|
|
457
460
|
export const linearFieldAggrScaleFunctions = {
|
|
458
461
|
[CHANNEL_SCALES.colorAggr]: {
|
|
459
|
-
[AGGREGATION_TYPES.average]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
460
|
-
[AGGREGATION_TYPES.maximum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
461
|
-
[AGGREGATION_TYPES.minimum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
462
|
-
[AGGREGATION_TYPES.median]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
463
|
-
[AGGREGATION_TYPES.stdev]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
464
|
-
[AGGREGATION_TYPES.sum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile],
|
|
465
|
-
[AGGREGATION_TYPES.variance]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile]
|
|
462
|
+
[AGGREGATION_TYPES.average]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
463
|
+
[AGGREGATION_TYPES.maximum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
464
|
+
[AGGREGATION_TYPES.minimum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
465
|
+
[AGGREGATION_TYPES.median]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
466
|
+
[AGGREGATION_TYPES.stdev]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
467
|
+
[AGGREGATION_TYPES.sum]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom],
|
|
468
|
+
[AGGREGATION_TYPES.variance]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom]
|
|
466
469
|
},
|
|
467
470
|
|
|
468
471
|
[CHANNEL_SCALES.sizeAggr]: {
|
|
@@ -486,7 +489,11 @@ export const ordinalFieldAggrScaleFunctions = {
|
|
|
486
489
|
// [CHANNEL_SCALES.colorAggr]: [SCALE_TYPES.ordinal, SCALE_TYPES.linear],
|
|
487
490
|
[CHANNEL_SCALES.colorAggr]: {
|
|
488
491
|
[AGGREGATION_TYPES.mode]: [SCALE_TYPES.ordinal],
|
|
489
|
-
[AGGREGATION_TYPES.countUnique]: [
|
|
492
|
+
[AGGREGATION_TYPES.countUnique]: [
|
|
493
|
+
SCALE_TYPES.quantize,
|
|
494
|
+
SCALE_TYPES.quantile,
|
|
495
|
+
SCALE_TYPES.custom
|
|
496
|
+
]
|
|
490
497
|
},
|
|
491
498
|
|
|
492
499
|
// Currently doesn't support yet
|
|
@@ -509,7 +516,7 @@ export const notSupportAggrOpts = {
|
|
|
509
516
|
*/
|
|
510
517
|
export const DEFAULT_AGGREGATION = {
|
|
511
518
|
[CHANNEL_SCALES.colorAggr]: {
|
|
512
|
-
[AGGREGATION_TYPES.count]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile]
|
|
519
|
+
[AGGREGATION_TYPES.count]: [SCALE_TYPES.quantize, SCALE_TYPES.quantile, SCALE_TYPES.custom]
|
|
513
520
|
},
|
|
514
521
|
[CHANNEL_SCALES.sizeAggr]: {
|
|
515
522
|
[AGGREGATION_TYPES.count]: [SCALE_TYPES.linear, SCALE_TYPES.sqrt, SCALE_TYPES.log]
|
|
@@ -629,6 +636,7 @@ export const DEFAULT_LAYER_COLOR = {
|
|
|
629
636
|
export const DEFAULT_TOOLTIP_FIELDS = [];
|
|
630
637
|
|
|
631
638
|
export const NO_VALUE_COLOR = [0, 0, 0, 0];
|
|
639
|
+
export const UNKNOWN_COLOR = [134, 141, 145];
|
|
632
640
|
|
|
633
641
|
export const LAYER_BLENDINGS = {
|
|
634
642
|
additive: {
|
package/src/constants/index.js
CHANGED
|
@@ -23,7 +23,12 @@ import {AGGREGATION_OPERATION, _BinSorter as BinSorter} from '@deck.gl/aggregati
|
|
|
23
23
|
import {console as Console} from 'global/window';
|
|
24
24
|
|
|
25
25
|
import {aggregate} from 'utils/aggregate-utils';
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
AGGREGATION_TYPES,
|
|
28
|
+
SCALE_FUNC,
|
|
29
|
+
UNKNOWN_COLOR,
|
|
30
|
+
SCALE_TYPES
|
|
31
|
+
} from 'constants/default-settings';
|
|
27
32
|
|
|
28
33
|
export const DECK_AGGREGATION_MAP = {
|
|
29
34
|
[AGGREGATION_OPERATION.SUM]: AGGREGATION_TYPES.sum,
|
|
@@ -97,7 +102,10 @@ export function getDimensionValueDomain(step, props, dimensionUpdater) {
|
|
|
97
102
|
[props[lowerPercentile.prop], props[upperPercentile.prop]]
|
|
98
103
|
);
|
|
99
104
|
|
|
100
|
-
this._setDimensionState(key, {
|
|
105
|
+
this._setDimensionState(key, {
|
|
106
|
+
// By default sortedBins order by ascending frecuency but if we've an ordinal scale we want to order by descending frecuency
|
|
107
|
+
valueDomain: props[scaleType.prop] === SCALE_TYPES.ordinal ? valueDomain.reverse() : valueDomain
|
|
108
|
+
});
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
export function getDimensionScale(step, props, dimensionUpdater) {
|
|
@@ -112,12 +120,20 @@ export function getDimensionScale(step, props, dimensionUpdater) {
|
|
|
112
120
|
const dimensionRange = props[range.prop];
|
|
113
121
|
const dimensionDomain = props[domain.prop] || this.state.dimensions[key].valueDomain;
|
|
114
122
|
|
|
115
|
-
const
|
|
123
|
+
const scaleTypeProp = scaleType && props[scaleType.prop];
|
|
124
|
+
const scaleFunctor = getScaleFunctor(scaleTypeProp)();
|
|
116
125
|
|
|
117
|
-
const scaleFunc = scaleFunctor
|
|
126
|
+
const scaleFunc = scaleFunctor
|
|
127
|
+
.domain(
|
|
128
|
+
scaleTypeProp === SCALE_TYPES.ordinal
|
|
129
|
+
? dimensionDomain.slice(0, dimensionRange.length)
|
|
130
|
+
: dimensionDomain
|
|
131
|
+
)
|
|
132
|
+
.range(dimensionRange)
|
|
133
|
+
.unknown(UNKNOWN_COLOR);
|
|
118
134
|
|
|
119
135
|
if (typeof onSet === 'object' && typeof props[onSet.props] === 'function') {
|
|
120
|
-
props[onSet.props](
|
|
136
|
+
props[onSet.props](this.state.dimensions[key].valueDomain);
|
|
121
137
|
}
|
|
122
138
|
this._setDimensionState(key, {scaleFunc});
|
|
123
139
|
}
|
|
@@ -180,12 +196,13 @@ function getSubLayerAccessor(dimensionState, dimension, layerProps) {
|
|
|
180
196
|
}
|
|
181
197
|
|
|
182
198
|
const cv = bin && bin.value;
|
|
183
|
-
const domain = scaleFunc.domain();
|
|
199
|
+
// const domain = scaleFunc.domain();
|
|
184
200
|
|
|
185
|
-
const isValueInDomain = cv >= domain[0] && cv <= domain[domain.length - 1];
|
|
201
|
+
// const isValueInDomain = cv >= domain[0] && cv <= domain[domain.length - 1];
|
|
186
202
|
|
|
187
203
|
// if cell value is outside domain, set alpha to 0
|
|
188
|
-
return isValueInDomain ? scaleFunc(cv) : dimension.nullValue;
|
|
204
|
+
// return isValueInDomain ? scaleFunc(cv) : dimension.nullValue;
|
|
205
|
+
return scaleFunc(cv);
|
|
189
206
|
};
|
|
190
207
|
}
|
|
191
208
|
|
|
@@ -53,7 +53,23 @@ export const getValueAggrFunc = (field, aggregation) => {
|
|
|
53
53
|
export const getFilterDataFunc = (filterRange, getFilterValue) => pt =>
|
|
54
54
|
getFilterValue(pt).every((val, i) => val >= filterRange[i][0] && val <= filterRange[i][1]);
|
|
55
55
|
|
|
56
|
-
const getLayerColorRange = colorRange =>
|
|
56
|
+
const getLayerColorRange = colorRange => {
|
|
57
|
+
const {colorMap} = colorRange;
|
|
58
|
+
|
|
59
|
+
if (colorMap) {
|
|
60
|
+
return colorMap.map(cMap => hexToRgb(cMap[1]));
|
|
61
|
+
}
|
|
62
|
+
return colorRange.colors.map(hexToRgb);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getLayerColorDomain = colorDomain => {
|
|
66
|
+
const {colorMap} = colorDomain;
|
|
67
|
+
|
|
68
|
+
if (colorMap) {
|
|
69
|
+
return colorMap.map(cMap => cMap[0]);
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
57
73
|
|
|
58
74
|
export const aggregateRequiredColumns = ['lat', 'lng'];
|
|
59
75
|
|
|
@@ -64,6 +80,7 @@ export default class AggregationLayer extends Layer {
|
|
|
64
80
|
this.getPositionAccessor = dataContainer =>
|
|
65
81
|
pointPosAccessor(this.config.columns)(dataContainer);
|
|
66
82
|
this.getColorRange = memoize(getLayerColorRange);
|
|
83
|
+
this.getColorDomain = memoize(getLayerColorDomain);
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
get isAggregated() {
|
|
@@ -315,6 +332,7 @@ export default class AggregationLayer extends Layer {
|
|
|
315
332
|
|
|
316
333
|
// color
|
|
317
334
|
colorRange: this.getColorRange(visConfig.colorRange),
|
|
335
|
+
colorDomain: this.getColorDomain(visConfig.colorRange),
|
|
318
336
|
colorScaleType: this.config.colorScale,
|
|
319
337
|
upperPercentile: visConfig.percentile[1],
|
|
320
338
|
lowerPercentile: visConfig.percentile[0],
|
package/src/layers/base-layer.js
CHANGED
|
@@ -35,7 +35,8 @@ import {
|
|
|
35
35
|
FIELD_OPTS,
|
|
36
36
|
SCALE_FUNC,
|
|
37
37
|
CHANNEL_SCALE_SUPPORTED_FIELDS,
|
|
38
|
-
MAX_GPU_FILTERS
|
|
38
|
+
MAX_GPU_FILTERS,
|
|
39
|
+
UNKNOWN_COLOR
|
|
39
40
|
} from 'constants/default-settings';
|
|
40
41
|
import {COLOR_RANGES} from 'constants/color-ranges';
|
|
41
42
|
import {DataVizColors} from 'constants/custom-color-ranges';
|
|
@@ -43,7 +44,6 @@ import {
|
|
|
43
44
|
LAYER_VIS_CONFIGS,
|
|
44
45
|
DEFAULT_TEXT_LABEL,
|
|
45
46
|
DEFAULT_COLOR_UI,
|
|
46
|
-
UNKNOWN_COLOR_KEY,
|
|
47
47
|
DEFAULT_HIGHLIGHT_COLOR,
|
|
48
48
|
DEFAULT_LAYER_LABEL
|
|
49
49
|
} from './layer-factory';
|
|
@@ -636,6 +636,7 @@ class Layer {
|
|
|
636
636
|
});
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
+
// eslint-disable-next-line complexity
|
|
639
640
|
updateColorRangeByColorUI(newConfig, previous, prop) {
|
|
640
641
|
// only update colorRange if changes in UI is made to 'reversed', 'steps' or steps
|
|
641
642
|
const shouldUpdate =
|
|
@@ -664,6 +665,10 @@ class Layer {
|
|
|
664
665
|
if (update && colorRange.reversed) {
|
|
665
666
|
update = reverseColorRange(true, update);
|
|
666
667
|
}
|
|
668
|
+
|
|
669
|
+
if (update && colorRange.colorMap) {
|
|
670
|
+
update = this.updateColorMap(prop, colorRange.colorMap, update);
|
|
671
|
+
}
|
|
667
672
|
}
|
|
668
673
|
}
|
|
669
674
|
|
|
@@ -676,6 +681,69 @@ class Layer {
|
|
|
676
681
|
}
|
|
677
682
|
}
|
|
678
683
|
|
|
684
|
+
updateColorMap(prop, colorMap, colorRange) {
|
|
685
|
+
// @ts-ignore
|
|
686
|
+
const {field, domain} = Object.values(this.visualChannels).find(value => value.range === prop);
|
|
687
|
+
const type = this.config[field]?.type;
|
|
688
|
+
|
|
689
|
+
if (type === 'string' || type === 'boolean' || type === 'date') {
|
|
690
|
+
return this.updateCategoryColorMap(colorMap, this.config[domain], colorRange);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// If no type or type is not string, boolean or date
|
|
694
|
+
return this.updateNumericColorMap(colorMap, this.config[domain], colorRange);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
updateCategoryColorMap(colorMap, domain, colorRange) {
|
|
698
|
+
const colors = colorRange.colors;
|
|
699
|
+
const assignedCategories = [];
|
|
700
|
+
const newColorMap = colorMap.slice(0, colors.length).map((cMap, index) => {
|
|
701
|
+
assignedCategories.push(cMap[0]);
|
|
702
|
+
return [cMap[0], colors[index]];
|
|
703
|
+
});
|
|
704
|
+
const unassignedColors = colors.slice(newColorMap.length, colors.length);
|
|
705
|
+
|
|
706
|
+
for (const color of unassignedColors) {
|
|
707
|
+
const category = domain.find(d => !assignedCategories.includes(d));
|
|
708
|
+
if (!category) {
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
assignedCategories.push(category);
|
|
712
|
+
newColorMap.push([category, color]);
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
...colorRange,
|
|
716
|
+
colorMap: newColorMap
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
updateNumericColorMap(colorMap, domain, update) {
|
|
721
|
+
const colors = update.colors;
|
|
722
|
+
let newColorMap = colorMap.slice(0, colors.length);
|
|
723
|
+
|
|
724
|
+
newColorMap = newColorMap.map((cMap, index) => {
|
|
725
|
+
const value = index === newColorMap.length - 1 ? null : cMap[0];
|
|
726
|
+
return [value, colors[index]];
|
|
727
|
+
});
|
|
728
|
+
const unassignedColors = colors.slice(newColorMap.length, colors.length);
|
|
729
|
+
|
|
730
|
+
if (unassignedColors.length > 0) {
|
|
731
|
+
const maxValue = domain[domain.length - 1];
|
|
732
|
+
const prevValue = newColorMap[newColorMap.length - 2][0];
|
|
733
|
+
const step = (maxValue - prevValue) / (unassignedColors.length + 1);
|
|
734
|
+
newColorMap[newColorMap.length - 1][0] = prevValue + step;
|
|
735
|
+
|
|
736
|
+
for (const [i, color] of unassignedColors.entries()) {
|
|
737
|
+
const value = i === unassignedColors.length - 1 ? null : prevValue + (step * (i + 2));
|
|
738
|
+
newColorMap.push([value, color]);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return {
|
|
742
|
+
...update,
|
|
743
|
+
colorMap: newColorMap
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
|
|
679
747
|
/**
|
|
680
748
|
* Check whether layer has all columns
|
|
681
749
|
* @returns {boolean} yes or no
|
|
@@ -724,10 +792,10 @@ class Layer {
|
|
|
724
792
|
});
|
|
725
793
|
|
|
726
794
|
// @ts-ignore d3 scale
|
|
727
|
-
const scale = SCALE_FUNC[
|
|
728
|
-
.domain(cMap.keys())
|
|
729
|
-
.range(cMap.values())
|
|
730
|
-
.unknown(
|
|
795
|
+
const scale = SCALE_FUNC[colorScale]()
|
|
796
|
+
.domain(Array.from(cMap.keys()))
|
|
797
|
+
.range(Array.from(cMap.values()))
|
|
798
|
+
.unknown(UNKNOWN_COLOR);
|
|
731
799
|
return scale;
|
|
732
800
|
}
|
|
733
801
|
|
|
@@ -795,6 +863,14 @@ class Layer {
|
|
|
795
863
|
}
|
|
796
864
|
|
|
797
865
|
getVisChannelScale(scale, domain, range, fixed) {
|
|
866
|
+
if (scale === SCALE_TYPES.ordinal) {
|
|
867
|
+
// @ts-ignore d3-scale type
|
|
868
|
+
return SCALE_FUNC[scale]()
|
|
869
|
+
.domain(domain.slice(0, range.length))
|
|
870
|
+
.range(range)
|
|
871
|
+
.unknown(UNKNOWN_COLOR);
|
|
872
|
+
}
|
|
873
|
+
|
|
798
874
|
// @ts-ignore d3-scale type
|
|
799
875
|
return SCALE_FUNC[fixed ? 'linear' : scale]()
|
|
800
876
|
.domain(domain)
|
|
@@ -1058,8 +1134,6 @@ class Layer {
|
|
|
1058
1134
|
return defaultDomain;
|
|
1059
1135
|
}
|
|
1060
1136
|
|
|
1061
|
-
// return dataset.getColumnLayerDomain(field, scaleType) || defaultDomain;
|
|
1062
|
-
|
|
1063
1137
|
const dataSetField = dataset.fields.find(f => f.name === field.name);
|
|
1064
1138
|
if (!dataSetField) {
|
|
1065
1139
|
// if new dataset doesn't contain previously set field
|
|
@@ -93,6 +93,7 @@ export default class ClusterLayer extends AggregationLayer {
|
|
|
93
93
|
|
|
94
94
|
// color
|
|
95
95
|
colorRange: this.getColorRange(visConfig.colorRange),
|
|
96
|
+
colorDomain: this.getColorDomain(visConfig.colorRange),
|
|
96
97
|
colorScaleType: this.config.colorScale,
|
|
97
98
|
colorAggregation: visConfig.colorAggregation,
|
|
98
99
|
|