feat(chart): support icons and text in the `deck.gl Geojson` visualization
User description
SUMMARY
The deck.gl Geojson visualization allows users to visualize point, line, and polygon geometries on maps using the GeoJSON specification. Currently, users can only render points as circles, however, deck.gl's GeoJsonLayer supports rendering points as circles, icons, and/or text according to the GeoJsonLayer documentation.
This pull request extends the existing functionality, allowing users to additionally render points as labels and/or icons.
Approach
To support both basic and advanced use cases, we implemented two configuration flows for adding labels and/or icons:
- "Basic" flow: This is the common case where users just want to show labels and/or icons with little customization. The user can customize the labels and/or icons using only UI controls.
- "Advanced" flow: This is the niche case where users need more per-point customization and/or would like to set options not exposed in the basic flow. The user does this by typing in a JavaScript function that returns a configuration object aligned with deck.gl's documentation.
Rationale
deck.gl's GeoJsonLayer supports many options for labels and icons, but exposing all of them in the UI would lead to a cluttered experience. The approach taken here avoids cluttering the UI while flexibly supporting both basic and advanced use cases.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Text/Label Support Demo
https://github.com/user-attachments/assets/f99802ef-cdb2-47da-a367-3e978f362cb8
Icon Support Demo
https://github.com/user-attachments/assets/86ece538-01cf-4d07-9d23-3b7dbda5b83a
TESTING INSTRUCTIONS
-
Create a GeoJSON dataset.
Click here for the sample dataset from the demo
You can use this query to create a dataset in Superset using the SQL Lab interface:SELECT '{ "type": "FeatureCollection", "name": "Top 10 Most Populous US States (2024 Estimates)", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-121.468926, 38.555605] }, "properties": { "longName": "California", "shortName": "CA" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-97.7431, 30.2672] }, "properties": { "longName": "Texas", "shortName": "TX" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-84.27277, 30.4518] }, "properties": { "longName": "Florida", "shortName": "FL" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-73.781339, 42.659829] }, "properties": { "longName": "New York", "shortName": "NY" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-76.875613, 40.269789] }, "properties": { "longName": "Pennsylvania", "shortName": "PA" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-89.650373, 39.78325] }, "properties": { "longName": "Illinois", "shortName": "IL" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-83.000647, 39.962245] }, "properties": { "longName": "Ohio", "shortName": "OH" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-84.39, 33.76] }, "properties": { "longName": "Georgia", "shortName": "GA" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-78.638, 35.771] }, "properties": { "longName": "North Carolina", "shortName": "NC" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-84.5467, 42.7335] }, "properties": { "longName": "Michigan", "shortName": "MI" } } ] }' as JSON -
Create a
deck.gl Geojsonchart/visualization using the dataset created in step 1. -
Under the
Querysection, fill the requiredGeoJson Columnfield (if using the sample dataset, selectJSON). -
Under the
GeoJson Settingssection, configure label and/or icon settings as was shown in the demo videos.
Notes
- For JavaScript mode, ensure that the
ENABLE_JAVASCRIPT_CONTROLSfeature flag is enabled. - For icons, image URLs must conform to your configured CSP settings. For the demo, I added
https://static.thenounproject.comto theconnect-srcdirective in the CSP found insuperset/config.py. If you simply want to test icons without modifying the CSP, you can try this sample image URL (it is hosted on cartocdn, which is included in the default CSP).
ADDITIONAL INFORMATION
- [x] Has associated issue: Fixes #34621
- [x] Required feature flags:
ENABLE_JAVASCRIPT_CONTROLS - [x] Changes UI
- [ ] Includes DB Migration (follow approval process in SIP-59)
- [ ] 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
CodeAnt-AI Description
Add optional icon and label rendering to GeoJSON map layer
What Changed
- Users can enable point labels and/or icons in the GeoJSON deck.gl chart via new checkboxes in the control panel; sizes, colors, and units are configurable and JavaScript-based generators are available when the JavaScript controls feature flag is on
- The layer now renders labels and icons on the map when enabled, using either the simple form controls or a user-provided JS generator; missing icon URLs or undefined colors are handled safely with sensible defaults so rendering no longer throws
- Added unit tests that validate extraction of label/icon options from both form data and JS outputs
Impact
β
Labels and icons on GeoJSON points
β
Fewer map rendering errors when color or icon inputs are missing
β
Easier per-point customization using optional JavaScript generators
π‘ Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
@codeant-ai ask: Your question here
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
@codeant-ai ask: Can you suggest a safer alternative to storing this secret?
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
@codeant-ai: Your feedback here
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
@codeant-ai: Do not flag unused imports.
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
@codeant-ai: review
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Code Review Agent Run #b486f3
Actionable Suggestions - 0
Review Details
-
Files reviewed - 5 Β· Commit Range:
f187f7a..c79c175- superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.test.ts
- superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.tsx
- superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/controlPanel.ts
- superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.tsx
- superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.ts
-
Files skipped - 0
-
Tools
- Eslint (Linter) - βοΈ Successful
- Whispers (Secret Scanner) - βοΈ Successful
- Detect-secrets (Secret Scanner) - βοΈ Successful
Bito Usage Guide
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 documentation for additional commands.
Configuration
This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at [email protected].
Documentation & Help
Waouw !! Great !! Congratulation !
+1 !!!
@DamianPendrak mind taking a look since it's deck.gl
πͺ Showtime deployed environment on GHA for c79c175
β’ Environment: http://34.213.178.163:8080 (admin/admin) β’ Lifetime: 48h auto-cleanup β’ Updates: New commits create fresh environments automatically
This looks SO cool!
The only thing I'd like to request right now (to prevent XSS attacks) is to put the Javascript forms and the checkboxes to reveal them behind the
ENABLE_JAVASCRIPT_CONTROLSfeature flag by addingisFeatureEnabled(FeatureFlag.ENABLE_JAVASCRIPT_CONTROLS)where relevant. A lot of orgs have that flag turned off for (very good) safety reasons.Otherwise, this is complete awesomeness!
@rusackas Thank you, and valid security concern! I made this change in 740b3c2f68daaa2004ff7f08189b108d5f754f5c.
Thanks for adding all the feature-flag checks. I guess what I'm wondering now, looking at it again, is if we overcorrected here.
Should parts of this work without the Javascript Controls feature flag turned on? I.e. Should I still be able to pick an icon URL, adjust size, or maybe use some of the other inputs (color, etc.)? If some of these new features work without Javascript inptus, that would be nice to leave those features enabled. I was under the impression that the JS inputs just add even more flexibility, and were somewhat optional. Correct me if I'm misunderstanding :)
Would love to be able to use as much of this as possible in deployments where JS controls are disabled (e.g. Preset, and... probably lots of others)
Otherwise, this is looking fantastic!
@rusackas
Should parts of this work without the Javascript Controls feature flag turned on? I.e. Should I still be able to pick an icon URL, adjust size, or maybe use some of the other inputs (color, etc.)? If some of these new features work without Javascript inptus, that would be nice to leave those features enabled. I was under the impression that the JS inputs just add even more flexibility, and were somewhat optional. Correct me if I'm misunderstanding :)
You are correct on everything you said here -- the JS inputs just adds more flexibility.
This behavior is still maintained after 740b3c2f68daaa2004ff7f08189b108d5f754f5c; it might be confusing because I was accounting for a potential edge case if I only changed the JS fields visibility logic. Scenario: a user initially had the JS feature flag turned on, then enabled JS mode on the visualization, then turned the JS feature flag off. If this happens, then all the customization controls would be hidden (the non-JS fields would be hidden because JS mode is enabled and the JS fields would be hidden because the feature flag is turned off). To avoid this, I show the non-JS fields if JS mode is disabled OR the feature flag is turned off. For example, here is the label color control:
Hopefully it makes sense (I can clarify further if needed). In any case, if it is not an edge case we need to consider, I can only change the JS fields visibility logic (which is what I believe you were expecting initially).
Pinging @sadpandajoe (cc @mistercrunch) who was (I believe) looking into Showtime failures. This one seems good to go by looking at the code, but I'd love to kick the tires on it before approving/merging.
Hey @rusackas, any update on getting this pull request merged?
OK, finally testing this now, and running into some questions/feedback:
- It looks like this (pre-existing) control for labels/markdown isn't working right. Not sure if it does outside of this PR:
But it seems like it kind of covers both use cases of this PR? I'm not sure where that feature falls short.
- It looks like you can use Labels OR Icons, but not both, is that accurate? I'm wondering if a "Labels/Icons/None" Select would make more sense, and showing/hiding the relevant controls according to the option selected.
- If you choose settings for the image, and uncheck/re-check the "Image" box, the settings are wiped/lost. Would be nice to persist that.
- The icon size options seem sensible, but i wonder if we should allow a freeform entry there.
- If you have an icon selected/working, then check the "Text" option, it hides the icons and shows the text (awesome!) but does not show the icon again if you un-check "Text"
- Changing the settings for icons doesn't seem to refresh the viz, even though the controls seem to indicate that they should. You have to click Update... so something probably just isn't getting sent to TransformProps quite right or something like that.
I'm most curious about the first point, regarding the markdown controls, and if/how we should get those working, and whether or not that would solve the same purposes of rendering different properties, adding icons, etc.
CodeAnt AI is reviewing your PR.
Nitpicks π
| πΒ No security issues identified |
β‘Β Recommended areas for review
|
CodeAnt AI finished reviewing your PR.
Appreciate the feedback @rusackas!
- It looks like this (pre-existing) control for labels/markdown isn't working right. Not sure if it does outside of this PR: [image]. But it seems like it kind of covers both use cases of this PR? I'm not sure where that feature falls short.
I'm most curious about the first point, regarding the markdown controls, and if/how we should get those working, and whether or not that would solve the same purposes of rendering different properties, adding icons, etc.
I do not think this PR impacted the tooltip functionality. In any case, the tooltip (presumably) only appears on hover. This is different from labels and icons, which remain visible without requiring a hover event.
- It looks like you can use Labels OR Icons, but not both, is that accurate? I'm wondering if a "Labels/Icons/None" Select would make more sense, and showing/hiding the relevant controls according to the option selected.
You can use both labels and icons at the same time:
If you are not using JavaScript though, the icon and label might overlap.
- If you choose settings for the image, and uncheck/re-check the "Image" box, the settings are wiped/lost. Would be nice to persist that.
Agreed! Done in 44bd0d676478196622cd8886b92defa5c744f7dc.
- The icon size options seem sensible, but i wonder if we should allow a freeform entry there.
It is actually free form, but it was not doing the string --> int conversion. Fixed in 8b83a50303e1edf1d4437430b9cf6a1ec648261f.
- If you have an icon selected/working, then check the "Text" option, it hides the icons and shows the text (awesome!) but does not show the icon again if you un-check "Text"
- Changing the settings for icons doesn't seem to refresh the viz, even though the controls seem to indicate that they should. You have to click Update... so something probably just isn't getting sent to TransformProps quite right or something like that.
The second bullet here appears to be due to deck.gl's IconLayer failing to initialize when the icon URL is empty. When this happens, you have to hit "Update chart" to reinitialize the IconLayer. Fixed in f25f57ba3ad908f68744fcecf46c9211511f29c6.
I was not able to reproduce the first bullet here, but I suspect it might be resolved with the same commit.
Hey @rusackas, any update on this pull request?
πͺ Showtime deployed environment on GHA for 44bd0d6
β’ Environment: http://54.188.146.143:8080 (admin/admin) β’ Lifetime: 48h auto-cleanup β’ Updates: New commits create fresh environments automatically
I was just wondering if the terms "Tooltip contents" and "Customize tooltips template" are appropriate and do not cause confusion with the real (non-persistent) tooltips in the field "JavaScript tooltip generator"?
The 2 sections "Tooltip contents"' and "Customize tooltips template" are actually related to the section "Enable labels" and allow for more finely tuned text display, right?
Wouldnβt it be clearer to name them 'Label contents' and 'Customize label template'?
Moreover, I canβt set up a display via these 2 sections. Could you provide an example script?
Thank you for the nice job !