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

Issue with checkboxes preventing submission of form

Currently working on a website project for a company that requires certain steps to be completed for deliveries. Unfortunately, I am facing issues with the submit button, and I apologize as I am still new to this. The code I have pasted is divided into tw ...

Passing an array to a PHP file using an AJAX request in jQuery is not supported

I'm attempting to send a serialized array through an ajax request to my saveData.php file so I can store the data in my database. var postData = $('#formular').serializeArray(); Here is the data I want to send. To prepare it for passing, I ...

Why is it that consolidating all my jQuery plugins into one file is ineffective?

Prior to this, I included the following scripts: <script type="text/javascript" src="{{MEDIA_URL}}js/plugins/json2.js"></script> <script type="text/javascript" src="{{MEDIA_URL}}js/plugins/jquery-msdropdown/js/jquery.dd.js"></script&g ...

Ways to trigger the keyup function on a textbox for each dynamically generated form in Angular8

When dynamically generating a form, I bind the calculateBCT function to a textbox like this: <input matInput type="text" (keyup)="calculateBCT($event)" formControlName="avgBCT">, and display the result in another textbox ...

Incorporate the block-input feature from sanity.io into your next.js blog for enhanced functionality

Currently, I'm in the process of creating a blog using next.js with sanity.io platform. However, I am facing some difficulties when it comes to utilizing the code-input plugin. What's working: I have successfully implemented the code component b ...

The save changes feature is not effectively syncing with the database

So, I have a button that triggers a javascript function, which initiates an AJAX request to call an actionresult that is supposed to update my database. Javascript Function function changeDepartment() { // Initializing and assigning variables va ...

AngularJS and Karma: Revoking ng-dirty status using setPristine

I'm currently facing an issue in one of my unit tests where I am testing the removal of ng-dirty when using setPristine on an input element. Even after calling setPristine, the ng-dirty is not being removed. My suspicion is that I may be incorrectly ...

What is the most effective method for combining data from two APIs into a single React table?

Looking to combine data from 2 separate APIs that both have pagination capabilities. What is the most efficient method to present the merged data in a table? The data needs to be joined based on their unique id, however one API provides fewer records tha ...

Effortlessly browse through directory with the seamless integration of AngularJS or

Hey there! I'm working on a really cool feature - creating a list with editable inputs. However, I've encountered a bit of an issue. Is there any way to navigate through this list using arrow keys and focus on the desired input? .content ul { ...

Creating interactive dropdown menus with PHP and Catalyst using Jquery

Currently, I am working on incorporating cascading dropdown menus into a catalyst web app. The main goal is to allow users to select a database table from the first dropdown menu and have the columns of that table populate the second dropdown menu. To achi ...

Adding a dynamic form to each row in a table: A step-by-step guide

Hey there! I'm facing a challenge with dynamically generated rows in a form. I want to send only the inputs from the selected row when a checkbox is clicked. Can you help me figure this out? I tried using let rowForm = $(event.currentTarget).closest( ...

Dividing a sentence by spaces to isolate individual words

Recently, I encountered a challenging question that has me stuck. I am working on creating an HTML text box where the submitted text is processed by a function to check for any links. If a link is detected, it should be wrapped in anchor tags to make it cl ...

Is it permissible to have circular references between JSON Schemas that are stored in separate files?

I am currently working with two JSON schemas that reference each other: schema.task.json and schema.dependency.json: //file: schema.task.json { "$schema": "http://json-schema.org/draft-04/schema", "type": "object", "properties": { "Dep ...

JavaScript allows users to input an array name themselves

When fetching rows from my database using AJAX, I transform them into an array with a variable identifier. Here is the PHP code: $query_val = $_GET["val"]; $result = mysql_query("SELECT * FROM eventos_main WHERE nome_evento LIKE '%$query_val%&apos ...

sending data from a servlet to ajax

Implementing a star-based voting system involves sending an ajax request to update the database through a servlet when a user casts their vote. This is the ajax code used: $.ajax({ type:'GET', contentType: "charset=utf- ...

Develop a function for locating a web element through XPath using JavaScriptExecutor

I have been working on developing a method in Java Script to find web elements using XPath as the locator strategy. I am seeking assistance in completing the code, the snippet of which is provided below: path = //input[@id='image'] def getElem ...

Update data in PHP dynamically without reloading the page

It would be great if they are doing well! I have encountered a minor issue - everything seems to work perfectly, but it doesn't quite meet my requirements. I am referring to this particular function: <script> var previous = null; var current = ...

Preserve file sequence with jquery file upload

I recently came across an interesting upload script at the following link: This script utilizes jquery file upload to allow for uploading multiple files simultaneously. I'm curious about how to transmit the order in which the files were selected to t ...

Changing the color of a div while implementing a show and hide effect in JavaScript

I have designed a checkout system with three distinct parts - shipping information, billing information, and order confirmation. These sections are all on the same page, allowing for a seamless flow during the checkout process. Once a customer completes t ...

Automatically scrolling through a nested list in ReactJs

I have a chat list integrated into my web application. The entire webpage is scrollable, as shown in the image at the bottom. I would like the messages list to automatically scroll to the bottom whenever a new message arrives. To achieve this, I created a ...