More robust fix to d3.interpolateTransform.

This commit is contained in:
Mike Bostock 2012-06-24 10:43:13 -07:00
Родитель e4f4a31252
Коммит 8598dc40bf
5 изменённых файлов: 134 добавлений и 7 удалений

3
d3.v2.js поставляемый
Просмотреть файл

@ -1035,7 +1035,8 @@ d3.interpolateTransform = function(a, b) {
}
if (ra != rb) {
q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, Math.abs(ra - rb) > 180 ? rb + 360 : rb)});
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path
q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)});
} else if (rb) {
s.push(s.pop() + "rotate(" + rb + ")");
}

6
d3.v2.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,127 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
table {
width: 960px;
border-spacing: 0;
border-collapse: collapse;
}
th, td {
padding: 4px;
}
th {
text-align: left;
}
td {
border: solid 1px #ccc;
text-align: right;
}
td.fail {
background: lightcoral;
}
td.success {
background: lightgreen;
}
</style>
<table>
<thead>
<th>start</th>
<th>end</th>
<th colspan=5>actual intermediate values</th>
<th>exp.</th>
<th>act.</th>
</thead>
<tbody>
</tbody>
</table>
<script src="../../d3.v2.js"></script>
<script>
var format = d3.format(",.2f");
var tests = [
{start: 170, end: 225, expected: [ 170.00, -176.25, -162.50, -148.75, -135.00]},
{start: 225, end: 170, expected: [-135.00, -148.75, -162.50, -176.25, 170.00]},
{start: -170, end: -225, expected: [-170.00, 176.25, 162.50, 148.75, 135.00]},
{start: -225, end: -170, expected: [ 135.00, 148.75, 162.50, 176.25, -170.00]},
{start: -170, end: 170, expected: [-170.00, -175.00, 180.00, 175.00, 170.00]},
{start: -170, end: 0, expected: [-170.00, -127.50, -85.00, -42.50, 0.00]},
{start: 170, end: 0, expected: [ 170.00, 127.50, 85.00, 42.50, 0.00]},
{start: -180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: 180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: -180, end: -90, expected: [-180.00, -157.50, -135.00, -112.50, -90.00]},
{start: 180, end: -90, expected: [ 180.00, -157.50, -135.00, -112.50, -90.00]}
];
var tr = d3.select("tbody").selectAll("tr")
.data(tests)
.enter().append("tr");
tr.append("td")
.text(function(d) { return format(d.start); });
tr.append("td")
.text(function(d) { return format(d.end); });
tr.selectAll(".actual")
.data(function(d) {
var interpolate = d3.interpolateTransform("rotate(" + d.start + ")", "rotate(" + d.end + ")");
return d.expected.map(function(expected, i) {
return {
expected: expected,
actual: d3.transform(interpolate(i / 4)).rotate
};
});
})
.enter().append("td")
.text(function(d, i) { return format(d.actual); })
.attr("class", function(d) { return Math.abs(d.actual - d.expected) < .01 ? "success" : "fail"; });
tr.append("td").attr("width", 40).append("svg")
.attr("width", 40)
.attr("height", 20)
.append("g")
.attr("transform", "translate(20,10)")
.append("path")
.attr("d", d3.svg.symbol().type("cross").size(120))
.each(animateExpected);
tr.append("td").attr("width", 40).append("svg")
.attr("width", 40)
.attr("height", 20)
.append("g")
.attr("transform", "translate(20,10)")
.append("path")
.attr("d", d3.svg.symbol().type("cross").size(120))
.each(animateActual);
function animateExpected(d) {
d3.select(this).transition()
.duration(2500)
.attrTween("transform", rotateTween)
.each("end", animateExpected);
function rotateTween(d) {
if (d.start - d.end > 180) d.end += 360;
else if (d.end - d.start > 180) d.start += 360;
return d3.interpolateString("rotate(" + d.start + ")", "rotate(" + d.end + ")");
}
}
function animateActual(d) {
d3.select(this)
.attr("transform", "rotate(" + d.start + ")")
.transition()
.duration(2500)
.attr("transform", "rotate(" + d.end + ")")
.each("end", animateActual);
}
</script>

Просмотреть файл

@ -57,8 +57,6 @@ for (var tx = -10; tx <= 10; tx += 5) {
}
}
if (d3.interpolateTransform("rotate(170)", "rotate(225)")(.5) != "rotate(197.5)") ++failures;
outcome.text(failures ? failures + " failures" : "Success!");
function matrix(el) {

Просмотреть файл

@ -117,7 +117,8 @@ d3.interpolateTransform = function(a, b) {
}
if (ra != rb) {
q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, Math.abs(ra - rb) > 180 ? rb + 360 : rb)});
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path
q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)});
} else if (rb) {
s.push(s.pop() + "rotate(" + rb + ")");
}