I am new to CartoDB.js and javascript in general, and I am attempting to highlight polygons in response to a mouse hover. My plan of attack attempts to utilize one of the interesting templates designed by Michael Keller. The basic elements of the visualization are there (it is a choropleth of demographic information in DC), but I can't seem to access the geometry field of the data (to build the polygon hover). Though I started without doing so, I tried to leverage parallel SQL call strategy suggested in Can individual feature properties be retrieved from the CartoDB.js API?.

Here is the code:

  <link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/themes/css/cartodb.css" />
  <script src="http://libs.cartocdn.com/cartodb.js/v3/cartodb.js"></script>
  <!--[if lte IE 8]>
    <link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v2/themes/css/cartodb.ie.css" />
    html, body {width:100%; height:100%; padding: 0; margin: 0;}
    #cartodb-map { width: 100%; height:100%; background: black;}

    var map;

    function init(){
      // initiate leaflet map
      map = new L.Map('cartodb-map', { 
        center: [38.88,-77],
        zoom: 12

        //Add basemap
        L.tileLayer('https://dnv9my2eseobd.cloudfront.net/v3/cartodb.map-4xtxp73f/{z}/{x}/{y}.png', {
                    attribution: 'Mapbox <a href="http://mapbox.com/about/maps" target="_blank">Terms & Feedback</a>'

        //Add Viz (data) layer
        var layerURL = 'http://choct155.cartodb.com/api/v2/viz/c46ade7e-980a-11e3-98b0-0e625a1c94a6/viz.json';

        //Set layer options
        var subLayerOptions = {
            //Define CSS properties
            //cartocss: "#ne_10m_populated_places_simple{marker-fill:#109DCD; marker-width:5; marker-line-color:white; marker-line-width: 0;}"

        //Load the layer onto the map
        cartodb.createLayer(map,layerURL, {
            // To make more simplified hover polygons (faster load time), decrease the .01
         sql: 'select  *, ST_AsGeoJSON(ST_Simplify(the_geom,.01)) as geometry from {{table_name}}',
         //sql: 'SELECT * FROM dcdem_by_area',
            //Columns involved in the hovers must be identified
            interactivity: 'cartodb_id, geometry, labels'
            //If it works
                //With a SQL call defined, we need to run the operation on the layer here (looks like a zero index and layers are held in a list)

                $.getJSON("http://choct155.cartodb.com/api/v2/sql?q=SELECT cartodb_id, labels, ST_AsGeoJSON(ST_Simplify(the_geom,.01)) as geometry FROM dcdem_by_area",function(data){
                    //Add neighborhood highlighting capability
                        if (data.cartodb_id != polygon.cartodb_id){

            //If it doesn't, inspect the object

    //Define polygon
    var polygon = {};

    //Define polygon aesthetic
    var polygon_style={

    //Create functions to draw and remove polygon highlights
    function drawHoverPolygon(data){
        polygon = new L.GeoJSON(JSON.parse(data.geometry),{

    function removePolygon(){


<body onload="init()">
  <div id='cartodb-map'></div>

Since I added the layer to the map (in what seems to me to be a redundant manner), I am not clear one why I can't seem to get access to the converted geometry field.

  • That's strange.. You do have a column titled 'geometry', right? Here's a fiddle of your map that others can use to problem solve jsfiddle.net/M78cq/10
    – jotamon
    Feb 18, 2014 at 20:29
  • The column in the base table is called the_geom. The geographies are simplified in the SQL call to a new field called geometry. That being said, I did attempt to comment out the SQL query (in createLayer) and switched the other references to the_geom. No dice I am afraid. Thanks for taking a look. Feb 18, 2014 at 21:36

1 Answer 1


There may be some better ways to achieve what you are doing. The CartoDB API will serve you GeoJSON directly, not just as a geom in otherwise flat JSON. To get it, use the CartoDB.js SQL API helper functions and tell it you want GeoJSON,

// fetch the geometry
var sql = new cartodb.SQL({ user: username, format: 'geojson' });
 .done(function(geojson) {
    var features = geojson.features;
    for(var i = 0; i < features.length; ++i) {
        //Do stuff

On top of that little optimization, you don't need to bring the full GeoJSON locally, but can grab each polygon on hover. You can see it all put together in this example,


If you want to debug what you've already go, the major problem comes from I think mixing older methods in the library with newer CartoDB.js methods. You can't set SQL or interactivity the way you are, because createLayer expects 1 to many layers. So take a look at this one being created on the fly, https://gist.github.com/javisantana/6493211#file-index-html-L44 You could fix it by loading the viz.json and then using setSQL and setCartoCSS after https://github.com/CartoDB/cartodb.js/blob/develop/doc/API.md#sublayersetsqlsql- but I think it could get tricky.

The second problem comes from the getJSON / layer.on confusion. layer.on is using the interactivity layer to return data AFTER you hover a feature, that returned data is called 'data', thus overriding the 'data' returned from the enclosing getJSON.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.