Cities cannot be obscured by a rotating globe

In my latest project, I have created a jsfiddle showcasing a Bostock spinning globe implementation.

After successfully plotting a few city markers, I encountered a problem where not all cities were being displayed. Additionally, the script intended to hide markers that are not visible behind the globe was not functioning properly, causing the markers to move unexpectedly when scrolled out of view.

To view the fiddle and script in question, click here: http://jsfiddle.net/Guill84/jg3axLmx/1/

Below is the script used to position the cities and 'hide' them behind the globe:

function position_cities() {
   var centerPos = projection.invert([380,380]);
   var arc = d3.geo.greatArc();
   svg.selectAll(".cities")
     .style("fill", "blue")
     .attr("cx", function(d) {
       return projection([d.lon, d.lat])[0];
     })
     .attr("cy", function(d) {
       return projection([d.lon, d.lat])[1];
     })
     .style({
       "color": "#FFF",
       "display": function(d) { 
         var x = projection([d.lon, d.lat])[0];
         var y = projection([d.lon, d.lat])[1];
         var d = arc.distance({
           source: [d.lat, d.lon],
           target: centerPos
         });
         return (d > 1.57) ? 'none' : 'inline';
       }
     });
 }

Furthermore, I am seeking assistance on how to add labels to these markers and modify their shape to be square instead of circular.

A question similar to mine can be found here: Cannot hide labels 'behind' spinning D3 Globe

For example, the marker in Brazil is still visible in the image linked here: https://i.sstatic.net/WnSfq.png

Answer №1

Close to the correct solution,

As mentioned in the feedback, the central point is located at 400,400:

var centerPos = projection.invert([400,400]);

There seems to be a mix-up in the order of latitude and longitude in the source coordinate provided:

var d = arc.distance({source: [d.lat, d.lon], target: centerPos});
  return (d > 1.57) ? 'none' : 'inline';

The correct order should be:

var d = arc.distance({source: [d.lon, d.lat], target: centerPos});
  return (d > 1.57) ? 'none' : 'inline';

Fiddle: http://jsfiddle.net/L51y3c1b/

Answer №2

Allow me to address the following query:

Furthermore - do you happen to know how one could incorporate labels into these markers and change their shape from circular to square?

Instead of the current method on line 72:

      .append("circle")
        .attr("cx", function(d) {
           return projection([d.lon, d.lat])[0];
           })
        .attr("cy", function(d) {
           return projection([d.lon, d.lat])[1];
           })

Consider appending a "g" element as follows:

      .append("g")
        .attr("transform", function(d) {
           return "translate("+ 
                    projection([d.lon, d.lat])[0] +
                    "," +
                    projection([d.lon, d.lat])[1]+
                    ")";
           })

Next, add a circle to the "g" element:

     cities.append("circle") 
           .attr("cx", 0)
           .attr("cy", 0)

Followed by:

    cities.append("text").text("New York");

You can adjust the x and y coordinates of the text. Additionally, whenever you modify the cx and cy attributes of a city, update the "transform" attribute of the g element as demonstrated above.

In regard to your primary question, it's noteworthy that d3.geo.greatArc(); is no longer supported. It might be beneficial to explore alternative approaches for calculating arc distance on a global scale.

Answer №3

The code snippet you provided on the js fiddle shows that the cities are set once but never called again. In the startAnimation method, you need to update the cities display in the same way you update the labels. Otherwise, the display will rely on the initial load.

Regarding the shape change, you define it when creating the cities as shown below:

var cities = svg.selectAll("circle")
            .data([
            {"code":"RIO","city":"RIO DE JANEIRO","country":"BRAZIL","lat":-22.90,"lon":-43.24},
            {"code":"BSB","city":"BRASILIA","country":"BRAZIL","lat":-15.67,"lon":-47.43},
            {"code":"ZNZ","city":"ZANZIBAR","country":"TANZANIA","lat":-6.13,"lon":39.31},
            {"code":"TYO","city":"TOKYO","country":"JAPAN","lat":35.68,"lon":139.76}
            ])
            .enter()
            .append("circle")
            .attr("cx", function(d) {
               return projection([d.lon, d.lat])[0];
               })
            .attr("cy", function(d) {
               return projection([d.lon, d.lat])[1];
               })
            .attr("r", 3)
            .style("fill", "red")
            .attr("d", path)
            .attr("class", "cities")
            .attr("id", function(d){ return d.code})

The attributes like cx, cy are specific to an SVG circle shape and the circle tag. To create different shapes, you will need to modify the tag and attributes to suit the shape you desire.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Step-by-Step Guide on Retrieving Filtered Data using React Context API

Currently, I am in the process of developing a dashboard application using React.js, React Context API, and ApexCharts. The app will visualize a 1000-length JSON data on 7-8 different charts, along with 6-7 variable filters. Overview of the App Structure: ...

Is there a way to remove a value from the search bar while updating the table at the same time?

Although I can successfully search the table based on the values in my search bar, I am having trouble with updating the state when deleting a value. To see my code in action, check out my sandbox here. ...

jquery counter is malfunctioning

I noticed a strange issue with the counters on my website. They count up as expected when the page loads, but for some reason, when the screen width shrinks below 800px, they don't start automatically. However, if I quickly scroll to where the counter ...

Efficient method for managing complex JSON object updates using setState in React

My task involves handling structured data in JSON format, which I am unable to modify due to API restrictions. The challenge is to update the JSON file based on user modifications. { "id": 1269, "name": "Fet", &quo ...

Creating a uniform system for PHP and CSS that eliminates the need for string parsing

I apologize for the insufficient title. In the given code snippet: <?php $css = 'foo-'.$data['style']; $html= "<table><tr><td class='{$css}>styled! /> </tr> </table>; ?> whe ...

Utilizing Vue.js to set the instance global property as the default value for a component prop

Is it possible to access a global property from my vue instance when setting a default prop value in my component? This is what I would like to achieve props: { id: { type: String, default: this.$utils.uuid } } I attempted to use an arrow fun ...

Using JavaScript promises to handle connection pooling and query execution

I am contemplating whether this approach is on the right track or if it requires further adjustments. Should I consider promisifying my custom MySQL getConnection method as well? request: function(queryRequest) { return new Promise(function(re ...

Firefox 3 fails to utilize cache when an ajax request is made while the page is loading

Upon loading the page DOM, I utilize jQuery to fetch JSON data via ajax like so: $(document).ready(function(){ getData(); }); ...where the function getData() executes a basic jQuery ajax call similar to this: function getData(){ $.ajax({cache: t ...

Switching a material-ui input control instead of a textfield for materials-ui-datepicker: the ultimate guide

Within my React application (v16.3), I am utilizing the DatePicker component from the material-ui-pickers library to render date-picker controls. This particular component renders a Material-UI TextField. However, I am interested in modifying it to only di ...

The click function operates only once

Here are two simple JavaScript functions: CTCC.Transactions.PieceRecuClick = function (source) { $(".chk input[type='checkbox']").attr('checked', true); } CTCC.Transactions.PieceNonRecuClick = function (source) { $(".chk input ...

Unidentified function error triggered by jQuery when clicked

Having trouble accessing a function defined by my colleague for a click event. The code snippet provided below is causing issues, any ideas on what could be wrong? function Start(data) { this.move= function() { .... }; $('.button').click( ...

How can I create a custom AppBar transition using Material-UI?

Is there a way to incorporate transitions into the AppBar element within Material-UI? I have tried adjusting the class properties, but unfortunately, I'm not seeing any animation. Can anyone pinpoint what the issue might be? To see the code in action ...

The ng-change functionality of Angular radio buttons only functions correctly the first time it

I am struggling to comprehend why the angular ng-change function is only being called on the first click. Take a look at this example: http://jsfiddle.net/ZPcSe/5/ The function in the provided example is triggered every time the radio selection is change ...

Having difficulty positioning two elements within a button using bootstrap

I am attempting to align two texts horizontally inside a button using Bootstrap 4. The word "Link" keeps getting pushed to the next line and I would like it to stay beside "Copy". I have experimented with using Float but it ends up moving "Link" too far t ...

Adaptive component transformation

Hey there, I'm having some trouble figuring this out... I need help with making sure that the element identified by the red rectangle in the images moves in alignment with the containers below, regardless of the screen size. I want to create a respon ...

Creating interactive carousel slides effortlessly with the power of Angular and the ngu-carousel module

I'm currently tackling the task of developing a carousel with the ngu-carousel Angular module, available at this link. However, I'm facing some challenges in configuring it to dynamically generate slides from an array of objects. From what I&apos ...

Tips for preventing visual glitches caused by inaccurate world coordinates in WebGL

Issue: Encountering rendering glitches while using world coordinates in the fragment shader to display a grid. The grid does not move uniformly when the plane it is rendered on is moved, resulting in one "half" moving while the other remains idle. Refer ...

Chrome hanging after AJAX delete operation has been executed

After conducting a same-origin AJAX delete using jQuery, any subsequent calls made by the same client to the server are getting stuck. The specific issue is outlined below. Can you please review and let me know if there's something incorrect, as this ...

Playing sound using jQuery when the body of the page is replaced

I am facing an issue with my website where I have implemented a jQuery full body refresh every 30 seconds. However, I want to add a short sound to play every time the page refreshes. Despite trying various methods, the sound works on my computer browsers ( ...

What causes CSS to fail to load in React but work normally in Next.js?

We are currently experiencing an issue with a component located in a Git Submodule that is being used by both Next.js and React. While everything is functioning correctly in Next.js, React is unable to accept the way the CSS is being loaded: import styles ...