Search code examples
javascriptd3.jsdatamaps

How do I pass event variable/place a marker on the map - when binding done events in Datamaps & D3?


I'm working on a US map that's created with datamaps on d3. I want to place a marker on the selected states based on the mouse XY. The #map-bubble is the marker that I want to place on the map.

I'm not sure if I'm using the correct approach for doing this, but the way I've chosen - there doesn't seem to be a way to grab the mouse XY in the on click bind. The only alternative I've found is this way: Javascript - Track mouse position which seems cumbersome.

var map = new Datamap({
        element: document.getElementById("map"),
        scope: 'usa',
        fills: {
            defaultFill: "#ABDDA4",
            win: '#0fa0fa'
        },
        geographyConfig: {
    dataUrl: null, //if not null, datamaps will fetch the map JSON (currently only supports topojson)
    hideAntarctica: true,
    borderWidth: 1,
    borderColor: '#FDFDFD',
    popupTemplate: function(geography, data) { //this function should just return a string
        return '';
    },
    popupOnHover: false, //disable the popup while hovering
    highlightOnHover: true,
    highlightFillColor: '#FC8D59',
    highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
    highlightBorderWidth: 2
},
data: {
    'TX': { fillKey: 'win' },
    'FL': { fillKey: 'win' },
    'NC': { fillKey: 'win' },
    'CA': { fillKey: 'win' },
    'NY': { fillKey: 'win' },
    'CO': { fillKey: 'win' }
},
done: function(datamap) {
    datamap.svg.selectAll('.datamaps-subunit').on('click', function(event, geography) {
        console.log(event.pageY)
        var bubbly = $("#map-bubble");      
        bubbly.css({
            position:"absolute", 
            top: event.pageY, 
            left: event.pageX 
        });
        console.log(bubbly)
            bubbly.fadeIn("slow");
        console.log(geography.properties.name);
    });
}
});

Solution

  • To access the mouse click event and get the pageX and pageYcoordinates, you can use the global d3.event object. Read more about it here.

    For your example, try replacing your done function with the following:

    done: function(datamap) {
        datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
            console.log(d3.event.pageY)
            var bubbly = $("#map-bubble");      
            bubbly.css({
                position:"absolute", 
                top: d3.event.pageY, 
                left: d3.event.pageX 
            });
            console.log(bubbly)
                bubbly.fadeIn("slow");
            console.log(geography.properties.name);
        });
    }   
    

    Notice how I also removed the first parameter, event.

    Here's a codepen showing a working example, and the result.