问题
I have a D3 map of the world with markers on latitude and longitude points that I am interested in.
Now I would like to draw simple, static lines connecting these points. How do I do this?
This is my code for the map with markers:
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 900,
height = 500;
// Create Projection
var projection = d3.geo.mercator()
// Generate paths based on projection
var path = d3.geo.path()
.projection(projection);
// Create SVG
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// Group for the map features
var features = svg.append("g")
.attr("class","features");
// Build map with markers
d3.json("countries.topojson",function(error,geodata) {
if (error) return console.log(error);
//Create a path for each map feature in the data
features.selectAll("path")
.data(topojson.feature(geodata, geodata.objects.subunits).features)
.enter()
.append("path")
.attr("d", path)
// Add markers for cities by their latitude and longitude.
d3.csv("cities.csv", function (error, data) {
features.selectAll("circle")
.data(data)
.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", 5)
.style("fill", "red");
});
});
</script>
cities.csv
:
name,lat,lon
LA,34.05,-118.25
NY,40.7127,-74.006
This code produces something like this:
Now I want to connect the markers with lines. Just a static line, doesn't need to be animated or anything. The result should look like:
I added a new group for the lines above the d3.json()
call:
var lines = features.append("g");
Then inside the d3.json()
call, I add something like this to create the array of line coordinates:
var theLines = [
{
type: "LineString",
coordinates: [
[ data[0].lon, data[0].lat ],
[ data[1].lon, data[1].lat ]
]
}
];
But I'm not sure what to do next (or if my approach is correct) to actually add in the lines connecting the markers.
I want to use CSS to style the color and size of the markers and lines.
Update:
I tried changing the code for the circles to draw a line instead but its not working:
As per srbdev's
answer, I changed lineString
to line
:
d3.csv("cities.csv", function (error, data) {
features.selectAll("line")
.data(data)
.enter()
.append("line")
.attr("x1", function (d) {
return projection([d.lon])[0];
})
.attr("y1", function (d) {
return projection([d.lat])[0];
})
.attr("x2", function (d) {
return projection([d.lon])[1];
})
.attr("y2", function (d) {
return projection([d.lat])[1];
})
.style("stroke", "red");
});
But I get the following result: x2
and y2
have "NaN"
values in the console.
回答1:
On your edit, you should change your code to:
d3.csv("cities.csv", function (error, data) {
features.selectAll("line")
.data(data)
.enter()
.append("line")
.attr("x1", function (d) {
return projection([d.lon])[0];
})
.attr("y1", function (d) {
return projection([d.lat])[0];
})
.attr("x2", function (d) {
return projection([d.lon])[1];
})
.attr("y2", function (d) {
return projection([d.lat])[1];
})
.style("stroke", "yellow");
});
I changed "lineString" to "line". For a list of available SVG elements, see this link.
Another solution, though not really the D3 way as Lars mentioned, is to assign an ID to each of the circles and create your line as follow:
svg.append("line")
.attr("x1", d3.select("#circle1").attr("cx"))
.attr("y1", d3.select("#circle1").attr("cy"))
.attr("x2", d3.select("#circle2").attr("cx"))
.attr("y2", d3.select("#circle2").attr("cy"))
.style("stroke", "yellow");
Hope this helps!
来源:https://stackoverflow.com/questions/26769083/add-static-lines-on-d3-map-between-latitude-and-longitude-points