question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Click to rotate to country using orthographic projection

See original GitHub issue

I’m have a legend with names of the specific countries I have highlighted on a world map using the orthographic projection.

I have the basic orthographic globe working here: https://studiobiodev.com/jb.dev/wp/partners/

What I would like to achieve is to click on a country name (on the left) and then have the map rotate and center on that country.

The closest thing I have found is this oft cited example: https://bl.ocks.org/mbostock/4183330 but I don’t really know how to integrate what’s there with Datamaps.

Any help or pointers in the right direction would be great. Thanks!

Here is my current code including qTip2 popups (instead of the built-in Datamaps popups):

var map;
var globalRotation = [90,-30];

function redraw() {
    d3.select("#map").html('');
    init();
} // redraw

function init() {
    map = new Datamap({
        scope: 'world',
        element: document.getElementById('map'),
        projection: 'orthographic',
        hideAntarctica: false,
        aspectRatio: 0.5,
        projectionConfig: {
            rotation: globalRotation
        },
        // done: function() {
        //  redraw('#map');
        // },
        responsive: true,
        fills: {
            // set fills
            defaultFill: "#cdcdcd",
            // partner: "#CD0000"
            partner: "#B8252F"
        },
        data: {
            ARG: { fillKey: "partner",}, // Argentina
            AUS: { fillKey: "partner" }, // Australia
            CHL: { fillKey: "partner" }, // Chile
            CHN: { fillKey: "partner" }, // China
            // COL: { fillKey: "partner" }, // Colombia
            CRI: { fillKey: "partner" }, // Costa Rica
            DEU: { fillKey: "partner" }, // Germany
            HKG: { fillKey: "partner" }, // Hong Kong
            IND: { fillKey: "partner" }, // India
            IDN: { fillKey: "partner" }, // Indonesia
            ITA: { fillKey: "partner" }, // Italy
            JPN: { fillKey: "partner" }, // Japan
            KOR: { fillKey: "partner" }, // Republic of Korea
            MYS: { fillKey: "partner" }, // Malaysia
            MEX: { fillKey: "partner" }, // Mexico
            NZL: { fillKey: "partner" }, // New Zealand
            PAK: { fillKey: "partner" }, // Pakistan
            PAN: { fillKey: "partner" }, // Panama
            PER: { fillKey: "partner" }, // Peru
            PHL: { fillKey: "partner" }, // Philippines
            SGP: { fillKey: "partner" }, // Singapore
            ZAF: { fillKey: "partner" }, // South Africa
            THA: { fillKey: "partner" }, // Thailand
            VNM: { fillKey: "partner" }, // Viet Nam
            USA: { fillKey: "partner" }, // United States
        },
          
        geographyConfig: {
            popupOnHover: false,
            // highlightFillColor: "#333",
            borderWidth: 1,
            borderOpacity: 1,
            borderColor: '#FDFDFD',
            highlightFillColor: false,
            highlightBorderColor: '#ffffff',

        },
        
    });

    window.addEventListener('resize', function() {
        map.resize();
        redraw();
    });

var drag = d3.behavior.drag().on('drag', function() {
    var dx = d3.event.dx;
    var dy = d3.event.dy;

    // var rotation = livemapScope.rotation;
    var rotation = map.projection.rotate();
    var radius = map.projection.scale();
    var scale = d3.scale.linear()
    .domain([-1 * radius, radius])
    .range([-90, 90]);
    var degX = scale(dx);
    var degY = scale(dy);
    rotation[0] += degX;
    rotation[1] -= degY;
    if (rotation[1] > 90) rotation[1] = 90;
    if (rotation[1] < -90) rotation[1] = -90;

    if (rotation[0] >= 180) rotation[0] -= 360;
    globalRotation = rotation;
    redraw();
})

d3.select("#map").select("svg").call(drag);

// qTip2 pop-ups
$('.datamaps-subunit').each(function() {
    // get #ids of ACF partner fields (ISO-3166)
    var $id = $('.map-partner').attr('id');
    // get ISO-3166 country code from class of map paths
    var $class = $(this).attr('class').split(' ')[1];

    // if hovering on map region, grab data from ACF fields for that region
    if ( $id == $class ) {
        // console.log($id, $class);
        $(this).qtip({
            content: {
                text: $('#' + $id)
            },
            position: {
                my: 'right bottom',
                at: ' top left',
                viewport: true,
            },
            style: { 
                classes: 'partner-info qtip-dark' 
            },
            hide: {
                event: 'unfocus'
            }
        });
    }
});

map.graticule();

// console.log(map.options.data);

} // init

redraw();

$('.close').click(function() {
    $(this).closest('.qtip').hide();
});

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
joshuaizcommented, Sep 7, 2018

@zaryab91 got it.

This is what worked for me: I dragged/rotated the globe to each of the countries I wanted links for and got the long and lat for each one. In my case, it is only a few countries.

I then added the coordinates as data attributes to my link like so:

<a class="partner-name" data-longitude="68.40" data-latitude="39.84">Argentina</a>

Then here is my jQuery click handler:

$('a[data-id]').on('click', function() {
    var long = $(this).data('longitude');
    var lat = $(this).data('latitude');
    rotate2Destination(long, lat);
})

And then a slightly adjusted function from above, sending the long,lat as parameters:

function rotate2Destination(long, lat) {
    nextRotate = [long, lat];
    d3.select("g")
    .transition()
    .attrTween("d", function (d) {
        var r = d3.interpolate(globalRotation, nextRotate);
        return function (t) {
            globalRotation = r(t);    
            return redraw();
        };
    })
    .duration(3000);
}

The -1 in the original function weren’t working but just sending the coordinates directly works.

An improvement on this would be to get the coordinates programmatically. Anyway, I’m pretty happy with this so thanks again.

0reactions
joshuaizcommented, Sep 11, 2018

Going to close this but thanks @zaryab91 again for the help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rotating Globe - amCharts
Orthographic projection allows projection of any map in a globe-like shape. Go ahead and try to rotate the map! Click and drag to...
Read more >
rotating orthographic globe to particular country's path
I have a globe, and I have a div with country names in it. When I click a country name, I want the...
Read more >
trying to rotate a globe in d3, centering on a particular country
represented').click(function(){ var countryabbrev = $(this).attr('id'); projection.origin(projection.invert(#path.centroid(#CAN))); //this line ...
Read more >
Spinning Globe changes Projection from D3 geoOrthographic ...
Click the 'CHANGE PROJECTION TO ORTHOGRAPHIC' text to change projection. 0.0 230 450 680 900 Cumulative number for 14 days of COVID 19...
Read more >
How to Create a Rotating Globe Using Python ... - Maker Portal
I will be using an orthographic projection to visualize earth ... For information and further exploration, click any of the links below:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found