@carto/kepler.gl 0.0.71-alpha.4 → 0.0.71-alpha.6
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/dropdown-list.js +4 -3
- package/dist/components/side-panel/layer-panel/color-range-selector.js +8 -22
- package/dist/components/side-panel/layer-panel/color-selector.js +2 -5
- package/dist/components/side-panel/layer-panel/layer-configurator.js +21 -23
- package/dist/constants/default-settings.js +1 -1
- package/dist/layers/base-layer.js +57 -12
- package/dist/schemas/vis-state-schema.js +68 -33
- package/dist/utils/data-utils.js +31 -1
- package/dist/utils/layer-utils.js +2 -1
- package/dist/utils/table-utils/kepler-table.js +17 -1
- package/package.json +1 -1
- package/src/components/common/item-selector/dropdown-list.js +2 -3
- package/src/components/side-panel/layer-panel/color-range-selector.js +7 -17
- package/src/components/side-panel/layer-panel/color-selector.js +1 -5
- package/src/components/side-panel/layer-panel/layer-configurator.js +9 -27
- package/src/layers/base-layer.js +45 -7
- package/src/layers/index.d.ts +3 -1
- package/src/schemas/vis-state-schema.js +23 -0
- package/src/utils/data-utils.d.ts +1 -0
- package/src/utils/data-utils.js +19 -0
- package/src/utils/layer-utils.js +1 -0
- package/src/utils/table-utils/kepler-table.js +12 -0
|
@@ -177,8 +177,6 @@ export default function LayerConfiguratorFactory(
|
|
|
177
177
|
channel={layer.visualChannels.color}
|
|
178
178
|
{...layerChannelConfigProps}
|
|
179
179
|
/>
|
|
180
|
-
</ConfigGroupCollapsibleContent>
|
|
181
|
-
<ConfigGroupCollapsibleContent>
|
|
182
180
|
<VisConfigSlider {...layer.visConfigSettings.opacity} {...visConfiguratorProps} />
|
|
183
181
|
</ConfigGroupCollapsibleContent>
|
|
184
182
|
</LayerConfigGroup>
|
|
@@ -192,11 +190,7 @@ export default function LayerConfiguratorFactory(
|
|
|
192
190
|
disabled={Boolean(layer.config.visConfig.customMarkers)}
|
|
193
191
|
>
|
|
194
192
|
{layer.config.strokeColorField ? (
|
|
195
|
-
<LayerColorRangeSelector
|
|
196
|
-
{...visConfiguratorProps}
|
|
197
|
-
property="strokeColorRange"
|
|
198
|
-
field="strokeColorField"
|
|
199
|
-
/>
|
|
193
|
+
<LayerColorRangeSelector {...visConfiguratorProps} channel="strokeColor" />
|
|
200
194
|
) : (
|
|
201
195
|
<LayerColorSelector
|
|
202
196
|
{...visConfiguratorProps}
|
|
@@ -712,11 +706,7 @@ export default function LayerConfiguratorFactory(
|
|
|
712
706
|
collapsible
|
|
713
707
|
>
|
|
714
708
|
{layer.config.strokeColorField ? (
|
|
715
|
-
<LayerColorRangeSelector
|
|
716
|
-
{...visConfiguratorProps}
|
|
717
|
-
property="strokeColorRange"
|
|
718
|
-
field="strokeColorField"
|
|
719
|
-
/>
|
|
709
|
+
<LayerColorRangeSelector {...visConfiguratorProps} channel="strokeColor" />
|
|
720
710
|
) : (
|
|
721
711
|
<LayerColorSelector
|
|
722
712
|
{...visConfiguratorProps}
|
|
@@ -899,11 +889,7 @@ export default function LayerConfiguratorFactory(
|
|
|
899
889
|
collapsible
|
|
900
890
|
>
|
|
901
891
|
{layer.config.strokeColorField ? (
|
|
902
|
-
<LayerColorRangeSelector
|
|
903
|
-
{...visConfiguratorProps}
|
|
904
|
-
property="strokeColorRange"
|
|
905
|
-
field="strokeColorField"
|
|
906
|
-
/>
|
|
892
|
+
<LayerColorRangeSelector {...visConfiguratorProps} channel="strokeColor" />
|
|
907
893
|
) : (
|
|
908
894
|
<LayerColorSelector
|
|
909
895
|
{...visConfiguratorProps}
|
|
@@ -1141,13 +1127,12 @@ export function LayerColorRangeSelectorFactory(ColorSelector) {
|
|
|
1141
1127
|
const {
|
|
1142
1128
|
layer,
|
|
1143
1129
|
onChange,
|
|
1144
|
-
|
|
1145
|
-
field = 'colorField',
|
|
1146
|
-
scale = 'colorScale',
|
|
1130
|
+
channel = 'color',
|
|
1147
1131
|
setColorUI,
|
|
1148
1132
|
fields,
|
|
1149
|
-
handleCustomOnSelectHexColumn
|
|
1133
|
+
handleCustomOnSelectHexColumn = () => null
|
|
1150
1134
|
} = this.props;
|
|
1135
|
+
const {range: property, field, scale} = layer.visualChannels[channel];
|
|
1151
1136
|
return (
|
|
1152
1137
|
<SidePanelSection>
|
|
1153
1138
|
<PanelLabel>
|
|
@@ -1160,23 +1145,20 @@ export function LayerColorRangeSelectorFactory(ColorSelector) {
|
|
|
1160
1145
|
selectedColor: layer.config.visConfig[property],
|
|
1161
1146
|
isRange: true,
|
|
1162
1147
|
setColor: colorRange => {
|
|
1163
|
-
layer.updateLayerConfig({
|
|
1164
|
-
[scale]: SCALE_TYPES.ordinal
|
|
1165
|
-
});
|
|
1166
1148
|
const {colorMap} = layer.config.visConfig[property];
|
|
1167
1149
|
const colorRangeUpdated = colorMap
|
|
1168
1150
|
? layer.updateColorMap(property, colorMap, colorRange)
|
|
1169
1151
|
: colorRange;
|
|
1170
1152
|
onChange({[property]: colorRangeUpdated});
|
|
1153
|
+
layer.validateScale(channel); // Validate scale to ensure that it changes from `identity` to the correct one.
|
|
1171
1154
|
}
|
|
1172
1155
|
}
|
|
1173
1156
|
]}
|
|
1174
1157
|
colorUI={layer.config.colorUI[property]}
|
|
1175
1158
|
setColorUI={newConfig => setColorUI(property, newConfig)}
|
|
1176
1159
|
onSelectHexColorColumn={colorColumn => {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1160
|
+
// It's defined in CN: see workspace-www/src/features/builder/ui/KeplerGl/SidePanel/LayerPanel/LayerColorRangeSelector.tsx
|
|
1161
|
+
handleCustomOnSelectHexColumn(layer, colorColumn);
|
|
1180
1162
|
|
|
1181
1163
|
layer.updateLayerConfig({
|
|
1182
1164
|
[field]: {
|
package/src/layers/base-layer.js
CHANGED
|
@@ -103,6 +103,9 @@ class Layer {
|
|
|
103
103
|
// meta
|
|
104
104
|
this.meta = {};
|
|
105
105
|
|
|
106
|
+
// legendSettings
|
|
107
|
+
this.legendSettings = {};
|
|
108
|
+
|
|
106
109
|
// visConfigSettings
|
|
107
110
|
this.visConfigSettings = {};
|
|
108
111
|
|
|
@@ -665,7 +668,8 @@ class Layer {
|
|
|
665
668
|
type: visConfig[prop].type,
|
|
666
669
|
steps: visConfig[prop].colors?.length,
|
|
667
670
|
reversed: Boolean(visConfig[prop].reversed),
|
|
668
|
-
hexColumn: this.
|
|
671
|
+
hexColumn: this.getHexColumn(prop),
|
|
672
|
+
isHexColumn: this.isColoredByColorColumn(prop)
|
|
669
673
|
}
|
|
670
674
|
}
|
|
671
675
|
}
|
|
@@ -1057,6 +1061,10 @@ class Layer {
|
|
|
1057
1061
|
this.meta = {...this.meta, ...meta};
|
|
1058
1062
|
}
|
|
1059
1063
|
|
|
1064
|
+
updateLayerLegend(settings) {
|
|
1065
|
+
this.legendSettings = {...this.legendSettings, ...settings};
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1060
1068
|
getDataUpdateTriggers({filteredIndex, id, allData}) {
|
|
1061
1069
|
const {columns} = this.config;
|
|
1062
1070
|
|
|
@@ -1111,7 +1119,7 @@ class Layer {
|
|
|
1111
1119
|
updateVisualChannelFields(dataset) {
|
|
1112
1120
|
for (const {field, range} of Object.values(this.visualChannels)) {
|
|
1113
1121
|
const oldField = this.config[field];
|
|
1114
|
-
const isUsingHexColorCode = this.config.visConfig[range].hexColor
|
|
1122
|
+
const isUsingHexColorCode = this.config.visConfig[range].hexColor;
|
|
1115
1123
|
if (!oldField) {
|
|
1116
1124
|
return;
|
|
1117
1125
|
}
|
|
@@ -1194,8 +1202,11 @@ class Layer {
|
|
|
1194
1202
|
*/
|
|
1195
1203
|
validateScale(channel) {
|
|
1196
1204
|
const visualChannel = this.visualChannels[channel];
|
|
1197
|
-
const {scale} = visualChannel;
|
|
1198
|
-
if (
|
|
1205
|
+
const {scale, range} = visualChannel;
|
|
1206
|
+
if (
|
|
1207
|
+
!scale ||
|
|
1208
|
+
(this.isColoredByColorColumn(range) && this.config[scale] === SCALE_TYPES.identity)
|
|
1209
|
+
) {
|
|
1199
1210
|
// visualChannel doesn't have scale
|
|
1200
1211
|
return;
|
|
1201
1212
|
}
|
|
@@ -1276,13 +1287,36 @@ class Layer {
|
|
|
1276
1287
|
if (channelConfig?.type === hexColor) {
|
|
1277
1288
|
const dataSetField = dataset.fields.find(f => f.name === field.colorColumn);
|
|
1278
1289
|
const colors = dataset.getColumnLayerDomain(dataSetField, SCALE_TYPES.ordinal);
|
|
1279
|
-
this.updateLayerVisConfig({
|
|
1290
|
+
this.updateLayerVisConfig({
|
|
1291
|
+
[channel.range]: {...channelConfig, colors: colors.slice(0, 20)}
|
|
1292
|
+
});
|
|
1280
1293
|
}
|
|
1281
1294
|
});
|
|
1282
1295
|
|
|
1283
1296
|
return this;
|
|
1284
1297
|
}
|
|
1285
1298
|
|
|
1299
|
+
calculateHexColumnLegend(datasets) {
|
|
1300
|
+
const dataset = this.getDataset(datasets);
|
|
1301
|
+
if (!datasets) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
const legendSettings = Object.keys(this.visualChannels).reduce((legends, channel) => {
|
|
1306
|
+
const {range, field: channelField} = this.visualChannels[channel];
|
|
1307
|
+
const channelConfig = this.config.visConfig[range];
|
|
1308
|
+
const field = this.config[channelField];
|
|
1309
|
+
|
|
1310
|
+
if (channelConfig?.type === hexColor) {
|
|
1311
|
+
const dataSetField = dataset.fields.find(f => f.name === field.colorColumn);
|
|
1312
|
+
const legend = dataset.calculateLegend(field, dataSetField);
|
|
1313
|
+
legends[channel] = legend;
|
|
1314
|
+
}
|
|
1315
|
+
return legends;
|
|
1316
|
+
}, {});
|
|
1317
|
+
this.updateLayerLegend(legendSettings);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1286
1320
|
hasHoveredObject(objectInfo) {
|
|
1287
1321
|
return this.isLayerHovered(objectInfo) && objectInfo.object ? objectInfo.object : null;
|
|
1288
1322
|
}
|
|
@@ -1374,7 +1408,7 @@ class Layer {
|
|
|
1374
1408
|
{getPosition, getRadius, radiusScale, updateTriggers, sharedProps},
|
|
1375
1409
|
renderOpts
|
|
1376
1410
|
) {
|
|
1377
|
-
const {data
|
|
1411
|
+
const {data} = renderOpts;
|
|
1378
1412
|
const {textLabel, visibilityByZoom} = this.config;
|
|
1379
1413
|
const extensions = [...sharedProps.extensions, collisionFilterExtension];
|
|
1380
1414
|
|
|
@@ -1494,12 +1528,16 @@ class Layer {
|
|
|
1494
1528
|
return () => null;
|
|
1495
1529
|
}
|
|
1496
1530
|
|
|
1497
|
-
|
|
1531
|
+
getHexColumn(range) {
|
|
1498
1532
|
const field = Object.values(this.visualChannels)?.find(value => value.range === range)?.field;
|
|
1499
1533
|
if (field) {
|
|
1500
1534
|
return this.config[field].colorColumn;
|
|
1501
1535
|
}
|
|
1502
1536
|
}
|
|
1537
|
+
|
|
1538
|
+
isColoredByColorColumn(range) {
|
|
1539
|
+
return this.config.visConfig[range]?.hexColor;
|
|
1540
|
+
}
|
|
1503
1541
|
}
|
|
1504
1542
|
|
|
1505
1543
|
export default Layer;
|
package/src/layers/index.d.ts
CHANGED
|
@@ -92,6 +92,8 @@ export class Layer {
|
|
|
92
92
|
hasInteractivity: boolean;
|
|
93
93
|
hasAllColumns(): boolean;
|
|
94
94
|
updateLayerConfig(p: Partial<LayerConfig>): Layer;
|
|
95
|
+
updateLayerMeta(p: any): Layer
|
|
96
|
+
updateLayerLegend(p: any): Layer
|
|
95
97
|
updateLayerDomain(datasets: Datasets, filter?: Filter): Layer;
|
|
96
98
|
updateLayerVisualChannel(dataset: KeplerTable, channel: string): Layer;
|
|
97
99
|
shouldCalculateLayerData(props: string[]): boolean;
|
|
@@ -100,7 +102,7 @@ export class Layer {
|
|
|
100
102
|
isValidToSave(): boolean;
|
|
101
103
|
validateVisualChannel(channel: string);
|
|
102
104
|
getVisualChannelDescription(key: string): {label: string, measure: string};
|
|
103
|
-
|
|
105
|
+
calculateHexColumnLegend(datasets: Datasets): any;
|
|
104
106
|
static findDefaultLayerProps(dataset: KeplerTable, foundLayers?: any[]);
|
|
105
107
|
// static findDefaultColumnField(defaultFields, allFields)
|
|
106
108
|
}
|
|
@@ -365,6 +365,25 @@ class VisualChannelSchemaV1 extends Schema {
|
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* V1: save [channel]: [{ label, color }, ...] for legend
|
|
370
|
+
*/
|
|
371
|
+
class LegendSettingsV1 extends Schema {
|
|
372
|
+
save(legendSettings, parents) {
|
|
373
|
+
return {
|
|
374
|
+
[this.key]: Object.keys(legendSettings).reduce((accu, key) => {
|
|
375
|
+
accu[key] = legendSettings[key];
|
|
376
|
+
return accu;
|
|
377
|
+
}, {})
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
load(ls, parents, accumulator) {
|
|
381
|
+
return {
|
|
382
|
+
...accumulator,
|
|
383
|
+
[this.key]: ls
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
368
387
|
const visConfigModificationV1 = {
|
|
369
388
|
point: (visConfig, parents, accumulated) => {
|
|
370
389
|
const modified = {};
|
|
@@ -459,6 +478,10 @@ export const layerPropsV1 = {
|
|
|
459
478
|
})
|
|
460
479
|
}
|
|
461
480
|
}),
|
|
481
|
+
legendSettings: new LegendSettingsV1({
|
|
482
|
+
version: VERSIONS.v1,
|
|
483
|
+
key: 'legendSettings'
|
|
484
|
+
}),
|
|
462
485
|
visualChannels: new VisualChannelSchemaV1({
|
|
463
486
|
version: VERSIONS.v1,
|
|
464
487
|
key: 'visualChannels'
|
|
@@ -13,6 +13,7 @@ export function isPlainObject(d: any): boolean;
|
|
|
13
13
|
export function numberSort(a: any, b: any): any;
|
|
14
14
|
export function unique(values: any[]): any[];
|
|
15
15
|
export function uniqueSortedByFrequency(values: any[]): any[];
|
|
16
|
+
export function uniqueSortedPairByFrequency(values: any[]): any[];
|
|
16
17
|
export function arrayMove(array: any[], from: number, to: number);
|
|
17
18
|
export function getSortingFunction(fieldType: string): numberSort | undefined;
|
|
18
19
|
export function preciseRound(num: number, decimals: number): string;
|
package/src/utils/data-utils.js
CHANGED
|
@@ -426,3 +426,22 @@ export function datetimeFormatter(timezone) {
|
|
|
426
426
|
.format(format)
|
|
427
427
|
: format => ts => moment.utc(ts).format(format);
|
|
428
428
|
}
|
|
429
|
+
|
|
430
|
+
export function uniqueSortedPairByFrequency(values) {
|
|
431
|
+
const frequencies = values.reduce((res, value) => {
|
|
432
|
+
if (notNullorUndefined(value)) {
|
|
433
|
+
if (!res[value]) {
|
|
434
|
+
res[value] = {
|
|
435
|
+
key: value,
|
|
436
|
+
frequency: 1
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
res[value].frequency += 1;
|
|
440
|
+
}
|
|
441
|
+
return res;
|
|
442
|
+
}, {});
|
|
443
|
+
|
|
444
|
+
return Object.values(frequencies)
|
|
445
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
446
|
+
.map(({key: [left, right]}) => ({left, right}));
|
|
447
|
+
}
|
package/src/utils/layer-utils.js
CHANGED
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
import {ALL_FIELD_TYPES, SCALE_TYPES} from 'constants/default-settings';
|
|
46
46
|
|
|
47
47
|
import {createDataContainer} from './data-container-utils';
|
|
48
|
+
import {uniqueSortedPairByFrequency} from 'utils/data-utils';
|
|
48
49
|
|
|
49
50
|
// Unique identifier of each field
|
|
50
51
|
const FID_KEY = 'name';
|
|
@@ -342,6 +343,17 @@ class KeplerTable {
|
|
|
342
343
|
}
|
|
343
344
|
}
|
|
344
345
|
|
|
346
|
+
calculateLegend(leftField, rightField) {
|
|
347
|
+
const leftValues = this.dataContainer.mapIndex(leftField.valueAccessor);
|
|
348
|
+
const rightValues = this.dataContainer.mapIndex(rightField.valueAccessor);
|
|
349
|
+
|
|
350
|
+
const pairing = leftValues.reduce((previous, current, idx) => {
|
|
351
|
+
previous.push([current, rightValues[idx]]);
|
|
352
|
+
return previous;
|
|
353
|
+
}, []);
|
|
354
|
+
return uniqueSortedPairByFrequency(pairing).map(row => ({label: row.left, color: row.right}));
|
|
355
|
+
}
|
|
356
|
+
|
|
345
357
|
/**
|
|
346
358
|
* Get a sample of rows to calculate layer boundaries
|
|
347
359
|
*/
|