@carto/kepler.gl 0.0.70 → 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.
- package/CHANGELOG.md +938 -0
- 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 +30 -10
- package/dist/constants/color-ranges.js +12 -2
- package/dist/constants/default-settings.js +2 -2
- package/dist/layers/base-layer.js +138 -44
- 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/package.json +1 -1
- 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 +50 -6
- package/src/constants/color-ranges.js +9 -0
- package/src/layers/base-layer.js +92 -26
- 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
|
@@ -29,16 +29,18 @@ import {PanelLabel, Button, Tooltip} from 'components/common/styled-components';
|
|
|
29
29
|
import Switch from 'components/common/switch';
|
|
30
30
|
import ColorPalette from './color-palette';
|
|
31
31
|
import CustomPalette from './custom-palette';
|
|
32
|
-
import {COLOR_RANGES} from 'constants/color-ranges';
|
|
32
|
+
import {COLOR_RANGES, hexColor} from 'constants/color-ranges';
|
|
33
33
|
import {numberSort} from 'utils/data-utils';
|
|
34
34
|
import {reverseColorRange} from 'utils/color-utils';
|
|
35
35
|
import {FormattedMessage} from 'localization';
|
|
36
36
|
import {SwapHorizontal} from 'components/common/icons';
|
|
37
|
+
import HexColumnConfig from './hex-column-config';
|
|
37
38
|
|
|
38
39
|
export const ALL_TYPES = uniq([
|
|
39
40
|
'all',
|
|
40
41
|
...COLOR_RANGES.map(c => c.type).filter(ctype => ctype),
|
|
41
|
-
'custom'
|
|
42
|
+
'custom',
|
|
43
|
+
{value: hexColor, divider: true}
|
|
42
44
|
]);
|
|
43
45
|
|
|
44
46
|
export const ALL_STEPS = uniq(COLOR_RANGES.map(d => d.colors.length)).sort(numberSort);
|
|
@@ -95,9 +97,11 @@ ColorRangeSelectFactory.deps = [ColorPaletteGroupFactory, PaletteConfigFactory];
|
|
|
95
97
|
export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig) {
|
|
96
98
|
class ColorRangeSelect extends Component {
|
|
97
99
|
static propTypes = {
|
|
100
|
+
fields: PropTypes.arrayOf(PropTypes.any),
|
|
98
101
|
colorPaletteUI: PropTypes.object.isRequired,
|
|
99
102
|
selectedColorRange: PropTypes.object.isRequired,
|
|
100
103
|
onSelectColorRange: PropTypes.func.isRequired,
|
|
104
|
+
onSelectColorColumn: PropTypes.func.isRequired,
|
|
101
105
|
setColorPaletteUI: PropTypes.func.isRequired,
|
|
102
106
|
// optional
|
|
103
107
|
colorRanges: PropTypes.arrayOf(PropTypes.any)
|
|
@@ -119,7 +123,7 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
119
123
|
(colorRanges, type, steps) => {
|
|
120
124
|
return colorRanges.filter(colorRange => {
|
|
121
125
|
const isType = type === 'all' || type === colorRange.type;
|
|
122
|
-
const isStep = Number(steps) === colorRange.colors.length;
|
|
126
|
+
const isStep = Number(steps || 6) === colorRange.colors.length;
|
|
123
127
|
|
|
124
128
|
return isType && isStep;
|
|
125
129
|
});
|
|
@@ -129,7 +133,7 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
129
133
|
_updateConfig = ({key, value}) => {
|
|
130
134
|
this._setColorRangeConfig({
|
|
131
135
|
[key]: value,
|
|
132
|
-
...(key === 'type' && {custom: value === 'custom'})
|
|
136
|
+
...(key === 'type' && {custom: value === 'custom', hexColumn: value === hexColor})
|
|
133
137
|
});
|
|
134
138
|
};
|
|
135
139
|
|
|
@@ -139,6 +143,12 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
139
143
|
});
|
|
140
144
|
};
|
|
141
145
|
|
|
146
|
+
_onSetHexColorColumn = config => {
|
|
147
|
+
this.props.setColorPaletteUI({
|
|
148
|
+
customPalette: config
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
142
152
|
_setColorRangeConfig = newConfig => {
|
|
143
153
|
this.props.setColorPaletteUI({
|
|
144
154
|
colorRangeConfig: newConfig
|
|
@@ -148,7 +158,7 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
148
158
|
_onCustomPaletteCancel = newConfig => {
|
|
149
159
|
this.props.setColorPaletteUI({
|
|
150
160
|
showSketcher: false,
|
|
151
|
-
colorRangeConfig: {custom: false}
|
|
161
|
+
colorRangeConfig: {custom: false, hexColumn: false}
|
|
152
162
|
});
|
|
153
163
|
};
|
|
154
164
|
|
|
@@ -158,6 +168,18 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
158
168
|
});
|
|
159
169
|
};
|
|
160
170
|
|
|
171
|
+
_onSelectColumn = column => {
|
|
172
|
+
this.props.onSelectColorColumn(column);
|
|
173
|
+
this._setColorRangeConfig({
|
|
174
|
+
type: hexColor,
|
|
175
|
+
hexColumn: column?.name
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
_handleOnChangePaletteType = ({key, value}) => {
|
|
180
|
+
this._updateConfig({key, value});
|
|
181
|
+
};
|
|
182
|
+
|
|
161
183
|
render() {
|
|
162
184
|
const {customPalette, showSketcher, colorRangeConfig} = this.props.colorPaletteUI;
|
|
163
185
|
const filteredColorRanges = this.filteredColorRange(this.props);
|
|
@@ -168,7 +190,8 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
168
190
|
{Object.keys(colorRangeConfig)
|
|
169
191
|
.filter(
|
|
170
192
|
key =>
|
|
171
|
-
Boolean(CONFIG_SETTINGS[key]) &&
|
|
193
|
+
Boolean(CONFIG_SETTINGS[key]) &&
|
|
194
|
+
(colorRangeConfig.custom || colorRangeConfig.hexColumn ? key === 'type' : true)
|
|
172
195
|
)
|
|
173
196
|
.map(key => {
|
|
174
197
|
return (
|
|
@@ -176,8 +199,8 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
176
199
|
key={key}
|
|
177
200
|
label={CONFIG_SETTINGS[key].label || key}
|
|
178
201
|
config={CONFIG_SETTINGS[key]}
|
|
179
|
-
value={colorRangeConfig[key]}
|
|
180
|
-
onChange={value => this.
|
|
202
|
+
value={colorRangeConfig[key] || 6}
|
|
203
|
+
onChange={value => this._handleOnChangePaletteType({key, value})}
|
|
181
204
|
/>
|
|
182
205
|
);
|
|
183
206
|
})}
|
|
@@ -193,6 +216,12 @@ export default function ColorRangeSelectFactory(ColorPaletteGroup, PaletteConfig
|
|
|
193
216
|
setCustomPalette={this._onSetCustomPalette}
|
|
194
217
|
onCancel={this._onCustomPaletteCancel}
|
|
195
218
|
/>
|
|
219
|
+
) : colorRangeConfig.hexColumn ? (
|
|
220
|
+
<HexColumnConfig
|
|
221
|
+
fields={this.props.fields}
|
|
222
|
+
value={colorRangeConfig.hexColumn}
|
|
223
|
+
onSelectColumn={this._onSelectColumn}
|
|
224
|
+
/>
|
|
196
225
|
) : (
|
|
197
226
|
<ColorPaletteGroup
|
|
198
227
|
colorRanges={filteredColorRanges}
|
|
@@ -64,6 +64,7 @@ ColorSelectorFactory.deps = [SingleColorPaletteFactory, ColorRangeSelectFactory]
|
|
|
64
64
|
function ColorSelectorFactory(SingleColorPalette, ColorRangeSelector) {
|
|
65
65
|
class ColorSelector extends Component {
|
|
66
66
|
static propTypes = {
|
|
67
|
+
fields: PropTypes.arrayOf(PropTypes.any),
|
|
67
68
|
colorSets: PropTypes.arrayOf(
|
|
68
69
|
PropTypes.shape({
|
|
69
70
|
selectedColor: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.any), PropTypes.object]),
|
|
@@ -124,6 +125,10 @@ function ColorSelectorFactory(SingleColorPalette, ColorRangeSelector) {
|
|
|
124
125
|
}
|
|
125
126
|
};
|
|
126
127
|
|
|
128
|
+
_onSelectColorColumn = column => {
|
|
129
|
+
this.props.onSelectHexColorColumn(column);
|
|
130
|
+
};
|
|
131
|
+
|
|
127
132
|
_showDropdown = (e, i) => {
|
|
128
133
|
e.stopPropagation();
|
|
129
134
|
e.preventDefault();
|
|
@@ -172,7 +177,9 @@ function ColorSelectorFactory(SingleColorPalette, ColorRangeSelector) {
|
|
|
172
177
|
<ColorRangeSelector
|
|
173
178
|
selectedColorRange={colorSets[editing].selectedColor}
|
|
174
179
|
onSelectColorRange={this._onSelectColor}
|
|
180
|
+
onSelectColorColumn={this._onSelectColorColumn}
|
|
175
181
|
setColorPaletteUI={this.props.setColorUI}
|
|
182
|
+
fields={this.props.fields}
|
|
176
183
|
colorPaletteUI={colorUI}
|
|
177
184
|
/>
|
|
178
185
|
) : (
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {FieldSelector} from 'components';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {PanelLabel} from 'components/common/styled-components';
|
|
4
|
+
import {FormattedMessage} from 'localization';
|
|
5
|
+
import React, {Component} from 'react';
|
|
6
|
+
|
|
7
|
+
class HexColumnConfig extends Component {
|
|
8
|
+
static propTypes = {
|
|
9
|
+
fields: PropTypes.arrayOf(PropTypes.any),
|
|
10
|
+
value: PropTypes.string,
|
|
11
|
+
onSelectColumn: PropTypes.func.isRequired
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
render() {
|
|
15
|
+
const {fields, value, onSelectColumn} = this.props;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<div className="color-palette__config__label">
|
|
20
|
+
<PanelLabel>
|
|
21
|
+
<FormattedMessage id={`color.hexColumn.field`} />
|
|
22
|
+
</PanelLabel>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<FieldSelector
|
|
26
|
+
fields={fields}
|
|
27
|
+
value={value}
|
|
28
|
+
placeholder={''}
|
|
29
|
+
onSelect={onSelectColumn}
|
|
30
|
+
erasable
|
|
31
|
+
onFocus={() => null}
|
|
32
|
+
onBlur={() => null}
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default HexColumnConfig;
|
|
@@ -47,6 +47,7 @@ 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
|
|
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
|
|
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
|
|
898
|
+
<LayerColorRangeSelector
|
|
899
|
+
{...visConfiguratorProps}
|
|
900
|
+
property="strokeColorRange"
|
|
901
|
+
field="strokeColorField"
|
|
902
|
+
/>
|
|
888
903
|
) : (
|
|
889
904
|
<LayerColorSelector
|
|
890
905
|
{...visConfiguratorProps}
|
|
@@ -1048,13 +1063,14 @@ LayerColorSelectorFactory.deps = [ColorSelectorFactory];
|
|
|
1048
1063
|
export function LayerColorSelectorFactory(ColorSelector) {
|
|
1049
1064
|
class LayerColorSelector extends Component {
|
|
1050
1065
|
render() {
|
|
1051
|
-
const {layer, onChange, selectedColor, property = 'color', setColorUI} = this.props;
|
|
1066
|
+
const {layer, onChange, selectedColor, property = 'color', setColorUI, fields} = this.props;
|
|
1052
1067
|
return (
|
|
1053
1068
|
<SidePanelSection>
|
|
1054
1069
|
<PanelLabel>
|
|
1055
1070
|
<FormattedMessage id="layer.color" />
|
|
1056
1071
|
</PanelLabel>
|
|
1057
1072
|
<ColorSelector
|
|
1073
|
+
fields={fields}
|
|
1058
1074
|
colorSets={[
|
|
1059
1075
|
{
|
|
1060
1076
|
selectedColor: selectedColor || layer.config.color,
|
|
@@ -1076,13 +1092,22 @@ ArcLayerColorSelectorFactory.deps = [ColorSelectorFactory];
|
|
|
1076
1092
|
export function ArcLayerColorSelectorFactory(ColorSelector) {
|
|
1077
1093
|
class ArcLayerColorSelector extends Component {
|
|
1078
1094
|
render() {
|
|
1079
|
-
const {
|
|
1095
|
+
const {
|
|
1096
|
+
layer,
|
|
1097
|
+
onChangeConfig,
|
|
1098
|
+
onChangeVisConfig,
|
|
1099
|
+
property = 'color',
|
|
1100
|
+
setColorUI,
|
|
1101
|
+
fields
|
|
1102
|
+
} = this.props;
|
|
1103
|
+
|
|
1080
1104
|
return (
|
|
1081
1105
|
<SidePanelSection>
|
|
1082
1106
|
<PanelLabel>
|
|
1083
1107
|
<FormattedMessage id="layer.colorRange" />
|
|
1084
1108
|
</PanelLabel>
|
|
1085
1109
|
<ColorSelector
|
|
1110
|
+
fields={fields}
|
|
1086
1111
|
colorSets={[
|
|
1087
1112
|
{
|
|
1088
1113
|
selectedColor: layer.config.color,
|
|
@@ -1109,13 +1134,21 @@ LayerColorRangeSelectorFactory.deps = [ColorSelectorFactory];
|
|
|
1109
1134
|
export function LayerColorRangeSelectorFactory(ColorSelector) {
|
|
1110
1135
|
class LayerColorRangeSelector extends Component {
|
|
1111
1136
|
render() {
|
|
1112
|
-
const {
|
|
1137
|
+
const {
|
|
1138
|
+
layer,
|
|
1139
|
+
onChange,
|
|
1140
|
+
property = 'colorRange',
|
|
1141
|
+
field = 'colorField',
|
|
1142
|
+
setColorUI,
|
|
1143
|
+
fields
|
|
1144
|
+
} = this.props;
|
|
1113
1145
|
return (
|
|
1114
1146
|
<SidePanelSection>
|
|
1115
1147
|
<PanelLabel>
|
|
1116
1148
|
<FormattedMessage id="layer.colorRange" />
|
|
1117
1149
|
</PanelLabel>
|
|
1118
1150
|
<ColorSelector
|
|
1151
|
+
fields={fields}
|
|
1119
1152
|
colorSets={[
|
|
1120
1153
|
{
|
|
1121
1154
|
selectedColor: layer.config.visConfig[property],
|
|
@@ -1131,6 +1164,17 @@ export function LayerColorRangeSelectorFactory(ColorSelector) {
|
|
|
1131
1164
|
]}
|
|
1132
1165
|
colorUI={layer.config.colorUI[property]}
|
|
1133
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
|
+
}}
|
|
1134
1178
|
/>
|
|
1135
1179
|
</SidePanelSection>
|
|
1136
1180
|
);
|
|
@@ -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
|
+
};
|
package/src/layers/base-layer.js
CHANGED
|
@@ -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,
|
|
@@ -100,7 +100,6 @@ export const colorMaker = generateColor();
|
|
|
100
100
|
class Layer {
|
|
101
101
|
constructor(props = {}) {
|
|
102
102
|
this.id = props.id || generateHashId(LAYER_ID_LENGTH);
|
|
103
|
-
|
|
104
103
|
// meta
|
|
105
104
|
this.meta = {};
|
|
106
105
|
|
|
@@ -609,8 +608,9 @@ class Layer {
|
|
|
609
608
|
};
|
|
610
609
|
|
|
611
610
|
this.updateLayerConfig({colorUI});
|
|
612
|
-
// if colorUI[prop] is colorRange
|
|
613
|
-
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);
|
|
614
614
|
|
|
615
615
|
if (isColorRange) {
|
|
616
616
|
this.updateColorUIByColorRange(newConfig, prop);
|
|
@@ -663,8 +663,9 @@ class Layer {
|
|
|
663
663
|
colorRangeConfig: {
|
|
664
664
|
...colorUI[prop].colorRangeConfig,
|
|
665
665
|
type: visConfig[prop].type,
|
|
666
|
-
steps: visConfig[prop].colors
|
|
667
|
-
reversed: Boolean(visConfig[prop].reversed)
|
|
666
|
+
steps: visConfig[prop].colors?.length,
|
|
667
|
+
reversed: Boolean(visConfig[prop].reversed),
|
|
668
|
+
hexColumn: this.isColoredByColorColumn(prop)
|
|
668
669
|
}
|
|
669
670
|
}
|
|
670
671
|
}
|
|
@@ -732,6 +733,12 @@ class Layer {
|
|
|
732
733
|
updateCategoryColorMap(colorMap, domain, colorRange) {
|
|
733
734
|
const colors = colorRange.colors;
|
|
734
735
|
const assignedCategories = [];
|
|
736
|
+
if (colorRange.type === hexColor) {
|
|
737
|
+
return {
|
|
738
|
+
...colorRange,
|
|
739
|
+
colorMap: []
|
|
740
|
+
};
|
|
741
|
+
}
|
|
735
742
|
const newColorMap = colorMap.slice(0, colors.length).map((cMap, index) => {
|
|
736
743
|
assignedCategories.push(cMap[0]);
|
|
737
744
|
return [cMap[0], colors[index]];
|
|
@@ -821,7 +828,11 @@ class Layer {
|
|
|
821
828
|
}
|
|
822
829
|
|
|
823
830
|
getColorScale(colorScale, colorDomain, colorRange) {
|
|
824
|
-
if (
|
|
831
|
+
if (colorRange.type === hexColor) {
|
|
832
|
+
return (_, color) => {
|
|
833
|
+
return hexToRgb(color);
|
|
834
|
+
};
|
|
835
|
+
} else if (Array.isArray(colorRange.colorMap)) {
|
|
825
836
|
const cMap = new Map();
|
|
826
837
|
colorRange.colorMap.forEach(([k, v]) => {
|
|
827
838
|
cMap.set(k, typeof v === 'string' ? hexToRgb(v) : v);
|
|
@@ -914,13 +925,15 @@ class Layer {
|
|
|
914
925
|
: this.getVisChannelScale(...args, isFixed);
|
|
915
926
|
|
|
916
927
|
attributeAccessors[accessor] = d =>
|
|
917
|
-
this.getEncodedChannelValue(
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
928
|
+
this.getEncodedChannelValue({
|
|
929
|
+
channel,
|
|
930
|
+
dataContainer,
|
|
931
|
+
scale: scaleFunction,
|
|
932
|
+
data: dataAccessor(dataContainer)(d),
|
|
933
|
+
field: fieldConfig,
|
|
934
|
+
_aggregation: aggregationValue,
|
|
922
935
|
nullValue
|
|
923
|
-
);
|
|
936
|
+
});
|
|
924
937
|
} else if (typeof getAttributeValue === 'function') {
|
|
925
938
|
attributeAccessors[accessor] = getAttributeValue(this.config);
|
|
926
939
|
} else {
|
|
@@ -990,17 +1003,35 @@ class Layer {
|
|
|
990
1003
|
return triggerChanged;
|
|
991
1004
|
}
|
|
992
1005
|
|
|
993
|
-
getEncodedChannelValue(
|
|
1006
|
+
getEncodedChannelValue({
|
|
1007
|
+
channel,
|
|
994
1008
|
scale,
|
|
995
1009
|
data,
|
|
996
1010
|
field,
|
|
1011
|
+
dataContainer,
|
|
997
1012
|
// In builder we overwrite the getValue function and we use the _aggregation parameter in spatial index layers as the QuadkeyLayer.
|
|
998
1013
|
_aggregation,
|
|
999
1014
|
nullValue = NO_VALUE_COLOR,
|
|
1000
1015
|
getValue = defaultGetFieldValue
|
|
1001
|
-
) {
|
|
1016
|
+
}) {
|
|
1017
|
+
let colorColumnValue;
|
|
1002
1018
|
const {type} = field;
|
|
1003
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
|
+
}
|
|
1004
1035
|
|
|
1005
1036
|
if (!notNullorUndefined(value)) {
|
|
1006
1037
|
return nullValue;
|
|
@@ -1010,9 +1041,9 @@ class Layer {
|
|
|
1010
1041
|
if (type === ALL_FIELD_TYPES.timestamp) {
|
|
1011
1042
|
// shouldn't need to convert here
|
|
1012
1043
|
// scale Function should take care of it
|
|
1013
|
-
attributeValue = scale(new Date(value));
|
|
1044
|
+
attributeValue = scale(new Date(value), colorColumnValue);
|
|
1014
1045
|
} else {
|
|
1015
|
-
attributeValue = scale(value);
|
|
1046
|
+
attributeValue = scale(value, colorColumnValue);
|
|
1016
1047
|
}
|
|
1017
1048
|
|
|
1018
1049
|
if (!notNullorUndefined(attributeValue)) {
|
|
@@ -1046,13 +1077,14 @@ class Layer {
|
|
|
1046
1077
|
if (!this.config.dataId) {
|
|
1047
1078
|
return {};
|
|
1048
1079
|
}
|
|
1049
|
-
const
|
|
1050
|
-
const {dataContainer} =
|
|
1080
|
+
const dataset = this.getDataset(datasets);
|
|
1081
|
+
const {dataContainer} = dataset;
|
|
1051
1082
|
|
|
1052
|
-
this.updateVisualChannelFields(
|
|
1083
|
+
this.updateVisualChannelFields(dataset);
|
|
1084
|
+
this.updateHexColorDomain(dataset);
|
|
1053
1085
|
|
|
1054
1086
|
const getPosition = this.getPositionAccessor(dataContainer);
|
|
1055
|
-
const dataUpdateTriggers = this.getDataUpdateTriggers(
|
|
1087
|
+
const dataUpdateTriggers = this.getDataUpdateTriggers(dataset);
|
|
1056
1088
|
const triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
|
|
1057
1089
|
|
|
1058
1090
|
if (triggerChanged.getMeta) {
|
|
@@ -1065,7 +1097,7 @@ class Layer {
|
|
|
1065
1097
|
// same data
|
|
1066
1098
|
data = oldLayerData.data;
|
|
1067
1099
|
} else {
|
|
1068
|
-
data = this.calculateDataAttribute(
|
|
1100
|
+
data = this.calculateDataAttribute(dataset, getPosition);
|
|
1069
1101
|
}
|
|
1070
1102
|
|
|
1071
1103
|
return {data, triggerChanged};
|
|
@@ -1077,12 +1109,20 @@ class Layer {
|
|
|
1077
1109
|
* @param {Object} dataset
|
|
1078
1110
|
*/
|
|
1079
1111
|
updateVisualChannelFields(dataset) {
|
|
1080
|
-
for (const {field} of Object.values(this.visualChannels)) {
|
|
1112
|
+
for (const {field, range} of Object.values(this.visualChannels)) {
|
|
1081
1113
|
const oldField = this.config[field];
|
|
1114
|
+
const isUsingHexColorCode = this.config.visConfig[range].hexColor
|
|
1082
1115
|
if (!oldField) {
|
|
1083
1116
|
return;
|
|
1084
1117
|
}
|
|
1085
|
-
|
|
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
|
+
}
|
|
1086
1126
|
this.updateLayerConfig({[field]: newDataSetField});
|
|
1087
1127
|
}
|
|
1088
1128
|
}
|
|
@@ -1103,6 +1143,7 @@ class Layer {
|
|
|
1103
1143
|
Object.values(this.visualChannels).forEach(channel => {
|
|
1104
1144
|
const {scale} = channel;
|
|
1105
1145
|
const scaleType = this.config[scale];
|
|
1146
|
+
|
|
1106
1147
|
// ordinal domain is based on dataContainer, if only filter changed
|
|
1107
1148
|
// no need to update ordinal domain
|
|
1108
1149
|
if (!newFilter || scaleType !== SCALE_TYPES.ordinal) {
|
|
@@ -1224,6 +1265,24 @@ class Layer {
|
|
|
1224
1265
|
return dataset.getColumnLayerDomain(dataSetField, scaleType) || defaultDomain;
|
|
1225
1266
|
}
|
|
1226
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
|
+
|
|
1227
1286
|
hasHoveredObject(objectInfo) {
|
|
1228
1287
|
return this.isLayerHovered(objectInfo) && objectInfo.object ? objectInfo.object : null;
|
|
1229
1288
|
}
|
|
@@ -1251,9 +1310,9 @@ class Layer {
|
|
|
1251
1310
|
|
|
1252
1311
|
if (!radiusChannel || this.config[radiusChannel.field]) {
|
|
1253
1312
|
return 1;
|
|
1254
|
-
} else {
|
|
1255
|
-
return this.config.visConfig.radius;
|
|
1256
1313
|
}
|
|
1314
|
+
|
|
1315
|
+
return this.config.visConfig.radius;
|
|
1257
1316
|
}
|
|
1258
1317
|
|
|
1259
1318
|
getMaxMarkerSize() {
|
|
@@ -1434,6 +1493,13 @@ class Layer {
|
|
|
1434
1493
|
// implemented in subclasses
|
|
1435
1494
|
return () => null;
|
|
1436
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
|
+
}
|
|
1437
1503
|
}
|
|
1438
1504
|
|
|
1439
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
|
}),
|