Using D3.js to plot data points on a topojson map's coordinates

Having difficulty converting latitude and longitude coordinates to "cx" and "cy" positions on my SVG map created with d3 and topojson. Despite researching solutions online, I am unable to successfully implement the conversion process. Each time I try to convert the coordinates provided in my JSON file using the projection function, it returns null for all calculations.

Please ignore the following code snippet:

//var geocoder = new google.maps.Geocoder();
//console.log(geocoder);
//figure out how to fix
//setIntervalAPI(alumni, geocoder, 1000);
console.log("Test");

  //canvas dimensions
  var width = 960,
  height = 500,
  centered;

  //SVG projection
  var projection = d3.geo.albersUsa()
      .scale(1070)
      .translate([width / 2, height / 2]);

  //projection path lines
  var path = d3.geo.path()
      .projection(projection)
      .pointRadius(1.5);

  //scalable SVG object
  var svg = d3.select("#usa").append("svg")
      .attr("width", width)
      .attr("height", height);

  //SVG elements
  svg.append("rect")
      .attr("class", "background")
      .attr("width", width)
      .attr("height", height)
      .on("click", clicked); //for click to zoom function

  //adding a group class to the SVG
  var g = svg.append("g");


  //queuing JSON files to load
  queue()
    .defer(d3.json, "https://gist.githubusercontent.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/us.json") // Load US Counties
    .defer(d3.json, "https://script.googleusercontent.com/macros/echo?user_content_key=K1E85EiRkGvkNnkwdiT6jmlX9xSU6hUvetLTNzpCcd_jSC2GpNbwZfr0KcbLfJdiHrUouVDeG7bCkVA0V_Fi5YMBTitaxVEdOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHa1ZsYSbt7G4nMhEEDL32U4DxjO7V7yvmJPXJTBuCiTGh3rUPjpYM_V0PJJG7TIaKp1q6LyBxbset-sbB7gU77AXzTewdOjiNZcuPDH50tUN-GOHXQiXJz0ANQ8AP0ES9ozQJv8DXWa1hoIgY-huuTFg&lib=MbpKbbfePtAVndrs259dhPT7ROjQYJ8yx")
    .await(ready); // Run 'ready' when JSONs are loaded

  function ready(error, usa, alumni){
    if(error) throw error;
    console.log(usa);
    console.log(alumni.Form1);

    //var geocoder = new google.maps.Geocoder();
    //console.log(geocoder);
    //figure out how to fix
    //setIntervalAPI(alumni, geocoder, 1000);
    console.log("Test");


    g.append("g")
      .attr("id", "states")
    .selectAll("path")
      .data(topojson.feature(usa, usa.objects.states).features)
    .enter().append("path")
      .attr("d", path)
      .on("click", clicked);

    g.append("path")
      .datum(topojson.mesh(usa, usa.objects.states, function(a, b) { return a !== b; }))
      .attr("id", "state-borders")
      .attr("d", path);

    /** appends circles to the map
    NEEDS FIXED
    */
    g.selectAll("circle")
      .data(alumni.Form1).enter()
      .append("circle")
      .attr("cx", function(d) { return projection(d.lat)})
      .attr("cy", function(d) {//console.log(projection(d.lng));
        return projection(d.lng)})
      .attr("r", "8px")
      .attr("fill", "blue");

An example of the JSON file structure is provided below (personal information has been omitted for privacy):

{
        "timestamp": "",
        "name": "",
        "location": "Austin, TX",
        "current_company": "",
        "current_position": "",
        "company_logo": "",
        "ta_start":,
        "ta_role": "",
        "favorite_memory": "",
        "how_ta_helped": "Always have a side hustle. ",
        "picture": "",
        "personal_handles": "",
        "linkedin": "",
        "lng": 30.267153,
        "lat": 97.7430607999999
    }

Answer №1

After some troubleshooting, I managed to find the solution to my issue. I discovered that the

var projection = d3.geo().albersUsa()
   .scale(1070)
   .translate([width / 2, height / 2]);

variable would return null if the coordinates provided were outside the bounds relative to the svg map. It became evident that the projection required a pair of coordinates rather than just a single coordinate. Therefore, I made a modification from

.attr("cx", function(d){ 
        return projection(d.lat)
})

to

.attr("cx", function(d) {
        var c = [d.lat, d.lng];
        var p = projection(c);
        console.log(p);
        return p[0]
}) 

This adjustment successfully resolved my plotting problem. Subsequently, I had to amend how I appended circles to my svg since the original method was incorrect once the coordinate issue was rectified.

Here is the revised solution:

g.selectAll("svg")
      .data(alumni.Form1).enter().append("svg:circle")
      .attr("cx", function(d) {
        var c = [d.lat, d.lng];
        p = projection(c);
        console.log(p);
        return p[0]
      })
      .attr("r", 2.5)
      .attr("cy", function(d){
        var c = [d.lat, d.lng];
        p = projection(c);
        return p[1]
      })
      .style("fill", "blue"); 

I hope this explanation assists someone facing a similar challenge.

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

Tips for transferring the cursor obtained from a mongo db find query and presenting it as an output in a flask application

I'm looking to execute a query on my MongoDB database to retrieve all entries in the stocksCollection collection. My current approach is using allStocks = list(stocksCollection.find({})), which successfully gives me a list of all the records in that c ...

Troubleshooting the compatibility between ActionScript3 and JSON: struggling to find a solution for adapting the code to the keyframe

Hey, I'm currently learning actionScript and JSON but I'm having trouble with adapting the code to paste it into the keyframe. The code was sourced from: Whenever I try to compile, I get this error message: Scene 1, Layer 'AC', Frame ...

Incorporating a TypeScript module into a JavaScript module within a React application

I'm encountering an issue with my React app that was created using create-react-app. I recently added a Typescript module to the project, which is necessary for functionality reasons. Although it will remain in Typescript, I made sure to install all t ...

Shuffling decks of cards among players at a table using JavaScript

Seems like such a simple task, but I can't seem to get it right. The idea is to have an array of 8 other arrays, each containing sets of cards (although in this case, they just have random numbers). Depending on whether passDirection is set to -1 or 1 ...

Looking to implement v-model with a group of checkboxes in a Custom Component in Vue3?

The code snippet below demonstrates the power of v-model. By checking and unchecking checkboxes, the checkedNames array will automatically add or remove names. No need to manually manipulate the array with push, slice, or filter operations. const { ref ...

Facing a dilemma: Javascript not updating HTML image source

I am facing an issue while attempting to modify the source of my HTML image element. Despite using document.getElementId('image') in my code, I am unable to make it work as intended. Surprisingly, there are no errors displayed. Interestingly, whe ...

JQuery enables nested sorting functionality

I need to enable the sortable feature specifically for the charts. Index.cshmtml <div id="sortable" class="col-lg-9"> <div class="col-lg-12 col-md-12 padding hidden" id=@($"chartNumber{Model.Charts[ ...

Determine the exact moment at which the value shifts within the table

Looking for assistance in automating the grade calculation process whenever there is a change in table values. Any suggestions on how to achieve this? I am new to events and AJAX, so any help would be appreciated as I am still learning. Please see the ima ...

What steps are involved in creating a video playlist with YouTube videos?

Is there a way to create a dynamic video playlist that supports embedded YouTube videos without refreshing the page? If a user clicks on another video, I want the video to change dynamically. You can check out this for an example. Do jPlayer, Video.js, Fl ...

Difficulty encountered when attempting to utilize keyup functionality on input-groups that are added dynamically

I've exhausted all available questions on this topic and attempted every solution, but my keyup function remains unresponsive. $(document).ready(function() { $(document).on('keyup', '.pollOption', function() { var empty = ...

What is the purpose of the json generated by Sphinx?

After exploring Sphinx, I noticed that it has the capability to create JSON documentation files. How are these specific files utilized? ...

How to separate an array of JSON objects into individual columns using Pyspark

Within my pyspark dataframe, there is a column that appears in the following format: [{key1: value1},{key2:value2}, {key3:value3}, {key4:value4}] Let's label this ColumnY as shown below: ColumnY [{key1: value1},{key2:value2}, {key3:value3}, ...

Extracting the call from REST API in JSON format

Working with a third-party database using a REST API, I encountered an error response (as expected). Here is the code snippet: transaction.commit(function(err) { if (err){ var par = JSON.parse(err); \\ leading to error: SyntaxError: Unexpecte ...

Having trouble with Semantic UI Modal onShow / onVisible functionality?

Seeking assistance with resizing an embedded google map in a Semantic UI modal after it is shown. After numerous attempts, I have narrowed down the issue to receiving callbacks when the modal becomes visible. Unfortunately, the onShow or onVisible functio ...

Pass a byte array from the back-end code to an AJAX request

I have a web method where I am converting HTML to PDF and saving it to a local folder. The goal is for the user to download the file without needing to reload the page. To achieve this, I am attempting to make an AJAX POST call to the web method to retriev ...

Unable to access the suggestion list within the modal

I incorporate the PrimeNG AutoComplete feature within a PrimeNG Dialog, displaying a list of elements below the AutoComplete in the dialog. My objectives are: To set the max-height of the modal dialog to 300, and have a visible scrollbar if the total ...

Obtain the value of "Placeholder" using JavaScript in Internet Explorer without the need for JQuery

I have some custom Javascript code that checks for browser support of placeholders and creates them if not supported. This solution works on some older browsers, but not all, especially IE. The issue I am facing is retrieving the "Placeholder" value; curr ...

Storing a MySQL query result in a global array in a Node.js environment

Just diving into the world of Node.js and Express, I'm trying to wrap my head around asynchronous functions and global variables. Specifically, I'm working on connecting to a MySQL database, fetching query results, and displaying them on a test.h ...

Dealing with code issues in Subscription forms using AJAX and JQuery

Currently, I am independently studying jQuery and grappling with the Mailchimp Opt-In form code. Despite various existing queries on this topic, I am curious about why my own implementation, as a beginner in jQuery, is not functioning correctly. My intenti ...

What strategies can I use to incorporate dynamic filtering using only AJAX while maintaining a functional browsing history?

As I work on implementing AJAX filtering for my e-commerce website, I am exploring different solutions. One approach I am considering involves generating all content statically server-side and then using AJAX requests on the same page with parameters. The ...