Skip to content

Commit

Permalink
[Feat] Add neighbor column mode to arc layer, support arc from hex (#…
Browse files Browse the repository at this point in the history
…2665)

- Cleanup columnMode logic, remove use of `assignColumnsByColumnMode`
- Add neighbor column mode to arc layer
- Support arc from hex_id
- [fix] Ensure Polygon layer filtering in table columns mode works
- [fix] Timestamp in the Trips layer is not required after switching from Polygon

Signed-off-by: Ihor Dykhta <dikhta.igor@gmail.com>
  • Loading branch information
igorDykhta committed Sep 24, 2024
1 parent 2bc5937 commit b6ac654
Show file tree
Hide file tree
Showing 33 changed files with 1,308 additions and 317 deletions.
24 changes: 21 additions & 3 deletions examples/demo-app/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ import sampleS2Data, {config as s2MapConfig, dataId as s2DataId} from './data/sa
import sampleAnimateTrip, {animateTripDataId} from './data/sample-animate-trip-data';
import sampleIconCsv, {config as savedMapConfig} from './data/sample-icon-csv';
import sampleGpsData from './data/sample-gps-data';

import {processCsvData, processGeojson} from '@kepler.gl/processors';
import sampleRowData, {config as rowDataConfig} from './data/sample-row-data';
import {processCsvData, processGeojson, processRowObject} from '@kepler.gl/processors';
/* eslint-enable no-unused-vars */

const BannerHeight = 48;
Expand Down Expand Up @@ -178,7 +178,25 @@ class App extends Component {
// this._loadH3HexagonData();
// this._loadS2Data();
// this._loadScenegraphLayer();
this._loadGpsData();
// this._loadGpsData();
// this._loadRowData();
}

_loadRowData() {
this.props.dispatch(
addDataToMap({
datasets: [
{
info: {
label: 'Sample Visit Data',
id: 'sample_visit_data'
},
data: processRowObject(sampleRowData)
}
],
config: rowDataConfig
})
);
}

_loadPointData() {
Expand Down
133 changes: 133 additions & 0 deletions examples/demo-app/src/data/sample-row-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

const data = [
{
venue_id: '7c69e9',
count: 10,
latitude: 41.852015,
longitude: -87.616047,
neighbors: [1, 2],
'source hex_id': '8a2664c1b74ffff',
'target latitude': 41.946969,
'target longitude': -87.693607,
'target hex_id': '8a2664ca51b7fff'
},
{
venue_id: 'fe26e3',
count: 22,
latitude: 41.946969,
longitude: -87.693607,
neighbors: [2, 3],
'source hex_id': '8a2664ca51b7fff',
'target latitude': 41.7552452681605,
'target longitude': -87.6322426600563,
'target hex_id': '8a2664cc3757fff'
},
{
venue_id: '5f3ec9',
count: 5,
latitude: 41.9228189446294,
longitude: -87.7459144592286,
neighbors: [3, 4],
'source hex_id': '8a2664ca22dffff',
'target latitude': 41.7552452681605,
'target longitude': -87.6322426600563,
'target hex_id': '8a2664cc3757fff'
},
{
venue_id: 'fe625f',
count: 11,
latitude: 41.9458364,
longitude: -87.7474061,
neighbors: [4, 5, 6],
'source hex_id': '8a2664ca66c7fff',
'target latitude': 41.990071,
'target longitude': -87.710537,
'target hex_id': '8a2664d8ad97fff'
},
{
venue_id: '7b1fe3',
count: 14,
latitude: 41.879519,
longitude: -87.6335512,
neighbors: [5, 6],
'source hex_id': '8a2664c1a89ffff',
'target latitude': 41.8801791917474,
'target longitude': -87.7507109194994,
'target hex_id': '8a2664c81567fff'
},
{
venue_id: 'd16c1b',
count: 8,
latitude: 41.7552452681605,
longitude: -87.6322426600563,
neighbors: [6, 7],
'source hex_id': '8a2664cc3757fff',
'target latitude': 41.9760432,
'target longitude': -87.7082406,
'target hex_id': '8a2664d8a71ffff'
},
{
venue_id: '5f3be3',
count: 6,
latitude: 41.990071,
longitude: -87.710537,
neighbors: [7, 8],
'source hex_id': '8a2664d8ad97fff',
'target latitude': 41.7552452681605,
'target longitude': -87.6322426600563,
'target hex_id': '8a2664cc3757fff'
},
{
venue_id: 'eeea20',
count: 5,
latitude: 41.8801791917474,
longitude: -87.7507109194994,
neighbors: [8, 9],
'source hex_id': '8a2664c81567fff',
'target latitude': 41.7753234651629,
'target longitude': -87.6832077690278,
'target hex_id': '8a2664cd1197fff'
}
];

export const config = {
version: 'v1',
config: {
visState: {
filters: [],
layers: [
{
id: 'iulge5',
type: 'point',
config: {
dataId: 'sample_visit_data',
label: 'point',
columns: {
lat: 'latitude',
lng: 'longitude',
neighbors: 'neighbors'
},
isVisible: true,
visConfig: {
radius: 20,
opacity: 1,
allowHover: true,
showNeighborOnHover: true,
showHighlightColor: false
}
},
visualChannels: {
colorField: {
name: 'count',
type: 'integer'
},
colorScale: 'quantile'
}
}
]
}
}
};
export default data;
13 changes: 10 additions & 3 deletions src/components/src/common/field-selector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import classnames from 'classnames';
import React, {Component, ComponentType} from 'react';
import styled from 'styled-components';
import {createSelector} from 'reselect';
Expand All @@ -25,7 +26,12 @@ const StyledFieldListItem = styled.div`
flex-direction: row;
align-items: center;
`;

const StyledFieldSelector = styled.div`
.item-selector__dropdown {
// smaller padding on the side to accomodate field token
padding: 0 6px;
}
`;
export type FieldListItemFactoryProps = {
value: Field;
displayOption: (field: Field) => string;
Expand Down Expand Up @@ -97,6 +103,7 @@ interface FieldSelectorFactoryProps {
CustomChickletComponent?: ComponentType<any>;
size?: string;
reorderItems?: (newOrder: any) => void;
className?: string;
}
function noop() {
return;
Expand Down Expand Up @@ -164,7 +171,7 @@ function FieldSelectorFactory(

render() {
return (
<div className="field-selector">
<StyledFieldSelector className={classnames('field-selector', this.props.className)}>
<ItemSelector
getOptionValue={d => d}
closeOnSelect={this.props.closeOnSelect}
Expand All @@ -187,7 +194,7 @@ function FieldSelectorFactory(
DropdownHeaderComponent={this.props.suggested ? SuggestedFieldHeader : null}
CustomChickletComponent={this.props.CustomChickletComponent}
/>
</div>
</StyledFieldSelector>
);
}
}
Expand Down
62 changes: 38 additions & 24 deletions src/components/src/side-panel/layer-panel/column-selector.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import React from 'react';
import React, {useMemo, ReactNode} from 'react';
import styled from 'styled-components';
import {FormattedMessage} from '@kepler.gl/localization';
import {PanelLabel} from '../../common/styled-components';
Expand All @@ -25,6 +25,7 @@ export type ColumnSelectorProps<FieldOption extends MinimalField> = {
| null
) => void;
fieldPairs: EnhancedFieldPair[] | null;
isActive?: boolean;
};

const ColumnRow = styled.div`
Expand All @@ -34,45 +35,58 @@ const ColumnRow = styled.div`
`;

const ColumnName = styled.div`
width: 27%;
width: 32%;
line-height: 1.2;
padding-right: 6px;
`;

const ColumnSelect = styled.div`
width: 73%;
width: 68%;
`;

ColumnSelectorFactory.deps = [FieldSelectorFactory];

const ColumnPanelLabel = styled(PanelLabel).attrs<{children: ReactNode}>({
className: 'side-panel-subpanel__label'
})`
font-size: 10px;
`;

function ColumnSelectorFactory(FieldSelector: ReturnType<typeof FieldSelectorFactory>) {
const ColumnSelector: React.FC<ColumnSelectorProps<any>> = ({
column,
columns,
label,
allFields,
onSelect,
fieldPairs
}) => (
<ColumnRow className="layer-config__column__selector">
<ColumnName className="layer-config__column__name">
<PanelLabel>
<FormattedMessage id={`columns.${label}`} />
{!column.optional ? ` *` : null}
</PanelLabel>
</ColumnName>
<ColumnSelect className="layer-config__column__select">
<FieldSelector
suggested={fieldPairs}
error={!validateColumn(column, columns, allFields)}
fields={allFields}
value={column.value}
erasable={Boolean(column.optional)}
onSelect={onSelect}
/>
</ColumnSelect>
</ColumnRow>
);
fieldPairs,
isActive = true
}) => {
const isError = useMemo(
() => isActive && !validateColumn(column, columns, allFields),
[isActive, column, columns, allFields]
);
return (
<ColumnRow className="layer-config__column__selector">
<ColumnName className="layer-config__column__name">
<ColumnPanelLabel>
<FormattedMessage id={`columns.${label}`} />
{!column.optional ? ` *` : null}
</ColumnPanelLabel>
</ColumnName>
<ColumnSelect className="layer-config__column__select">
<FieldSelector
suggested={fieldPairs as any}
error={isError}
fields={allFields}
value={column.value}
erasable
onSelect={onSelect}
/>
</ColumnSelect>
</ColumnRow>
);
};
return ColumnSelector;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type LayerColumnConfigProps<FieldOption extends MinimalField> = {
columnPairs?: ColumnPairs | null;
fieldPairs?: FieldPair[];
columnLabels: ColumnLabels | null;
isActive: boolean;
};

/**
Expand Down Expand Up @@ -61,7 +62,8 @@ function LayerColumnConfigFactory(ColumnSelector: ReturnType<typeof ColumnSelect
fields,
updateLayerConfig,
assignColumn,
assignColumnPairs
assignColumnPairs,
isActive
}) => {
const enhancedFieldPairs: EnhancedFieldPair[] | null = useMemo(
() =>
Expand Down Expand Up @@ -109,6 +111,7 @@ function LayerColumnConfigFactory(ColumnSelector: ReturnType<typeof ColumnSelect
key
)}
onSelect={val => onUpdateColumn(key, val)}
isActive={isActive}
/>
))}
</div>
Expand Down
Loading

0 comments on commit b6ac654

Please sign in to comment.