When using the current version (v3 as of March 2017) of Carto.js with maps using Carto's new Builder interface, there are some issues you are likely to run into. Here I run through the common issues and some suggested workarounds.
This is because Carto.js v3 doesn't understand them. Sorry but there is no easy workaround here. In the case of Analysis you could save it as its own layer and use that layer instead.
This is because Builder's legends are a little too fancy for Carto.js v3.
You can make your own legend as a workaround. Here's an example where you can use the CSS in Carto.js, and the core of it is that you add a div
with class cartodb-legend color
:
<div class="cartodb-legend color">
<div class="legend-title">Watsan in Kibera</div>
<ul class="legend-list">
<li><div class="bullet" style="background-color: #5F4690;"></div> water tap</li>
<li><div class="bullet" style="background-color: #EDAD08;"></div> water tank</li>
<li><div class="bullet" style="background-color: #187750;"></div> dumping site</li>
</ul>
</div>
Copy the li
elements for each category and change the background color as necessary.
For more advanced legends your best bet will to either be writing the HTML and CSS yourself or using an image for the legend.
This is because the HTML for the popups changed in Builder, and Carto.js v3 doesn't know how to style them.
You can fix this by defining your own HTML for the popups using the older version of Carto's popup HTML code. Here is an example of doing this but the most important lines are:
dataLayer = layers[1].getSubLayer(0);
var popupTemplate = '<div class="cartodb-popup v2"> <a href="#close" class="cartodb-popup-close-button close">x</a> <div class="cartodb-popup-content-wrapper"> <div class="cartodb-popup-content"> {{name}} watsan: {{watsan}}</div> </div> <div class="cartodb-popup-tip-container"></div> </div>';
dataLayer.infowindow.set('template_type', 'mustache');
dataLayer.infowindow.set('template', popupTemplate);
The key is that whatever HTML you put in popupTemplate
will be the HTML used to make your popup, where words wrapped in {{}}
are replaced with a column from your data. The code above is an example for one of my maps, more generally you will want to start with
var popupTemplate = '<div class="cartodb-popup v2"> <a href="#close" class="cartodb-popup-close-button close">x</a> <div class="cartodb-popup-content-wrapper"> <div class="cartodb-popup-content"> YOUR CONTENT HERE </div> </div> <div class="cartodb-popup-tip-container"></div> </div>';
and replace YOUR CONTENT HERE
with the content you want in your popup.
Similarly to popups, above, you will want to create your own hover popups. Here's an example, and the important bit is:
cartodb.createVis('map', 'https://thenewschool.carto.com/u/brelsfoeagain/api/v2/viz/5d74528a-f60c-45c8-bfde-92ecd4c386d4/viz.json')
.done(function (vis, layers) {
dataLayer = layers[1].getSubLayer(0);
dataLayer.setInteractivity('name, watsan');
vis.addOverlay({
type: 'tooltip',
layer: dataLayer,
template: '<div class="cartodb-tooltip-content-wrapper"><div class="cartodb-tooltip-content"><h3>Name</h3><p>{{name}}</p><h3>Watsan</h3><p>{{watsan}}</p></div></div>',
position: 'bottom|right',
fields: [{name: 'name', watsan: 'watsan'}]
});
});
That is, you get your data layer, then call vis.addOverlay()
. You will likely want to change two things:
- The HTML in
template
. - The fields listed in
dataLayer.setInteractivity()
. Just add a comma and the field name. - The
fields
, which is a little weird looking. I suggest using it the way I have above, so:
{field1: 'field1', field2: 'field2'}
for each field you want to use in your popup.
If you don't like editing the HTML in one long string as I have here, you should look at this example, which puts the hover popup in the HTML and I think is a lot easier to read and change.
That is, you have custom SQL on a layer in your map that filters the features shown on the map, but when you use Carto.js all of the features show up. This is because Builder treats SQL on a layer as a type of Analysis, and Analysis doesn't work with Carto.js v3.
This is pretty easy to fix. Set the SQL as soon as the map loads. Here's an example and the core of it is:
cartodb.createVis('map', 'https://thenewschool.carto.com/u/brelsfoeagain/api/v2/viz/b1dd3eb7-dc48-4dff-8d31-948b2f451cf6/viz.json')
.done(function (vis, layers) {
dataLayer = layers[1].getSubLayer(0);
// Immediately set the SQL on the layer. We do this here because setting the SQL
// in Builder is an Analysis so doesn't work with Carto.js v3.
dataLayer.setSQL("SELECT * FROM watsan WHERE watsan = 'urban_agriculture'");
});
If that won't work for you, consider making a new layer with the SQL you want to run and using that layer instead.
This is likely because the buttons changed in Builder.
You can work around this by using Leaflet and manually adding the buttons. See this example, and the core of it is:
cartodb.createVis('map', 'https://thenewschool.carto.com/u/brelsfoeagain/api/v2/viz/6b3c46d3-2025-4214-9081-dd187fa9d3f9/viz.json')
.done(function (vis, layers) {
// Get the "native" Leaflet map and add a zoom control to it
vis.getNativeMap().addControl(L.control.zoom());
});
The styling isn't perfect but you can control the CSS of the zoom buttons to customize them or make them look more like the Carto elements.