
CARTO for React
Build compelling spatial apps using CARTO, React and deck.gl.
Layers and Widgets
On this guide we’re going to explain how to add a new page (view) showing a layer from a CARTO dataset stored in your account. We will also show how you can add widgets that are integrated with your layer.
Uploading the sample dataset to your CARTO account
Go to your dashboard and click on New Dataset
. In the Add new dataset
dialog select the URL
option within the Cloud Files
section.
Copy the following URL and click on Submit
:
https://public.carto.com/api/v2/sql?filename=retail_stores&q=select+*+from+public.retail_stores&format=shp
If you want to access the dataset from the application, you can make it public or you can create an API KEY and keep it private. In the latter case, you will need to introduce the generated API key in the initial state slice as explained in the Getting Started guide.
Creating a view
Now we’re going to create a view called Stores
that will be accesible in the /stores
path.
The easiest way to create a new view in the application is to use the code generator. You need to enter the following command:
|
|
and select these options:
|
|
The code generator will perform three different actions:
-
Modify the route settings in the application to add the
/stores
path. -
Add the view to the Header
-
Create a new file for the view with the following filename:
src/components/views/Stores.js
Now you’re ready to start the local development server using the following command:
|
|
You should see the map component with a Hello World
text on the left sidebar and a link to the new view in the top navigation bar.
Creating a source
A source is a key piece in a CARTO for React application. Both layers and widgets depend on sources. A source exports a plain object with a certain structure that will be understood by the CARTO for React library to feed layers or widgets using the CARTO SQL and/or Maps APIs.
The different sources are stored inside the /data/sources
folder. The goal of the /data
folder is to easily differentiate the parts of the application that have a communication with external services, like CARTO APIs, your own backend, GeoJSON files…
To create a source, the easiest way is again to use the code generator:
|
|
In this case, we’re creating a new source that can feed a layers & widgets with the dataset we uploaded before. It is going to be called StoresSource
to follow a convention. You need to choose the following options:
|
|
The code generator will generated a new file named src/data/sources/storesSource.js
that will contains the following basic structure:
|
|
Creating a layer
Once we have defined the source, we can add now the layer the map.
We create the layer by using the code generator:
|
|
We select the following options:
|
|
The code generator will perform two different actions:
-
Create a new layer in a file named
src/components/layers/StoresLayer.js
, -
Attach the layer to the view in the
src/components/views/Stores.js
file.
If you reload the page, you will see the new layer in the map.
The code that has been added to the view to attach the layer is the following:
|
|
The dispatch
function is used to dispatch an action to the Redux store. This is how this works:
-
The view dispatches the new source to the store.
-
The view dispatches the new layer to the store.
-
The Map Component is re-rendered since the store has changed.
-
The Map Component get all the layers in the store and draw them.
This is how reactive programming works: we can add the layer from any place in the application just by dispatching the right action.
Now let’s take a look at src/components/layers/StoresLayer.js
:
|
|
This is the summary:
-
To create a layer you need to:
- Define a function that returns a deck.gl layer.
- Exports the ID as a constant.
-
The layer must be added to the application layers array.
-
You need to add the source and the layer to the store.
-
You need to add
cartoLayerProps
if required.
Adding widgets
Now we are ready to create a Formula and a Category Widget inside the View.
The first thing you need to do is to add the following imports at the top of the src/components/views/Stores.js
file:
|
|
Then, in the same file, you need to replace the Hello World
text with:
|
|
Understanding how the pieces work together
There are two main elements in the store: the source and the viewport. When we change these elements, the following actions are triggered:
-
The layer is filtered when the source changes.
-
The widget is re-rendered when the source or viewport changes.
-
Any time we change the map extent (pan or zoom), the viewport changes and all the widgets (with the
viewportFilter
prop) are refreshed. -
Any time a widget applies a filter (for example clicking on a widget category), the filter is dispatched to the store. When we add a filter, we are changing the source, so all the components depending on the source are updated: the widgets are re-rendered and the layers are filtered. The map applies the filters using the
DataFilterExtension
from deck.gl.