score:1

EDITS w/ Better Squiggle

For a more all purpose squiggle formula, I think two opposite arcs to the midpoint looks good (c is array of `[[x1,y1], [x2,y2]]` of long, lat):

``````function twoArc(c){
var source = projection(c),
target = projection(c),
mid = [(source + target)/2, (source + target)/2],
dx1 = mid - source,
dx2 = target - mid,
dy1 = mid - source,
dy2 = target - mid,
dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1),
dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);

var rv = "M";
rv += source + "," + source;
rv += "A" + dr1 + "," + dr1 + " 0 0,1 ";
rv += mid + "," + mid;
rv += "A" + dr2 + "," + dr2 + " 0 0,0 ";
rv += target + "," + target;

return rv;
}
``````

Here's a running example with various "random" coordinates:

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

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34],
[-74, 40],
[-86.75, 33.57],
[-92.38, 35.22],
[-84.87, 34.53],
[-83.80, 41.60],
[-96.07, 33.07],
[-112.02, 41.18],
[-111.0, 41.33]
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(twoRand())
.attr("d", twoArc)
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function twoArc(c){
var source = projection(c),
target = projection(c),
mid = [(source + target)/2, (source + target)/2],
dx1 = mid - source,
dx2 = target - mid,
dy1 = mid - source,
dy2 = target - mid,
dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1),
dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);

var rv = "M";
rv += source + "," + source;
rv += "A" + dr1 + "," + dr1 + " 0 0,1 ";
rv += mid + "," + mid;
rv += "A" + dr2 + "," + dr2 + " 0 0,0 ";
rv += target + "," + target;

return rv;
}

function twoRand(){
var i1 = Math.floor(Math.random() * coordinates.length),
i2 = Math.floor(Math.random() * coordinates.length);
return [coordinates[i1], coordinates[i2]];
}

function anim() {

line.datum(twoRand())
.attr("d", twoArc);

line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>``````

EDITS with First Squiggle Attempt

Here's an example with a "squiggly" line. I generate it by inserting jittered points into an array and using a `d3` line-fit interpolation:

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

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34], //start point
[-74, 40] //end point
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var lF = d3.svg.line()
.interpolate("basis")
.x(function(d){ return d })
.y(function(d){ return d });

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(coordinates)
.attr("d", function(c) {
var d = {
source: projection(c),
target: projection(c)
},
points = [];

points.push(d.source);
points.push([(d.target - d.source) * 0.4, d.target]);
points.push([(d.target - d.source) * 0.8, d.source]);
points.push(d.target);

return lF(points);
})
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function anim() {
line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>``````

With Single Arc

Coded this up before I saw your comment, but you seem to be stuck on not the dash tween but how to compute a path. I see know you want a curved path, but here's an example with a simple arc on a map (from LA to NY):

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

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34], //start point
[-74, 40] //end point
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(coordinates)
.attr("d", function(c) {
var d = {
source: projection(c),
target: projection(c)
};
var dx = d.target - d.source,
dy = d.target - d.source,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source + "," + d.source + "A" + dr + "," + dr +
" 0 0,1 " + d.target + "," + d.target;
})
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function anim() {
line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>``````

Give me a few minutes and all see about a "snaked" line.