Display geographic data using d3 with geoJSON

I am struggling to render a geoJSON file using d3 because I am having trouble targeting the correct features for projection.

Instead of working with the typical us.json file used in many d3 examples, my current map focuses on United States "Commuting Zones" (CZ's) rather than land, states, or counties.

In my usual process, I call

topojson.feature(us, us.objects.states)

to display the correct layer. However, the file I'm currently working with is not organized into objects and does not have multiple layers. Here is an excerpt from the geoJSON file:

{"type":"FeatureCollection","bbox":[-120.30602148510043,6.667736880597216,-70.95829310710806,34.46308750538215],"features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-83.802805983004,22.64602264051764],[-83.8080569412408,22.638128812605782],

Below is the code I am using, which is not successfully rendering the map:

d3.json("CZ90.zip.geojson", function(error, us) {
    if (error) throw error;

    d3.select("svg").append("path")
        .datum(topojson.feature(us, us.CZ90))
        .attr("d", d3.geo.path());
});

Since there are no objects defined in the file, I omitted the ".object". When I view the file in Mapshaper, it renders correctly with a layer titled "CZ90", leading me to try "us.CZ90" instead of "us.objects.states"

I understand that I may be using "topojson.feature" instead of something geoJSON specific, but I have been unsuccessful in converting the file to topoJSON in Mapshaper without losing projection information.

What is the right way to target this layer in the .datum call?

This issue would be resolved if I could find a topoJSON file similar to us.json that includes a commuting zones layer!

Answer №1

After receiving assistance from a developer friend of mine, I discovered that the solution to my problem was much simpler than I had initially thought.

It turns out that d3.json() is inherently designed to interpret the structure of my geoJSON file without requiring the use of datum(). All I needed to do was make the following call:

d3.json("CZ90.zip.geojson", function(error, geoData) {
    d3.select("svg").append("path")
        .attr("d", path(geoData));
}

Just a side note: this code snippet is based on d3.v4

Below is the complete script that successfully rendered the map:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    path {
      fill: #ccc;
      stroke: #fff;
      stroke-linejoin: round;
    }
</style>

<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>

<script>

var width = 960;
var height = 620;

var chosenProjection = d3.geoMercator()
  .scale(600)
  .translate([1300, 450])

  var path = d3.geoPath()
    .projection(chosenProjection);

d3.json("CZ90.zip.geojson", function(error, geoData) {

  d3.select("svg").append("path")
      .attr("d", path(geoData));
});

</script>

I hope this explanation can assist others who may find themselves stuck on a seemingly simple obstacle!

Answer №2

Upon reviewing the topojson documentation, it is clear that topojson.feature:

Returns the GeoJSON Feature or FeatureCollection for the specified object in the given topology. If the specified object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned.

Additionally, according to the d3 documentation, a d3 geopath:

Renders the given object, which may be any GeoJSON feature

Regarding this statement:

I realize I'm calling "topojson.feature" instead of something geoJSON specific

It should be noted that you are already using something geoJSON specific. Topojson.js is used to convert topoJSON back to geoJSON for D3 map usage. So, in response to your inquiry:

What is the correct way to target this layer in the .datum call?

The appropriate method is simply:

.datum(us) // feature collection or single feature

This will append a single path. However, if you wish to append multiple paths with the same dataset (for different coloring or mouse interaction):

.data(us.features) // feature collection

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

Nuxt: Delaying Loading of Google Maps in VueJS Until Data is Fully Prepared

Hello, I am currently working on my very first VueJS project and I have successfully implemented the vue2-google-maps. However, I have encountered a problem while trying to connect the map markers to my site's JSON feed through the Wordpress REST API. ...

What is the most effective method for implementing COPY/INSERT functionality with cascading effects in PostgreSQL?

Seeking advice on the most effective method to perform an "on cascade copy/insert" of linked elements within PostgreSQL. To better explain my scenario, I've crafted a straightforward example: Understanding the Database Structure Within the datab ...

What is the correct method for downloading an Excel file in a Vue.js application?

I am having difficulty downloading an Excel file in xlsx format using my Vue.js application. The Vue.js application sends a post request to the Node.js application which then downloads the Excel file from a remote SFTP server. The backend application is fu ...

To update the JSON values in a YAML file using Python, you can embed the JSON within the YAML

I have a YAML configuration file that looks like this: api: v1 hostname: abc metadata: name: test annotations: { "ip" : "1.1.1.1", "login" : "fad-login", "vip" : "1.1.1.1", &qu ...

React - callbackFromApp function is executing only one time when clicked

Whenever I click a button within my child React module, it is meant to increment the timer and then pass back the timer in minutes and total seconds to the parent component where it will be stored as state. The issue I am facing is that when I click the b ...

Utilizing Vue.js to apply conditional statements or filters on v-for generated outputs

Currently, I am working on organizing my results by category. I believe there is room for improvement in the way it's being done: <div><h2>Gloves</h2></div> <div v-for="stash in stashes" :key="stash.id"> <div v-for= ...

How can a loading circle be displayed upon clicking a button on a PHP website using JavaScript?

As a newcomer to the world of JavaScript programming, I'm facing a challenge that seems deceptively simple. My goal is to display a loading circle when a user clicks on an upload button, trigger external PHP code for image processing, and then make th ...

Embed the website onto a webpage using ajax or an iframe without any need for navigation

I have a unique challenge ahead. Imagine there are two websites, one is a web page and the other is hosted within the same domain. My goal is to load the entire second website into a div or iframe of the first web page, similar to how a free proxy browser ...

Display a loading dialog when an AJAX request is made

I am working on a Grails application and I would like to implement a visual indicator, such as a modal dialog, to show when an AJAX request is in progress. Currently, I rely on JQuery for all my AJAX requests. While they are triggered using Grails tags at ...

Steps for generating an array entry containing an ObjectId and a Number

I am a newbie when it comes to mongodb and I am attempting to create an entry like this: { "resources": [ { "amount": 1, "resource": { "_id": "61be82b9549b4ede ...

Utilizing variable values in Google Charts with AngularJS

Hello everyone, I am attempting to display a chart using data obtained from an API. The output of the API is in the form of List<String> and not in JSON format. Here is the snippet of my JS file: google.load('visualization', '1', ...

Please elaborate on the appropriate application of angularjs Directives in this specific scenario

From my experience with Angular, I've learned that directives are used for manipulating the DOM while controllers are more about controlling functionality. I've been struggling to convert a small wizard into generic directives, aiming for reusab ...

Unusual behavior encountered with JSON, exploring the scope of a JavaScript variable

In my PHP code, I have an array stored in the variable $result. After using echo json_encode($result);, the output is: [{"id":"4","rank":"adm","title":"title 1"}, {"id":"2","rank":"mod",,"title":"title 2"}, {"id":"5","rank":"das","title":"title 3"}, {"id ...

Understanding the mechanics of utilizing node modules and requiring them within an Express 4 router

After initiating a node project using an express 4 generator, I have set up the following routing code in the /routes/index.js file: // ./routes/index.js var express = require('express'); var router = express.Router(); router.get('/' ...

Merging data sets with Javascript: A comprehensive guide

As a newcomer to the world of javscript, I'm faced with what seems like a simple question. I'm working with two datasets that contain a common column and I'd like to merge them together. The structure of the datasets is as follows: const da ...

Refreshing Form in Angular 2

When I remove a form control from my form, it causes the form to always be invalid. However, if I delete a character from another input field and then add the same character back in (to trigger a change event), the form becomes valid as expected. Is ther ...

The React callback is failing to update before navigating to the next page

I'm facing an issue that seems like it can be resolved through the use of async/await, but I am unsure of where to implement it. In my application, there are three components involved. One component acts as a timer and receives a callback from its pa ...

What might be the reason for npm live-server to cease detecting file updates?

Everything was working perfectly on my system, but now I'm facing an issue. I have the live-server version 0.8.1 installed globally. npm install live-server -g However, when I start it, I no longer see the "Live reload enabled." message in the brow ...

Is there a way to trigger the animation of this text effect only when the mouse is scrolled to that specific section?

Here is a cool typing text effect created using HTML, CSS, and JavaScript. Check out the code below: (function($) { var s, spanizeLetters = { settings: { letters: $('.js-spanize'), }, init: function() { ...

Is there a foolproof way to generate JSON data using PHP?

I am new to JSON and I have XML results that I want to convert to JSON format. The data is retrieved from a mySQL array. My issue arises when dealing with multiple nodes with the same name in the XML result, as shown below: <results> <result ...