user10963024
user10963024

Reputation:

D3.js Issue when projection y values

I'm struggling to plot a line from latitude & longitude in D3, specifically when projecting the y values.

I draw the line using the following code & sample json array.

var json_str = [
{
    "lng1": 53.587,
    "lat1": -2.159,
    "lng2": 53.587,
    "lat2": -2.159,
},
{
    "lng1": 53.587,
    "lat1": -2.159,
    "lng2": 53.587,
    "lat2": -2.157,
}
];

d3.select("#lines").selectAll("line")
.data(json_str)
.enter()
.append("line")
.attr("x1", function (d) { return projection([d.lat1])[0]; })
.attr("y1", function (d) { return projection([d.lng1])[0]; })
.attr("x2", function (d) { return projection([d.lat2])[0]; })
.attr("y2", function (d) { return projection([d.lng2])[0]; })
.style("stroke", "black")
.style("stroke-width", 5);

When I project the x values, it comes out with the correct value & projects on my map correctly, however when I project Y, using the same functions but on a different field, it gives me crazy values and therefore isn't plotting within the bounds of my SVG. Somewhere in the region of 1299***.

I've used the same function to project x & y values for point data no problem.

d3.select("#points").selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
        .attr("cx", function (d) { return projection([d.y, d.x])[0] })
        .attr("cy", function (d) { return projection([d.y, d.x])[1] })

EDIT: Marks answer below gets me close, but the projection is still out of shape.

I've created a Plunker showing my problem, which incorporates Marks answer below. Essentially the 'lines' SVG plots 90 degrees out & I can;t fathom why..

Upvotes: 1

Views: 360

Answers (1)

Mark
Mark

Reputation: 108512

The documentation states that (bolding mine):

projection(point)

Returns a new array [x, y] (typically in pixels) representing the projected point of the given point. The point must be specified as a two-element array [longitude, latitude] in degrees. May return null if the specified point has no defined projected position, such as when the point is outside the clipping bounds of the projection.

You are passing a singular lat/long values in return projection([d.lat1])[0];. This won't work.

I'd refactor it as:

var json_str = [
{
  "lng1": 53.587,
  "lat1": -2.159,
  "lng2": 53.587,
  "lat2": -2.159,
},
{
  "lng1": 53.587,
  "lat1": -2.159,
  "lng2": 53.587,
  "lat2": -2.157,
}
];

d3.select("#lines").selectAll("line")
  .data(json_str)
  .enter()
  .append("line")
  .each(function(d){
    d.p1 = projection([d.lng1, d.lat1]);
    d.p2 = projection([d.lng2, d.lat2]);
  })
  .attr("x1", function (d) { return d.p1[0]; })
  .attr("y1", function (d) { return d.p1[1]; })
  .attr("x2", function (d) { return d.p2[0]; })
  .attr("y2", function (d) { return d.p2[1]; })
  .style("stroke", "black")
  .style("stroke-width", 5);

Upvotes: 1

Related Questions