You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "jansule (via GitHub)" <gi...@apache.org> on 2026/04/29 11:48:43 UTC
[PR] feat(cartodiagram): fix for v6 + additional controls [superset]
jansule opened a new pull request, #39760:
URL: https://github.com/apache/superset/pull/39760
<!---
Please write the PR title following the conventions at https://www.conventionalcommits.org/en/v1.0.0/
Example:
fix(dashboard): load charts correctly
-->
### SUMMARY
<!--- Describe the change below, including rationale and design decisions -->
This updates the cartodiagram viz type with following additional features:
- support for WellKnownText and WellKnownBinary formatted geo-data (as addition to GeoJSON)
- control for limiting the map extent (limiting panning left, right, up, down on the map)
- controls for setting min and max zoom levels
- control for specifying a padding around the geospatial extend of the data
- config option for specifying the default background layers
- previous editing of MainPreset.ts was marked as deprecated, but still works
- now in config.py, so this can be adjusted without touching the code
- config option for specifying the coordinate reference system of the data
- config option for configuring the map styling capabilities (from very basic features to very advanced features)
- fix some minor issues that came up with the upgrade to superset v6
This reflects the changes that were done in the last year in our superset fork, which we now want to stream back to upstream. This also works as a preparational step for the introduction of a new geo-related visualization type, that will be introduced in a separate PR.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
<!--- Skip this if not applicable -->
Support for additional geo-data formats WellKnownText (EWKT), WellKnownBinary (EWKB)
<img width="967" height="559" alt="image" src="https://github.com/user-attachments/assets/cfe5c07c-9bf9-434e-9603-f413c3c71f43" />
Additional controls Map Padding, Min Zoom, Max Zoom
<img width="976" height="599" alt="image" src="https://github.com/user-attachments/assets/35a9cb2c-f862-45d5-9492-be3c4fb06907" />
### TESTING INSTRUCTIONS
<!--- Required! What steps can be taken to manually verify the changes? -->
Example Datasets:
GeoJson
```sql
SELECT 'SRID=4326;POINT(10.021094598147045 51.12881242291189)' as geom, 1 as foo, 'bar' as cat
union
SELECT 'SRID=4326;POINT(10.021094598147045 51.12881242291189)' as geom, 1 as foo, 'baz' as cat
union
SELECT 'SRID=4326;POINT(9.573277401918602 50.77733656456951)' as geom, 1 as foo, 'far' as cat
union
SELECT 'SRID=4326;POINT(9.573277401918602 50.77733656456951)' as geom, 1 as foo, 'faz' as cat
```
EWKT
```sql
SELECT 'SRID=4326;POINT(10.021094598147045 51.12881242291189)' as geom, 1 as foo, 'bar' as cat
union
SELECT 'SRID=4326;POINT(10.021094598147045 51.12881242291189)' as geom, 1 as foo, 'baz' as cat
union
SELECT 'SRID=4326;POINT(9.573277401918602 50.77733656456951)' as geom, 1 as foo, 'far' as cat
union
SELECT 'SRID=4326;POINT(9.573277401918602 50.77733656456951)' as geom, 1 as foo, 'faz' as cat
```
EWKB
```sql
SELECT '0101000020e6100000e05342e9cc0a2440d0dcebec7c904940' as geom, 1 as foo, 'bar' as cat
union
SELECT '0101000020e6100000e05342e9cc0a2440d0dcebec7c904940' as geom, 1 as foo, 'baz' as cat
union
SELECT '0101000020e6100000708d999d84252340d067b9c37f634940' as geom, 1 as foo, 'far' as cat
union
SELECT '0101000020e6100000708d999d84252340d067b9c37f634940' as geom, 1 as foo, 'faz' as cat
```
Simply paste the above statements into the SQL-Lab and create three datasets. You can then use these three datasets respectively to first create a pie chart and afterwards the cartodiagram. Make sure to select the right geometry column (`geom`) and the right geometry format. If you see the charts on the map, everything works as expected.
### ADDITIONAL INFORMATION
<!--- Check any relevant boxes with "x" -->
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3165354043
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/bootstrapDataUtil.ts:
##########
@@ -0,0 +1,41 @@
+/**
+ * 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.
+ */
+
+/**
+ * Based on superset-frontend/src/utils/getBootstrapData.ts. Replicated
+ * in order to circumvent creating circular dependencies.
+ */
+
+export const getBootstrapData = () => {
+ const appContainer = document.getElementById('app');
+ const dataBootstrap = appContainer?.getAttribute('data-bootstrap');
+ return dataBootstrap ? JSON.parse(dataBootstrap) : {};
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Semantic Duplication</b></div>
<div id="fix">
This file duplicates logic from superset-frontend/src/utils/getBootstrapData.ts to avoid circular dependencies, but this creates divergence risk if the original changes. Ensure synchronization or consider alternative dependency resolution.
</div>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset/config.py:
##########
@@ -2437,6 +2437,83 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument # noq
},
}
+# Map projections of the datasources. If not provided, only
+# EPSG:3857 and EPSG:4326 are supported. The projection definitions
+# can be found on https://epsg.io in the Proj.4 section and should
+# be added here in following structure:
+#
+# {'EPSG:Code': 'definition'}
+#
+# e.g.
+#
+# {
+# 'EPSG:25832': (
+# '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# 'EPSG:25833': (
+# '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# }
+#
+MAP_PROJECTIONS = {}
+
+# Default layers that will be added to all visualizations of plugin-chart-cartodiagram.
+# For a list of supported types, and configuration details see the README.md
+# of plugin-chart-cartodiagram.
+MAP_DEFAULT_LAYERS = [
+ {
+ "type": "WMS",
+ "version": "1.3.0",
+ "url": "https://ows.terrestris.de/osm-gray/service",
+ "layersParam": "OSM-WMS",
+ "title": "OpenStreetMap",
+ "attribution": (
+ "ยฉ Map data from "
+ '<a href="openstreetmap.org/copyright">OpenStreetMap</a>. '
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Broken Attribution Link</b></div>
<div id="fix">
The attribution link for OpenStreetMap copyright is missing the protocol, causing it to be treated as a relative link. This would break navigation if users click it, as it would attempt to load 'openstreetmap.org/copyright' relative to the current domain instead of the intended https://openstreetmap.org/copyright.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
'<a href="https://openstreetmap.org/copyright">OpenStreetMap</a>. '
````
</div>
</details>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsPopoverContent.tsx:
##########
@@ -337,7 +425,69 @@ export const LayerConfigsPopoverContent: FC<
return () => {
clearTimeout(timer);
};
- }, [currentLayerConf]);
+ }, [currentLayerConf, colTypeMapping, dataFeatureCollection]);
+
+ const geoStylerContext: GeoStylerContextInterface = useMemo(
+ () =>
+ createGeoStylerContext(
+ geostylerLocale,
+ geostylerData,
+ geostylerComposition,
+ ),
+ [geostylerLocale, geostylerData, geostylerComposition],
+ );
+
+ useEffect(() => {
+ if (feedback.success !== null) {
+ const timer = setTimeout(
+ () => setFeedback({ success: null, message: null }),
+ 3000,
+ );
+ return () => clearTimeout(timer);
+ }
+ return undefined;
+ }, [feedback.success]);
+
+ const beforeUpload = (file: File): boolean => {
+ const reader = new FileReader();
+ reader.onload = async event => {
+ const sldContent = event.target?.result as string;
+ const sldParser = new SldStyleParser();
+
+ try {
+ const geoStylerResponse = await sldParser.readStyle(sldContent);
+ const { output, errors } = geoStylerResponse;
+
+ if (errors && errors.length > 0) {
+ throw new Error(errors.join('\n'));
+ }
+
+ const updatedStyle = {
+ name: output?.name,
+ rules: output?.rules,
+ };
+
+ setCurrentLayerConf(prevState => ({
+ ...prevState,
+ style: updatedStyle as GsStyle,
+ }));
+
+ setFeedback({
+ success: true,
+ message: null,
+ });
+ } catch (error) {
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Broad exception catch</b></div>
<div id="fix">
The catch in beforeUpload is broad; type error as unknown for better safety.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
} catch (error: unknown) {
````
</div>
</details>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -137,10 +152,41 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ * @param featureCollection The featureCollection for the layer source
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
+ });
+
+ let writeStyleResult;
+ if (style) {
+ const olParser = new OlParser();
+ writeStyleResult = await olParser.writeStyle(style);
+ if (writeStyleResult.errors) {
+ console.warn('Could not create ol-style', writeStyleResult.errors);
+ return undefined;
+ }
+ }
+
+ return new VectorLayer({
+ source: dataSource,
+ style: writeStyleResult?.output,
+ });
+};
+
/**
* Create a layer instance with the provided configuration.
*
* @param layerConf The layer configuration
+ * @param featureCollection The featureCollection for the dataLayer
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Documentation Mismatch</b></div>
<div id="fix">
The JSDoc comment documents a @param featureCollection that isn't in the function signature, which could confuse developers expecting this parameter.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- a/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
+++ b/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
@@ -185,7 +185,6 @@
/**
* Create a layer instance with the provided configuration.
*
- * @param featureCollection The featureCollection for the dataLayer
* @param layerConf The layer configuration
*
* @returns The created layer
*/
export const createLayer = async (layerConf: LayerConf) => {
```
</div>
</details>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts:
##########
@@ -25,24 +26,84 @@ import {
groupByLocationGenericX,
stripGeomFromColnamesAndTypes,
stripGeomColumnFromLabelMap,
+ getWkbColumns,
+ getWktColumns,
} from '../../src/util/transformPropsUtil';
import {
nonTimeSeriesChartData,
groupedTimeseriesChartData,
geom1,
geom2,
groupedTimeseriesLabelMap,
+ nonTimeSeriesWkbChartData,
+ nonTimeSeriesWktChartData,
} from '../testData';
describe('transformPropsUtil', () => {
const groupedTimeseriesParams = {
x_axis: 'mydate',
};
+ const sliceId = 1;
+
const groupedTimeseriesQueryData = {
label_map: groupedTimeseriesLabelMap,
};
+ describe('getWkbColumns', () => {
+ test('gets the WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(1);
+ expect(result[0]).toEqual(2);
+ });
+
+ test('gets multiple WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol, wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(2);
+ expect(result[0]).toEqual(2);
+ });
+
+ test('returns empty array when no WKB column is included', () => {
+ const columns = ['foo', 'bar'];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(0);
+ });
+ });
+
+ describe('getWktColumns', () => {
+ test('gets the WKT columns', () => {
+ const wktCol = 'POINT(8 53)';
+ const columns = ['foo', 'bar', wktCol];
+
+ const result = getWktColumns(columns);
+ expect(result).toHaveLength(1);
+ expect(result[0]).toEqual(2);
+ });
+
+ test('gets multiple WKT columns', () => {
+ const wktCol = 'POINT(8 53)';
+ const columns = ['foo', 'bar', wktCol, wktCol];
+
+ const result = getWktColumns(columns);
+ expect(result).toHaveLength(2);
+ expect(result[0]).toEqual(2);
+ });
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Incomplete test assertion</b></div>
<div id="fix">
Similar to the WKB test, the 'gets multiple WKT columns' test only checks the first index but not the second (should be 3). Complete the assertions to ensure full behavior coverage.
</div>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -55,6 +69,42 @@ export const getGeojsonColumns = (columns: string[]) =>
return [...prev, idx];
}, []);
+export const getWkbColumns = (columns: string[]) =>
+ columns.reduce((prev, current, idx) => {
+ let isWkb;
+
+ try {
+ new WKB().readFeature(current);
+ isWkb = true;
+ } catch {
+ isWkb = false;
+ }
+ if (!isWkb) {
+ return [...prev];
+ }
+ return [...prev, idx];
+ }, []);
+
+const WktFormatIdentifiers = [
+ 'SRID=',
+ 'POINT',
+ 'LINESTRING',
+ 'POLYGON',
+ 'MULTIPOINT',
+ 'MULTILINESTRING',
+ 'MULTIPOLYGON',
+];
+export const getWktColumns = (columns: string[]) =>
+ columns.reduce((prev, current, idx) => {
+ const isWkt = WktFormatIdentifiers.some(identifier =>
+ current.startsWith(identifier),
+ );
+ if (!isWkt) {
+ return [...prev];
+ }
+ return [...prev, idx];
+ }, []);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Code Duplication</b></div>
<div id="fix">
The geometry format selection logic is duplicated between groupByLocationGenericX and stripGeomFromColnamesAndTypes. Introduce a helper function to centralize this logic, reducing maintenance burden and divergence risk.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
}, []);
export const getGeomColumns = (columns: string[], geomFormat: GeometryFormat): number[] => {
if (geomFormat === GeometryFormat.GEOJSON) {
return getGeojsonColumns(columns);
} else if (geomFormat === GeometryFormat.WKB) {
return getWkbColumns(columns);
} else {
return getWktColumns(columns);
}
};
````
</div>
</details>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts:
##########
@@ -25,24 +26,84 @@ import {
groupByLocationGenericX,
stripGeomFromColnamesAndTypes,
stripGeomColumnFromLabelMap,
+ getWkbColumns,
+ getWktColumns,
} from '../../src/util/transformPropsUtil';
import {
nonTimeSeriesChartData,
groupedTimeseriesChartData,
geom1,
geom2,
groupedTimeseriesLabelMap,
+ nonTimeSeriesWkbChartData,
+ nonTimeSeriesWktChartData,
} from '../testData';
describe('transformPropsUtil', () => {
const groupedTimeseriesParams = {
x_axis: 'mydate',
};
+ const sliceId = 1;
+
const groupedTimeseriesQueryData = {
label_map: groupedTimeseriesLabelMap,
};
+ describe('getWkbColumns', () => {
+ test('gets the WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(1);
+ expect(result[0]).toEqual(2);
+ });
+
+ test('gets multiple WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol, wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(2);
+ expect(result[0]).toEqual(2);
+ });
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Incomplete test assertion</b></div>
<div id="fix">
The test for 'gets multiple WKB columns' checks array length and the first index but misses verifying the second index (should be 3). This incomplete assertion risks missing bugs in multi-column detection. Add expect(result[1]).toEqual(3); to fully validate the logic.
</div>
</div>
<small><i>Code Review Run #aa3025</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4523193440
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4357519489
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-5022109937
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3291583595
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerTreeItem.tsx:
##########
@@ -18,7 +18,6 @@
*/
import { Icons } from '@superset-ui/core/components/Icons';
import { Button } from '@superset-ui/core/components';
-import { Tag } from 'src/components';
import { FC } from 'react';
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>CWE-N/A: Missing Unit Test Coverage</b></div>
<div id="fix">
The LayerTreeItem component lacks unit test coverage. BITO.md rule [6262] requires tests to verify actual behavior (click handlers, rendering structure), not just that components render. Without tests, this refactoring removing the Tag wrapper creates regression risk that could go undetected.
</div>
</div>
<small><i>Code Review Run #c40662</i></small>
</div><div>
<div id="suggestion">
<div id="issue"><b>Tag component functionality removed</b></div>
<div id="fix">
Replacing `<Tag>` with `<div>` removes non-cosmetic functionality from `src/components/Tag/index.tsx`: (1) Tooltip wrapping around children, (2) styled top/bottom margins via `theme.sizeUnit`, (3) `data-test="tag"` attribute for testing, and (4) conditional link rendering when `id` prop is present. The `className` prop is passed through to StyledTag and applied to the AntdTag element, so removing the Tag wrapper changes observable behavior beyond styling. Either restore the Tag wrapper or explicitly remove the features via component props.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -152,8 +196,71 @@ export const createLayer = async (layerConf: LayerConf) => {
layer = await createWfsLayer(layerConf);
} else if (isXyzLayerConf(layerConf)) {
layer = createXyzLayer(layerConf);
+ } else if (isDataLayerConf(layerConf)) {
+ layer = await createDataLayer(layerConf);
} else {
console.warn('Provided layerconfig is not recognized');
}
return layer;
};
+
+export const removeSelectionLayer = (olMap: Map) => {
+ const selectionLayer = olMap
+ .getLayers()
+ .getArray()
+ .filter(l => l.get(LAYER_NAME_PROP) === SELECTION_LAYER_NAME)
+ .pop();
+ if (selectionLayer) {
+ olMap.removeLayer(selectionLayer);
+ }
+};
+
+export const getSelectedFeatures = (
+ dataLayers: VectorLayer<VectorSource>[],
+ filterState: FilterState,
+ crossFilterColumn: string,
+) => {
+ let selectedFeatures: Feature[] = [];
+ if (
+ filterState.selectedValues !== null &&
+ filterState.selectedValues !== undefined &&
+ dataLayers
+ ) {
+ selectedFeatures = dataLayers.flatMap(dataLayer =>
+ dataLayer
+ .getSource()!
+ .getFeatures()
+ .filter(f =>
+ filterState.selectedValues.includes(f.get(crossFilterColumn)),
+ ),
+ );
+ }
+ return selectedFeatures;
+};
+
+export const setSelectionBackgroundOpacity = (
+ dataLayers: VectorLayer<VectorSource>[],
+ opacity: number,
+) => {
+ dataLayers.forEach(dataLayer => {
+ dataLayer.setOpacity(opacity);
+ });
+};
+
+export const createSelectionLayer = (
+ dataLayers: VectorLayer<VectorSource>[],
+ features: Feature[],
+) => {
+ const selectionLayer = new VectorLayer({
+ source: new VectorSource({
+ features,
+ }),
+ });
+ selectionLayer.set(LAYER_NAME_PROP, SELECTION_LAYER_NAME);
+ // TODO how can we handle multiple data layers?
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>TODO acknowledges incomplete logic</b></div>
<div id="fix">
TODO comment at line 260 acknowledges incomplete handling of multiple data layers in `createSelectionLayer`. The function currently only uses the style from `dataLayers[0]`, which may not be appropriate when multiple layers have different styles.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/geometryUtil.ts:
##########
@@ -58,3 +59,13 @@ export const getExtentFromFeatures = (features: Feature[]) => {
source.addFeatures(features);
return source.getExtent();
};
+
+/**
+ * Generates a padding array for the map extent.
+ * @param mapExtentPadding The selected map extent padding value
+ * @returns An array with the padding values or undefined
+ */
+export const getMapExtentPadding = (
+ mapExtentPadding?: number,
+): FitOptions['padding'] | undefined =>
+ mapExtentPadding !== undefined ? Array(4).fill(mapExtentPadding) : undefined;
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing unit tests for new function</b></div>
<div id="fix">
The new `getMapExtentPadding` function lacks unit tests. Per project guidelines, new utility functions should have dedicated tests covering success paths and edge cases. The existing test file at `test/util/geometryUtil.test.ts` only tests `getProjectedCoordinateFromPointGeoJson` and `getExtentFromFeatures`.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsPopoverContent.tsx:
##########
@@ -273,29 +345,47 @@ export const LayerConfigsPopoverContent: FC<
conf = {
...baseConfs,
type: currentLayerConf.type,
+ url: currentLayerConf.url,
};
- } else {
+ } else if (isWfsLayerConf(currentLayerConf)) {
conf = {
...baseConfs,
type: currentLayerConf.type,
+ url: currentLayerConf.url,
version: currentLayerConf.version,
typeName: currentLayerConf.typeName,
maxFeatures: currentLayerConf.maxFeatures,
style: currentLayerConf.style,
};
+ } else {
+ conf = {
+ ...baseConfs,
+ type: currentLayerConf.type,
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Redundant type assignment</b></div>
<div id="fix">
The `type: currentLayerConf.type` property is set in `baseConfs` (line 331) and then redundantly reassigned in each branch conf object at lines 341, 347, 353, and 363. The spread operator `...baseConfs` already propagates this value, making the per-branch assignments dead code within the diff.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,183 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ context.composition!.Rules.disableClassification =
+ !data?.exampleFeatures.features.length;
+
+ return context;
+};
+
+/**
+ * Get the GeoStylerLocale derived from the application locale.
+ * @param appLocale The application locale.
+ * @returns The matching GeoStylerLocale.
+ */
+export const getGeoStylerLocale = (appLocale: string) => {
+ let gsLocale = (locale as Record<string, GeoStylerLocale>)[appLocale];
+ if (!gsLocale) {
+ const localeKeys = Object.keys(locale);
+ const localeKey = localeKeys.find(
+ l => l.split('_')[0].toLowerCase() === appLocale.toLowerCase(),
+ );
+ gsLocale = localeKey
+ ? (locale as Record<string, GeoStylerLocale>)[localeKey]
+ : locale.en_US;
+ }
+ return gsLocale;
+};
+
+/**
+ * Get the default style depending on given geometry types.
+ * @param geomTypes List of distinct geometry types.
+ * @param styleName Name of the style.
+ * @param ruleName Name of the rule.
+ * @returns GeoStylerStyle.
+ */
+export const getDefaultStyle = (
+ geomTypes: GeoJsonGeometryTypes[] = [],
+ styleName: string,
+ ruleName: string,
+ theme: SupersetTheme,
+) => {
+ const symbolizers: Symbolizer[] = [];
+ if (geomTypes.includes('Polygon') || geomTypes.includes('MultiPolygon')) {
+ symbolizers.push({
+ kind: 'Fill',
+ // eslint-disable-next-line theme-colors/no-literal-colors
+ color: theme.colorTextBase,
+ });
+ }
+ if (
+ geomTypes.includes('LineString') ||
+ geomTypes.includes('MultiLineString')
+ ) {
+ symbolizers.push({
+ kind: 'Line',
+ // eslint-disable-next-line theme-colors/no-literal-colors
+ color: theme.colorTextBase,
+ width: 2,
+ });
+ }
+ if (geomTypes.includes('Point') || geomTypes.includes('MultiPoint')) {
+ symbolizers.push({
+ kind: 'Mark',
+ wellKnownName: 'circle',
+ // eslint-disable-next-line theme-colors/no-literal-colors
+ color: theme.colorTextBase,
+ });
+ }
+ const style: Style = {
+ name: styleName,
+ rules: [
+ {
+ name: ruleName,
+ symbolizers,
+ },
+ ],
+ };
+ return style;
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing unit tests for new utilities</b></div>
<div id="fix">
Add comprehensive unit tests for this new utility module covering: type mapping logic, data transformation, context creation with various inputs, locale fallback behavior, and default style generation for different geometry types.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsPopoverContent.tsx:
##########
@@ -482,25 +642,74 @@ export const LayerConfigsPopoverContent: FC<
{
key: LAYER_CONFIG_TABS.GEOSTYLER,
label: styleTabLabel,
- disabled: !isWfsLayerConf(currentLayerConf),
- children: isWfsLayerConf(currentLayerConf) && (
- <StyledGeoStyler
- style={currentLayerConf.style}
- onStyleChange={onStyleChange}
- data={geostylerData}
- />
+ disabled:
+ !isWfsLayerConf(currentLayerConf) &&
+ !isDataLayerConf(currentLayerConf),
+ children: (isWfsLayerConf(currentLayerConf) ||
+ isDataLayerConf(currentLayerConf)) && (
+ <>
+ <StyledUploadButtonContainer>
+ <div>
+ <StyledFeedbackMessage success={!!feedback.success}>
+ {feedback.message}
+ </StyledFeedbackMessage>
+ </div>
+ <Upload
+ beforeUpload={beforeUpload}
+ showUploadList={false}
+ accept=".sld"
+ >
+ <Button
+ buttonSize="small"
+ buttonStyle="secondary"
+ icon={
+ feedback.success !== null ? (
+ feedback.success ? (
+ <CheckOutlined
+ style={{ color: theme.colorSuccess }}
+ />
+ ) : (
+ <CloseOutlined
+ style={{ color: theme.colorError }}
+ />
+ )
+ ) : (
+ <UploadOutlined />
+ )
+ }
+ style={{ float: 'right' }}
+ >
+ {t('Import SLD')}
+ </Button>
+ </Upload>
+ </StyledUploadButtonContainer>
+ <GeoStylerContext.Provider value={geoStylerContext}>
+ <StyledGeoStyler
+ style={currentLayerConf.style}
+ onStyleChange={onStyleChange}
+ />
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing `data` prop in GeoStyler</b></div>
<div id="fix">
The `data` prop was present in the old GeoStyler usage (line 490) but is missing in the new code. This prop provides parsed geo data for the style editor to display feature information.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -55,6 +70,55 @@ export const getGeojsonColumns = (columns: string[]) =>
return [...prev, idx];
}, []);
+export const getWkbColumns = (columns: string[]) =>
+ columns.reduce((prev, current, idx) => {
+ let isWkb;
+
+ try {
+ new WKB().readFeature(current);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>WKB parser reuse</b></div>
<div id="fix">
Move the `new WKB()` instantiation outside of the `reduce` callback into a block-bodied arrow function so that the same parser instance is reused for each column.
</div>
</div>
<small><i>Code Review Run #5c3657</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3161221164
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/index.ts:
##########
@@ -54,17 +55,18 @@ export default class CartodiagramPlugin extends ChartPlugin {
],
});
- if (opts.defaultLayers) {
- const layerConfig = getLayerConfig(controlPanel);
-
- // set defaults for layer config if found
- if (layerConfig) {
- layerConfig.config.default = opts.defaultLayers;
- } else {
+ const layerConfig = getLayerConfig(controlPanel);
+ const mapDefaultLayers = getMapDefaultLayers();
+ if (layerConfig) {
+ if (mapDefaultLayers.length > 0) {
+ layerConfig.config.default = mapDefaultLayers;
+ }
+ if (opts?.defaultLayers) {
// eslint-disable-next-line no-console
- console.warn(
- 'Cannot set defaultLayers. layerConfig not found in control panel. Please check if the path to layerConfig should be adjusted.',
+ console.error(
+ 'Warning: [CartodiagramPlugin] Setting defaultLayers via MainPreset.js is deprecated. Please use MAP_DEFAULT_LAYERS in your config file instead.',
);
+ layerConfig.config.default = opts.defaultLayers;
}
Review Comment:
Logic works as expected.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422835661
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -79,6 +144,7 @@ export const createColumnName = (columns: string[], ignoreIdx: number[]) =>
export const groupByLocationGenericX = (
Review Comment:
I added tests accordingly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-6520933287
Thanks for the review @sadpandajoe! I applied your remarks. Could you take another look? I will update the package-lock.json as soon as I get new feedback from you, since conflicts come up here quite quickly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "netlify[bot] (via GitHub)" <gi...@apache.org>.
netlify[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4343402647
### <span aria-hidden="true">โ
</span> Deploy Preview for *superset-docs-preview* ready!
| Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">๐จ</span> Latest commit | 7e6ab170d32bf6d854ecc5d752355d6e84c83035 |
|<span aria-hidden="true">๐</span> Latest deploy log | https://app.netlify.com/projects/superset-docs-preview/deploys/69f1f01b8cf67b00074de4a6 |
|<span aria-hidden="true">๐</span> Deploy Preview | [https://deploy-preview-39760--superset-docs-preview.netlify.app](https://deploy-preview-39760--superset-docs-preview.netlify.app) |
|<span aria-hidden="true">๐ฑ</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br /><br /><br />_Use your smartphone camera to open QR code link._</details> |
|<span aria-hidden="true">๐ค</span> Make changes | [Run an agent on this branch](https://app.netlify.com/projects/superset-docs-preview/agent-runs#Dco7DoAgDADQu3S2SSGkoDfwGHzjgJQQFmO8u2xveC_0IXefcABsEIZv8VrWpBnJoHYorT4Y_ZiyQsq9ynOmVXgvqpAKLha2gYisSdl4hu8H) |
---
<!-- [superset-docs-preview Preview](https://deploy-preview-39760--superset-docs-preview.netlify.app) -->
_To edit notification comments on pull requests, go to your [Netlify project configuration](https://app.netlify.com/projects/superset-docs-preview/configuration/notifications#deploy-notifications)._
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4377999381
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
`createDataLayer` passes `attribution` to the `VectorSource` unescaped, while the WMS, XYZ and WFS creators in this file all go through `escapeAttribution` because OpenLayers renders attributions as HTML. A chart owner can save `layer_configs` with `type: 'DATA'` and an attribution like `<img src=x onerror=...>` (via the UI field or the chart API), and the script runs for anyone who opens the chart or a dashboard containing it. Should this use `escapeAttribution(attribution)` like the other layer types, with a matching case next to the existing escape tests in `layerUtil.test.ts`?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/transformProps.ts:
##########
@@ -17,44 +17,63 @@
* under the License.
*/
import { ChartProps, getChartTransformPropsRegistry } from '@superset-ui/core';
-import {
- getChartConfigs,
- parseSelectedChart,
-} from '../util/transformPropsUtil';
+import { getChartConfigs, parseSelectedChart } from '../util/transformPropsUtil';
+import { ChartConfig } from '../types';
export default function transformProps(chartProps: ChartProps) {
const { width, height, formData, hooks, theme } = chartProps;
const {
geomColumn,
+ geomFormat,
selectedChart: selectedChartString,
chartSize,
layerConfigs,
+ mapExtentPadding,
+ mapMaxExtent,
Review Comment:
`mapMaxExtent` (and `geomFormat`, `minZoom`, `maxZoom`, `mapExtentPadding`) are read straight from `formData` with no fallback. Charts saved before this change have none of these keys in their stored params, and dashboards render from the stored params rather than the control defaults that Explore applies. For such a chart `OlChartMap` destructures `extentMode` from an undefined `mapMaxExtent` and throws on mount, and a missing `geomFormat` sends GeoJSON data through the WKT path so the map comes up empty. Should `transformProps` default these values (for example to the control defaults) so existing saved charts keep rendering?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -20,21 +20,67 @@ import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import Point from 'ol/geom/Point';
-import { View } from 'ol';
+import { Map, View } from 'ol';
import BaseEvent from 'ol/events/Event';
+import GeoJSON from 'ol/format/GeoJSON';
import { unByKey } from 'ol/Observable';
-import { toLonLat } from 'ol/proj';
+import { toLonLat, transformExtent } from 'ol/proj';
import { debounce } from 'lodash-es';
-import { fitMapToCharts } from '../util/mapUtil';
+import { fitMapToData } from '../util/mapUtil';
import { ChartLayer } from './ChartLayer';
import { createLayer } from '../util/layerUtil';
import {
ChartConfig,
LayerConf,
+ MapMaxExtentConfigs,
MapViewConfigs,
OlChartMapProps,
} from '../types';
import { isChartConfigEqual } from '../util/chartUtil';
+import {
+ getExtentFromFeatures,
+ getMapExtentPadding,
+} from '../util/geometryUtil';
+
+/**
+ * Computes a transformed extent from a MapMaxExtentConfigs (if CUSTOM mode)
+ * and applies it by setting a new view on the map.
+ */
+const applyMapExtentView = (
+ olMap: Map,
+ mapMaxExtentConf: MapMaxExtentConfigs,
+) => {
+ const { extentMode, fixedMaxX, fixedMaxY, fixedMinX, fixedMinY } =
+ mapMaxExtentConf;
+ const view = olMap.getView();
+ const center = view.getCenter();
+ const zoom = view.getZoom();
+ let extent;
+
+ if (
+ extentMode === 'CUSTOM' &&
+ fixedMaxX !== undefined &&
+ fixedMaxY !== undefined &&
+ fixedMinX !== undefined &&
+ fixedMinY !== undefined
+ ) {
+ extent = transformExtent(
+ [fixedMinX, fixedMinY, fixedMaxX, fixedMaxY],
+ 'EPSG:4326',
+ 'EPSG:3857',
+ );
+ }
+
+ olMap.setView(
Review Comment:
This replaces the map's `View` whenever `currentMapMaxExtent` changes, but the zoom-sync listener further down (the `change:resolution` handler, deps `[olMap, setControlValue, chartSize]`) stays attached to the view it captured earlier. After switching Max. Extent to CUSTOM or clicking "Use current extent" and then zooming, that handler never sees the zoom event, so `chart_size.configs.zoom` stops following the map and the zoom-based size controls compute against a stale zoom. Should that effect also re-subscribe when the extent (and therefore the view) changes?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:
##########
@@ -0,0 +1,155 @@
+/**
+ * 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 { ControlHeader } from '@superset-ui/chart-controls';
+import { t } from '@apache-superset/core/translation';
+import { css, styled } from '@apache-superset/core/theme';
+import { Button, Radio, RadioChangeEvent } from '@superset-ui/core/components';
+import { FC } from 'react';
+import { mix } from 'polished';
+import {
+ MapMaxExtentConfigs,
+ MapMaxExtentConfigsControlProps,
+} from '../../types';
+import MapMaxExtentTag from './MapMaxExtentTag';
+
+export const StyledMaxExtentButton = styled(Button)`
+ ${({ theme }) => css`
+ flex: 1;
+ margin-right: 4px;
+ line-height: 1.5715;
+ border-radius: ${theme.borderRadius}px;
+ background-color: ${theme.colorPrimaryBg};
+ color: ${theme.colorPrimaryText};
+ font-size: ${theme.fontSizeSM}px;
+ font-weight: ${theme.fontWeightStrong};
+ text-transform: uppercase;
+ min-width: ${theme.sizeUnit * 36}px;
+ min-height: ${theme.padding}px;
+ box-shadow: none;
+ border-width: 0px;
+ border-style: none;
+ border-color: transparent;
+ margin-left: 9px;
+ margin-top: 10px;
+ &:hover {
+ background-color: ${mix(0.1, theme.colorPrimary, theme.colorPrimaryBg)};
+ color: ${theme.colorPrimaryText};
+ }
+ `}
+`;
+
+export const StyledMaxExtentTag = styled(MapMaxExtentTag)`
+ ${() => css`
+ margin-left: 9px;
+ `}
+`;
+
+export const MapMaxExtentViewControl: FC<MapMaxExtentConfigsControlProps> = ({
+ value,
+ onChange = () => {},
+ name,
+ label,
+ description,
+ renderTrigger,
+ hovered,
+ validationErrors,
+}) => {
+ const isCustomMode = () => value?.extentMode === 'CUSTOM';
+
+ const onModeChange = (e: RadioChangeEvent) => {
+ if (!value) return;
+
+ const newMode = e.target.value;
+ let changedValue: MapMaxExtentConfigs = {
+ ...value,
+ extentMode: newMode,
+ };
+ if (newMode === 'NONE') {
+ changedValue = {
+ ...value,
+ fixedMaxX: undefined,
+ fixedMaxY: undefined,
+ fixedMinX: undefined,
+ fixedMinY: undefined,
+ extentMode: newMode,
+ };
+ }
+
+ onChange(changedValue);
+ };
+
+ const onButtonClick = () => {
Review Comment:
The capture/clear flow in this control and `OlChartMap` has no component-level coverage: `onButtonClick` copies the live `minX/minY/maxX/maxY` into the fixed bounds, and switching back to NONE has to clear them, but the current utility tests never render the control. A regression where the capture copies stale bounds, or NONE leaves the fixed values behind (so the map stays clamped), would pass the suite. Could you add a test that renders the control with live bounds, clicks "Use current extent" and asserts `onChange` receives the fixed values, then selects NONE and asserts they are `undefined`?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/package.json:
##########
@@ -31,8 +31,9 @@
"dependencies": {
"@types/geojson": "^7946.0.16",
"geojson": "^0.5.0",
- "lodash": "^4.18.1",
- "lodash-es": "^4.18.1"
+ "geostyler-legend": "^5.2.1",
Review Comment:
`geostyler-legend` is added as a runtime dependency (with matching webpack resolve/babel-exclude entries and a large lockfile addition), but nothing under the plugin or `superset-frontend/src` imports it. Fresh installs pull it and its d3 tree for no functionality. Is there a follow-up that uses it, or can it be dropped from this PR?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422821934
##########
superset-frontend/plugins/plugin-chart-cartodiagram/package.json:
##########
@@ -31,8 +31,9 @@
"dependencies": {
"@types/geojson": "^7946.0.16",
"geojson": "^0.5.0",
- "lodash": "^4.18.1",
- "lodash-es": "^4.18.1"
+ "geostyler-legend": "^5.2.1",
Review Comment:
It will be used in a follow up, so I would prefer to keep it for now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3291583601
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts:
##########
@@ -88,6 +94,27 @@ const config: ControlPanelConfig = {
},
},
],
+ [
+ {
+ name: 'geom_format',
+ config: {
+ type: 'SelectControl',
+ label: t('Geometry Format'),
+ renderTrigger: false,
+ description: t(
+ 'The format of the geometry column. GeoJSON columns are expected to use WGS84 coordinates. The EWKB and EWKT formats allow for arbitrary projections, which will be read from the data.',
+ ),
+ default: GeometryFormat.GEOJSON,
+ choices: [
+ [GeometryFormat.GEOJSON, t('GeoJSON')],
+ [GeometryFormat.WKB, t('EWKB')],
+ [GeometryFormat.WKT, t('EWKT')],
+ ],
+ clearable: false,
+ validators: [validateNonEmpty],
+ },
+ },
+ ],
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing test coverage for new formats</b></div>
<div id="fix">
The `geom_format` control adds WKB and WKT geometry format options (lines 108-111), but `transformProps.test.ts` only exercises `GeometryFormat.GEOJSON`. The new WKB and WKT code paths in `transformPropsUtil.ts` and `mapUtil.tsx` will remain untested.
</div>
</div>
<small><i>Code Review Run #c40662</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerTreeItem.tsx:
##########
@@ -18,7 +18,6 @@
*/
import { Icons } from '@superset-ui/core/components/Icons';
import { Button } from '@superset-ui/core/components';
-import { Tag } from 'src/components';
import { FC } from 'react';
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>CWE-N/A: Missing Unit Test Coverage</b></div>
<div id="fix">
The LayerTreeItem component lacks unit test coverage. BITO.md rule [6262] requires tests to verify actual behavior (click handlers, rendering structure), not just that components render. Without tests, this refactoring removing the Tag wrapper creates regression risk that could go undetected.
</div>
</div>
<small><i>Code Review Run #c40662</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsPopoverContent.tsx:
##########
@@ -16,23 +16,41 @@
* specific language governing permissions and limitations
* under the License.
*/
+import {
+ CheckOutlined,
+ CloseOutlined,
+ UploadOutlined,
+} from '@ant-design/icons';
import { t } from '@apache-superset/core/translation';
import { JsonValue } from '@superset-ui/core';
import { css, styled, useTheme } from '@apache-superset/core/theme';
// eslint-disable-next-line no-restricted-imports
import { Button } from '@superset-ui/core/components/Button';
import { Form } from '@superset-ui/core/components/Form';
import Tabs from '@superset-ui/core/components/Tabs';
-import { Data as GsData } from 'geostyler-data';
+import { Upload } from 'antd';
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Use @<!-- -->superset-ui/core for Upload</b></div>
<div id="fix">
Direct antd import at line 31 violates the project's guideline to use @superset-ui/core component wrappers. An Upload component wrapper exists in @superset-ui/core/components/Upload that re-exports from antd.
</div>
</div>
<small><i>Code Review Run #c40662</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/webpack.config.js:
##########
@@ -516,7 +516,58 @@ const config = {
{
test: /\.jsx?$/,
// include source code for plugins, but exclude node_modules and test files within them
- exclude: [/superset-ui.*\/node_modules\//, /\.test.jsx?$/],
+ exclude: [
+ /superset-ui.*\/node_modules\//,
+ /\.test.jsx?$/,
+ path.resolve(
+ __dirname,
+ './plugins/plugin-chart-cartodiagram/node_modules/geostyler-openlayers-parser',
+ ),
+ path.resolve(
+ __dirname,
+ './plugins/plugin-chart-cartodiagram/node_modules/geostyler-legend',
+ ),
+ path.resolve(
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Dead code: non-existent path exclusions</b></div>
<div id="fix">
These `path.resolve` patterns exclude directories that don't exist in the repository (plugin-chart-cartodiagram has no node_modules). Additionally, directory paths without trailing wildcards won't match nested files. If these exclusions are intended for transitive dependencies of geostyler-openlayers-parser, either use RegExp patterns like `/plugin-chart-cartodiagram\/node_modules\/(geostyler|d3)/` or remove if not applicable.
</div>
</div>
<small><i>Code Review Run #c40662</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613201734
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -258,16 +424,39 @@ export const OlChartMap = (props: OlChartMapProps) => {
if (!chartLayer) {
return;
}
- const extent = chartLayer.getExtent();
+
+ const features = new GeoJSON().readFeatures(chartLayer.chartConfigs, {
+ featureProjection: 'EPSG:4326',
+ });
+
+ const extent = getExtentFromFeatures(features);
+
if (!extent) {
return;
}
+
+ const transformedExtent = transformExtent(
+ extent,
+ 'EPSG:4326',
+ olMap.getView().getProjection(),
+ );
+
const view = olMap.getView();
- view.fit(extent, {
- size: [250, 250],
- });
+ const padding = getMapExtentPadding(mapExtentPadding);
+
+ view.fit(transformedExtent, { padding });
}
- }, [olMap, currentMapView.mode]);
+ }, [olMap, currentMapView.mode, mapExtentPadding]);
Review Comment:
**Suggestion:** The FIT_DATA extent effect does not depend on chart data, so when features change but mode stays FIT_DATA, the map will not refit and will show an outdated extent. Include the chart data dependency (or a stable version/hash of it) so the fit runs on data updates. [logic error]
<details>
<summary><b>Severity Level:</b> Critical ๐จ</summary>
```mdx
- โ ๏ธ New data may render outside current viewport.
- โ ๏ธ Users must manually adjust map after data refresh.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Create or open a cartodiagram chart where `map_view` defaults to FIT_DATA in the
control panel (`controlPanel.ts:126-138`), so `currentMapView.mode` is initially
`'FIT_DATA'`.
2. The FIT_DATA effect in `OlChartMap.tsx:416-449` runs once after mount; it locates the
`ChartLayer` on the map, parses its `chartConfigs` into features, computes an extent, and
calls `view.fit(transformedExtent, { padding })`.
3. Change filters or time range in Explore so that a new query is issued and new
`chartConfigs` are passed via `transformProps` (in
`superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/transformProps.ts`) to
`OlChartMap`, while `map_view.mode` remains `'FIT_DATA'`.
4. Because the FIT_DATA effect depends only on `[olMap, currentMapView.mode,
mapExtentPadding]` (line 449) and not on any chart data or `chartConfigs`, it does not
re-run on data changes; the map remains fitted to the old extent, and new data points may
appear off-screen until the user manually pans or zooms.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=af75daa444ec4805b8fe57c5d039a2d7&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=af75daa444ec4805b8fe57c5d039a2d7&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx
**Line:** 449:449
**Comment:**
*Logic Error: The FIT_DATA extent effect does not depend on chart data, so when features change but mode stays FIT_DATA, the map will not refit and will show an outdated extent. Include the chart data dependency (or a stable version/hash of it) so the fit runs on data updates.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=1499bf15d5bd4f94e7f8bdfc90dcfb55abe39919bebba935445e380e3bea33a4&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=1499bf15d5bd4f94e7f8bdfc90dcfb55abe39919bebba935445e380e3bea33a4&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -159,6 +211,64 @@ export const OlChartMap = (props: OlChartMapProps) => {
break;
}
}
+
+ switch (extentMode) {
+ case 'CUSTOM': {
+ if (
+ fixedMaxX === undefined ||
+ fixedMaxY === undefined ||
+ fixedMinX === undefined ||
+ fixedMinY === undefined
+ ) {
+ break;
+ }
+ const [minx, miny, maxx, maxy] = transformExtent(
+ [fixedMinX, fixedMinY, fixedMaxX, fixedMaxY],
+ 'EPSG:4326',
+ 'EPSG:3857',
+ );
+
+ olMap.setView(
+ new View({
+ center: view.getCenter(),
+ zoom: view.getZoom(),
+ extent: [minx, miny, maxx, maxy],
+ maxZoom: view.getMaxZoom(),
+ minZoom: view.getMinZoom(),
+ }),
+ );
+ break;
+ }
+ default: {
+ const newView = new View({
+ center: view.getCenter(),
+ zoom: view.getZoom(),
+ maxZoom: view.getMaxZoom(),
+ minZoom: view.getMinZoom(),
+ });
+ olMap.setView(newView);
+
+ const [minx, miny, maxx, maxy] = newView.calculateExtent(
+ olMap.getSize(),
Review Comment:
**Suggestion:** `calculateExtent` is called with `olMap.getSize()` without checking for `undefined`; OpenLayers can return undefined before layout/target initialization, which can throw at runtime. Guard size availability before calling `calculateExtent`. [possible bug]
<details>
<summary><b>Severity Level:</b> Critical ๐จ</summary>
```mdx
- โ Cartodiagram visualization can crash on initial render.
- โ ๏ธ Charts in hidden tabs risk initialization failure.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Configure a cartodiagram chart with the default `map_max_extent` control value
(`extentMode: 'NONE'`) from `controlPanel.ts:199-208`, then open the chart in Explore.
2. On mount, `OlChartMap` first attaches the map to its DOM target via
`olMap.setTarget(mapId)` in the effect at `OlChartMap.tsx:80-82`.
3. The "Set initial map extent" effect at `OlChartMap.tsx:171-272` runs with an empty
dependency array; for `extentMode === 'NONE'` it creates `newView` and then calls
`newView.calculateExtent(olMap.getSize())` at lines 251-252.
4. If `olMap.getSize()` is still `undefined` at that moment (OpenLayers returns undefined
before the container has a measured size, e.g., when the chart is rendered in a hidden tab
or during early layout), `calculateExtent(undefined)` will dereference the size array
internally and throw a TypeError, crashing the cartodiagram visualization during
initialization.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=316cdf79eed94475bc0f291f056ee0c6&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=316cdf79eed94475bc0f291f056ee0c6&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx
**Line:** 251:252
**Comment:**
*Possible Bug: `calculateExtent` is called with `olMap.getSize()` without checking for `undefined`; OpenLayers can return undefined before layout/target initialization, which can throw at runtime. Guard size availability before calling `calculateExtent`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=554eb318eb74d85b0d45590edd025879c8482fd4f0b7211913dc56645f47b6da&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=554eb318eb74d85b0d45590edd025879c8482fd4f0b7211913dc56645f47b6da&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts:
##########
@@ -101,16 +128,87 @@ const config: ControlPanelConfig = {
type: 'MapViewControl',
renderTrigger: true,
description: t(
- 'The extent of the map on application start. FIT DATA automatically sets the extent so that all data points are included in the viewport. CUSTOM allows users to define the extent manually.',
+ 'The map center on application start. FIT DATA automatically sets the center so that all data points are included in the viewport. CUSTOM allows users to define the center manually.',
),
- label: t('Extent'),
+ label: t('Initial Map Center'),
dontRefreshOnChange: true,
default: {
mode: 'FIT_DATA',
},
},
},
],
+ [
+ {
+ name: 'map_extent_padding',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Map Padding'),
+ description: t(
+ 'Set the map extent padding. The selected value is applied to all edges of the map.',
+ ),
+ default: 30,
+ min: 0,
+ max: 100,
+ step: 10,
+ visibility: ({
+ controls,
+ }: {
+ controls: ControlPanelsContainerProps['controls'] & {
+ map_view?: { value?: Partial<MapViewConfigs> };
+ };
+ }) => Boolean(controls?.map_view?.value?.mode === 'FIT_DATA'),
+ },
+ },
+ ],
+ [
+ {
+ name: 'min_zoom',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Min Zoom'),
+ description: t('The minimal zoom of the map'),
+ default: MIN_ZOOM_LEVEL,
+ min: MIN_ZOOM_LEVEL,
+ max: MAX_ZOOM_LEVEL,
+ step: 1,
+ },
+ },
+ ],
+ [
+ {
+ name: 'max_zoom',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Max Zoom'),
+ description: t('The maximal zoom of the map'),
+ default: MAX_ZOOM_LEVEL,
+ min: MIN_ZOOM_LEVEL,
+ max: MAX_ZOOM_LEVEL,
+ step: 1,
+ },
+ },
Review Comment:
**Suggestion:** `min_zoom` and `max_zoom` are independently editable without cross-field validation, allowing `min_zoom > max_zoom` and creating inconsistent zoom constraints at runtime. Add validation to enforce `min_zoom <= max_zoom`. [logic error]
<details>
<summary><b>Severity Level:</b> Major โ ๏ธ</summary>
```mdx
- โ ๏ธ Users can configure nonsensical zoom constraints.
- โ ๏ธ Map zooming may behave unpredictably or feel broken.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. In the cartodiagram chart configuration UI, use the "Map Options" section defined in
`controlPanel.ts:121-212` to edit the `min_zoom` slider (`controlPanel.ts:167-178`) and
`max_zoom` slider (`controlPanel.ts:181-192`).
2. Set `min_zoom` to a value higher than `max_zoom` (for example, `min_zoom = 12`,
`max_zoom = 5`), which the current control configuration allows because there is no
cross-field validation.
3. These values are passed through `transformProps` (`plugin/transformProps.ts`) to
`OlChartMap` as `minZoom` and `maxZoom` props (`OlChartMap.tsx:59-62`).
4. The dedicated effects at `OlChartMap.tsx:452-459` call `view.setMinZoom(minZoom)` and
`view.setMaxZoom(maxZoom)` respectively; with `minZoom > maxZoom`, the zoom constraints
are inconsistent and can cause unexpected clamping or inability to zoom, degrading map
interaction.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=839f4c9262b54cb394e20527d718dca1&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=839f4c9262b54cb394e20527d718dca1&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts
**Line:** 167:193
**Comment:**
*Logic Error: `min_zoom` and `max_zoom` are independently editable without cross-field validation, allowing `min_zoom > max_zoom` and creating inconsistent zoom constraints at runtime. Add validation to enforce `min_zoom <= max_zoom`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=7be1b549ecfde6c14614874fceb98dbf6371a473741f4e212feca60fa569e34b&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=7be1b549ecfde6c14614874fceb98dbf6371a473741f4e212feca60fa569e34b&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/dataUtil.ts:
##########
@@ -0,0 +1,75 @@
+/**
+ * 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 { DataRecord, QueryData } from '@superset-ui/core';
+import { Feature, FeatureCollection } from 'geojson';
+import { Feature as OlFeature } from 'ol';
+import GeoJSON from 'ol/format/GeoJSON';
+import { dataRecordsToOlFeatures } from './mapUtil';
+import { GeometryFormat } from '../constants';
+
+export const geojsonDataToFeatureCollection = (
+ data: QueryData['data'],
+ geomColumn: string,
+) => {
+ const features = data
+ .map((d: DataRecord) => {
+ const { [geomColumn]: geometry, ...restProps } = d;
+ if (!geometry) {
+ return undefined;
+ }
+ try {
+ const parsedGeom = JSON.parse(geometry as string);
Review Comment:
**Suggestion:** This parser unconditionally treats geometry as a JSON string; if the datasource already returns a GeoJSON object, `JSON.parse` throws and the feature is silently dropped, causing missing map data. Handle both string and object geometry types before parsing. [type error]
<details>
<summary><b>Severity Level:</b> Major โ ๏ธ</summary>
```mdx
- โ Valid geospatial rows can be silently omitted from map.
- โ ๏ธ Charts against JSON geometry columns show incomplete data.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Use a datasource where the geometry column is stored as JSON and Superset returns it to
the frontend as a GeoJSON object in `QueryData['data']` (rather than a string), for
example via a JSON-type column.
2. Call `geojsonDataToFeatureCollection` from
`superset-frontend/plugins/plugin-chart-cartodiagram/src/util/dataUtil.ts:26-57` with this
query data and the geometry column name, as done from cartodiagram transform logic.
3. For each record, the destructuring at `dataUtil.ts:32` assigns the GeoJSON object to
`geometry`; the code then executes `JSON.parse(geometry as string)` at line 37.
4. Because `geometry` is already an object, `JSON.parse` throws, the error is caught at
line 45, and `undefined` is returned; the subsequent `.filter` drops these features,
producing a `FeatureCollection` at lines 51-56 that is missing valid geometries, so parts
or all of the dataset fail to render on the map.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=05699a2634384a49a8dc104e690c421c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=05699a2634384a49a8dc104e690c421c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/dataUtil.ts
**Line:** 37:37
**Comment:**
*Type Error: This parser unconditionally treats geometry as a JSON string; if the datasource already returns a GeoJSON object, `JSON.parse` throws and the feature is silently dropped, causing missing map data. Handle both string and object geometry types before parsing.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=e3925eb341abe590c73cf6513344a4328917d22053ccf22f49a95413545c555e&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=e3925eb341abe590c73cf6513344a4328917d22053ccf22f49a95413545c555e&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-5022695464
@villebro I know it's been a while, but could you take another look? The failing checks are not related to my changes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3171983146
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -232,37 +306,165 @@ export const stripGeomColumnFromLabelMap = (
export const stripGeomColumnFromQueryData = (
queryData: any,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>TypeScript: Missing return type</b></div>
<div id="fix">
Function `formatSeriesName` lacks an explicit return type annotation, reducing clarity and type checking. Add `: string` as in the original echarts version.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -327,7 +327,7 @@
export const formatSeriesName = (
name: DataRecordValue | undefined,
{
numberFormatter,
timeFormatter,
coltype,
}: {
numberFormatter?: ValueFormatter;
timeFormatter?: TimeFormatter;
coltype?: GenericDataType;
} = {},
- ) => {
+ ): string => {
if (name === undefined || name === null) {
return NULL_STRING;
}
```
</div>
</details>
</div>
<div id="suggestion">
<div id="issue"><b>Code: Semantic duplication</b></div>
<div id="fix">
Functions `formatSeriesName`, `extractGroupbyLabel`, and `getColtypesMapping` duplicate logic from `superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts`. Duplication risks divergence and increases maintenance. If shared, import them; otherwise, document why copied.
</div>
</div>
<div id="suggestion">
<div id="issue"><b>TypeScript: Missing return type</b></div>
<div id="fix">
Function `extractGroupbyLabel` lacks an explicit return type annotation. Add `: string` for consistency.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -363,7 +363,7 @@
export const extractGroupbyLabel = ({
datum = {},
groupby,
numberFormatter,
timeFormatter,
coltypeMapping = {},
}: {
datum?: DataRecord;
groupby?: string[] | null;
numberFormatter?: NumberFormatter;
timeFormatter?: TimeFormatter;
coltypeMapping?: Record<string, GenericDataType>;
- }) =>
+ }): string =>
ensureIsArray(groupby)
.map(val =>
formatSeriesName(datum[val], {
numberFormatter,
timeFormatter,
...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
}),
)
.join(', ');
```
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsControl.tsx:
##########
@@ -86,12 +108,79 @@ export const LayerConfigsControl: FC<LayerConfigsControlProps> = ({
name,
label,
description,
+ formData,
+ formWatchers,
+ featureCollectionTransformer,
renderTrigger,
hovered,
+ enableDataLayer = false,
+ colTypeMapping,
validationErrors,
}) => {
const [popoverVisible, setPopoverVisible] = useState<boolean>(false);
const [editItem, setEditItem] = useState<EditItem>(getEmptyEditItem());
+ const [currentFormData, setCurrentFormData] = useState(formData);
+ const [chartData, setChartData] = useState<FeatureCollection | undefined>();
+
+ /**
+ * We only want to watch for changes for a dynamic set of properties
+ * of the formData. To prevent unwanted http requests in the render cycles,
+ * we use the proxy currentFormData instead.
+ */
+ useEffect(() => {
+ setCurrentFormData(oldCurrentFormData => {
+ if (!formWatchers) {
+ return oldCurrentFormData;
+ }
+
+ const hasChanges = formWatchers.some(
+ watcher => !isEqual(formData?.[watcher], oldCurrentFormData?.[watcher]),
+ );
+ if (hasChanges) {
+ return formData;
+ }
+ return oldCurrentFormData;
+ });
+ }, [formData, formWatchers]);
+
+ useEffect(() => {
+ if (!currentFormData || !enableDataLayer) {
+ return;
+ }
+ const buildQueryRegistry = getChartBuildQueryRegistry();
+ const chartQueryBuilder = buildQueryRegistry.get(
+ currentFormData.viz_type,
+ ) as any;
+ const chartQuery = chartQueryBuilder(currentFormData);
+ const fetchChartData = async () => {
+ const body = JSON.stringify(chartQuery);
+ const response = await fetch('/api/v1/chart/data', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body,
+ });
+ if (!response.ok) {
+ return;
+ }
+ const responseJson = await response.json();
+ let { data } = responseJson.result[0];
+
+ if (featureCollectionTransformer) {
+ data = featureCollectionTransformer(data, currentFormData);
+ }
+
+ setChartData(data);
+ };
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Error Handling Missing</b></div>
<div id="fix">
The fetchChartData function lacks error handling, leading to unhandled promise rejections if the fetch or JSON parsing fails. Additionally, accessing responseJson.result[0] without checking if result exists or has elements could cause a runtime error. This may result in silent failures or crashes when loading chart data for data layers.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
const fetchChartData = async () => {
try {
const body = JSON.stringify(chartQuery);
const response = await fetch('/api/v1/chart/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (!response.ok) {
return;
}
const responseJson = await response.json();
if (!responseJson.result || responseJson.result.length === 0) {
return;
}
let { data } = responseJson.result[0];
if (featureCollectionTransformer) {
data = featureCollectionTransformer(data, currentFormData);
}
setChartData(data);
} catch (error) {
console.error('Error fetching chart data:', error);
}
};
````
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/dataUtil.ts:
##########
@@ -0,0 +1,75 @@
+/**
+ * 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 { DataRecord, QueryData } from '@superset-ui/core';
+import { Feature, FeatureCollection } from 'geojson';
+import { Feature as OlFeature } from 'ol';
+import GeoJSON from 'ol/format/GeoJSON';
+import { dataRecordsToOlFeatures } from './mapUtil';
+import { GeometryFormat } from '../constants';
+
+export const geojsonDataToFeatureCollection = (
+ data: QueryData['data'],
+ geomColumn: string,
+) => {
+ const features = data
+ .map((d: DataRecord) => {
+ const { [geomColumn]: geometry, ...restProps } = d;
+ if (!geometry) {
+ return undefined;
+ }
+ try {
+ const parsedGeom = JSON.parse(geometry as string);
+ const feature: Feature = {
+ type: 'Feature',
+ geometry: parsedGeom,
+ properties: restProps,
+ };
+ return feature;
+ } catch (error) {
+ console.error('Error parsing geometry:', error);
+ return undefined;
+ }
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Broad exception catch</b></div>
<div id="fix">
Avoid broad exception catches; handle only expected SyntaxError from JSON.parse to prevent masking other bugs.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
} catch (error) {
if (error instanceof SyntaxError) {
console.error('Error parsing geometry:', error);
return undefined;
} else {
throw error;
}
}
````
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/layerUtil.test.ts:
##########
@@ -89,9 +160,89 @@ describe('layerUtil', () => {
});
});
+ describe('createDataLayer', () => {
+ test('properly applies style', async () => {
+ const dataLayer = await createDataLayer(dataLayerConf);
+ const style = dataLayer!.getStyle();
+ // @ts-ignore
+ expect(style!.length).toEqual(3);
+
+ // @ts-ignore upgrade `ol` package for better type of StyleLike type.
+ const colorAtLayer = style![2].getFill().getColor();
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>TypeScript error suppression inconsistency</b></div>
<div id="fix">
The new test uses @ts-ignore for TypeScript error suppression, but the existing identical code in the createWfsLayer test uses @ts-expect-error. For consistency and best practice (as @ts-expect-error explicitly expects an error), update to @ts-expect-error.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
const dataLayer = await createDataLayer(dataLayerConf);
const style = dataLayer!.getStyle();
// @ts-expect-error
expect(style!.length).toEqual(3);
// @ts-expect-error upgrade `ol` package for better type of StyleLike type.
const colorAtLayer = style![2].getFill().getColor();
````
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/bootstrapDataUtil.ts:
##########
@@ -0,0 +1,41 @@
+/**
+ * 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.
+ */
+
+/**
+ * Based on superset-frontend/src/utils/getBootstrapData.ts. Replicated
+ * in order to circumvent creating circular dependencies.
+ */
+
+export const getBootstrapData = () => {
+ const appContainer = document.getElementById('app');
+ const dataBootstrap = appContainer?.getAttribute('data-bootstrap');
+ return dataBootstrap ? JSON.parse(dataBootstrap) : {};
+};
+
+export const getMapProjections = () => {
+ const bootstrapData = getBootstrapData();
+ const mapProjections = bootstrapData?.common?.conf?.MAP_PROJECTIONS;
+ return mapProjections ?? {};
+};
+
+export const getMapDefaultLayers = () => {
+ const bootstrapData = getBootstrapData();
+ const mapDefaultLayers = bootstrapData?.common?.conf?.MAP_DEFAULT_LAYERS;
+ return mapDefaultLayers ?? [];
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Code Quality & Performance Issues</b></div>
<div id="fix">
Import `BootstrapData` and `DEFAULT_BOOTSTRAP_DATA` from your shared types and constants, add a cached variable so `getBootstrapData` only parses once, wrap `JSON.parse` in a try/catch to fall back to `DEFAULT_BOOTSTRAP_DATA`, and add explicit TypeScript return types for all exported functions.
</div>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -232,37 +306,165 @@ export const stripGeomColumnFromLabelMap = (
export const stripGeomColumnFromQueryData = (
queryData: any,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
+ dataByLocation: LocationConfigMapping,
+ strippedQueryData: any,
+ sliceId: number,
+) => {
+ // Call color singleton to reserve label colors
+ // get needed control values from underlying chart config
+ const { colorScheme = '', groupby = [], dateFormat } = formData;
+ const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
+ const groupbyLabels = groupby.map(getColumnLabel);
+ Object.keys(dataByLocation).forEach(location => {
+ const coltypeMapping = getColtypesMapping({
+ ...strippedQueryData,
+ data: dataByLocation[location],
+ });
+ dataByLocation[location].forEach(datum => {
+ const name = extractGroupbyLabel({
+ datum,
+ groupby: groupbyLabels,
+ coltypeMapping,
+ timeFormatter: getTimeFormatter(dateFormat),
+ });
+
+ colorFn(name, sliceId);
+ });
+ });
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>TypeScript: Avoid `any` types</b></div>
<div id="fix">
Parameter `strippedQueryData` is typed as `any`, violating TypeScript best practices. Use `ChartDataResponseResult` for consistency and safety.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -418,7 +418,7 @@
export const reserveLabelColors = (
formData: Record<string, any>,
dataByLocation: LocationConfigMapping,
strippedQueryData: any,
sliceId: number,
) => {
```
</div>
</details>
</div>
<details>
<summary><b>Citations</b></summary>
<ul>
<li>
Rule Violated: <a href="https://github.com/apache/superset/blob/d42dce1/.cursor/rules/dev-standard.mdc#L16">dev-standard.mdc:16</a>
</li>
</ul>
</details>
<div id="suggestion">
<div id="issue"><b>TypeScript: Missing return type</b></div>
<div id="fix">
Function `reserveLabelColors` lacks an explicit return type annotation. Add `: void` since it doesn't return a value.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -418,7 +418,7 @@
export const reserveLabelColors = (
formData: Record<string, any>,
dataByLocation: LocationConfigMapping,
strippedQueryData: any,
sliceId: number,
- ) => {
+ ): void => {
// Call color singleton to reserve label colors
// get needed control values from underlying chart config
const { colorScheme = '', groupby = [], dateFormat } = formData;
```
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx:
##########
@@ -50,3 +56,157 @@ export const fitMapToCharts = (olMap: Map, chartConfigs: ChartConfig) => {
size: [250, 250],
});
};
+
+const fitToData = (
+ olMap: Map,
+ features: Feature[],
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const view = olMap.getView();
+ const extent = getExtentFromFeatures(features) || defaultExtent;
+
+ if (padding) {
+ view.fit(extent, { padding });
+ } else {
+ view.fit(extent);
+ }
+};
+
+const extractSridFromWkt = (wkt: string) => {
+ const extract: { geom: string; srid: string | null } = {
+ geom: wkt,
+ srid: null,
+ };
+ if (wkt.startsWith('SRID=')) {
+ // WKT with SRID, strip it
+ const srid = wkt.match(/SRID=(\d+);/);
+ if (srid) {
+ extract.srid = `EPSG:${srid[1]}`;
+ extract.geom = wkt.replace(/SRID=\d+;/, '');
+ }
+ }
+ return extract;
+};
+
+export const wkbToGeoJSON = (wkb: string) => {
+ const format = new WKB();
+ const feature = format.readFeature(wkb, {
+ featureProjection: 'EPSG:3857',
+ });
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+export const wktToGeoJSON = (wkt: string) => {
+ const format = new WKT();
+ const wktOpts: any = {
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Type Safety Violation</b></div>
<div id="fix">
Replace 'any' types with proper TypeScript types for OpenLayers readFeature options to comply with dev standards prohibiting 'any' usage. This improves type safety and maintainability without changing behavior.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
import { GeometryFormat } from '../constants';
+
+interface ReadOptions {
+ featureProjection?: string;
+ dataProjection?: string;
+}
+
// default map extent of world if no features are found
@@ -103,1 +107,1 @@
- const wktOpts: any = {
+ const wktOpts: ReadOptions = {
@@ -143,1 +147,1 @@
- const opts: any = {
+ const opts: ReadOptions = {
```
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4401903838
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,187 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ // If disableClassification is not explicitly set to true,
+ // determine its value based on the presence of example features.
+ if (context.composition?.Rules.disableClassification !== true) {
Review Comment:
`context.composition` is the memoized `MAP_GEOSTYLER_COMPOSITION` object itself, and this block mutates it. On first render `data` is undefined, so `Rules.disableClassification` is written as `true`; when the WFS features arrive, the same object is passed back in and the `!== true` check reads that generated value as an explicit operator setting, so classification stays disabled even though example features now exist. Could the composition be cloned before deriving `disableClassification`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4349210595
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3160732370
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -232,37 +309,165 @@ export const stripGeomColumnFromLabelMap = (
export const stripGeomColumnFromQueryData = (
queryData: any,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
+ dataByLocation: LocationConfigMapping,
+ strippedQueryData: any,
Review Comment:
**Suggestion:** Replace `any` with a concrete query-data type (or a well-defined partial type) for `strippedQueryData` to preserve compile-time safety. [custom_rule]
**Severity Level:** Minor โ ๏ธ
<details>
<summary><b>Why it matters? ๐ค </b></summary>
The signature explicitly uses `any`, which violates the type-safety rule described by the suggestion. This is a genuine untyped parameter in the new code.
</details>
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FtransformPropsUtil.ts%0A%2A%2ALine%3A%2A%2A%20424%3A424%0A%2A%2AComment%3A%2A%2A%0A%09%2ACustom%20Rule%3A%20Replace%20%60any%60%20with%20a%20concrete%20query-data%20type%20%28or%20a%20well-defined%20partial%20type%29%20for%20%60strippedQueryData%60%20to%20preserve%20compile-time%20safety.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%2
0the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FtransformPropsUtil.ts%0A%2A%2ALine%3A%2A%2A%20424%3A424%0A%2A%2AComment%3A%2A%2A%0A%09%2ACustom%20Rule%3A%20Replace%20%60any%60%20with%20a%20concrete%20query-data%20type%20%28or%20a%20well-defined%20partial%20type%29%20for%20%60strippedQueryData%60%20to%20preserve%20compile-time%20safety.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20we
ll.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 424:424
**Comment:**
*Custom Rule: Replace `any` with a concrete query-data type (or a well-defined partial type) for `strippedQueryData` to preserve compile-time safety.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=3d7ec8bcdfcf5fda933659203d93f44cee8c63ad8478e647735ce8f3729547fd&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=3d7ec8bcdfcf5fda933659203d93f44cee8c63ad8478e647735ce8f3729547fd&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -232,37 +309,165 @@ export const stripGeomColumnFromLabelMap = (
export const stripGeomColumnFromQueryData = (
queryData: any,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
Review Comment:
**Suggestion:** Replace `Record<string, any>` with a concrete form-data type (or a narrowed interface) so the function signature is type-safe and avoids `any`. [custom_rule]
**Severity Level:** Minor โ ๏ธ
<details>
<summary><b>Why it matters? ๐ค </b></summary>
The code uses `Record<string, any>`, which still relies on `any` and is a real type-safety issue under the stated rule. A narrower form-data interface would avoid the unchecked value type.
</details>
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FtransformPropsUtil.ts%0A%2A%2ALine%3A%2A%2A%20422%3A422%0A%2A%2AComment%3A%2A%2A%0A%09%2ACustom%20Rule%3A%20Replace%20%60Record%3Cstring%2C%20any%3E%60%20with%20a%20concrete%20form-data%20type%20%28or%20a%20narrowed%20interface%29%20so%20the%20function%20signature%20is%20type-safe%20and%20avoids%20%60any%60.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20c
omments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FtransformPropsUtil.ts%0A%2A%2ALine%3A%2A%2A%20422%3A422%0A%2A%2AComment%3A%2A%2A%0A%09%2ACustom%20Rule%3A%20Replace%20%60Record%3Cstring%2C%20any%3E%60%20with%20a%20concrete%20form-data%20type%20%28or%20a%20narrowed%20interface%29%20so%20the%20function%20signature%20is%20type-safe%20and%20avoids%20%60any%60.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20th
e%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 422:422
**Comment:**
*Custom Rule: Replace `Record<string, any>` with a concrete form-data type (or a narrowed interface) so the function signature is type-safe and avoids `any`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=176ea2f14cd3b6c515ad7be1b68c420ba48c1c7b58084ea7125d570263ceed0c&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=176ea2f14cd3b6c515ad7be1b68c420ba48c1c7b58084ea7125d570263ceed0c&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613186105
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -137,6 +152,36 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ * @param featureCollection The featureCollection for the layer source
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
Review Comment:
**Suggestion:** The doc comment states there is a `featureCollection` parameter, but the function does not accept it; this mismatch is misleading and will cause incorrect usage assumptions. Update the comment to match the actual function contract. [comment mismatch]
<details>
<summary><b>Severity Level:</b> Minor ๐งน</summary>
```mdx
- WARNING misleading JSDoc may confuse future data-layer callers.
- WARNING documentation-only issue, runtime behavior remains correct.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. A developer reads the JSDoc comment for `createDataLayer` at
`superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:155-162`,
which documents both `dataLayerConf` and `featureCollection` parameters.
2. Based on the comment, the developer attempts to call `createDataLayer(dataLayerConf,
featureCollection)` from a new component.
3. TypeScript at the call site reports an argument count/type mismatch because the
implementation at `layerUtil.tsx:163` only accepts a single `dataLayerConf: DataLayerConf`
parameter.
4. The developer must inspect the implementation to realize `featureCollection` is not
part of the contract; existing callers do not pass this parameter today, so the mismatch
is documentation-only and does not currently affect runtime behavior.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=320815aab77e442b8f6a55912aeadc04&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=320815aab77e442b8f6a55912aeadc04&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
**Line:** 158:163
**Comment:**
*Comment Mismatch: The doc comment states there is a `featureCollection` parameter, but the function does not accept it; this mismatch is misleading and will cause incorrect usage assumptions. Update the comment to match the actual function contract.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=436f6fa38b5001258c1a6f36e3d058b566471a52ffd6574be09e2cdfd81ed757&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=436f6fa38b5001258c1a6f36e3d058b566471a52ffd6574be09e2cdfd81ed757&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -152,8 +197,71 @@ export const createLayer = async (layerConf: LayerConf) => {
layer = await createWfsLayer(layerConf);
} else if (isXyzLayerConf(layerConf)) {
layer = createXyzLayer(layerConf);
+ } else if (isDataLayerConf(layerConf)) {
+ layer = await createDataLayer(layerConf);
} else {
console.warn('Provided layerconfig is not recognized');
}
return layer;
};
+
+export const removeSelectionLayer = (olMap: Map) => {
+ const selectionLayer = olMap
+ .getLayers()
+ .getArray()
+ .filter(l => l.get(LAYER_NAME_PROP) === SELECTION_LAYER_NAME)
+ .pop();
+ if (selectionLayer) {
+ olMap.removeLayer(selectionLayer);
+ }
+};
+
+export const getSelectedFeatures = (
+ dataLayers: VectorLayer<VectorSource>[],
+ filterState: FilterState,
+ crossFilterColumn: string,
+) => {
+ let selectedFeatures: Feature[] = [];
+ if (
+ filterState.selectedValues !== null &&
+ filterState.selectedValues !== undefined &&
+ dataLayers
+ ) {
+ selectedFeatures = dataLayers.flatMap(dataLayer =>
+ dataLayer
+ .getSource()!
+ .getFeatures()
+ .filter(f =>
+ filterState.selectedValues.includes(f.get(crossFilterColumn)),
+ ),
+ );
+ }
+ return selectedFeatures;
+};
+
+export const setSelectionBackgroundOpacity = (
+ dataLayers: VectorLayer<VectorSource>[],
+ opacity: number,
+) => {
+ dataLayers.forEach(dataLayer => {
+ dataLayer.setOpacity(opacity);
+ });
+};
+
+export const createSelectionLayer = (
+ dataLayers: VectorLayer<VectorSource>[],
+ features: Feature[],
+) => {
+ const selectionLayer = new VectorLayer({
+ source: new VectorSource({
+ features,
+ }),
+ });
+ selectionLayer.set(LAYER_NAME_PROP, SELECTION_LAYER_NAME);
+ // TODO how can we handle multiple data layers?
+ const layerStyle = dataLayers[0].getStyle();
Review Comment:
**Suggestion:** `createSelectionLayer` assumes at least one data layer exists and directly reads index `0`; when an empty array is passed this throws at runtime. Add a guard for an empty array before accessing the first element and only copy style when a source layer is present. [possible bug]
<details>
<summary><b>Severity Level:</b> Major โ ๏ธ</summary>
```mdx
- CRITICAL selection overlay creation throws when no data layers.
- WARNING map cross-filter highlight fails degrading user experience.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Import `createSelectionLayer` from
`superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:251-267` in a
test or development harness.
2. Call `createSelectionLayer([] as VectorLayer[], features)` with an empty `dataLayers`
array and any valid `Feature[]` (for example, features returned from
`VectorSource.getFeatures()`).
3. Inside `createSelectionLayer`, the code at `layerUtil.tsx:262` evaluates
`dataLayers[0].getStyle()` without checking that `dataLayers.length > 0`.
4. At runtime `dataLayers[0]` is `undefined`, so accessing `.getStyle()` throws a
`TypeError`, aborting selection layer creation; current repo graph context shows no
callers yet, so this is a latent bug that will manifest as soon as the helper is used with
an empty layer list.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=7b59e8ee91124f58a67f57150483dd2c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=7b59e8ee91124f58a67f57150483dd2c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
**Line:** 262:262
**Comment:**
*Possible Bug: `createSelectionLayer` assumes at least one data layer exists and directly reads index `0`; when an empty array is passed this throws at runtime. Add a guard for an empty array before accessing the first element and only copy style when a source layer is present.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=54eee555a05a30d76b8615cac6da0ec9502ba0c645d37d3491599d98d88f1609&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=54eee555a05a30d76b8615cac6da0ec9502ba0c645d37d3491599d98d88f1609&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4401903848
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -196,6 +325,10 @@ export const OlChartMap = (props: OlChartMapProps) => {
addLayers(layerConfigs);
}, [olMap, layerConfigs]);
+ useEffect(() => {
+ applyMapExtentView(olMap, currentMapMaxExtent);
Review Comment:
This replaces the map's `View` (via `olMap.setView(...)`) whenever the max extent changes, but the zoom-sync effect further down (the `view.on('change:resolution', ...)` subscription, deps `[olMap, setControlValue, chartSize]`) bound to `olMap.getView()` once and is not re-run for a new view. After picking CUSTOM or clicking "Use current extent", zooming no longer reaches `onViewChange`, so `chart_size.configs.zoom` (and the "Current Zoom" display / zoom-relative size editing) stays stale until something else retriggers this effect. Should the view (or `currentMapMaxExtent`) be part of this effect's dependencies?
##########
superset/config.py:
##########
@@ -3492,6 +3492,83 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument # noq
},
}
+# Map projections of the datasources. If not provided, only
+# EPSG:3857 and EPSG:4326 are supported. The projection definitions
+# can be found on https://epsg.io in the Proj.4 section and should
+# be added here in following structure:
+#
+# {'EPSG:Code': 'definition'}
+#
+# e.g.
+#
+# {
+# 'EPSG:25832': (
+# '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# 'EPSG:25833': (
+# '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# }
+#
+MAP_PROJECTIONS = {}
+
+# Default layers that will be added to all visualizations of plugin-chart-cartodiagram.
+# For a list of supported types, and configuration details see the README.md
+# of plugin-chart-cartodiagram.
+MAP_DEFAULT_LAYERS = [
+ {
+ "type": "WMS",
+ "version": "1.3.0",
+ "url": "https://ows.terrestris.de/osm-gray/service",
+ "layersParam": "OSM-WMS",
+ "title": "OpenStreetMap",
+ "attribution": (
+ "ยฉ Map data from "
+ '<a href="https://openstreetmap.org/copyright">OpenStreetMap</a>. '
Review Comment:
The default `attribution` here contains `<a href=...>` markup, but the plugin always runs attributions through `escapeAttribution` before handing them to OpenLayers, so on the map users will see the literal `<a href="https://openstreetmap.org/copyright">OpenStreetMap</a>` text rather than links. Should this default (and the documented pattern operators will copy) be plain text, or should operator-supplied layers be allowed trusted HTML?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
`createDataLayer` passes the creator-supplied `attribution` straight to `VectorSource`, while the WMS, XYZ and WFS paths run it through `escapeAttribution` because OpenLayers renders attributions via `innerHTML`. A saved chart whose `layer_configs` contains `{"type":"DATA","attribution":"<img src=x onerror=...>"}` would execute script in any viewer's browser when the attribution control renders (the renderer picks DATA purely from `type`, regardless of whether the Explore UI offers it). Should this use `escapeAttribution(attribution)` like the other layer types?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -79,6 +144,7 @@ export const createColumnName = (columns: string[], ignoreIdx: number[]) =>
export const groupByLocationGenericX = (
Review Comment:
`groupByLocationGenericX` now has WKT/WKB branches (geometry detected inside timeseries `label_map` entries, then stripped from the series label), but every `groupByLocationGenericX` test still passes `GeometryFormat.GEOJSON`; the new WKT/WKB tests only cover the column detectors and non-timeseries `getChartConfigs`. If the WKT/WKB grouping or label-stripping broke, nothing would fail. Could a test feed a `label_map` like `['SRID=4326;POINT(8 53)', 'A']` with WKT and the WKB equivalent, asserting each location gets the right series values and the geometry is absent from the resulting column name?
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,187 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ // If disableClassification is not explicitly set to true,
+ // determine its value based on the presence of example features.
+ if (context.composition?.Rules.disableClassification !== true) {
Review Comment:
`context.composition` is the memoized `MAP_GEOSTYLER_COMPOSITION` object itself, and this block mutates it. On first render `data` is undefined, so `Rules.disableClassification` is written as `true`; when the WFS features arrive, the same object is passed back in and the `!== true` check reads that generated value as an explicit operator setting, so classification stays disabled even though example features now exist. Could the composition be cloned before deriving `disableClassification`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4412015990
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/transformProps.ts:
##########
@@ -17,44 +17,63 @@
* under the License.
*/
import { ChartProps, getChartTransformPropsRegistry } from '@superset-ui/core';
-import {
- getChartConfigs,
- parseSelectedChart,
-} from '../util/transformPropsUtil';
+import { getChartConfigs, parseSelectedChart } from '../util/transformPropsUtil';
+import { ChartConfig } from '../types';
export default function transformProps(chartProps: ChartProps) {
const { width, height, formData, hooks, theme } = chartProps;
const {
geomColumn,
+ geomFormat,
selectedChart: selectedChartString,
chartSize,
layerConfigs,
+ mapExtentPadding,
+ mapMaxExtent,
Review Comment:
The defaults are also being applied in dashboards, so existing charts will not crash when this code will be merged. See also https://github.com/apache/superset/blob/master/superset-frontend/src/dashboard/actions/dashboardState.ts#L947
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3160963516
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsPopoverContent.tsx:
##########
@@ -369,6 +519,14 @@ export const LayerConfigsPopoverContent: FC<
serviceVersions.WMS.map(version => ({ value: version, label: version }));
const wfsVersionOptions: { value: any; label: string }[] =
serviceVersions.WFS.map(version => ({ value: version, label: version }));
+ const layerTypeOptions: { value: string; label: string }[] = [
+ { value: 'WMS', label: t('WMS') },
+ { value: 'WFS', label: t('WFS') },
+ { value: 'XYZ', label: t('XYZ') },
+ ];
+ if (enableDataLayer) {
+ layerTypeOptions.push({ value: 'DATA', label: 'DATA' });
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Translation Inconsistency</b></div>
<div id="fix">
The 'DATA' label in layerTypeOptions is hardcoded without using the translation function, unlike other labels (WMS, WFS, XYZ) which use t(). This violates the rule [6516] to wrap all user-facing text with t().
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
layerTypeOptions.push({ value: 'DATA', label: t('DATA') });
````
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/dataUtil.ts:
##########
@@ -0,0 +1,70 @@
+/**
+ * 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 { DataRecord, QueryData } from '@superset-ui/core';
+import { Feature, FeatureCollection } from 'geojson';
+import { Feature as OlFeature } from 'ol';
+import GeoJSON from 'ol/format/GeoJSON';
+import { dataRecordsToOlFeatures } from './mapUtil';
+import { GeometryFormat } from '../constants';
+
+export const geojsonDataToFeatureCollection = (
+ data: QueryData['data'],
+ geomColumn: string,
+) => {
+ const features = data
+ .map((d: DataRecord) => {
+ const { [geomColumn]: geometry, ...restProps } = d;
+ if (!geometry) {
+ return undefined;
+ }
+ const feature: Feature = {
+ type: 'Feature',
+ geometry: JSON.parse(geometry as string),
+ properties: restProps,
+ };
+
+ return feature;
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Unhandled JSON Parse Error</b></div>
<div id="fix">
The JSON.parse call on geometry could throw TypeError if geometry is not a string or SyntaxError if it's invalid JSON, causing the function to crash. Add a typeof check and try-catch to gracefully handle invalid geometry data by returning undefined, preventing runtime errors.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
const { [geomColumn]: geometry, ...restProps } = d;
if (!geometry || typeof geometry !== 'string') {
return undefined;
}
try {
const feature: Feature = {
type: 'Feature',
geometry: JSON.parse(geometry),
properties: restProps,
};
return feature;
} catch {
return undefined;
}
````
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/layerUtil.test.ts:
##########
@@ -89,9 +160,89 @@ describe('layerUtil', () => {
});
});
+ describe('createDataLayer', () => {
+ test('properly applies style', async () => {
+ const dataLayer = await createDataLayer(dataLayerConf);
+ const style = dataLayer!.getStyle();
+ // @ts-ignore
+ expect(style!.length).toEqual(3);
+
+ // @ts-ignore upgrade `ol` package for better type of StyleLike type.
+ const colorAtLayer = style![2].getFill().getColor();
+ expect(colorAtLayer).toEqual(fillColor);
+ });
+ });
+
describe('createLayer', () => {
test('exists', () => {
expect(createLayer).toBeDefined();
});
});
+
+ describe('removeSelectionLayer', () => {
+ test('removes the selection layer from the map', () => {
+ expect(map.getLayers().getArray()).toHaveLength(2);
+ removeSelectionLayer(map);
+ const selectionLayers = map
+ .getLayers()
+ .getArray()
+ .filter(l => l.get(LAYER_NAME_PROP) === SELECTION_LAYER_NAME);
+ expect(map.getLayers().getArray()).toHaveLength(1);
+ expect(selectionLayers).toHaveLength(0);
+ });
+
+ test('does not remove other layers', () => {
+ expect(map.getLayers().getArray()).toHaveLength(2);
+ removeSelectionLayer(map);
+ expect(map.getLayers().getArray()).toHaveLength(1);
+ expect(map.getLayers().getArray()[0]).toEqual(dataLayer);
+ });
+ });
+
+ describe('getSelectedFeatures', () => {
+ test('returns the selected features from the data layers', () => {
+ const selectedFeatures = getSelectedFeatures(
+ [dataLayer],
+ {
+ selectedValues: ['bar'],
+ },
+ 'foo',
+ );
+ expect(selectedFeatures).toHaveLength(1);
+ expect(selectedFeatures[0]).toEqual(matchingFeature);
+ });
+ });
+
+ describe('setSelectionBackgroundOopacity', () => {
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Test naming typo</b></div>
<div id="fix">
The describe block has a typo: 'setSelectionBackgroundOopacity' should be 'setSelectionBackgroundOpacity'. This mismatch could confuse readers and make the test harder to locate by name.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
describe('setSelectionBackgroundOpacity', () => {
````
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/types.ts:
##########
@@ -38,45 +40,75 @@ export interface WfsLayerConf extends BaseLayerConf {
export interface XyzLayerConf extends BaseLayerConf {
type: 'XYZ';
+ url: string;
}
export interface WmsLayerConf extends BaseLayerConf {
type: 'WMS';
+ url: string;
version: string;
layersParam: string;
}
-export interface FlatLayerDataNode extends TreeDataNode {
- layerConf: LayerConf;
+export interface DataLayerConf extends BaseLayerConf {
+ type: 'DATA';
+ style?: Style;
}
export interface FlatLayerTreeProps {
- layerConfigs: LayerConf[];
+ layerConfigs: LayerConfWithId[];
onAddLayer?: () => void;
onRemoveLayer?: (idx: number) => void;
- onEditLayer?: (layerConf: LayerConf, idx: number) => void;
- onMoveLayer?: (layerConfigs: LayerConf[]) => void;
+ onEditLayer?: (layerConf: LayerConfWithId, idx: number) => void;
+ onMoveLayer?: (dragIndex: number, hoverIndex: number) => void;
draggable?: boolean;
className?: string;
}
-export type LayerConf = WmsLayerConf | WfsLayerConf | XyzLayerConf;
+export type LayerConf =
+ | WmsLayerConf
+ | WfsLayerConf
+ | XyzLayerConf
+ | DataLayerConf;
-export type DropInfoType<T extends TreeProps['onDrop']> = T extends Function
- ? Parameters<T>[0]
- : undefined;
+export type LayerConfWithId = LayerConf & { id: string };
export interface EditItem {
layerConf: LayerConf;
idx: number;
}
-export type LayerConfigsControlProps = ControlComponentProps<LayerConf[]>;
+export type ColTypeMapping = {
+ /** Mapping between a column and its type */
+ [column_name: string]: string;
+};
+
+export type LayerConfigsControlProps = ControlComponentProps<LayerConf[]> & {
+ /** Set to true, if chart data should be included as layer. */
+ enableDataLayer?: boolean;
+ /** Mapping object providing the types for each column. Only needed if enableDataLayer is true. */
+ colTypeMapping?: ColTypeMapping;
+ /** List of formData attributes to watch for changes. If a change was detected, the
+ * chart data will be fetched again. Only needed if enableDataLayer is true.
+ */
+ formWatchers?: string[];
+ /** Transformer function that transforms the chart data into a feature collection.
+ * Only needed if enableDataLayer is true.
+ */
+ featureCollectionTransformer?: (
+ data: any,
+ formData: QueryFormData,
+ ) => FeatureCollection;
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Type Safety Violation</b></div>
<div id="fix">
The `data` parameter in `featureCollectionTransformer` uses the `any` type, violating TypeScript best practices that prohibit `any` types. Replace with `unknown` to maintain flexibility while enforcing type checks.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
featureCollectionTransformer?: (
data: unknown,
formData: QueryFormData,
) => FeatureCollection;
````
</div>
</details>
</div>
<details>
<summary><b>Citations</b></summary>
<ul>
<li>
Rule Violated: <a href="https://github.com/apache/superset/blob/7e6ab17/AGENTS.md#L32">AGENTS.md:32</a>
</li>
</ul>
</details>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -258,16 +424,39 @@ export const OlChartMap = (props: OlChartMapProps) => {
if (!chartLayer) {
return;
}
- const extent = chartLayer.getExtent();
+
+ const features = new GeoJSON().readFeatures(chartLayer.chartConfigs, {
+ featureProjection: 'EPSG:4326',
+ });
+
+ const extent = getExtentFromFeatures(features);
+
if (!extent) {
return;
}
+
+ const transformedExtent = transformExtent(
+ extent,
+ 'EPSG:4326',
+ olMap.getView().getProjection(),
+ );
+
const view = olMap.getView();
- view.fit(extent, {
- size: [250, 250],
- });
+ const padding = getMapExtentPadding(mapExtentPadding);
+
+ view.fit(transformedExtent, { padding });
}
- }, [olMap, currentMapView.mode]);
+ }, [olMap, currentMapView.mode, mapExtentPadding]);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing useEffect Dependency</b></div>
<div id="fix">
The useEffect for FIT_DATA mode uses chartLayer.chartConfigs but does not include currentChartConfigs in its dependency array. This means if the chart data changes while in FIT_DATA mode, the map won't re-fit to the new data extent, leading to incorrect map display.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
````suggestion
view.fit(transformedExtent, { padding });
}
}, [olMap, currentMapView.mode, mapExtentPadding, currentChartConfigs]);
````
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts:
##########
@@ -22,7 +22,11 @@ import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import { ChartConfig } from '../../src/types';
-import { fitMapToCharts } from '../../src/util/mapUtil';
+import {
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Dead code introduced</b></div>
<div id="fix">
The import of fitMapToCharts was removed from the test file, making the function unused in the codebase. This introduces dead code that should be cleaned up.
</div>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts:
##########
@@ -106,11 +110,54 @@ describe('mapUtil', () => {
});
// should set center
- fitMapToCharts(olMap, chartConfig);
+ fitMapToData(olMap, chartConfig);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Misleading test name</b></div>
<div id="fix">
The test describe title 'fitMapToCharts' does not match the function being tested 'fitMapToData', which is misleading for readers and could cause confusion during debugging or maintenance.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
- describe('mapUtil', () => {
- describe('fitMapToCharts', () => {
- test('should fit map to chart data', () => {
+ describe('mapUtil', () => {
+ describe('fitMapToData', () => {
+ test('should fit map to chart data', () => {
```
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/index.ts:
##########
@@ -54,17 +55,18 @@ export default class CartodiagramPlugin extends ChartPlugin {
],
});
- if (opts.defaultLayers) {
- const layerConfig = getLayerConfig(controlPanel);
-
- // set defaults for layer config if found
- if (layerConfig) {
- layerConfig.config.default = opts.defaultLayers;
- } else {
+ const layerConfig = getLayerConfig(controlPanel);
+ const mapDefaultLayers = getMapDefaultLayers();
+ if (layerConfig) {
+ if (mapDefaultLayers.length > 0) {
+ layerConfig.config.default = mapDefaultLayers;
+ }
+ if (opts?.defaultLayers) {
// eslint-disable-next-line no-console
- console.warn(
- 'Cannot set defaultLayers. layerConfig not found in control panel. Please check if the path to layerConfig should be adjusted.',
+ console.error(
+ 'Warning: [CartodiagramPlugin] Setting defaultLayers via MainPreset.js is deprecated. Please use MAP_DEFAULT_LAYERS in your config file instead.',
);
+ layerConfig.config.default = opts.defaultLayers;
}
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Logic Error and Logging Inconsistency</b></div>
<div id="fix">
The change removed the warning for when opts?.defaultLayers is set but layerConfig is not found, leading to silent failure instead of notifying the user. Also, console.error is used with a "Warning" message, which should be console.warn for consistency.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
- const layerConfig = getLayerConfig(controlPanel);
- const mapDefaultLayers = getMapDefaultLayers();
- if (layerConfig) {
- if (mapDefaultLayers.length > 0) {
- layerConfig.config.default = mapDefaultLayers;
- }
- if (opts?.defaultLayers) {
- // eslint-disable-next-line no-console
- console.error(
- 'Warning: [CartodiagramPlugin] Setting defaultLayers via MainPreset.js is deprecated. Please use MAP_DEFAULT_LAYERS in your config file instead.',
- );
- layerConfig.config.default = opts.defaultLayers;
- }
- }
+ const layerConfig = getLayerConfig(controlPanel);
+ const mapDefaultLayers = getMapDefaultLayers();
+ if (layerConfig) {
+ if (mapDefaultLayers.length > 0) {
- layerConfig.config.default = mapDefaultLayers;
- }
- if (opts?.defaultLayers) {
- // eslint-disable-next-line no-console
- console.warn(
- 'Warning: [CartodiagramPlugin] Setting defaultLayers via MainPreset.js is deprecated. Please use MAP_DEFAULT_LAYERS in your config file instead.',
- );
- layerConfig.config.default = opts.defaultLayers;
- }
- }
- if (!layerConfig && opts?.defaultLayers) {
- // eslint-disable-next-line no-console
- console.warn(
- 'Cannot set defaultLayers. layerConfig not found in control panel. Please check if the path to layerConfig should be adjusted.',
- );
- }
```
</div>
</details>
</div>
<small><i>Code Review Run #6db292</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613188909
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:
##########
@@ -0,0 +1,156 @@
+/**
+ * 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 { ControlHeader } from '@superset-ui/chart-controls';
+import { t } from '@apache-superset/core/translation';
+import { css, styled } from '@apache-superset/core/theme';
+import { Button, Radio } from 'antd';
+import { FC } from 'react';
+import { mix } from 'polished';
+import { RadioChangeEvent } from 'antd/lib/radio';
+import {
+ MapMaxExtentConfigs,
+ MapMaxExtentConfigsControlProps,
+} from '../../types';
+import MapMaxExtentTag from './MapMaxExtentTag';
+
+export const StyledMaxExtentButton = styled(Button)`
+ ${({ theme }) => css`
+ flex: 1;
+ margin-right: 4px;
+ line-height: 1.5715;
+ border-radius: ${theme.borderRadius}px;
+ background-color: ${theme.colorPrimaryBg};
+ color: ${theme.colorPrimaryText};
+ font-size: ${theme.fontSizeSM}px;
+ font-weight: ${theme.fontWeightStrong};
+ text-transform: uppercase;
+ min-width: ${theme.sizeUnit * 36};
Review Comment:
**Suggestion:** The `min-width` CSS value is emitted as a unitless number, which is invalid for width properties and gets ignored by the browser. Append a length unit (for example px) so the button width constraint is actually applied. [possible bug]
<details>
<summary><b>Severity Level:</b> Minor ๐งน</summary>
```mdx
- โ ๏ธ Min-width styling for extent button is not applied.
- โ ๏ธ Cartodiagram control UI may appear cramped or inconsistent.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Open `StyledMaxExtentButton` in
`superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:32-56`;
note the CSS rule `min-width: ${theme.sizeUnit * 36};` on line 43, which expands to a bare
number (e.g. `min-width: 288;`) without units.
2. Observe that `StyledMaxExtentButton` is rendered in the control body of
`MapMaxExtentViewControl` at `MapMaxExtentViewControl.tsx:144-150` when `extentMode ===
'CUSTOM'`, providing the "Use current extent" button.
3. Run Superset, open the Explore view for a cartodiagram chart (control panel wired via
`superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts`), switch
the "Max extent" control to custom mode so that `MapMaxExtentViewControl` renders.
4. Inspect the "Use current extent" button in browser dev tools: the computed style shows
the `min-width` declaration as invalid (unitless) and ignored, allowing the button to
shrink below the intended minimum width when the layout is tight.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=9ea8be681c344972b57eac4780e63a2d&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=9ea8be681c344972b57eac4780e63a2d&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx
**Line:** 43:43
**Comment:**
*Possible Bug: The `min-width` CSS value is emitted as a unitless number, which is invalid for width properties and gets ignored by the browser. Append a length unit (for example px) so the button width constraint is actually applied.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=cd1c7483d312a4be9f26df260796a264d63720f0d1f689b05fa3043a187b78eb&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=cd1c7483d312a4be9f26df260796a264d63720f0d1f689b05fa3043a187b78eb&reaction=dislike'>๐</a>
##########
superset/config.py:
##########
@@ -2442,6 +2442,83 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument # noq
},
}
+# Map projections of the datasources. If not provided, only
+# EPSG:3857 and EPSG:4326 are supported. The projection definitions
+# can be found on https://epsg.io in the Proj.4 section and should
+# be added here in following structure:
+#
+# {'EPSG:Code': 'definition'}
+#
+# e.g.
+#
+# {
+# 'EPSG:25832': (
+# '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# 'EPSG:25833': (
+# '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# }
+#
+MAP_PROJECTIONS = {}
+
+# Default layers that will be added to all visualizations of plugin-chart-cartodiagram.
+# For a list of supported types, and configuration details see the README.md
+# of plugin-chart-cartodiagram.
+MAP_DEFAULT_LAYERS = [
Review Comment:
**Suggestion:** The comment contains a clear typo: โextendโ should be โextentโ in this geospatial context, which can mislead readers when configuring map extent behavior. [typo]
<details>
<summary><b>Severity Level:</b> Minor ๐งน</summary>
```mdx
- โ ๏ธ Minor documentation typo; no runtime or UI impact.
- โ ๏ธ Potential slight confusion for developers reading config comments.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Open `superset/config.py` around the cartodiagram-related configuration comments
(approximately lines 2470-2485 in the new hunk).
2. Locate the comment `# control for specifying a padding around the geospatial extend of
the data`, which describes padding around a mapโs spatial coverage.
3. Note that in geospatial terminology the correct noun is โextentโ (bounding box or
coverage), while โextendโ is the verb form.
4. Because this line is a comment only and not executed, the typo cannot cause runtime
issues but may slightly mislead readers configuring map extent behavior.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=612266c49e9243e3a8db52b98ea01a48&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=612266c49e9243e3a8db52b98ea01a48&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset/config.py
**Line:** 2470:2470
**Comment:**
*Typo: The comment contains a clear typo: โextendโ should be โextentโ in this geospatial context, which can mislead readers when configuring map extent behavior.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=62f6ea6db068a174116bda1c653ee4e7663c6973fb49568dc91159c8a55b7d2d&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=62f6ea6db068a174116bda1c653ee4e7663c6973fb49568dc91159c8a55b7d2d&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-5024269524
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4400962907
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,183 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ context.composition!.Rules.disableClassification =
Review Comment:
The first thought was to ensure classification will not be disabled unintentionally. But it makes sense to allow for explicit disabling. Adjusted in https://github.com/apache/superset/pull/39760/commits/7df9a0a5019a3068919eb060b4cd48d29a28e244
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4399781655
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
Unlike the WMS/WFS/XYZ constructors above, this branch passes `attribution` to the source without `escapeAttribution()`. OpenLayers renders attributions through `innerHTML`, so a chart saved through the API with `{"type":"DATA","attribution":"<img src=x onerror=...>"}` (the UI selector for DATA being disabled doesn't stop API-supplied `layer_configs`) would inject markup for every viewer wherever CSP allows inline handlers. Should this use `escapeAttribution(attribution)` like the other layer types?
```suggestion
attributions: escapeAttribution(attribution),
```
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -196,6 +325,10 @@ export const OlChartMap = (props: OlChartMapProps) => {
addLayers(layerConfigs);
}, [olMap, layerConfigs]);
+ useEffect(() => {
+ applyMapExtentView(olMap, currentMapMaxExtent);
Review Comment:
`applyMapExtentView` calls `olMap.setView(new View(...))`, but the `change:resolution` listener in the chart-size effect further down is bound to `olMap.getView()` at the time that effect ran, and its deps (`olMap`, `setControlValue`, `chartSize`) don't change when the extent does. After toggling Max. Extent (NONE/CUSTOM) and then zooming, the old view fires the events, so `chart_size.configs.zoom` stops updating and later size edits use a stale reference zoom. Could the listener be re-bound when the view is replaced (e.g. include `currentMapMaxExtent` in that effect's deps)?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4401919595
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,183 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ context.composition!.Rules.disableClassification =
Review Comment:
Thanks for preserving an explicit `true`. The helper still mutates the memoized `MAP_GEOSTYLER_COMPOSITION` object it receives: the first render (no data) writes `Rules.disableClassification = true` into it, and when WFS features arrive that written value is read back as an explicit operator setting, so classification stays disabled even with usable data. Could the composition be cloned before the flag is derived?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613165460
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -230,39 +298,167 @@ export const stripGeomColumnFromLabelMap = (
* @returns query data without geom column.
*/
export const stripGeomColumnFromQueryData = (
- queryData: any,
+ queryData: TimeseriesChartDataResponseResult,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
Review Comment:
**Suggestion:** Replace the `any` in the form data type with a specific interface or a well-scoped typed record that reflects the expected fields. [custom_rule]
**Severity Level:** Major โ ๏ธ
<details>
<summary><b>Why it matters? โญ </b></summary>
The rule forbids `any` types, and this line explicitly uses `Record<string, any>`. The suggestion accurately identifies a real violation in the final file state.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 16)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=11a4ec25108b4fb1943c563249dea18e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=11a4ec25108b4fb1943c563249dea18e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 413:413
**Comment:**
*Custom Rule: Replace the `any` in the form data type with a specific interface or a well-scoped typed record that reflects the expected fields.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=f603892c72a5f0ce94a1d3963bb31e97fb70ad7c82787bb23c627feb4ad62d77&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=f603892c72a5f0ce94a1d3963bb31e97fb70ad7c82787bb23c627feb4ad62d77&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts:
##########
@@ -75,6 +81,112 @@ export const nonTimeSeriesChartData: any = [
},
];
Review Comment:
**Suggestion:** Replace the `any` annotation with a concrete array item type that describes the shape of each data object. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
The custom rule forbids `any` types. This line explicitly annotates the exported array as `any`, so the violation is real and present in the current file.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 16)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4c198f98adc94c6195ad03936ea9ce29&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4c198f98adc94c6195ad03936ea9ce29&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts
**Line:** 83:83
**Comment:**
*Custom Rule: Replace the `any` annotation with a concrete array item type that describes the shape of each data object.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=873b0de9e0905caea957f042d07e16f89c2afd09d5ebdab4b738745f442719d2&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=873b0de9e0905caea957f042d07e16f89c2afd09d5ebdab4b738745f442719d2&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -230,39 +298,167 @@ export const stripGeomColumnFromLabelMap = (
* @returns query data without geom column.
*/
export const stripGeomColumnFromQueryData = (
- queryData: any,
+ queryData: TimeseriesChartDataResponseResult,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
+ dataByLocation: LocationConfigMapping,
+ strippedQueryData: any,
Review Comment:
**Suggestion:** Replace the untyped query data parameter with a specific Superset response type (or a narrowed subset type) to preserve type safety. [custom_rule]
**Severity Level:** Major โ ๏ธ
<details>
<summary><b>Why it matters? โญ </b></summary>
The rule forbids `any` types, and this parameter is explicitly typed as `any` in the final code. This is a direct, real violation of the custom rule.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 16)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=a48c805da9394036a0e05efbf3019f4e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=a48c805da9394036a0e05efbf3019f4e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 415:415
**Comment:**
*Custom Rule: Replace the untyped query data parameter with a specific Superset response type (or a narrowed subset type) to preserve type safety.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=27efc9b599991f7ae51f0c00dd2a0b4e3a25a31003f139f1551cb208122daf83&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=27efc9b599991f7ae51f0c00dd2a0b4e3a25a31003f139f1551cb208122daf83&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts:
##########
@@ -75,6 +81,112 @@ export const nonTimeSeriesChartData: any = [
},
];
+export const nonTimeSeriesWkbChartData: any = [
+ {
+ geom: wkbGeom1,
+ my_value: 'apple',
+ my_count: 347,
+ },
+ {
+ geom: wkbGeom1,
+ my_value: 'apple',
+ my_count: 360,
+ },
+ {
+ geom: wkbGeom1,
+ my_value: 'lemon',
+ my_count: 335,
+ },
+ {
+ geom: wkbGeom1,
+ my_value: 'lemon',
+ my_count: 333,
+ },
+ {
+ geom: wkbGeom1,
+ my_value: 'lemon',
+ my_count: 353,
+ },
+ {
+ geom: wkbGeom1,
+ my_value: 'lemon',
+ my_count: 359,
+ },
+ {
+ geom: wkbGeom2,
+ my_value: 'lemon',
+ my_count: 347,
+ },
+ {
+ geom: wkbGeom2,
+ my_value: 'apple',
+ my_count: 335,
+ },
+ {
+ geom: wkbGeom2,
+ my_value: 'apple',
+ my_count: 356,
+ },
+ {
+ geom: wkbGeom2,
+ my_value: 'banana',
+ my_count: 218,
+ },
+];
+
Review Comment:
**Suggestion:** Replace the `any` annotation with a specific array item type for the WKT dataset objects. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
The custom rule forbids `any` types. This export is annotated with `any`, so it is a genuine violation in the final file state.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 16)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=8f957ef984c1476f9ffef6321b40d71b&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=8f957ef984c1476f9ffef6321b40d71b&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts
**Line:** 136:136
**Comment:**
*Custom Rule: Replace the `any` annotation with a specific array item type for the WKT dataset objects.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=a766dd189232f82f5c9f2e4f5daffc745865734b7861ea8bab505803f0c971d2&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=a766dd189232f82f5c9f2e4f5daffc745865734b7861ea8bab505803f0c971d2&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts:
##########
@@ -22,10 +22,14 @@ import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import { ChartConfig } from '../../src/types';
-import { fitMapToCharts } from '../../src/util/mapUtil';
+import {
+ fitMapToData,
+ wkbToGeoJSON,
+ wktToGeoJSON,
+} from '../../src/util/mapUtil';
describe('mapUtil', () => {
- describe('fitMapToCharts', () => {
+ describe('fitMapToData', () => {
Review Comment:
**Suggestion:** Replace this nested suite block with a `test()` case to follow the no-`describe()` testing rule. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
The custom rule explicitly says to use test() instead of describe(). This file contains a describe() wrapper for the fitMapToData group, so the suggestion correctly identifies a real rule violation.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 43)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=b706f6035b3c4566ba6e5c13be10dc34&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=b706f6035b3c4566ba6e5c13be10dc34&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts
**Line:** 32:32
**Comment:**
*Custom Rule: Replace this nested suite block with a `test()` case to follow the no-`describe()` testing rule.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=e3caf4a926f00df4ce505f2cc857b75db463192a1ecd2c840a1454654f20a05c&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=e3caf4a926f00df4ce505f2cc857b75db463192a1ecd2c840a1454654f20a05c&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts:
##########
@@ -106,11 +110,54 @@ describe('mapUtil', () => {
});
// should set center
- fitMapToCharts(olMap, chartConfig);
+ fitMapToData(olMap, chartConfig);
const updatedCenter = olMap.getView().getCenter();
expect(initialCenter).not.toEqual(updatedCenter);
});
});
+
+ describe('wkbToGeoJSON', () => {
+ test('converts WKB to GeoJSON', () => {
+ const wkb = '0101000020E610000000000000000020400000000000804A40';
+ const geoJSON = wkbToGeoJSON(wkb);
+ expect(geoJSON).toEqual({
+ type: 'Feature',
+ geometry: {
+ type: 'Point',
+ coordinates: [8, 53],
+ },
+ properties: null,
+ });
+ });
+ });
+
+ describe('wktToGeoJSON', () => {
Review Comment:
**Suggestion:** Remove this `describe()` wrapper and keep the related assertions as standalone `test()` blocks. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
This also directly violates the rule requiring test() instead of describe(). The existing code wraps the WKT tests in a describe() block, so the suggestion is valid.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 43)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4f2d004332e94ab39215b980082c0582&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4f2d004332e94ab39215b980082c0582&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts
**Line:** 136:136
**Comment:**
*Custom Rule: Remove this `describe()` wrapper and keep the related assertions as standalone `test()` blocks.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=08fa5cb84a6b98f319b8295835a1e9eab451b30527190538d560f5ce85e301ad&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=08fa5cb84a6b98f319b8295835a1e9eab451b30527190538d560f5ce85e301ad&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts:
##########
@@ -25,24 +26,86 @@ import {
groupByLocationGenericX,
stripGeomFromColnamesAndTypes,
stripGeomColumnFromLabelMap,
+ getWkbColumns,
+ getWktColumns,
} from '../../src/util/transformPropsUtil';
import {
nonTimeSeriesChartData,
groupedTimeseriesChartData,
geom1,
geom2,
groupedTimeseriesLabelMap,
+ nonTimeSeriesWkbChartData,
+ nonTimeSeriesWktChartData,
} from '../testData';
describe('transformPropsUtil', () => {
const groupedTimeseriesParams = {
x_axis: 'mydate',
};
+ const sliceId = 1;
+
const groupedTimeseriesQueryData = {
label_map: groupedTimeseriesLabelMap,
};
+ describe('getWkbColumns', () => {
Review Comment:
**Suggestion:** Replace this nested suite wrapper with `test()` cases so the new tests follow the flat testing pattern. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
This is a test file and the new coverage is wrapped in a `describe()` block, which violates the stated rule to use `test()` instead of `describe()`.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 43)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4733aba8b3604ab5b04e1e777e7c1a49&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4733aba8b3604ab5b04e1e777e7c1a49&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts
**Line:** 53:53
**Comment:**
*Custom Rule: Replace this nested suite wrapper with `test()` cases so the new tests follow the flat testing pattern.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=0700647c86d61f9e6f9ea98da858e1c0ca7ccbea5e89c46575d5bc51dbf35558&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=0700647c86d61f9e6f9ea98da858e1c0ca7ccbea5e89c46575d5bc51dbf35558&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts:
##########
@@ -25,24 +26,86 @@ import {
groupByLocationGenericX,
stripGeomFromColnamesAndTypes,
stripGeomColumnFromLabelMap,
+ getWkbColumns,
+ getWktColumns,
} from '../../src/util/transformPropsUtil';
import {
nonTimeSeriesChartData,
groupedTimeseriesChartData,
geom1,
geom2,
groupedTimeseriesLabelMap,
+ nonTimeSeriesWkbChartData,
+ nonTimeSeriesWktChartData,
} from '../testData';
describe('transformPropsUtil', () => {
const groupedTimeseriesParams = {
x_axis: 'mydate',
};
+ const sliceId = 1;
+
const groupedTimeseriesQueryData = {
label_map: groupedTimeseriesLabelMap,
};
+ describe('getWkbColumns', () => {
+ test('gets the WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(1);
+ expect(result[0]).toEqual(2);
+ });
+
+ test('gets multiple WKB columns', () => {
+ const wkbCol = '0101000020E610000000000000000020400000000000804A40';
+ const columns = ['foo', 'bar', wkbCol, wkbCol];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(2);
+ expect(result[0]).toEqual(2);
+ expect(result[1]).toEqual(3);
+ });
+
+ test('returns empty array when no WKB column is included', () => {
+ const columns = ['foo', 'bar'];
+
+ const result = getWkbColumns(columns);
+ expect(result).toHaveLength(0);
+ });
+ });
+
+ describe('getWktColumns', () => {
Review Comment:
**Suggestion:** Convert this suite declaration into `test()` usage to comply with the no-`describe()` testing rule. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
This new suite wrapper uses `describe()` in a test file, which matches the custom rule requiring `test()` instead of `describe()`.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 43)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=cc46bc6109c84f8ab493878117005e3e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=cc46bc6109c84f8ab493878117005e3e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts
**Line:** 81:81
**Comment:**
*Custom Rule: Convert this suite declaration into `test()` usage to comply with the no-`describe()` testing rule.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=33c9080968d441f475c4cc213f9ac5554d9890b6b39f4e2180e5dccf57498b98&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=33c9080968d441f475c4cc213f9ac5554d9890b6b39f4e2180e5dccf57498b98&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts:
##########
@@ -106,11 +110,54 @@ describe('mapUtil', () => {
});
// should set center
- fitMapToCharts(olMap, chartConfig);
+ fitMapToData(olMap, chartConfig);
const updatedCenter = olMap.getView().getCenter();
expect(initialCenter).not.toEqual(updatedCenter);
});
});
+
+ describe('wkbToGeoJSON', () => {
Review Comment:
**Suggestion:** Convert this `describe()` block into one or more `test()` calls directly under the parent scope. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
This is a real violation of the no-describe rule because the test file uses a describe() block for the wkbToGeoJSON section instead of standalone test() calls.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 43)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=c0e729fb7954432eac485b33e558e408&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=c0e729fb7954432eac485b33e558e408&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/test/util/mapUtil.test.ts
**Line:** 121:121
**Comment:**
*Custom Rule: Convert this `describe()` block into one or more `test()` calls directly under the parent scope.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=2c320dc0124e07978b1194644f2c5e1dbc8650991b46c72e6b3df79e67fd781a&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=2c320dc0124e07978b1194644f2c5e1dbc8650991b46c72e6b3df79e67fd781a&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613163201
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx:
##########
@@ -0,0 +1,48 @@
+/**
+ * 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 } from '@apache-superset/core/translation';
+import { Tag } from 'antd';
Review Comment:
**Suggestion:** Replace the direct Ant Design import with the corresponding component wrapper from @superset-ui/core/components. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
The file directly imports `Tag` from `antd`, which violates the rule requiring Superset UI core wrappers from `@superset-ui/core/components` instead of direct Ant Design imports.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 19)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=c1ff36d086584dc883b6470dcf6b46d5&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=c1ff36d086584dc883b6470dcf6b46d5&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx
**Line:** 21:21
**Comment:**
*Custom Rule: Replace the direct Ant Design import with the corresponding component wrapper from @superset-ui/core/components.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=52549cf90c4241be2b6f9d2505a3d4e48f15904899f72ed26e667b96c801ef44&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=52549cf90c4241be2b6f9d2505a3d4e48f15904899f72ed26e667b96c801ef44&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:
##########
@@ -0,0 +1,156 @@
+/**
+ * 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 { ControlHeader } from '@superset-ui/chart-controls';
+import { t } from '@apache-superset/core/translation';
+import { css, styled } from '@apache-superset/core/theme';
+import { Button, Radio } from 'antd';
Review Comment:
**Suggestion:** Replace the direct Ant Design component import with the corresponding component wrappers from `@superset-ui/core/components`. [custom_rule]
**Severity Level:** Major โ ๏ธ
<details>
<summary><b>Why it matters? โญ </b></summary>
The rule requires using @superset-ui/core wrappers instead of importing Ant Design directly. This code imports Button and Radio from 'antd', so it is a real violation.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 19)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4d028b708d7d4d66bae839a2a3254658&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4d028b708d7d4d66bae839a2a3254658&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx
**Line:** 22:22
**Comment:**
*Custom Rule: Replace the direct Ant Design component import with the corresponding component wrappers from `@superset-ui/core/components`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=72ba00a5d7da0bbd0bd73efb6f392e2b2733ecd2b5c917585c7314eb4a5a6ae4&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=72ba00a5d7da0bbd0bd73efb6f392e2b2733ecd2b5c917585c7314eb4a5a6ae4&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:
##########
@@ -0,0 +1,156 @@
+/**
+ * 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 { ControlHeader } from '@superset-ui/chart-controls';
+import { t } from '@apache-superset/core/translation';
+import { css, styled } from '@apache-superset/core/theme';
+import { Button, Radio } from 'antd';
+import { FC } from 'react';
+import { mix } from 'polished';
+import { RadioChangeEvent } from 'antd/lib/radio';
Review Comment:
**Suggestion:** Avoid importing internal Ant Design module paths and use the appropriate type exports through Superset UI core-supported imports. [custom_rule]
**Severity Level:** Major โ ๏ธ
<details>
<summary><b>Why it matters? โญ </b></summary>
This is still a direct Ant Design import, just from an internal module path. The custom rule forbids direct Ant Design imports in favor of Superset UI core-supported components and imports, so this is a valid violation.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 19)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=aa30573c20724584bd3705b95ac70476&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=aa30573c20724584bd3705b95ac70476&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx
**Line:** 25:25
**Comment:**
*Custom Rule: Avoid importing internal Ant Design module paths and use the appropriate type exports through Superset UI core-supported imports.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=fb951bc67295d86df6f010345a969c9954f5d31a06bd4bc861b6cf14a0ac0f88&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=fb951bc67295d86df6f010345a969c9954f5d31a06bd4bc861b6cf14a0ac0f88&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -118,12 +130,48 @@ export const OlChartMap = (props: OlChartMapProps) => {
});
}, [mapView]);
+ /**
+ * The prop mapMaxExtent will always be created on the fly,
+ * therefore the shallow comparison of the effect hooks will
+ * always trigger. In this hook, we compare only those props
+ * that might be changed from outside of the component, i.e the
+ * fixed properties and the mode. Only if these values differ will
+ * we set the state to the new object. All other effect hooks that
+ * depend on mapView should now depend on currentMapMaxExtent instead.
Review Comment:
**Suggestion:** Rewrite this comment to remove time-specific wording (for example, avoid using โnowโ) so it remains accurate over time. [custom_rule]
**Severity Level:** Minor ๐งน
<details>
<summary><b>Why it matters? โญ </b></summary>
The comment uses the time-specific word โnow,โ which matches the custom rule forbidding time-specific language in code comments. This is a real violation present in the existing code.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .github/copilot-instructions.md === (line 95)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4a38e7ae474148d698ea5fd65d8579af&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4a38e7ae474148d698ea5fd65d8579af&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx
**Line:** 140:140
**Comment:**
*Custom Rule: Rewrite this comment to remove time-specific wording (for example, avoid using โnowโ) so it remains accurate over time.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=51c40f43050bb6156605b8604e7a8de1b572ea9d03d72d201dfbe303f37a3b49&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=51c40f43050bb6156605b8604e7a8de1b572ea9d03d72d201dfbe303f37a3b49&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/transformProps.ts:
##########
@@ -26,35 +26,56 @@ export default function transformProps(chartProps: ChartProps) {
const { width, height, formData, hooks, theme } = chartProps;
const {
geomColumn,
+ geomFormat,
selectedChart: selectedChartString,
chartSize,
layerConfigs,
+ mapExtentPadding,
+ mapMaxExtent,
mapView,
+ maxZoom,
+ minZoom,
chartBackgroundColor,
chartBackgroundBorderRadius,
+ sliceId,
} = formData;
const { setControlValue = () => {} } = hooks;
const selectedChart = parseSelectedChart(selectedChartString);
const transformPropsRegistry = getChartTransformPropsRegistry();
const chartTransformer = transformPropsRegistry.get(selectedChart.viz_type);
- const chartConfigs = getChartConfigs(
- selectedChart,
- geomColumn,
- chartProps,
- chartTransformer,
- );
+ let chartConfigs;
Review Comment:
**Suggestion:** Add an explicit concrete type annotation for this variable instead of leaving it implicitly typed, so it does not default to an `any`-like type. [custom_rule]
**Severity Level:** Major โ ๏ธ
<details>
<summary><b>Why it matters? โญ </b></summary>
The variable is declared without a type annotation or initializer, so it is effectively an implicit any-like declaration in TypeScript. That directly violates the no-any-types rule.
</details>
<details>
<summary><b>Rule source ๐ </b></summary>
=== .cursor/rules/dev-standard.mdc === (line 16)
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=7cd07da889bc4710b232c5e5ac7d441c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=7cd07da889bc4710b232c5e5ac7d441c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/transformProps.ts
**Line:** 47:47
**Comment:**
*Custom Rule: Add an explicit concrete type annotation for this variable instead of leaving it implicitly typed, so it does not default to an `any`-like type.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=8b6a985c97b329ab322b57bcdecdab1bd83ff341f774a90d43f274db1b978994&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=8b6a985c97b329ab322b57bcdecdab1bd83ff341f774a90d43f274db1b978994&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "rusackas (via GitHub)" <gi...@apache.org>.
rusackas commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4437031920
Thanks for chipping away at the bot comments. Once those are addressed or refuted and marked resolved, and the conflicts are ironed out, @villebro and I will take a test spin and review this. Appreciate the maintenance work :D
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422811095
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -20,21 +20,67 @@ import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import Point from 'ol/geom/Point';
-import { View } from 'ol';
+import { Map, View } from 'ol';
import BaseEvent from 'ol/events/Event';
+import GeoJSON from 'ol/format/GeoJSON';
import { unByKey } from 'ol/Observable';
-import { toLonLat } from 'ol/proj';
+import { toLonLat, transformExtent } from 'ol/proj';
import { debounce } from 'lodash-es';
-import { fitMapToCharts } from '../util/mapUtil';
+import { fitMapToData } from '../util/mapUtil';
import { ChartLayer } from './ChartLayer';
import { createLayer } from '../util/layerUtil';
import {
ChartConfig,
LayerConf,
+ MapMaxExtentConfigs,
MapViewConfigs,
OlChartMapProps,
} from '../types';
import { isChartConfigEqual } from '../util/chartUtil';
+import {
+ getExtentFromFeatures,
+ getMapExtentPadding,
+} from '../util/geometryUtil';
+
+/**
+ * Computes a transformed extent from a MapMaxExtentConfigs (if CUSTOM mode)
+ * and applies it by setting a new view on the map.
+ */
+const applyMapExtentView = (
+ olMap: Map,
+ mapMaxExtentConf: MapMaxExtentConfigs,
+) => {
+ const { extentMode, fixedMaxX, fixedMaxY, fixedMinX, fixedMinY } =
+ mapMaxExtentConf;
+ const view = olMap.getView();
+ const center = view.getCenter();
+ const zoom = view.getZoom();
+ let extent;
+
+ if (
+ extentMode === 'CUSTOM' &&
+ fixedMaxX !== undefined &&
+ fixedMaxY !== undefined &&
+ fixedMinX !== undefined &&
+ fixedMinY !== undefined
+ ) {
+ extent = transformExtent(
+ [fixedMinX, fixedMinY, fixedMaxX, fixedMaxY],
+ 'EPSG:4326',
+ 'EPSG:3857',
+ );
+ }
+
+ olMap.setView(
Review Comment:
Yes, that will likely lead to inconsistencies. I adjusted so that we now use the event listeners of the map instance, which will not be recreated. So recreating the view does not affect the listeners any more.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422833151
##########
superset/config.py:
##########
@@ -3492,6 +3492,83 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument # noq
},
}
+# Map projections of the datasources. If not provided, only
+# EPSG:3857 and EPSG:4326 are supported. The projection definitions
+# can be found on https://epsg.io in the Proj.4 section and should
+# be added here in following structure:
+#
+# {'EPSG:Code': 'definition'}
+#
+# e.g.
+#
+# {
+# 'EPSG:25832': (
+# '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# 'EPSG:25833': (
+# '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m '
+# '+no_defs +type=crs'
+# ),
+# }
+#
+MAP_PROJECTIONS = {}
+
+# Default layers that will be added to all visualizations of plugin-chart-cartodiagram.
+# For a list of supported types, and configuration details see the README.md
+# of plugin-chart-cartodiagram.
+MAP_DEFAULT_LAYERS = [
+ {
+ "type": "WMS",
+ "version": "1.3.0",
+ "url": "https://ows.terrestris.de/osm-gray/service",
+ "layersParam": "OSM-WMS",
+ "title": "OpenStreetMap",
+ "attribution": (
+ "ยฉ Map data from "
+ '<a href="https://openstreetmap.org/copyright">OpenStreetMap</a>. '
Review Comment:
I prefer to keep things simple and consistent. So I removed the markup from the attribution.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4343412561
## [Codecov](https://app.codecov.io/gh/apache/superset/pull/39760?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 55.42%. Comparing base ([`b791f4c`](https://app.codecov.io/gh/apache/superset/commit/b791f4c2cd2e3489572c191bda79089a2fafe010?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`7e6ab17`](https://app.codecov.io/gh/apache/superset/commit/7e6ab170d32bf6d854ecc5d752355d6e84c83035?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
:warning: Report is 22 commits behind head on master.
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## master #39760 +/- ##
==========================================
- Coverage 64.48% 55.42% -9.06%
==========================================
Files 2566 2566
Lines 133926 133893 -33
Branches 31096 31090 -6
==========================================
- Hits 86357 74213 -12144
- Misses 46074 59025 +12951
+ Partials 1495 655 -840
```
| [Flag](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage ฮ | |
|---|---|---|
| [hive](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | |
| [mysql](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | |
| [postgres](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | |
| [presto](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `41.52% <100.00%> (-0.03%)` | :arrow_down: |
| [python](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `41.52% <100.00%> (-20.35%)` | :arrow_down: |
| [sqlite](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | |
| [unit](https://app.codecov.io/gh/apache/superset/pull/39760/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `?` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
</details>
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/apache/superset/pull/39760?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
<details><summary> :rocket: New features to boost your workflow: </summary>
- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4343389751
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4494467838
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-5106358600
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
<details>
<summary>
Bito Usage Guide
</summary>
**Commands**
Type the following command in the pull request comment and save the comment.
- `/review` - Manually triggers a full AI review.
- `/pause` - Pauses automatic reviews on this pull request.
- `/resume` - Resumes automatic reviews.
- `/resolve` - Marks all Bito-posted review comments as resolved.
- `/abort` - Cancels all in-progress reviews.
Refer to the <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
**Configuration**
This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
**Documentation & Help**
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
- <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3613252952
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx:
##########
@@ -50,3 +57,157 @@ export const fitMapToCharts = (olMap: Map, chartConfigs: ChartConfig) => {
size: [250, 250],
});
};
+
+const fitToData = (
+ olMap: Map,
+ features: Feature[],
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const view = olMap.getView();
+ const extent = getExtentFromFeatures(features) || defaultExtent;
+
+ if (padding) {
+ view.fit(extent, { padding });
+ } else {
+ view.fit(extent);
+ }
+};
+
+const extractSridFromWkt = (wkt: string) => {
+ const extract: { geom: string; srid: string | null } = {
+ geom: wkt,
+ srid: null,
+ };
+ if (wkt.startsWith('SRID=')) {
+ // WKT with SRID, strip it
+ const srid = wkt.match(/SRID=(\d+);/);
+ if (srid) {
+ extract.srid = `EPSG:${srid[1]}`;
+ extract.geom = wkt.replace(/SRID=\d+;/, '');
+ }
+ }
+ return extract;
+};
+
+export const wkbToGeoJSON = (wkb: string) => {
+ const format = new WKB();
+ const feature = format.readFeature(wkb, {
+ featureProjection: 'EPSG:3857',
+ });
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+export const wktToGeoJSON = (wkt: string) => {
+ const format = new WKT();
+ const wktOpts: ReadOptions = {
+ featureProjection: 'EPSG:3857',
+ dataProjection: 'EPSG:4326', // default to WGS84
+ };
+ const extract = extractSridFromWkt(wkt);
+ const cleanedWkt = extract.geom;
+ if (extract.srid) {
+ wktOpts.dataProjection = extract.srid;
+ }
+ const feature = format.readFeature(cleanedWkt, wktOpts);
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+/**
+ * Create OL Features from data records.
+ *
+ * @param dataRecords The data records to transform.
+ * @param geomColumn The name of the column holding the geodata.
+ * @returns List of OL Features.
+ */
+export const dataRecordsToOlFeatures = (
+ dataRecords: DataRecord[],
+ geomColumn: string,
+ geomFormat: GeometryFormat.WKB | GeometryFormat.WKT,
+) => {
+ let format: WKB | WKT = new WKB();
+
+ if (geomFormat === GeometryFormat.WKT) {
+ format = new WKT();
+ }
+ const features = dataRecords
+ .map(item => {
+ const geom = item[geomColumn];
+ if (typeof geom !== 'string') {
+ return undefined;
+ }
+
+ let cleanedGeom = geom;
+ const opts: ReadOptions = {
+ featureProjection: 'EPSG:3857',
+ };
+ if (geomFormat === GeometryFormat.WKT) {
+ const extract = extractSridFromWkt(geom);
+ cleanedGeom = extract.geom;
+ if (extract.srid) {
+ opts.dataProjection = extract.srid;
+ }
+ }
+ const feature = format.readFeature(cleanedGeom, opts);
+ feature.setProperties({ ...item });
Review Comment:
**Suggestion:** A single malformed WKT/WKB value will throw from `readFeature` and abort processing of the entire dataset. Wrap parsing per record and skip invalid geometries so one bad row does not crash map fitting/rendering. [possible bug]
<details>
<summary><b>Severity Level:</b> Major โ ๏ธ</summary>
```mdx
- โ Cartodiagram map crashes on malformed WKT/WKB record.
- โ ๏ธ Map extent fitting fails for affected datasets.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. In `superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx:189`, call
the exported function `fitMapToDataRecords(olMap, dataRecords, geomColumn, geomFormat,
padding)` with `geomFormat` set to `GeometryFormat.WKT` or `GeometryFormat.WKB`.
2. Ensure `dataRecords` includes at least one record where `dataRecord[geomColumn]` is a
string that is not valid WKT/WKB (for example, a truncated or otherwise malformed geometry
string).
3. Inside `fitMapToDataRecords`, at `mapUtil.tsx:196-201`, the function calls
`dataRecordsToOlFeatures(dataRecords, geomColumn, geomFormat)` to convert each record into
OpenLayers `Feature` instances.
4. In `dataRecordsToOlFeatures` (`mapUtil.tsx:126-161`), when processing the malformed
record, `format.readFeature(cleanedGeom, opts)` at line 154 throws from the OpenLayers
WKT/WKB parser; because this exception is not caught, it aborts `dataRecordsToOlFeatures`,
`fitToData` (`mapUtil.tsx:61-74`), and thus `fitMapToDataRecords`, causing any caller
using this helper to fail rendering/fitting the cartodiagram map.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=1a47b2a8e4f840159f460a321fd9d019&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=1a47b2a8e4f840159f460a321fd9d019&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx
**Line:** 154:155
**Comment:**
*Possible Bug: A single malformed WKT/WKB value will throw from `readFeature` and abort processing of the entire dataset. Wrap parsing per record and skip invalid geometries so one bad row does not crash map fitting/rendering.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=6062995249c9b4e64e382e196067055f791f27a2502255170719a8f1d172c25a&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=6062995249c9b4e64e382e196067055f791f27a2502255170719a8f1d172c25a&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -230,39 +298,167 @@ export const stripGeomColumnFromLabelMap = (
* @returns query data without geom column.
*/
export const stripGeomColumnFromQueryData = (
- queryData: any,
+ queryData: TimeseriesChartDataResponseResult,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
+ dataByLocation: LocationConfigMapping,
+ strippedQueryData: any,
+ sliceId: number,
+) => {
+ // Call color singleton to reserve label colors
+ // get needed control values from underlying chart config
+ const { colorScheme = '', groupby = [], dateFormat } = formData;
+ const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
+ const groupbyLabels = groupby.map(getColumnLabel);
+ Object.keys(dataByLocation).forEach(location => {
Review Comment:
**Suggestion:** `groupby` can be `null` in Superset form data, and this code calls `.map` on it directly, which will throw at runtime. Normalize `groupby` with an array guard (for example via `ensureIsArray`) before mapping so color reservation does not crash chart rendering. [possible bug]
<details>
<summary><b>Severity Level:</b> Critical ๐จ</summary>
```mdx
- โ Cartodiagram fails when underlying chart has null groupby.
- โ ๏ธ Dashboard render may show blank or error state.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Render a cartodiagram visualization that references another Superset chart whose saved
form-data has `groupby` explicitly set to `null` (not `undefined`), which is passed
through `selectedChart.params` into `getChartConfigs` in
`superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:451-458`.
2. In `getChartConfigs`, `chartFormData` is created from `selectedChart.params` and stored
in `baseConfig.formData` (`transformPropsUtil.ts:459-463`), then
`reserveLabelColors(baseConfig.formData, dataByLocation, strippedQueryData, sliceId)` is
called at `transformPropsUtil.ts:507-512`.
3. Inside `reserveLabelColors` (`transformPropsUtil.ts:412-438`), destructuring at line
421 assigns `groupby = null` because the default `[]` only applies when the property is
`undefined`, not `null`.
4. The subsequent line `groupby.map(getColumnLabel)` at `transformPropsUtil.ts:423`
executes `map` on `null`, throwing `TypeError: groupby.map is not a function`, which
aborts `reserveLabelColors` and `getChartConfigs`, preventing the cartodiagram pluginโs
transformProps from completing and resulting in the map failing to render.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=cf2dfc7a2c3545599ee0afda7a96ef63&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=cf2dfc7a2c3545599ee0afda7a96ef63&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 421:423
**Comment:**
*Possible Bug: `groupby` can be `null` in Superset form data, and this code calls `.map` on it directly, which will throw at runtime. Normalize `groupby` with an array guard (for example via `ensureIsArray`) before mapping so color reservation does not crash chart rendering.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=342d37d35c0765747ce98ab71b34c6b180d39546e199b592d6cb70b5a407553e&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=342d37d35c0765747ce98ab71b34c6b180d39546e199b592d6cb70b5a407553e&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -95,16 +160,16 @@ export const groupByLocationGenericX = (
return;
}
- const geojsonCols = getGeojsonColumns(labelMap);
+ const geomColumns = getGeomColumns(geomFormat, labelMap);
- if (geojsonCols.length > 1) {
+ if (geomColumns.length > 1) {
// TODO what should we do, if there is more than one geom column?
console.log(
'More than one geometry column detected. Using first found.',
);
}
- const location = labelMap[geojsonCols[0]];
- const filter = geojsonCols.length ? [geojsonCols[0]] : [];
+ const location = labelMap[geomColumns[0]];
+ const filter = geomColumns.length ? [geomColumns[0]] : [];
const leftOverKey = createColumnName(labelMap, filter);
Review Comment:
**Suggestion:** When no geometry column is detected, this indexes `labelMap` with `undefined`, which creates an invalid location key and can later cascade into geometry parsing failures. Add an explicit `geomColumns.length === 0` branch to skip or safely handle records with no detected geometry. [logic error]
<details>
<summary><b>Severity Level:</b> Major โ ๏ธ</summary>
```mdx
- โ Data grouped under invalid 'undefined' geometry location.
- โ ๏ธ Downstream geometry parsing fails for such locations.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Use a referenced chart whose `label_map` entries for a non-`x_axis` key contain no
values detectable as geometry by `getGeomColumns(geomFormat, labelMap)` (for example, a
metric column only), and render a cartodiagram with generic x-axis configuration so
`groupByLocationGenericX` is used (`transformPropsUtil.ts:140-149`).
2. In `groupByLocationGenericX` (`transformPropsUtil.ts:140-225`), for such a key `k`,
`labelMap` is taken from `queryData.label_map[k]` at lines 154-155, and `geomColumns =
getGeomColumns(geomFormat, labelMap)` at line 163 returns an empty array.
3. With `geomColumns.length === 0`, `location = labelMap[geomColumns[0]]` at line 171
yields `location === undefined`, while `filter` becomes `[]` at line 172 and `leftOverKey`
is computed from the full `labelMap` at line 173.
4. The code then uses `locations[location]` at lines 175-176, creating a location key
`'undefined'`; later, in `getChartConfigs` (`transformPropsUtil.ts:480-549`),
`Object.keys(dataByLocation)` is iterated, and each `location` string is treated as
geometry (parsed via JSON/WKB/WKT in `getChartConfigs` at lines 525-537), so the
`'undefined'` key leads to invalid geometry parsing and can cause runtime errors or
missing features in the resulting FeatureCollection.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=40da8fcb931249389b98961e11cdbc09&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) [](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=40da8fcb931249389b98961e11cdbc09&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
**Line:** 171:173
**Comment:**
*Logic Error: When no geometry column is detected, this indexes `labelMap` with `undefined`, which creates an invalid location key and can later cascade into geometry parsing failures. Add an explicit `geomColumns.length === 0` branch to skip or safely handle records with no detected geometry.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=c0a4ce073249cf0a1aff7e325c92c3a6c32f2dc6cd368c429f400060236b53dc&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=c0a4ce073249cf0a1aff7e325c92c3a6c32f2dc6cd368c429f400060236b53dc&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4400966450
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/FlatLayerTree.tsx:
##########
@@ -81,7 +104,85 @@ export const StyledLayerTreeItem = styled(LayerTreeItem)`
`}
`;
-// forwardRef is needed here in order for emotion and antd tree to work properly
+interface DraggableLayerTreeItemProps {
+ layerConf: LayerConfWithId;
+ index: number;
+ draggable?: boolean;
+ onEditLayer: (layerConf: LayerConfWithId, idx: number) => void;
+ onRemoveLayer: (idx: number) => void;
+ onMoveLayerByIndex: (dragIndex: number, hoverIndex: number) => void;
+}
+
+const DraggableLayerTreeItem: FC<DraggableLayerTreeItemProps> = ({
+ layerConf,
+ index,
+ draggable = false,
+ onEditLayer,
+ onRemoveLayer,
+ onMoveLayerByIndex,
+}) => {
+ const ref = useRef<HTMLDivElement>(null);
+
+ const [, drag] = useDrag<DragItem, void, unknown>({
Review Comment:
Adjusted the tests in https://github.com/apache/superset/pull/39760/commits/4a188a01d4dc9def94d602b8aff57cfa85666452
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422827676
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,183 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ context.composition!.Rules.disableClassification =
Review Comment:
Done. I'm now creating a clone of the composition before assigning it to the context.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on PR #39760:
URL: https://github.com/apache/superset/pull/39760#issuecomment-4485292911
@rusackas @villebro this should be ready for testing now
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3271365421
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -202,21 +268,30 @@ export const stripGeomFromColnamesAndTypes = (
*
* @param queryData The querydata.
* @param geomColumn Name of the geom column.
+ * @param geomFormat The format of the geometries.
* @returns labelMap without the geom column.
*/
export const stripGeomColumnFromLabelMap = (
labelMap: { [key: string]: string[] },
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const newLabelMap: Record<string, string[]> = {};
Object.entries(labelMap).forEach(([key, value]) => {
if (key === geomColumn) {
return;
}
- const geojsonCols = getGeojsonColumns(value);
- const filter = geojsonCols.length ? [geojsonCols[0]] : [];
+ let geomColumns: number[];
+ if (geomFormat === GeometryFormat.GEOJSON) {
+ geomColumns = getGeojsonColumns(value);
+ } else if (geomFormat === GeometryFormat.WKB) {
+ geomColumns = getWkbColumns(value);
+ } else {
+ geomColumns = getWktColumns(value);
+ }
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>CWE-1041: Semantic duplication with getGeomColumns</b></div>
<div id="fix">
Semantic duplication: Lines 284-291 replicate the logic in `getGeomColumns` (lines 109-120). Use the existing helper to avoid divergence risk. ([CWE-1041](https://cwe.mitre.org/data/definitions/1041.html))
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -281,15 +281,8 @@ export const stripGeomColumnFromLabelMap = (
if (key === geomColumn) {
return;
}
- let geomColumns: number[];
- if (geomFormat === GeometryFormat.GEOJSON) {
- geomColumns = getGeojsonColumns(value);
- } else if (geomFormat === GeometryFormat.WKB) {
- geomColumns = getWkbColumns(value);
- } else {
- geomColumns = getWktColumns(value);
- }
+ const geomColumns = getGeomColumns(geomFormat, value);
const filter = geomColumns.length ? [geomColumns[0]] : [];
const columnName = createColumnName(value, filter);
const restItems = value.filter((v, idx) => !geomColumns.includes(idx));
```
</div>
</details>
</div>
<small><i>Code Review Run #2bc862</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/webpack.config.js:
##########
@@ -513,10 +513,70 @@ const config = {
exclude: [/\.test.tsx?$/, /node_modules/],
use: [createSwcLoader('typescript', true)],
},
+ {
+ test: /\.js$/,
+ include: /node_modules\/geostyler/,
+ resolve: {
+ // Currently, GeoStyler uses imports without file extension
+ // on ESM modules, which is not supported by webpack.
+ fullySpecified: false,
+ },
+ },
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>SEMANTIC_DUPLICATION in webpack rules</b></div>
<div id="fix">
This new rule is semantically duplicating the existing rule at lines 505-510. Both target `.js` files in `node_modules/geostyler` with identical `fullySpecified: false` resolve configuration. The pre-existing rule is more comprehensive, covering `geostyler-openlayers-parser`, `geostyler-mapbox-parser`, and `geostyler-sld-parser` in addition to `geostyler` itself. Remove this redundant rule to avoid maintenance divergence.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/webpack.config.js
+++ superset-frontend/webpack.config.js
@@ -513,14 +513,6 @@
use: [createSwcLoader('typescript', true)],
},
- {
- test: /\.js$/,
- include: /node_modules\/geostyler/,
- resolve: {
- // Currently, GeoStyler uses imports without file extension
- // on ESM modules, which is not supported by webpack.
- fullySpecified: false,
- },
- },
{
test: /\.jsx?$/,
```
</div>
</details>
</div>
<small><i>Code Review Run #2bc862</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/constants.ts:
##########
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+export const TIMESLIDER_HEIGHT = 28;
+
+export enum TimesliderTooltipFormat {
+ DATE,
+ TIME,
+ DATETIME,
+}
+
+export enum GeometryFormat {
+ GEOJSON = 'GEOJSON',
+ WKB = 'WKB',
+ WKT = 'WKT',
+}
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/constants.ts
+export const NULL_STRING = '<NULL>';
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Semantic duplication of NULL_STRING</b></div>
<div id="fix">
`NULL_STRING` is already defined in `src/utils/common.ts` with the same value. This creates semantic duplication with divergence risk. Consider importing from the shared location instead of copying.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/constants.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/constants.ts
@@ -30,9 +30,8 @@ export enum GeometryFormat {
WKT = 'WKT',
}
-// copy of
-// superset-frontend/plugins/plugin-chart-echarts/src/constants.ts
-export const NULL_STRING = '<NULL>';
+// Import shared constant instead of duplicating
+export { NULL_STRING } from 'src/utils/common';
export const SELECTION_LAYER_NAME = 'thematic-selection-layer';
```
</div>
</details>
</div>
<small><i>Code Review Run #2bc862</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/FlatLayerTree.tsx:
##########
@@ -81,8 +104,89 @@ export const StyledLayerTreeItem = styled(LayerTreeItem)`
`}
`;
-// forwardRef is needed here in order for emotion and antd tree to work properly
-export const FlatLayerTree = forwardRef<HTMLDivElement, FlatLayerTreeProps>(
+interface DraggableLayerTreeItemProps {
+ layerConf: LayerConfWithId;
+ index: number;
+ draggable?: boolean;
+ onEditLayer: (layerConf: LayerConfWithId, idx: number) => void;
+ onRemoveLayer: (idx: number) => void;
+ onMoveLayerByIndex: (dragIndex: number, hoverIndex: number) => void;
+}
+
+const DraggableLayerTreeItem: FC<DraggableLayerTreeItemProps> = ({
+ layerConf,
+ index,
+ draggable = false,
+ onEditLayer,
+ onRemoveLayer,
+ onMoveLayerByIndex,
+}) => {
+ const ref = useRef<HTMLDivElement>(null);
+
+ const [, drag] = useDrag<DragItem, void, unknown>({
+ item: {
+ type: LAYER_CONFIG_DRAG_TYPE,
+ dragIndex: index,
+ },
+ canDrag: draggable,
+ });
+
+ const [, drop] = useDrop({
+ accept: LAYER_CONFIG_DRAG_TYPE,
+ hover(item: DragItem, monitor: DropTargetMonitor) {
+ // Stop early when dragging is disabled or the item node is not ready yet
+ if (!draggable || !ref.current) {
+ return;
+ }
+ const { dragIndex } = item;
+ const hoverIndex = index;
+ if (dragIndex === hoverIndex) {
+ return;
+ }
+
+ const hoverBoundingRect = ref.current.getBoundingClientRect();
+ const hoverMiddleY =
+ (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
+ const clientOffset = monitor.getClientOffset();
+ const hoverClientY = clientOffset?.y
+ ? clientOffset?.y - hoverBoundingRect.top
+ : 0;
+
+ // Move only after crossing the middle to avoid jumpy reordering
+ if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
+ return;
+ }
+ if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
+ return;
+ }
+
+ onMoveLayerByIndex(dragIndex, hoverIndex);
+ // Note: we're mutating the monitor item here!
+ // Generally it's better to avoid mutations,
+ // but it's good here for the sake of performance
+ // to avoid expensive index searches.
+ // eslint-disable-next-line no-param-reassign
+ item.dragIndex = hoverIndex;
+ },
+ });
+
+ drag(drop(ref));
+
+ return (
+ <DragContainer ref={ref}>
+ <StyledLayerTreeItem
+ layerConf={layerConf}
+ onEditClick={() => onEditLayer(layerConf, index)}
+ onRemoveClick={() => onRemoveLayer(index)}
+ />
+ </DragContainer>
+ );
+};
+
+export const FlatLayerTree: FC<FlatLayerTreeProps> = forwardRef<
+ HTMLDivElement,
+ FlatLayerTreeProps
+>(
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Incorrect FC with forwardRef typing</b></div>
<div id="fix">
Combining `FC<FlatLayerTreeProps>` with `forwardRef<HTMLDivElement, FlatLayerTreeProps>` is redundant. `FC` adds implicit `children` and conflicts with `forwardRef` typing. Use `forwardRef` directly without `FC` wrapper.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/src/explore/components/controls/LayerConfigsControl/FlatLayerTree.tsx
+++ superset-frontend/src/explore/components/controls/LayerConfigsControl/FlatLayerTree.tsx
@@ -183,7 +183,7 @@ const DraggableLayerTreeItem: FC<DraggableLayerTreeItemProps> = ({
);
};
-export const FlatLayerTree: FC<FlatLayerTreeProps> = forwardRef<
+export const FlatLayerTree = forwardRef<
HTMLDivElement,
FlatLayerTreeProps
>(
```
</div>
</details>
</div>
<small><i>Code Review Run #2bc862</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -152,8 +197,71 @@ export const createLayer = async (layerConf: LayerConf) => {
layer = await createWfsLayer(layerConf);
} else if (isXyzLayerConf(layerConf)) {
layer = createXyzLayer(layerConf);
+ } else if (isDataLayerConf(layerConf)) {
+ layer = await createDataLayer(layerConf);
} else {
console.warn('Provided layerconfig is not recognized');
}
return layer;
};
+
+export const removeSelectionLayer = (olMap: Map) => {
+ const selectionLayer = olMap
+ .getLayers()
+ .getArray()
+ .filter(l => l.get(LAYER_NAME_PROP) === SELECTION_LAYER_NAME)
+ .pop();
+ if (selectionLayer) {
+ olMap.removeLayer(selectionLayer);
+ }
+};
+
+export const getSelectedFeatures = (
+ dataLayers: VectorLayer<VectorSource>[],
+ filterState: FilterState,
+ crossFilterColumn: string,
+) => {
+ let selectedFeatures: Feature[] = [];
+ if (
+ filterState.selectedValues !== null &&
+ filterState.selectedValues !== undefined &&
+ dataLayers
+ ) {
+ selectedFeatures = dataLayers.flatMap(dataLayer =>
+ dataLayer
+ .getSource()!
+ .getFeatures()
+ .filter(f =>
+ filterState.selectedValues.includes(f.get(crossFilterColumn)),
+ ),
+ );
+ }
+ return selectedFeatures;
+};
+
+export const setSelectionBackgroundOpacity = (
+ dataLayers: VectorLayer<VectorSource>[],
+ opacity: number,
+) => {
+ dataLayers.forEach(dataLayer => {
+ dataLayer.setOpacity(opacity);
+ });
+};
+
+export const createSelectionLayer = (
+ dataLayers: VectorLayer<VectorSource>[],
+ features: Feature[],
+) => {
+ const selectionLayer = new VectorLayer({
+ source: new VectorSource({
+ features,
+ }),
+ });
+ selectionLayer.set(LAYER_NAME_PROP, SELECTION_LAYER_NAME);
+ // TODO how can we handle multiple data layers?
+ const layerStyle = dataLayers[0].getStyle();
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Unsafe array access</b></div>
<div id="fix">
Accessing `dataLayers[0]` without checking array length risks runtime error if empty array passed. Add guard check.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx
@@ -258,7 +258,9 @@
});
selectionLayer.set(LAYER_NAME_PROP, SELECTION_LAYER_NAME);
// TODO how can we handle multiple data layers?
- const layerStyle = dataLayers[0].getStyle();
+ const layerStyle = dataLayers.length > 0 ? dataLayers[0].getStyle() : undefined;
- if (layerStyle) {
+ if (layerStyle) {
selectionLayer.setStyle(layerStyle);
}
return selectionLayer;
```
</div>
</details>
</div>
<small><i>Code Review Run #2bc862</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3160753538
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx:
##########
@@ -0,0 +1,48 @@
+/**
+ * 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 } from '@apache-superset/core/translation';
+import { Tag } from 'antd';
+import { FC } from 'react';
+import { MapMaxExtentTagProps } from '../../types';
+
+export const MapMaxExtentTag: FC<MapMaxExtentTagProps> = ({
+ value,
+ className,
+}) => {
+ const unsetName = t('unset');
+ const lowerLeftName = t('Lower left (Lat | Lon)');
+ const upperRightName = t('Upper right (Lat | Lon)');
+
+ return (
+ <Tag className={className}>
+ {upperRightName}:{' '}
+ {value.fixedMaxX && value.fixedMaxY
+ ? `${value.fixedMaxY.toFixed(6)} | ${value.fixedMaxX.toFixed(6)}`
+ : unsetName}
+ <br />
+ {lowerLeftName}:{' '}
+ {value.fixedMinX && value.fixedMinY
+ ? `${value.fixedMinY.toFixed(6)} | ${value.fixedMinX.toFixed(6)}`
Review Comment:
**๐ Architect Review โ HIGH**
Map extent coordinates are rendered using truthy checks (e.g. value.fixedMaxX && value.fixedMaxY), so valid 0-valued bounds (lat/lon = 0) are treated as "unset" and not displayed.
**Suggestion:** Replace the truthy checks with explicit undefined/null checks (e.g. value.fixedMaxX !== undefined && value.fixedMaxY !== undefined) so 0.0 is rendered as a valid coordinate.
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20an%20%2A%2AArchitect%20%2F%20Logical%20Review%2A%2A%20comment%20left%20during%20a%20code%20review.%20These%20reviews%20are%20first-class%2C%20important%20findings%20%E2%80%94%20not%20optional%20suggestions.%20Do%20NOT%20dismiss%20this%20as%20a%20%27big%20architectural%20change%27%20just%20because%20the%20title%20says%20architect%20review%3B%20most%20of%20these%20can%20be%20resolved%20with%20a%20small%2C%20localized%20fix%20once%20the%20intent%20is%20understood.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2036%3A42%0A%2A%2AComment%3A%2A%2A%0A%09%2AHIGH%3A%20Map%20extent%20coordinates%20are%20rendered%20using%20truthy%20checks%20%28e.g.%20value.fixedMaxX%20%26%26%20value.fixedMaxY%29%2C%20so%20valid%200-valued%20bounds%20%28lat%2Flon%20%3D%200%29%20are%20treated%20as%20%22unset%22%
20and%20not%20displayed.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AIf%20a%20suggested%20approach%20is%20provided%20above%2C%20use%20it%20as%20the%20authoritative%20instruction.%20If%20no%20explicit%20code%20suggestion%20is%20given%2C%20you%20MUST%20still%20draft%20and%20apply%20your%20own%20minimal%2C%20localized%20fix%20%E2%80%94%20do%20not%20punt%20back%20with%20%27no%20suggestion%20provided%2C%20review%20manually%27.%20Keep%20the%20change%20as%20small%20as%20possible%3A%20add%20a%20guard%20clause%2C%20gate%20on%20a%20loading%20state%2C%20reorder%20an%20await%2C%20wrap%20in%20a%20conditional%2C%20etc.%20Do%20not%20refactor%20surrounding%20code%20or%20expand%20scope%20beyond%20the%20finding.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20u
ser%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20an%20%2A%2AArchitect%20%2F%20Logical%20Review%2A%2A%20comment%20left%20during%20a%20code%20review.%20These%20reviews%20are%20first-class%2C%20important%20findings%20%E2%80%94%20not%20optional%20suggestions.%20Do%20NOT%20dismiss%20this%20as%20a%20%27big%20architectural%20change%27%20just%20because%20the%20title%20says%20architect%20review%3B%20most%20of%20these%20can%20be%20resolved%20with%20a%20small%2C%20localized%20fix%20once%20the%20intent%20is%20understood.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2036%3A42%0A%2A%2AComment%3A%2A%2A%0A%09%2AHIGH%3A%20Map%20exte
nt%20coordinates%20are%20rendered%20using%20truthy%20checks%20%28e.g.%20value.fixedMaxX%20%26%26%20value.fixedMaxY%29%2C%20so%20valid%200-valued%20bounds%20%28lat%2Flon%20%3D%200%29%20are%20treated%20as%20%22unset%22%20and%20not%20displayed.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AIf%20a%20suggested%20approach%20is%20provided%20above%2C%20use%20it%20as%20the%20authoritative%20instruction.%20If%20no%20explicit%20code%20suggestion%20is%20given%2C%20you%20MUST%20still%20draft%20and%20apply%20your%20own%20minimal%2C%20localized%20fix%20%E2%80%94%20do%20not%20punt%20back%20with%20%27no%20suggestion%20provided%2C%20review%20manually%27.%20Keep%20the%20change%20as%20small%20as%20possible%3A%20add%20a%20guard%20clause%2C%20gate%20on%20a%20loading%20state%2C%20reorder%20an%20await%2C%20wrap%20in%20a%20conditional%2C%20etc.%20
Do%20not%20refactor%20surrounding%20code%20or%20expand%20scope%20beyond%20the%20finding.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings โ not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx
**Line:** 36:42
**Comment:**
*HIGH: Map extent coordinates are rendered using truthy checks (e.g. value.fixedMaxX && value.fixedMaxY), so valid 0-valued bounds (lat/lon = 0) are treated as "unset" and not displayed.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix โ do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx:
##########
@@ -50,3 +56,157 @@ export const fitMapToCharts = (olMap: Map, chartConfigs: ChartConfig) => {
size: [250, 250],
});
};
+
+const fitToData = (
+ olMap: Map,
+ features: Feature[],
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const view = olMap.getView();
+ const extent = getExtentFromFeatures(features) || defaultExtent;
+
+ if (padding) {
+ view.fit(extent, { padding });
+ } else {
+ view.fit(extent);
+ }
+};
+
+const extractSridFromWkt = (wkt: string) => {
+ const extract: { geom: string; srid: string | null } = {
+ geom: wkt,
+ srid: null,
+ };
+ if (wkt.startsWith('SRID=')) {
+ // WKT with SRID, strip it
+ const srid = wkt.match(/SRID=(\d+);/);
+ if (srid) {
+ extract.srid = `EPSG:${srid[1]}`;
+ extract.geom = wkt.replace(/SRID=\d+;/, '');
+ }
+ }
+ return extract;
+};
+
+export const wkbToGeoJSON = (wkb: string) => {
+ const format = new WKB();
+ const feature = format.readFeature(wkb, {
+ featureProjection: 'EPSG:3857',
+ });
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+export const wktToGeoJSON = (wkt: string) => {
+ const format = new WKT();
+ const wktOpts: any = {
+ featureProjection: 'EPSG:3857',
+ dataProjection: 'EPSG:4326', // default to WGS84
+ };
+ const extract = extractSridFromWkt(wkt);
+ const cleanedWkt = extract.geom;
+ if (extract.srid) {
+ wktOpts.dataProjection = extract.srid;
+ }
+ const feature = format.readFeature(cleanedWkt, wktOpts);
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+/**
+ * Create OL Features from data records.
+ *
+ * @param dataRecords The data records to transform.
+ * @param geomColumn The name of the column holding the geodata.
+ * @returns List of OL Features.
+ */
+export const dataRecordsToOlFeatures = (
+ dataRecords: DataRecord[],
+ geomColumn: string,
+ geomFormat: GeometryFormat.WKB | GeometryFormat.WKT,
+) => {
+ let format: WKB | WKT = new WKB();
+
+ if (geomFormat === GeometryFormat.WKT) {
+ format = new WKT();
+ }
+ const features = dataRecords
+ .map(item => {
+ const geom = item[geomColumn];
+ if (typeof geom !== 'string') {
+ return undefined;
+ }
+
+ let cleanedGeom = geom;
+ const opts: any = {
+ featureProjection: 'EPSG:3857',
+ };
+ if (geomFormat === GeometryFormat.WKT) {
+ const extract = extractSridFromWkt(geom);
+ cleanedGeom = extract.geom;
+ if (extract.srid) {
+ opts.dataProjection = extract.srid;
+ }
+ }
+ const feature = format.readFeature(cleanedGeom, opts);
+ feature.setProperties({ ...item });
+
+ return feature;
+ })
+ .filter(f => f !== undefined);
+ return features;
+};
+
+/**
+ * Fit map to the spatial extent of provided data.
+ *
+ * @param olMap The OpenLayers map
+ * @param featureCollection The feature collection to get the extent from.
+ */
+export const fitMapToData = (
+ olMap: Map,
+ featureCollection: FeatureCollection,
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const features = new GeoJSON().readFeatures(featureCollection, {
+ featureProjection: 'EPSG:3857',
+ });
+ fitToData(olMap, features, padding);
+};
+
+/**
+ * Fit map to the spatial extent of provided data.
+ *
+ * @param olMap The OpenLayers map
+ * @param dataRecords The data records to get the extent from.
+ * @param geomColumn The name of the column holding the geodata.
+ * @param geomFormat The format of the geometry column.
+ * @param padding Optional padding for the fit operation.
+ */
+export const fitMapToDataRecords = (
+ olMap: Map,
+ dataRecords: DataRecord[],
+ geomColumn: string,
+ geomFormat: GeometryFormat.WKB | GeometryFormat.WKT,
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const features = dataRecordsToOlFeatures(
+ dataRecords,
+ geomColumn,
+ geomFormat,
+ ) as Feature[];
+ fitToData(olMap, features, padding);
+};
+
+/**
+ * Register map projections.
+ * @param mapProjections The map projections to register.
+ */
+export const registerMapProjections = (mapProjections: MapProjections) => {
+ Object.entries(mapProjections).forEach(([code, definition]) => {
+ proj4.defs(code, definition);
+ });
+ register(proj4);
+};
Review Comment:
**๐ Architect Review โ HIGH**
Custom CRS support is not wired up: MAP_PROJECTIONS is exposed via bootstrap data, but registerMapProjections is never called, so configured EPSG definitions are never registered and EWKT/EWKB geometries with non-built-in SRIDs cannot be correctly interpreted.
**Suggestion:** During cartodiagram initialization (before any WKT/WKB parsing), call registerMapProjections(getMapProjections()) so MAP_PROJECTIONS entries are registered with proj4, and optionally log or surface an error when a geometry references an SRID that is not registered.
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20an%20%2A%2AArchitect%20%2F%20Logical%20Review%2A%2A%20comment%20left%20during%20a%20code%20review.%20These%20reviews%20are%20first-class%2C%20important%20findings%20%E2%80%94%20not%20optional%20suggestions.%20Do%20NOT%20dismiss%20this%20as%20a%20%27big%20architectural%20change%27%20just%20because%20the%20title%20says%20architect%20review%3B%20most%20of%20these%20can%20be%20resolved%20with%20a%20small%2C%20localized%20fix%20once%20the%20intent%20is%20understood.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FmapUtil.tsx%0A%2A%2ALine%3A%2A%2A%20207%3A212%0A%2A%2AComment%3A%2A%2A%0A%09%2AHIGH%3A%20Custom%20CRS%20support%20is%20not%20wired%20up%3A%20MAP_PROJECTIONS%20is%20exposed%20via%20bootstrap%20data%2C%20but%20registerMapProjections%20is%20never%20called%2C%20so%20configured%20EPSG%20definitions%20are%20never%20registered%20and%20EWKT%2FEWKB%20geomet
ries%20with%20non-built-in%20SRIDs%20cannot%20be%20correctly%20interpreted.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AIf%20a%20suggested%20approach%20is%20provided%20above%2C%20use%20it%20as%20the%20authoritative%20instruction.%20If%20no%20explicit%20code%20suggestion%20is%20given%2C%20you%20MUST%20still%20draft%20and%20apply%20your%20own%20minimal%2C%20localized%20fix%20%E2%80%94%20do%20not%20punt%20back%20with%20%27no%20suggestion%20provided%2C%20review%20manually%27.%20Keep%20the%20change%20as%20small%20as%20possible%3A%20add%20a%20guard%20clause%2C%20gate%20on%20a%20loading%20state%2C%20reorder%20an%20await%2C%20wrap%20in%20a%20conditional%2C%20etc.%20Do%20not%20refactor%20surrounding%20code%20or%20expand%20scope%20beyond%20the%20finding.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20t
he%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20an%20%2A%2AArchitect%20%2F%20Logical%20Review%2A%2A%20comment%20left%20during%20a%20code%20review.%20These%20reviews%20are%20first-class%2C%20important%20findings%20%E2%80%94%20not%20optional%20suggestions.%20Do%20NOT%20dismiss%20this%20as%20a%20%27big%20architectural%20change%27%20just%20because%20the%20title%20says%20architect%20review%3B%20most%20of%20these%20can%20be%20resolved%20with%20a%20small%2C%20localized%20fix%20once%20the%20intent%20is%20understood.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Futil%2FmapUtil.tsx%0A%2A%2ALine%3A%2A%2A%20207%3A212%0A%2A%2AComment%3A%2A%2A%0A%09%2AHIG
H%3A%20Custom%20CRS%20support%20is%20not%20wired%20up%3A%20MAP_PROJECTIONS%20is%20exposed%20via%20bootstrap%20data%2C%20but%20registerMapProjections%20is%20never%20called%2C%20so%20configured%20EPSG%20definitions%20are%20never%20registered%20and%20EWKT%2FEWKB%20geometries%20with%20non-built-in%20SRIDs%20cannot%20be%20correctly%20interpreted.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AIf%20a%20suggested%20approach%20is%20provided%20above%2C%20use%20it%20as%20the%20authoritative%20instruction.%20If%20no%20explicit%20code%20suggestion%20is%20given%2C%20you%20MUST%20still%20draft%20and%20apply%20your%20own%20minimal%2C%20localized%20fix%20%E2%80%94%20do%20not%20punt%20back%20with%20%27no%20suggestion%20provided%2C%20review%20manually%27.%20Keep%20the%20change%20as%20small%20as%20possible%3A%20add%20a%20guard%20clause%2C%20g
ate%20on%20a%20loading%20state%2C%20reorder%20an%20await%2C%20wrap%20in%20a%20conditional%2C%20etc.%20Do%20not%20refactor%20surrounding%20code%20or%20expand%20scope%20beyond%20the%20finding.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings โ not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx
**Line:** 207:212
**Comment:**
*HIGH: Custom CRS support is not wired up: MAP_PROJECTIONS is exposed via bootstrap data, but registerMapProjections is never called, so configured EPSG definitions are never registered and EWKT/EWKB geometries with non-built-in SRIDs cannot be correctly interpreted.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix โ do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3160750980
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx:
##########
@@ -0,0 +1,48 @@
+/**
+ * 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 } from '@apache-superset/core/translation';
+import { Tag } from 'antd';
+import { FC } from 'react';
+import { MapMaxExtentTagProps } from '../../types';
+
+export const MapMaxExtentTag: FC<MapMaxExtentTagProps> = ({
+ value,
+ className,
+}) => {
+ const unsetName = t('unset');
+ const lowerLeftName = t('Lower left (Lat | Lon)');
+ const upperRightName = t('Upper right (Lat | Lon)');
+
+ return (
+ <Tag className={className}>
+ {upperRightName}:{' '}
+ {value.fixedMaxX && value.fixedMaxY
+ ? `${value.fixedMaxY.toFixed(6)} | ${value.fixedMaxX.toFixed(6)}`
+ : unsetName}
+ <br />
+ {lowerLeftName}:{' '}
+ {value.fixedMinX && value.fixedMinY
+ ? `${value.fixedMinY.toFixed(6)} | ${value.fixedMinX.toFixed(6)}`
+ : unsetName}
Review Comment:
**Suggestion:** The lower-left extent display has the same truthiness bug: coordinates equal to `0` are treated as absent. This causes valid bounds to render as "unset" for many real map extents. Use explicit `undefined` checks for both values. [logic error]
<details>
<summary><b>Severity Level:</b> Minor ๐งน</summary>
```mdx
- โ ๏ธ Max. Extent control hides zero lower-left coordinates.
- โ ๏ธ Confusing display for extents touching 0 latitude/longitude.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Open or create a Cartodiagram chart in Explore; the `map_max_extent` control is wired
to `MapMaxExtentViewControl` via
`superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts` lines
98โ111, and `MapMaxExtentViewControl` renders `StyledMaxExtentTag` (wrapping
`MapMaxExtentTag`) when `extentMode === 'CUSTOM'` at
`src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx` line 142.
2. Interact with the map so that the viewport extent stored in `map_max_extent` (set from
the live map via `setControlValue('map_max_extent', { ...currentMapMaxExtent, maxX, maxY,
minX, minY })` in `src/components/OlChartMap.tsx` lines 109โ138) yields a lower-left
latitude or longitude equal to `0` (for example, a dataset whose spatial extent touches
the equator or prime meridian).
3. Click the "Use current extent" button in `MapMaxExtentViewControl` (`onButtonClick` at
lines 98โ110), which copies `minX`/`minY` into `fixedMinX`/`fixedMinY` in the
`MapMaxExtentConfigs` value passed to `MapMaxExtentTag`.
4. Observe the "Max. Extent" summary tag output by `MapMaxExtentTag` at
`src/components/MapMaxExtentControl/MapMaxExtentTag.tsx` lines 40โ43: the lower-left
extent uses `{value.fixedMinX && value.fixedMinY ? ... : unsetName}`, so any `0`
coordinate is treated as falsy and the label shows `unset` instead of the valid `0.000000`
value, even though the map constraint itself still works because `OlChartMap.tsx` checks
`fixedMinX !== undefined`/`fixedMinY !== undefined`.
```
</details>
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2041%3A43%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20The%20lower-left%20extent%20display%20has%20the%20same%20truthiness%20bug%3A%20coordinates%20equal%20to%20%600%60%20are%20treated%20as%20absent.%20This%20causes%20valid%20bounds%20to%20render%20as%20%22unset%22%20for%20many%20real%20map%20extents.%20Use%20explicit%20%60undefined%60%20checks%20for%20both%20values.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user
%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2041%3A43%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20The%20lower-left%20extent%20display%20has%20the%20same%20truthiness%20bug%3A%20coordinates%20equal%20to%20%600%60%20are%20treated%20as%20absent.%20This%20causes%20valid%20bounds%20to%20render%20as%20%22unset%22%20for%20many%20real%20map%20extents.%20Use%20explicit%20%60undefined%60%20checks%20for%20both%20values.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%
20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx
**Line:** 41:43
**Comment:**
*Logic Error: The lower-left extent display has the same truthiness bug: coordinates equal to `0` are treated as absent. This causes valid bounds to render as "unset" for many real map extents. Use explicit `undefined` checks for both values.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=2516f279eb84277926094903294e1e0ed2df93b37dd288c3b3603669b58a567f&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=2516f279eb84277926094903294e1e0ed2df93b37dd288c3b3603669b58a567f&reaction=dislike'>๐</a>
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx:
##########
@@ -0,0 +1,48 @@
+/**
+ * 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 } from '@apache-superset/core/translation';
+import { Tag } from 'antd';
+import { FC } from 'react';
+import { MapMaxExtentTagProps } from '../../types';
+
+export const MapMaxExtentTag: FC<MapMaxExtentTagProps> = ({
+ value,
+ className,
+}) => {
+ const unsetName = t('unset');
+ const lowerLeftName = t('Lower left (Lat | Lon)');
+ const upperRightName = t('Upper right (Lat | Lon)');
+
+ return (
+ <Tag className={className}>
+ {upperRightName}:{' '}
+ {value.fixedMaxX && value.fixedMaxY
+ ? `${value.fixedMaxY.toFixed(6)} | ${value.fixedMaxX.toFixed(6)}`
+ : unsetName}
Review Comment:
**Suggestion:** The upper-right extent display incorrectly treats `0` as "unset" because it relies on truthiness checks. Valid coordinates on the equator/prime meridian (`0`) will be hidden. Check explicitly for `undefined` instead of using `&&` truthiness. [logic error]
<details>
<summary><b>Severity Level:</b> Minor ๐งน</summary>
```mdx
- โ ๏ธ Max. Extent control hides zero upper-right coordinates.
- โ ๏ธ Users near equator/meridian see misleading "unset" text.
```
</details>
<details>
<summary><b>Steps of Reproduction โ
</b></summary>
```mdx
1. Open or create a Cartodiagram chart in Explore, which uses the cartodiagram control
panel defined in
`superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts` lines
98โ111, where the `map_max_extent` control is configured with `type:
MapMaxExtentViewControl`.
2. In the "Map Options" section, switch the "Max. Extent" control to `CUSTOM`, causing
`MapMaxExtentViewControl` in
`src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx` lines 64โ74 and 139โ143
to render `<StyledMaxExtentTag value={value} />`, which wraps `MapMaxExtentTag`.
3. Pan/zoom the map so that the current viewport extent stored in `map_max_extent` (set
from the map via `setControlValue('map_max_extent', { ...currentMapMaxExtent, maxX, maxY,
minX, minY })` in `src/components/OlChartMap.tsx` lines 109โ138) produces an upper-right
longitude or latitude equal to `0` after transformation; then click "Use current extent"
in `MapMaxExtentViewControl` (lines 98โ110) so that `fixedMaxX`/`fixedMaxY` are set to
those values.
4. Observe the "Max. Extent" summary tag rendered by `MapMaxExtentTag` at
`src/components/MapMaxExtentControl/MapMaxExtentTag.tsx` lines 35โ38: because it uses
`{value.fixedMaxX && value.fixedMaxY ? ... : unsetName}`, any `0` value is treated as
falsy and the upper-right extent is displayed as `unset` instead of showing the valid
`0.000000` coordinate, even though other logic (e.g. in `OlChartMap.tsx` lines 62โ82)
correctly checks against `undefined`.
```
</details>
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2036%3A38%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20The%20upper-right%20extent%20display%20incorrectly%20treats%20%600%60%20as%20%22unset%22%20because%20it%20relies%20on%20truthiness%20checks.%20Valid%20coordinates%20on%20the%20equator%2Fprime%20meridian%20%28%600%60%29%20will%20be%20hidden.%20Check%20explicitly%20for%20%60undefined%60%20instead%20of%20using%20%60%26%26%60%20truthiness.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20P
R%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset-frontend%2Fplugins%2Fplugin-chart-cartodiagram%2Fsrc%2Fcomponents%2FMapMaxExtentControl%2FMapMaxExtentTag.tsx%0A%2A%2ALine%3A%2A%2A%2036%3A38%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20The%20upper-right%20extent%20display%20incorrectly%20treats%20%600%60%20as%20%22unset%22%20because%20it%20relies%20on%20truthiness%20checks.%20Valid%20coordinates%20on%20the%20equator%2Fprime%20meridian%20%28%600%60%29%20will%20be%20hidden.%20Check%20explicitly%20for%20%60undefined%60%20instead%20of%20using%20%60%26%26%60%20truthiness.%0A%0AValidate%20the%20correctness%20of%20t
he%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent ๐ค </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentTag.tsx
**Line:** 36:38
**Comment:**
*Logic Error: The upper-right extent display incorrectly treats `0` as "unset" because it relies on truthiness checks. Valid coordinates on the equator/prime meridian (`0`) will be hidden. Check explicitly for `undefined` instead of using `&&` truthiness.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=d0f849bd48326fb924731275f73ccd3cd129f611ddfafcef3b17ce5912c0b522&reaction=like'>๐</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39760&comment_hash=d0f849bd48326fb924731275f73ccd3cd129f611ddfafcef3b17ce5912c0b522&reaction=dislike'>๐</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r3614248511
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/LayerConfigsControl.tsx:
##########
@@ -86,12 +108,83 @@ export const LayerConfigsControl: FC<LayerConfigsControlProps> = ({
name,
label,
description,
+ formData,
+ formWatchers,
+ featureCollectionTransformer,
renderTrigger,
hovered,
+ enableDataLayer = false,
+ colTypeMapping,
validationErrors,
}) => {
const [popoverVisible, setPopoverVisible] = useState<boolean>(false);
const [editItem, setEditItem] = useState<EditItem>(getEmptyEditItem());
+ const [currentFormData, setCurrentFormData] = useState(formData);
+ const [chartData, setChartData] = useState<FeatureCollection | undefined>();
+
+ /**
+ * We only want to watch for changes for a dynamic set of properties
+ * of the formData. To prevent unwanted http requests in the render cycles,
+ * we use the proxy currentFormData instead.
+ */
+ useEffect(() => {
+ setCurrentFormData(oldCurrentFormData => {
+ if (!formWatchers) {
+ return oldCurrentFormData;
+ }
+
+ const hasChanges = formWatchers.some(
+ watcher => !isEqual(formData?.[watcher], oldCurrentFormData?.[watcher]),
+ );
+ if (hasChanges) {
+ return formData;
+ }
+ return oldCurrentFormData;
+ });
+ }, [formData, formWatchers]);
+
+ useEffect(() => {
+ if (!currentFormData || !enableDataLayer) {
+ return;
+ }
+ const buildQueryRegistry = getChartBuildQueryRegistry();
+ const chartQueryBuilder = buildQueryRegistry.get(
+ currentFormData.viz_type,
+ ) as any;
+ const chartQuery = chartQueryBuilder(currentFormData);
+ const fetchChartData = async () => {
+ try {
+ const body = JSON.stringify(chartQuery);
+ const response = await fetch('/api/v1/chart/data', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body,
+ });
+ if (!response.ok) {
+ return;
+ }
+ const responseJson = await response.json();
+ let { data } = responseJson.result[0];
+
+ if (featureCollectionTransformer) {
+ data = featureCollectionTransformer(data, currentFormData);
+ }
+
+ setChartData(data);
+ } catch (err) {
+ console.error('Error fetching chart data for LayerConfigsControl', err);
+ }
+ };
+
+ fetchChartData();
+ }, [currentFormData, enableDataLayer, featureCollectionTransformer]);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Missing fetch abort cleanup</b></div>
<div id="fix">
The async `fetchChartData` has no cleanup mechanism. When the component unmounts or `formData` changes rapidly, pending requests may complete after unmount, causing React state updates on unmounted components and memory leaks. Add `AbortController` with cleanup.
</div>
</div>
<small><i>Code Review Run #80d42d</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/mapUtil.tsx:
##########
@@ -50,3 +57,157 @@ export const fitMapToCharts = (olMap: Map, chartConfigs: ChartConfig) => {
size: [250, 250],
});
};
+
+const fitToData = (
+ olMap: Map,
+ features: Feature[],
+ padding?: FitOptions['padding'] | undefined,
+) => {
+ const view = olMap.getView();
+ const extent = getExtentFromFeatures(features) || defaultExtent;
+
+ if (padding) {
+ view.fit(extent, { padding });
+ } else {
+ view.fit(extent);
+ }
+};
+
+const extractSridFromWkt = (wkt: string) => {
+ const extract: { geom: string; srid: string | null } = {
+ geom: wkt,
+ srid: null,
+ };
+ if (wkt.startsWith('SRID=')) {
+ // WKT with SRID, strip it
+ const srid = wkt.match(/SRID=(\d+);/);
+ if (srid) {
+ extract.srid = `EPSG:${srid[1]}`;
+ extract.geom = wkt.replace(/SRID=\d+;/, '');
+ }
+ }
+ return extract;
+};
+
+export const wkbToGeoJSON = (wkb: string) => {
+ const format = new WKB();
+ const feature = format.readFeature(wkb, {
+ featureProjection: 'EPSG:3857',
+ });
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
+
+export const wktToGeoJSON = (wkt: string) => {
+ const format = new WKT();
+ const wktOpts: ReadOptions = {
+ featureProjection: 'EPSG:3857',
+ dataProjection: 'EPSG:4326', // default to WGS84
+ };
+ const extract = extractSridFromWkt(wkt);
+ const cleanedWkt = extract.geom;
+ if (extract.srid) {
+ wktOpts.dataProjection = extract.srid;
+ }
+ const feature = format.readFeature(cleanedWkt, wktOpts);
+ return new GeoJSON().writeFeatureObject(feature, {
+ featureProjection: 'EPSG:3857',
+ });
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Duplicated geometry parsing logic</b></div>
<div id="fix">
The `wkbToGeoJSON` (lines 92-100) and `wktToGeoJSON` (lines 102-117) functions contain nearly identical structure: create format instance, read feature, write GeoJSON. This duplication (8 vs 16 lines) creates maintenance risk where changes to one may need mirroring in the other. Extract shared logic into a private helper.
</div>
</div>
<small><i>Code Review Run #80d42d</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts:
##########
@@ -232,37 +306,165 @@ export const stripGeomColumnFromLabelMap = (
export const stripGeomColumnFromQueryData = (
queryData: any,
geomColumn: string,
+ geomFormat: GeometryFormat,
) => {
const queryDataClone = {
...structuredClone(queryData),
- ...stripGeomFromColnamesAndTypes(queryData, geomColumn),
+ ...stripGeomFromColnamesAndTypes(queryData, geomColumn, geomFormat),
};
if (queryDataClone.label_map) {
queryDataClone.label_map = stripGeomColumnFromLabelMap(
queryData.label_map,
geomColumn,
+ geomFormat,
);
}
return queryDataClone;
};
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const formatSeriesName = (
+ name: DataRecordValue | undefined,
+ {
+ numberFormatter,
+ timeFormatter,
+ coltype,
+ }: {
+ numberFormatter?: ValueFormatter;
+ timeFormatter?: TimeFormatter;
+ coltype?: GenericDataType;
+ } = {},
+) => {
+ if (name === undefined || name === null) {
+ return NULL_STRING;
+ }
+ if (typeof name === 'boolean' || typeof name === 'bigint') {
+ return name.toString();
+ }
+ if (name instanceof Date || coltype === GenericDataType.Temporal) {
+ const normalizedName =
+ typeof name === 'string' ? normalizeTimestamp(name) : name;
+ const d =
+ normalizedName instanceof Date
+ ? normalizedName
+ : new Date(normalizedName);
+
+ return timeFormatter ? timeFormatter(d) : d.toISOString();
+ }
+ if (typeof name === 'number') {
+ return numberFormatter ? numberFormatter(name) : name.toString();
+ }
+ return name;
+};
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const extractGroupbyLabel = ({
+ datum = {},
+ groupby,
+ numberFormatter,
+ timeFormatter,
+ coltypeMapping = {},
+}: {
+ datum?: DataRecord;
+ groupby?: string[] | null;
+ numberFormatter?: NumberFormatter;
+ timeFormatter?: TimeFormatter;
+ coltypeMapping?: Record<string, GenericDataType>;
+}) =>
+ ensureIsArray(groupby)
+ .map(val =>
+ formatSeriesName(datum[val], {
+ numberFormatter,
+ timeFormatter,
+ ...(coltypeMapping[val] && { coltype: coltypeMapping[val] }),
+ }),
+ )
+ .join(', ');
+
+// copy of
+// superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+export const getColtypesMapping = ({
+ coltypes = [],
+ colnames = [],
+}: Pick<ChartDataResponseResult, 'coltypes' | 'colnames'>): Record<
+ string,
+ GenericDataType
+> =>
+ colnames.reduce(
+ (accumulator, item, index) => ({ ...accumulator, [item]: coltypes[index] }),
+ {},
+ );
+
+/**
+ * Reserve label colors for the chart.
+ *
+ * We call the CategoricalColorNamespace singleton to reserve
+ * label colors for the chart. This is necessary to ensure that
+ * we do not run into color collisions when rendering multiple
+ * charts in the same cartodiagram.
+ *
+ * TODO This only works in the context of a dashboard,
+ * since only there, the CategoricalColorNamespace singleton is being used.
+ * In the explore view, label colors cannot be reserved without changing
+ * the overall color handling in superset.
+ *
+ * @param formData The formdata of the underlying chart
+ * @param dataByLocation The data grouped by location
+ * @param strippedQueryData The query data without the geom column
+ * @param sliceId The id of the chart slice
+ */
+export const reserveLabelColors = (
+ formData: Record<string, any>,
+ dataByLocation: LocationConfigMapping,
+ strippedQueryData: any,
+ sliceId: number,
+) => {
+ // Call color singleton to reserve label colors
+ // get needed control values from underlying chart config
+ const { colorScheme = '', groupby = [], dateFormat } = formData;
+ const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
+ const groupbyLabels = groupby.map(getColumnLabel);
+ Object.keys(dataByLocation).forEach(location => {
+ const coltypeMapping = getColtypesMapping({
+ ...strippedQueryData,
+ data: dataByLocation[location],
+ });
+ dataByLocation[location].forEach(datum => {
+ const name = extractGroupbyLabel({
+ datum,
+ groupby: groupbyLabels,
+ coltypeMapping,
+ timeFormatter: getTimeFormatter(dateFormat),
+ });
+
+ colorFn(name, sliceId);
+ });
+ });
+};
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>TypeScript: Avoid `any` types</b></div>
<div id="fix">
Parameter `strippedQueryData` is typed as `any`, violating TypeScript best practices. Use `ChartDataResponseResult` for consistency and safety.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -418,7 +418,7 @@
export const reserveLabelColors = (
formData: Record<string, any>,
dataByLocation: LocationConfigMapping,
strippedQueryData: any,
sliceId: number,
) => {
```
</div>
</details>
</div>
<details>
<summary><b>Citations</b></summary>
<ul>
<li>
Rule Violated: <a href="https://github.com/apache/superset/blob/d42dce1/.cursor/rules/dev-standard.mdc#L16">dev-standard.mdc:16</a>
</li>
</ul>
</details>
<div id="suggestion">
<div id="issue"><b>TypeScript: Missing return type</b></div>
<div id="fix">
Function `reserveLabelColors` lacks an explicit return type annotation. Add `: void` since it doesn't return a value.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
--- superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
+++ superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts
@@ -418,7 +418,7 @@
export const reserveLabelColors = (
formData: Record<string, any>,
dataByLocation: LocationConfigMapping,
strippedQueryData: any,
sliceId: number,
- ) => {
+ ): void => {
// Call color singleton to reserve label colors
// get needed control values from underlying chart config
const { colorScheme = '', groupby = [], dateFormat } = formData;
```
</div>
</details>
</div>
<small><i>Code Review Run #96ad42</i></small>
</div><div>
<div id="suggestion">
<div id="issue"><b>Missing test coverage for reserveLabelColors</b></div>
<div id="fix">
The new `reserveLabelColors` function (lines 412-439) has no corresponding tests in transformPropsUtil.test.ts. Without tests, regression risk increases if the color reservation logic changes.
</div>
</div>
<small><i>Code Review Run #80d42d</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -196,6 +307,39 @@ export const OlChartMap = (props: OlChartMapProps) => {
addLayers(layerConfigs);
}, [olMap, layerConfigs]);
+ useEffect(() => {
+ const { extentMode, fixedMaxX, fixedMaxY, fixedMinX, fixedMinY } =
+ currentMapMaxExtent;
+ const view = olMap.getView();
+ const center = view.getCenter();
+ const zoom = view.getZoom();
+ let extent;
+
+ if (
+ extentMode === 'CUSTOM' &&
+ fixedMaxX !== undefined &&
+ fixedMaxY !== undefined &&
+ fixedMinX !== undefined &&
+ fixedMinY !== undefined
+ ) {
+ extent = transformExtent(
+ [fixedMinX, fixedMinY, fixedMaxX, fixedMaxY],
+ 'EPSG:4326',
+ 'EPSG:3857',
+ );
+ }
+
+ olMap.setView(
+ new View({
+ center,
+ zoom,
+ extent,
+ maxZoom: view.getMaxZoom(),
+ minZoom: view.getMinZoom(),
+ }),
+ );
+ }, [olMap, currentMapMaxExtent]);
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Semantic duplication of extent logic</b></div>
<div id="fix">
This new useEffect duplicates the extent transformation and view update logic from the initial effect (lines 215-272). The initial effect runs once (empty deps), the new effect runs on `currentMapMaxExtent` changes. Both do: get extent from config, transform from EPSG:4326 to EPSG:3857, call `olMap.setView()`.
</div>
</div>
<small><i>Code Review Run #80d42d</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/plugin/controlPanel.ts:
##########
@@ -101,16 +128,87 @@ const config: ControlPanelConfig = {
type: 'MapViewControl',
renderTrigger: true,
description: t(
- 'The extent of the map on application start. FIT DATA automatically sets the extent so that all data points are included in the viewport. CUSTOM allows users to define the extent manually.',
+ 'The map center on application start. FIT DATA automatically sets the center so that all data points are included in the viewport. CUSTOM allows users to define the center manually.',
),
- label: t('Extent'),
+ label: t('Initial Map Center'),
dontRefreshOnChange: true,
default: {
mode: 'FIT_DATA',
},
},
},
],
+ [
+ {
+ name: 'map_extent_padding',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Map Padding'),
+ description: t(
+ 'Set the map extent padding. The selected value is applied to all edges of the map.',
+ ),
+ default: 30,
+ min: 0,
+ max: 100,
+ step: 10,
+ visibility: ({
+ controls,
+ }: {
+ controls: ControlPanelsContainerProps['controls'] & {
+ map_view?: { value?: Partial<MapViewConfigs> };
+ };
+ }) => Boolean(controls?.map_view?.value?.mode === 'FIT_DATA'),
+ },
+ },
+ ],
+ [
+ {
+ name: 'min_zoom',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Min Zoom'),
+ description: t('The minimal zoom of the map'),
+ default: MIN_ZOOM_LEVEL,
+ min: MIN_ZOOM_LEVEL,
+ max: MAX_ZOOM_LEVEL,
+ step: 1,
+ },
+ },
+ ],
+ [
+ {
+ name: 'max_zoom',
+ config: {
+ type: 'SliderControl',
+ renderTrigger: true,
+ label: t('Max Zoom'),
+ description: t('The maximal zoom of the map'),
+ default: MAX_ZOOM_LEVEL,
+ min: MIN_ZOOM_LEVEL,
+ max: MAX_ZOOM_LEVEL,
+ step: 1,
+ },
+ },
+ ],
+ [
+ {
+ name: 'map_max_extent',
+ config: {
+ type: MapMaxExtentViewControl,
+ renderTrigger: true,
+ description: t(
+ "The constrained extent of the map on application start. NONE won't set any constrained extent. CUSTOM allows users to define the extent manually based on the current shown map extent.",
+ ),
+ label: t('Max. Extent'),
+ dontRefreshOnChange: true,
+ default: {
+ extentMode: 'NONE',
+ },
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Incomplete default value</b></div>
<div id="fix">
The `map_max_extent` default only sets `extentMode: 'NONE'` but omits required fields `maxX`, `maxY`, `minX`, `minY` defined in `MapMaxExtentConfigs` type. When the `MapMaxExtentViewControl` component calls `onButtonClick`, it copies these undefined values to `fixedMaxX`, `fixedMaxY`, etc., causing incorrect behavior.
</div>
</div>
<small><i>Code Review Run #80d42d</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4399781686
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/geoStylerUtil.ts:
##########
@@ -0,0 +1,183 @@
+/**
+ * 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 { FeatureCollection, GeoJsonGeometryTypes } from 'geojson';
+import { VectorData } from 'geostyler-data';
+import { GeoStylerContextInterface, GeoStylerLocale, locale } from 'geostyler';
+
+import { Style, Symbolizer } from 'geostyler-style';
+import { ColTypeMapping } from './types';
+import { SupersetTheme } from '@apache-superset/core/theme';
+
+/**
+ * Map Superset column type to GeoStyler column type.
+ * @param colType The Superset columntype
+ * @returns The GeoStyler column type.
+ */
+export const colTypeToGeoStylerType = (colType: string) => {
+ // TODO add missing types
+ switch (colType) {
+ case 'LONGINTEGER':
+ case 'INTEGER':
+ return 'integer';
+ case 'STRING':
+ return 'string';
+ case 'DATETIME':
+ case 'DATE':
+ case 'FLOAT':
+ case 'DECIMAL':
+ return 'number';
+ default:
+ return colType;
+ }
+};
+
+/**
+ * Map Superset column types to GeoStyler data.
+ * @param colTypes The superset column types.
+ * @returns A geotyler-data object.
+ */
+export const colTypesToGeoStylerData = (
+ colTypes: ColTypeMapping,
+ dataFeatureCollection: FeatureCollection = {
+ type: 'FeatureCollection',
+ features: [],
+ },
+) => {
+ const data: VectorData = {
+ schema: {
+ type: 'object',
+ properties: Object.keys(colTypes).reduce(
+ (prev, cur) => ({
+ ...prev,
+ [cur]: {
+ type: colTypeToGeoStylerType(colTypes[cur]),
+ },
+ }),
+ {},
+ ),
+ },
+ exampleFeatures: dataFeatureCollection,
+ };
+ return data;
+};
+
+/**
+ * Create a GeoStylerContext.
+ *
+ * Sets the locales, GsData, and enables and disables certain features
+ * depending on given data and their geometries.
+ *
+ * @param gsLocale The locales of the active language.
+ * @param data The GeoStyler Data.
+ * @param geomTypes List of distinct geometry types.
+ * @returns The GeoStylerContext.
+ */
+export const createGeoStylerContext = (
+ gsLocale: GeoStylerLocale,
+ data: VectorData | undefined,
+ composition: GeoStylerContextInterface['composition'],
+) => {
+ const context: GeoStylerContextInterface = {
+ locale: gsLocale,
+ composition: composition ?? {},
+ };
+
+ if (data) {
+ context.data = data;
+ }
+
+ if (!context.composition!.Rules) {
+ context.composition!.Rules = {};
+ }
+ context.composition!.Rules.disableClassification =
Review Comment:
This unconditionally overwrites `composition.Rules.disableClassification` with the data-derived value, so an operator who sets `MAP_GEOSTYLER_COMPOSITION = {"Rules": {"disableClassification": True}}` gets classification re-enabled as soon as any WFS sample features load. It also mutates the object passed in as `composition`. Should an explicit `true` from the configuration be preserved (and the composition copied rather than mutated)?
##########
superset-frontend/src/explore/components/controls/LayerConfigsControl/FlatLayerTree.tsx:
##########
@@ -81,7 +104,85 @@ export const StyledLayerTreeItem = styled(LayerTreeItem)`
`}
`;
-// forwardRef is needed here in order for emotion and antd tree to work properly
+interface DraggableLayerTreeItemProps {
+ layerConf: LayerConfWithId;
+ index: number;
+ draggable?: boolean;
+ onEditLayer: (layerConf: LayerConfWithId, idx: number) => void;
+ onRemoveLayer: (idx: number) => void;
+ onMoveLayerByIndex: (dragIndex: number, hoverIndex: number) => void;
+}
+
+const DraggableLayerTreeItem: FC<DraggableLayerTreeItemProps> = ({
+ layerConf,
+ index,
+ draggable = false,
+ onEditLayer,
+ onRemoveLayer,
+ onMoveLayerByIndex,
+}) => {
+ const ref = useRef<HTMLDivElement>(null);
+
+ const [, drag] = useDrag<DragItem, void, unknown>({
Review Comment:
`useDrag`/`useDrop` now require a react-dnd provider, but the existing `LayerConfigsControl.test.tsx` `setup()` renders without `{ useDnd: true }`, so any test that renders a non-empty layer list hits "Expected drag drop context". Its reorder test also still looks up `.ant-tree-treenode` (line ~258), which this rewrite no longer renders. Could the harness be updated to render with the DnD provider and the reorder test rewritten to drive the new drag/drop boundary and assert the emitted layer order?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -196,6 +325,10 @@ export const OlChartMap = (props: OlChartMapProps) => {
addLayers(layerConfigs);
}, [olMap, layerConfigs]);
+ useEffect(() => {
+ applyMapExtentView(olMap, currentMapMaxExtent);
Review Comment:
`applyMapExtentView` calls `olMap.setView(new View(...))`, but the `change:resolution` listener in the chart-size effect further down is bound to `olMap.getView()` at the time that effect ran, and its deps (`olMap`, `setControlValue`, `chartSize`) don't change when the extent does. After toggling Max. Extent (NONE/CUSTOM) and then zooming, the old view fires the events, so `chart_size.configs.zoom` stops updating and later size edits use a stale reference zoom. Could the listener be re-bound when the view is replaced (e.g. include `currentMapMaxExtent` in that effect's deps)?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
Unlike the WMS/WFS/XYZ constructors above, this branch passes `attribution` to the source without `escapeAttribution()`. OpenLayers renders attributions through `innerHTML`, so a chart saved through the API with `{"type":"DATA","attribution":"<img src=x onerror=...>"}` (the UI selector for DATA being disabled doesn't stop API-supplied `layer_configs`) would inject markup for every viewer wherever CSP allows inline handlers. Should this use `escapeAttribution(attribution)` like the other layer types?
```suggestion
attributions: escapeAttribution(attribution),
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4401903823
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
`createDataLayer` passes the creator-supplied `attribution` straight to `VectorSource`, while the WMS, XYZ and WFS paths run it through `escapeAttribution` because OpenLayers renders attributions via `innerHTML`. A saved chart whose `layer_configs` contains `{"type":"DATA","attribution":"<img src=x onerror=...>"}` would execute script in any viewer's browser when the attribution control renders (the renderer picks DATA purely from `type`, regardless of whether the Explore UI offers it). Should this use `escapeAttribution(attribution)` like the other layer types?
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -196,6 +325,10 @@ export const OlChartMap = (props: OlChartMapProps) => {
addLayers(layerConfigs);
}, [olMap, layerConfigs]);
+ useEffect(() => {
+ applyMapExtentView(olMap, currentMapMaxExtent);
Review Comment:
This replaces the map's `View` (via `olMap.setView(...)`) whenever the max extent changes, but the zoom-sync effect further down (the `view.on('change:resolution', ...)` subscription, deps `[olMap, setControlValue, chartSize]`) bound to `olMap.getView()` once and is not re-run for a new view. After picking CUSTOM or clicking "Use current extent", zooming no longer reaches `onViewChange`, so `chart_size.configs.zoom` (and the "Current Zoom" display / zoom-relative size editing) stays stale until something else retriggers this effect. Should the view (or `currentMapMaxExtent`) be part of this effect's dependencies?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422817114
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/MapMaxExtentControl/MapMaxExtentViewControl.tsx:
##########
@@ -0,0 +1,155 @@
+/**
+ * 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 { ControlHeader } from '@superset-ui/chart-controls';
+import { t } from '@apache-superset/core/translation';
+import { css, styled } from '@apache-superset/core/theme';
+import { Button, Radio, RadioChangeEvent } from '@superset-ui/core/components';
+import { FC } from 'react';
+import { mix } from 'polished';
+import {
+ MapMaxExtentConfigs,
+ MapMaxExtentConfigsControlProps,
+} from '../../types';
+import MapMaxExtentTag from './MapMaxExtentTag';
+
+export const StyledMaxExtentButton = styled(Button)`
+ ${({ theme }) => css`
+ flex: 1;
+ margin-right: 4px;
+ line-height: 1.5715;
+ border-radius: ${theme.borderRadius}px;
+ background-color: ${theme.colorPrimaryBg};
+ color: ${theme.colorPrimaryText};
+ font-size: ${theme.fontSizeSM}px;
+ font-weight: ${theme.fontWeightStrong};
+ text-transform: uppercase;
+ min-width: ${theme.sizeUnit * 36}px;
+ min-height: ${theme.padding}px;
+ box-shadow: none;
+ border-width: 0px;
+ border-style: none;
+ border-color: transparent;
+ margin-left: 9px;
+ margin-top: 10px;
+ &:hover {
+ background-color: ${mix(0.1, theme.colorPrimary, theme.colorPrimaryBg)};
+ color: ${theme.colorPrimaryText};
+ }
+ `}
+`;
+
+export const StyledMaxExtentTag = styled(MapMaxExtentTag)`
+ ${() => css`
+ margin-left: 9px;
+ `}
+`;
+
+export const MapMaxExtentViewControl: FC<MapMaxExtentConfigsControlProps> = ({
+ value,
+ onChange = () => {},
+ name,
+ label,
+ description,
+ renderTrigger,
+ hovered,
+ validationErrors,
+}) => {
+ const isCustomMode = () => value?.extentMode === 'CUSTOM';
+
+ const onModeChange = (e: RadioChangeEvent) => {
+ if (!value) return;
+
+ const newMode = e.target.value;
+ let changedValue: MapMaxExtentConfigs = {
+ ...value,
+ extentMode: newMode,
+ };
+ if (newMode === 'NONE') {
+ changedValue = {
+ ...value,
+ fixedMaxX: undefined,
+ fixedMaxY: undefined,
+ fixedMinX: undefined,
+ fixedMinY: undefined,
+ extentMode: newMode,
+ };
+ }
+
+ onChange(changedValue);
+ };
+
+ const onButtonClick = () => {
Review Comment:
I added tests accordingly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422811095
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx:
##########
@@ -20,21 +20,67 @@ import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import Point from 'ol/geom/Point';
-import { View } from 'ol';
+import { Map, View } from 'ol';
import BaseEvent from 'ol/events/Event';
+import GeoJSON from 'ol/format/GeoJSON';
import { unByKey } from 'ol/Observable';
-import { toLonLat } from 'ol/proj';
+import { toLonLat, transformExtent } from 'ol/proj';
import { debounce } from 'lodash-es';
-import { fitMapToCharts } from '../util/mapUtil';
+import { fitMapToData } from '../util/mapUtil';
import { ChartLayer } from './ChartLayer';
import { createLayer } from '../util/layerUtil';
import {
ChartConfig,
LayerConf,
+ MapMaxExtentConfigs,
MapViewConfigs,
OlChartMapProps,
} from '../types';
import { isChartConfigEqual } from '../util/chartUtil';
+import {
+ getExtentFromFeatures,
+ getMapExtentPadding,
+} from '../util/geometryUtil';
+
+/**
+ * Computes a transformed extent from a MapMaxExtentConfigs (if CUSTOM mode)
+ * and applies it by setting a new view on the map.
+ */
+const applyMapExtentView = (
+ olMap: Map,
+ mapMaxExtentConf: MapMaxExtentConfigs,
+) => {
+ const { extentMode, fixedMaxX, fixedMaxY, fixedMinX, fixedMinY } =
+ mapMaxExtentConf;
+ const view = olMap.getView();
+ const center = view.getCenter();
+ const zoom = view.getZoom();
+ let extent;
+
+ if (
+ extentMode === 'CUSTOM' &&
+ fixedMaxX !== undefined &&
+ fixedMaxY !== undefined &&
+ fixedMinX !== undefined &&
+ fixedMinY !== undefined
+ ) {
+ extent = transformExtent(
+ [fixedMinX, fixedMinY, fixedMaxX, fixedMaxY],
+ 'EPSG:4326',
+ 'EPSG:3857',
+ );
+ }
+
+ olMap.setView(
Review Comment:
Yes, that will likely lead to inconsistencies. I adjusted so the we now use the eventlisteners of the map instance, which will not be recreated. So recreating the view does not affect the listeners any more.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] feat(cartodiagram): fix for v6 + additional controls [superset]
Posted by "jansule (via GitHub)" <gi...@apache.org>.
jansule commented on code in PR #39760:
URL: https://github.com/apache/superset/pull/39760#discussion_r4422798411
##########
superset-frontend/plugins/plugin-chart-cartodiagram/src/util/layerUtil.tsx:
##########
@@ -158,6 +173,35 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
});
};
+/**
+ * Create a DATA layer.
+ *
+ * @param dataLayerConf The layer configuration
+ *
+ * @returns The created DATA layer
+ */
+export const createDataLayer = async (dataLayerConf: DataLayerConf) => {
+ const { attribution, style } = dataLayerConf;
+ const dataSource = new VectorSource({
+ attributions: attribution,
Review Comment:
Good catch! I adjusted this and attributions for dataLayers will now also be escaped.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org