我最近才开始编码,这是我第一次发帖,所以对任何违反协议的行为表示道歉;-P
我正在尝试从这个Mike Bostock bl.ock重现投影过渡
http://bl.ocks.org/mbostock/3711652
但是在d3.v4。我可以让转换执行,但没有动画。我认为这与我执行 ProjectionTween 函数的方式或者 Update 选择svg的方式有关,但我似乎无法将其转换为否则。
非常感谢任何帮助。
//Options, insert projections here
var options = [
{name: "Mercator", projection: d3.geoMercator()},
{name: "Hammer", projection: d3.geoHammer()},
{name: "ConicEqual", projection: d3.geoConicEqualArea()},
{name: "ConicEqui", projection: d3.geoConicEquidistant()},
{name: "ConicConformal", projection: d3.geoConicConformal()},
{name: "Ginzburg8", projection: d3.geoGinzburg8()},
{name: "Laskowski", projection: d3.geoLaskowski()},
{name: "Times", projection: d3.geoTimes()},
{name: "LaGrange", projection: d3.geoLagrange()}
];
options.forEach(function(o) {
o.projection.rotate([0, 0]).center([0, 0]);
});
var interval = setInterval(loop, 1500),
i = 0,
n = options.length - 1;
var c = document.getElementById('container');
var width = c.offsetWidth;
var height = width / 2;
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var graticule = d3.geoGraticule();
var menu = d3.select("#projection-menu")
.on("change", change);
menu.selectAll("option")
.data(options)
.enter().append("option")
.text(function(d) { return d.name; });
setup(width,height);
function setup(width,height){
projection = options[i].projection // N.B. geoPeirceQuincuncial in 1.1+
.translate([(width/2), (height/2)])
.scale( width / 2 / Math.PI);
//path = d3.geo.path().projection(projection);
path = d3.geoPath().projection(projection);
svg = d3.select("#container").append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
g = svg.append("g");
g.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
g.append("path")
.datum({type: "Sphere"})
.attr("class", "sphere")
.attr("d", path)
.attr("fill", "#f1f1f1")
.attr("stroke", "black")
.attr("opacity", 0.3);
}
d3.queue()
.defer(d3.json, "world-50m.v1.json")
.await(ready);
function ready(error, world) {
var countries = topojson.feature(world, world.objects.countries).features;
topo = countries;
draw(topo);
}
function draw(topo) {
var country = g.selectAll(".country").data(topo);
country.enter().insert("path")
.attr("class", "country")
.attr("d", path)
.style("fill", "black");
}
//Loop / interval / option / update
function loop() {
var j = Math.floor(Math.random() * n);
menu.property("selectedIndex", i = j + (j >= i));
update(options[i]);
}
function change() {
clearInterval(interval);
update(options[this.selectedIndex]);
}
function update(option) {
svg.selectAll("path").transition()
.duration(750)
.attrTween("d", projectionTween(projection, projection = option.projection));
}
function projectionTween(projection0, projection1) {
return function(d) {
var t = 0;
projection = options[i].projection // N.B. geoPeirceQuincuncial in 1.1+
.translate([(width/2), (height/2)])
.scale( width / 2 / Math.PI);
//path = d3.geo.path().projection(projection);
path = d3.geoPath().projection(projection);
function project(λ, φ) {
λ *= 180 / Math.PI, φ *= 180 / Math.PI;
var p0 = projection0([λ, φ]), p1 = projection1([λ, φ]);
return [(1 - t) * p0[0] + t * p1[0], (1 - t) * -p0[1] + t * -p1[1]];
}
return function(_) {
t = _;
return path(d);
};
};
}
.country {
fill: grey;
stroke-width: 0.1px;
}
.graticule {
fill: none;
stroke: grey;
stroke-width: 0.5px;
stroke-opacity: 0.3;
}
#container {
margin:10px 10%;
border:2px solid #000;
border-radius: 5px;
height:100%;
overflow:hidden;
background: none;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<select id="projection-menu"></select>
</head>
<body>
<div id="container"></div>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-geo-projection.v1.min.js"></script>
<script src="//d3js.org/topojson.v2.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
</body>
</html>
答案 0 :(得分:2)
我明白了!我误解了projectionTween函数是如何工作的。我基本上忘了把它从v3转换到v4。所以代码:
var projection = d3.geo.projection(project) .scale(1) .translate([width / 2,height / 2]);
变为:
var projection = d3.geoProjection(project) .scale(1) .translate([width / 2,height / 2]);
希望这有助于某人!