Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Deck.gl Contour Layer #24154

Merged
merged 41 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f92f0ec
feat: add contour layers
Mattc1221 May 15, 2023
97dee50
fix: close contour menu on save/close
Mattc1221 May 20, 2023
8e73baa
fix: remove duplicate tooltip in contour list
Mattc1221 May 20, 2023
050490c
fix: updates to contour popover trigger
Mattc1221 May 20, 2023
c3e216f
fix: fix typo
Mattc1221 May 20, 2023
473358c
chore: package updates
Mattc1221 May 20, 2023
43e2b9f
feat: open contour popover from contour option
Mattc1221 May 20, 2023
70de247
fix: autofill contour values with defaults when editing
Mattc1221 May 20, 2023
6ff3ee4
feat: update current contour on edit
Mattc1221 May 20, 2023
db3cbc8
fix: updated thumbnails
Mattc1221 May 20, 2023
9872306
fix: persist changes and update position of new contour popover
Mattc1221 May 21, 2023
6310d86
chore: clean up imports
Mattc1221 May 21, 2023
ae8f763
feat: validation in contour popover
Mattc1221 May 21, 2023
0c0bc6e
feat: replace cell size with slider and render trigger for cell size …
Mattc1221 May 21, 2023
4e942b9
fix: convert cell size to text field instead of slider
Mattc1221 May 21, 2023
3ebc382
chore: fix typescript linting and warnings
Mattc1221 May 21, 2023
db2414f
fix: run prettier formatter
Mattc1221 May 21, 2023
1f7adde
Merge branch 'master' into deck_gl_contour_layer
Mattc1221 May 28, 2023
7e78126
fix: deck.gl types
Mattc1221 May 28, 2023
b5275e8
fix: replace os.getevn with get_env_variable
Mattc1221 Jun 23, 2023
fac6267
fix: replace uppercase enums with PascalCase
Mattc1221 Jun 23, 2023
f0c4b2b
fix: update remaing uppercase enum references
Mattc1221 Jun 23, 2023
dbb1621
Merge branch 'master' into deck_gl_contour_layer
Mattc1221 Jul 2, 2023
b3326cb
fix: type definition typo
Mattc1221 Jul 2, 2023
606756b
Merge branch 'master' into deck_gl_contour_layer
Mattc1221 Aug 25, 2023
49b1165
fix: retain control values
Mattc1221 Aug 25, 2023
905100e
fix: add translations
Mattc1221 Aug 25, 2023
67446e4
fix: PascalCase for Types and update case for setPopoverVisible
Mattc1221 Aug 25, 2023
1889b66
fix: use theme grid units
Mattc1221 Aug 25, 2023
a7cfb1b
fix: update types
Mattc1221 Aug 25, 2023
ee01a42
fix: remove redundant type check
Mattc1221 Aug 25, 2023
675a87d
fix: add min and max options
Mattc1221 Aug 25, 2023
c6e0cf0
fix: close popover on save
Mattc1221 Aug 25, 2023
f805d92
fix: popover change type and validation
Mattc1221 Aug 25, 2023
26dad87
fix: tooltip
Mattc1221 Aug 25, 2023
8de7811
fix: stroke width validation
Mattc1221 Aug 25, 2023
91b27ab
fix: linting errors
Mattc1221 Aug 25, 2023
f114e9b
fix: python misc test
Mattc1221 Aug 25, 2023
1823a1d
Merge branch 'master' into deck_gl_contour_layer
Mattc1221 Aug 28, 2023
7880019
Merge branch 'master' into deck_gl_contour_layer
Mattc1221 Sep 29, 2023
1a42048
fix: keep focus after typing
Mattc1221 Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker/pythonpath_dev/superset_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class CeleryConfig:

SQLLAB_CTAS_NO_LIMIT = True

MAPBOX_API_KEY = get_env_variable("MAPBOX_API_KEY")

#
# Optionally import superset_config_docker.py (which will have been included on
# the PYTHONPATH) in order to allow for local settings to be overridden
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ContourLayer } from 'deck.gl';
import React from 'react';
import { t } from '@superset-ui/core';
import { commonLayerProps } from '../common';
import sandboxedEval from '../../utils/sandbox';
import { createDeckGLComponent, getLayerType } from '../../factory';
import TooltipRow from '../../TooltipRow';

function setTooltipContent(o: any) {
return (
<div className="deckgl-tooltip">
<TooltipRow
label={t('Centroid (Longitude and Latitude): ')}
value={`(${o.coordinate[0]}, ${o.coordinate[1]})`}
/>
</div>
);
}
export const getLayer: getLayerType<unknown> = (
formData,
payload,
setTooltip,
) => {
const fd = formData;
const {
aggregation = 'SUM',
js_data_mutator: jsFnMutator,
contours: rawContours,
cellSize = '200',
} = fd;
let data = payload.data.features;

const contours = rawContours?.map(
(contour: {
color: any;
Mattc1221 marked this conversation as resolved.
Show resolved Hide resolved
lowerThreshold: number;
upperThreshold?: number;
strokeWidth?: number;
}) => {
const { lowerThreshold, upperThreshold, color, strokeWidth } = contour;
if (upperThreshold) {
// Isoband format
return {
threshold: [lowerThreshold, upperThreshold],
color: [color.r, color.g, color.b],
};
}
// Isoline format
return {
threshold: lowerThreshold,
color: [color.r, color.g, color.b],
strokeWidth,
};
},
);

if (jsFnMutator) {
// Applying user defined data mutator if defined
const jsFnMutatorFunction = sandboxedEval(fd.js_data_mutator);
data = jsFnMutatorFunction(data);
}

return new ContourLayer({
id: `contourLayer-${fd.slice_id}`,
data,
contours,
cellSize: Number(cellSize || '200'),
aggregation: aggregation.toUpperCase(),
getPosition: (d: { position: number[]; weight: number }) => d.position,
getWeight: (d: { weight: any }) => d.weight || 0,
Mattc1221 marked this conversation as resolved.
Show resolved Hide resolved
...commonLayerProps(fd, setTooltip, setTooltipContent),
});
};

function getPoints(data: any[]) {
return data.map(d => d.position);
}

export default createDeckGLComponent(getLayer, getPoints);
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ControlPanelConfig, sections } from '@superset-ui/chart-controls';
import { t, validateNonEmpty } from '@superset-ui/core';
import {
autozoom,
filterNulls,
jsColumns,
jsDataMutator,
jsOnclickHref,
jsTooltip,
mapboxStyle,
spatial,
viewport,
} from '../../utilities/Shared_DeckGL';

const config: ControlPanelConfig = {
controlPanelSections: [
sections.legacyRegularTime,
{
label: t('Query'),
expanded: true,
controlSetRows: [
[spatial],
['row_limit'],
['size'],
[filterNulls],
['adhoc_filters'],
],
},
{
label: t('Map'),
expanded: true,
controlSetRows: [
[mapboxStyle, viewport],
[autozoom],
[
{
name: 'cellSize',
config: {
type: 'TextControl',
label: t('Cell Size'),
default: 300,
isInt: true,
description: t('The size of each cell in meters'),
renderTrigger: true,
clearable: false,
},
},
],
[
{
name: 'aggregation',
config: {
type: 'SelectControl',
label: t('Aggregation'),
description: t(
'The function to use when aggregating points into groups',
),
default: 'sum',
clearable: false,
renderTrigger: true,
choices: [
['sum', t('sum')],
['mean', t('mean')],
Mattc1221 marked this conversation as resolved.
Show resolved Hide resolved
],
},
},
],
[
{
name: 'contours',
config: {
type: 'ContourControl',
label: t('Contours'),
renderTrigger: true,
description: t(
'Define contour layers. Isolines represent a collection of line segments that ' +
'serparate the area above and below a given threshold. Isobands represent a ' +
'collection of polygons that fill the are containing values in a given ' +
'threshold range.',
),
},
},
],
],
},
{
label: t('Advanced'),
controlSetRows: [
[jsColumns],
[jsDataMutator],
[jsTooltip],
[jsOnclickHref],
],
},
],
controlOverrides: {
size: {
label: t('Weight'),
description: t("Metric used as a weight for the grid's coloring"),
validators: [validateNonEmpty],
},
},
formDataOverrides: formData => ({
Mattc1221 marked this conversation as resolved.
Show resolved Hide resolved
...formData,
}),
};

export default config;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import transformProps from '../../transformProps';
import controlPanel from './controlPanel';
import thumbnail from './images/thumbnail.png';

const metadata = new ChartMetadata({
category: t('Map'),
credits: ['https://uber.github.io/deck.gl'],
description: t(
'Uses Gaussian Kernel Density Estimation to visualize spatial distribution of data',
),
name: t('deck.gl Countour'),
thumbnail,
useLegacyApi: true,
tags: [t('deckGL'), t('Spatial'), t('Comparison'), t('Experimental')],
});

export default class ContourChartPlugin extends ChartPlugin {
constructor() {
super({
loadChart: () => import('./Contour'),
controlPanel,
metadata,
transformProps,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import PathChartPlugin from './layers/Path';
import PolygonChartPlugin from './layers/Polygon';
import ScatterChartPlugin from './layers/Scatter';
import ScreengridChartPlugin from './layers/Screengrid';
import ContourChartPlugin from './layers/Contour';

export default class DeckGLChartPreset extends Preset {
constructor() {
Expand All @@ -43,6 +44,7 @@ export default class DeckGLChartPreset extends Preset {
new PolygonChartPlugin().configure({ key: 'deck_polygon' }),
new ScatterChartPlugin().configure({ key: 'deck_scatter' }),
new ScreengridChartPlugin().configure({ key: 'deck_screengrid' }),
new ContourChartPlugin().configure({ key: 'deck_contour' }),
],
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,37 @@ declare module 'deck.gl' {
aggregation?: string;
}

interface ContourLayerProps<T extends object = any> extends LayerProps<T> {
id?: string;
data?: T[];
getPosition?: (d: T) => number[] | null | undefined;
getWeight?: (d: T) => number | null | undefined;
contours: {
color?: colorType | undefined;
lowerThreshold?: any | undefined;
upperThreshold?: any | undefined;
strokeWidth?: any | undefined;
zIndex?: any | undefined;
};
cellSize: number;
colorRange?: number[][];
intensity?: number;
aggregation?: string;
}

export class HeatmapLayer<T extends object = any> extends Layer<
T,
HeatmapLayerProps<T>
> {
constructor(props: HeatmapLayerProps<T>);
}

export class ContourLayer<T extends object = any> extends Layer<
T,
ContourLayerProps<T>
> {
constructor(props: ContourLayerProps<T>);
}
}

declare module '*.png' {
Expand Down
Loading
Loading