An example of d3.svg.ribbon using Napoleon's March through Russia made famous by Minard's map. Dataset comes from Ben Schmidt's use of it in his excellent d3.trail layout.
The pattern for using d3.svg.ribbon with geodata is simply to factor the projection into the accessors:
projection = d3.geo.equirectangular().translate([-3300,7800]).scale(8000);
sizeScale = d3.scale.linear().domain([6000,340000]).range([1,10])
ribbon = d3.svg.ribbon()
.x(function(d) {return projection([d.lon, d.lat])[0]})
.y(function(d) {return projection([d.lon, d.lat])[1]})
.r(function(d) {return sizeScale(d.size)});
xxxxxxxxxx
<html>
<head>
<title>d3.svg.ribbon with Napoleon's March</title>
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="d3.svg.ribbon.js" type="text/JavaScript"></script>
</head>
<style>
svg {
height: 2000px;
width: 2000px;
}
</style>
<body>
<div id="viz">
<svg>
</svg>
</div>
</body>
<footer>
<script>
colorScale = d3.scale.ordinal().range(["#96abb1", "#313746", "#b0909d", "#687a97", "#292014"])
army = [
/* Group 1 */
{lon:24.0, lat:54.9, size:340000, dir:1, group:1},
{lon:24.5, lat:55.0, size:340000, dir:1, group:1},
{lon:25.5, lat:54.6, size:340000, dir:1, group:1},
{lon:26.0, lat:54.7, size:320000, dir:1, group:1},
{lon:27.0, lat:54.8, size:300000, dir:1, group:1},
{lon:28.0, lat:54.9, size:280000, dir:1, group:1},
{lon:28.5, lat:55.0, size:240000, dir:1, group:1},
{lon:29.0, lat:55.1, size:210000, dir:1, group:1},
{lon:30.0, lat:55.2, size:180000, dir:1, group:1},
{lon:30.3, lat:55.3, size:175000, dir:1, group:1},
{lon:32.0, lat:54.8, size:145000, dir:1, group:1},
{lon:33.2, lat:54.9, size:140000, dir:1, group:1},
{lon:34.4, lat:55.5, size:127100, dir:1, group:1},
{lon:35.5, lat:55.4, size:100000, dir:1, group:1},
{lon:36.0, lat:55.5, size:100000, dir:1, group:1},
{lon:37.6, lat:55.8, size:100000, dir:1, group:1},
{lon:37.65, lat:55.65, size:100000, dir:-1, group:1},
{lon:37.45, lat:55.62, size:98000, dir:-1, group:1},
{lon:37.0, lat:55.0, size:97000, dir:-1, group:1},
{lon:36.8, lat:55.0, size:96000, dir:-1, group:1},
{lon:35.4, lat:55.3, size:87000, dir:-1, group:1},
{lon:34.3, lat:55.2, size:55000, dir:-1, group:1},
{lon:33.3, lat:54.8, size:37000, dir:-1, group:1},
{lon:32.0, lat:54.6, size:24000, dir:-1, group:1},
{lon:30.4, lat:54.4, size:20000, dir:-1, group:1},
{lon:29.2, lat:54.3, size:20000, dir:-1, group:1},
{lon:29.13, lat:54.29, size:50000, dir:-1, group:1}, /* joined by group 2 */
{lon:28.5, lat:54.2, size:50000, dir:-1, group:1},
{lon:28.3, lat:54.3, size:48000, dir:-1, group:1},
{lon:26.8, lat:54.3, size:12000, dir:-1, group:1},
{lon:26.8, lat:54.4, size:14000, dir:-1, group:1},
{lon:25.0, lat:54.4, size:8000, dir:-1, group:1},
{lon:24.4, lat:54.4, size:4000, dir:-1, group:1},
{lon:24.2, lat:54.4, size:4000, dir:-1, group:1},
{lon:24.1, lat:54.4, size:4000, dir:-1, group:1},
/* Group 2 */
{lon:24.0, lat:55.1, size:60000, dir:1, group:2},
{lon:24.5, lat:55.2, size:60000, dir:1, group:2},
{lon:25.5, lat:54.7, size:60000, dir:1, group:2},
{lon:26.6, lat:55.7, size:40000, dir:1, group:2},
{lon:27.4, lat:55.6, size:33000, dir:1, group:2},
{lon:28.7, lat:55.5, size:33000, dir:1, group:2},
{lon:28.7, lat:55.5, size:33000, dir:-1, group:2},
{lon:29.2, lat:54.29, size:30000, dir:-1, group:2},
/* Group 3 */
{lon:24.0, lat:55.2, size:22000, dir:1, group:3},
{lon:24.5, lat:55.3, size:22000, dir:1, group:3},
{lon:24.6, lat:55.8, size:6000, dir:1, group:3},
{lon:24.6, lat:55.8, size:6000, dir:-1, group:3},
{lon:24.2, lat:54.4, size:6000, dir:-1, group:3},
{lon:24.1, lat:54.4, size:6000, dir:-1, group:3}
];
projection = d3.geo.equirectangular().translate([-3300,7800]).scale(8000);
sizeScale = d3.scale.linear().domain([6000,340000]).range([1,10])
ribbon = d3.svg.ribbon()
.x(function(d) {return projection([d.lon, d.lat])[0]})
.y(function(d) {return projection([d.lon, d.lat])[1]})
.r(function(d) {return sizeScale(d.size)});
drag = d3.behavior.drag().on("drag", function (d) {
d.x = d3.event.x;
d.y = d3.event.y;
redraw();
});
var groupNest = d3.nest().key(function (d) {return d.group}).entries(army);
d3.select("svg")
.selectAll("path.minard")
.data(groupNest)
.enter()
.append("path")
.attr("class", "minard")
.style("fill", function (d) {return colorScale(d.key)})
.style("stroke", "gray")
.style("stroke-opacity", 0.15)
.style("stroke-width", "2px")
.attr("d", function (d) {return ribbon(d.values)})
</script>
</footer>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js