https://cartojavi1.netlify.app/
Demo application with Deck.gl and Carto Layers
Run nx serve cartojavi1
for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.
- Deck.gl: Map component
- React, redux, redux-toolkit: Layer styles configuration and layer rendering are on different branches of the react tree. While we could do it without it, redux provides us with convenient helpers.
- Carto Layers: Data from Carto, initial configuration is on src/App/layer/store/initialLayerState.ts
- Mui and Styled Components: Ready to use components and css-in-js library
- Nx standalone react template: Alternative to CRA with vite and vitest, to quickstart the project
### Icon rendering
Icons render pixelated. The reason for that is that Cartolayer is replacing loadOptions and we can't provide the options for a better upscale algorithm. See it on GitHub
I would love to create a PR to fix this but I run out of time for this technical test.
There are a lot of functionalities I didn't implement:
- Change from circles/icons in point layers
- Support for non thematic styles for polygon layers
- Themes based on lineColor instead of fillColor
- Thematic rendering of point layers
- Themes for the non tileset layers (I think we would need to query the statistics separately)
- Display legend for layers with thematic rendering
I did a custom representation of symbols to preview them in the layer configuration widget.
While it works, I feel that deck.gl should probably provide a simpler option. It would be a good idea to investigate this further and replace the thumbnails if deck.gl provides them already.
I was happy discovering that deck.gl is diffing the layers and not recreating all the map when the layers change. While I started memoizing the layers object and it's properties, I finally refactored these out.
See Should I be Creating New Layers on Every Render? for more information.
To make deck.gl aware of the changes in accessor functions (getFillColor, getLineColor, getIcon...) I had to provide updateTriggers
I was not that happy when saw the bundle size. To improve the experience I did several things:
- Added a spinner to index.html
- Extracted the map to another chunk and load it async
- Made the Map lazy and displayed a Skeleton while it loads
- Copy MAP_TYPES enum to my own code to prevent other references to deck.gl
- Removed moment.js timezones from the bundle
Most of the weight of the application is removed from the main bundle. And the UX improves because parts of the application load faster.
The size of the map chunk is still very high. There are parts of deck.gl and its dependencies we are not using and there may be a way not to load them. It's worth investigating it in the future.
The most important cases are unit tested. More tests would be helpful, please see coverage result to identify the less tested spots with npm run coverage
.