I've started doing this as a side project to learn D3. So please go easy on me;
Goal: Making an interactive airports map. When mouse is over a city planes will take off from that city's airport and land on to the destination.
Steps I've followed;
Problem: When I have more than one plane to take from a city it's just not moving. Instead it stays on the same position until the transition ends. I can't add concurrent transitions to the objects.
My transition function is like;
function myTransition(destPoi, originPoi) {
var tr_bl = true;
pathData = []; t_dest_poi = [];
if (tr_bl) {
//Origin destination coordinates taken from the Origin Poi
originPoint[0] = originPoi[1];
originPoint[1] = originPoi[2];
originPoint = geoMercator(originPoint);//Need transformation before using on screen.
var lineGenerator = d3.line().curve(d3.curveCatmullRom);
// Destination coordinate pairs transformed to screen coordinates
// and assigned to an array
for (i = 0; i < destPoi.length; i++) {
t_dest_poi[i] = geoMercator(destPoi[i]);
}
//appending new group g2 with id fp
var g2 = map_svg.append("g").attr("id", "fp");
// Creating the planes and flight paths programmatically.*************************************
for (i = 0; i < destPoi.length; i++) {
var plane = map_svg.append("path")
.attr("class", "plane")
.attr("d", "m25.21488,3.93375c-0.44355,0 -0.84275,0.18332 -1.17933,0.51592c-0.33397,0.33267 -0.61055,0.80884 -0.84275,1.40377c-0.45922,1.18911 -0.74362,2.85964 -0.89755,4.86085c-0.15655,1.99729 -0.18263,4.32223 -0.11741,6.81118c-5.51835,2.26427 -16.7116,6.93857 -17.60916,7.98223c-1.19759,1.38937 -0.81143,2.98095 -0.32874,4.03902l18.39971,-3.74549c0.38616,4.88048 0.94192,9.7138 1.42461,13.50099c-1.80032,0.52703 -5.1609,1.56679 -5.85232,2.21255c-0.95496,0.88711 -0.95496,3.75718 -0.95496,3.75718l7.53,-0.61316c0.17743,1.23545 0.28701,1.95767 0.28701,1.95767l0.01304,0.06557l0.06002,0l0.13829,0l0.0574,0l0.01043,-0.06557c0,0 0.11218,-0.72222 0.28961,-1.95767l7.53164,0.61316c0,0 0,-2.87006 -0.95496,-3.75718c-0.69044,-0.64577 -4.05363,-1.68813 -5.85133,-2.21516c0.48009,-3.77545 1.03061,-8.58921 1.42198,-13.45404l18.18207,3.70115c0.48009,-1.05806 0.86881,-2.64965 -0.32617,-4.03902c-0.88969,-1.03062 -11.81147,-5.60054 -17.39409,-7.89352c0.06524,-2.52287 0.04175,-4.88024 -0.1148,-6.89989l0,-0.00476c-0.15655,-1.99844 -0.44094,-3.6683 -0.90277,-4.8561c-0.22699,-0.59493 -0.50356,-1.07111 -0.83754,-1.40377c-0.33658,-0.3326 -0.73578,-0.51592 -1.18194,-0.51592l0,0l-0.00001,0l0,0z")
.style("opacity", 1)
.style("fill", "transparent");
//creating flight path data with line generator
pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
//appending created flight path to variable
var path = g2.append("path").data([
[originPoint],
[t_dest_poi[i]]
]).attr("d", d3.line());
//flight path
g2.selectAll('path')
.data([
[originPoint],
[t_dest_poi[i]]
])
.attr('d', pathData)
.attr("stroke", "blue")
.attr("fill", "transparent");
plane.style("fill", "grey");
var route = g2.append("path")
.datum({
type: "LineString", coordinates: [
[originPoint],
[t_dest_poi[i]]]
})
.attr("class", "route")
.attr("d", geoPath)
.attr("stroke", "blue")
.attr("fill", "transparent");
// adding transition to plane
plane.transition()
.duration(5000)
.attrTween("transform", translateAlong([originPoint, t_dest_poi[i]], path.node()))
.remove();
}
}
else {
}}
function translateAlong(co, path) {
var l = path.getTotalLength();
return function (d, i, a) {
return function (t) {
var p = path.getPointAtLength(t * l);
[a1, b1] = co[0];
[a2, b2] = co[1];
aci = Math.atan((b2 - b1) / (a2 - a1));
aci = aci * 180 / Math.PI;
if (a2 > a1) {
aci = aci + 90;
} else {
aci = aci - 90;
}
return "translate(" + (p.x) + "," + (p.y) + ") scale(" + Math.sin(Math.PI * t) + ") rotate(" + aci + ")";
};
};
}
This seems like an issue with updating the path of the #fp element during the transition. The relatively easy fix in this case is to handle the transitions separately.
In your code, in basemap.js circa line 58-63, you call myTransition() on an array of multiple elements after populating the array in a for loop.
for (i = 0; i <= n - 1; i++) {
fp[i] = [destAirportObjects[i][1], destAirportObjects[i][2]];
}
myTransition(fp, OriginAirport);
Call the function from within the for loop instead and your transition works fine:
for (i = 0; i <= n - 1; i++) {
fp[i] = [destAirportObjects[i][1], destAirportObjects[i][2]];
myTransition([fp[i]], OriginAirport);
}
If you choose this solution, you should update myTransition() to take a single set of coordinates to make the code easier to understand.
Alternatively , don't make any changes to the basemap.js file, but update myTransition so that the creation of the group (var g2) is completed within the destination for loop. Here's what you currently have in move.js starting at line 21:
var g2 = map_svg.append("g").attr("id", "fp");
// Creating the planes and flight paths programmatically.*************************************
for (i = 0; i < destPoi.length; i++) {
//creating flight path data with line generator
pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
//continue with loop
This is causing the g2 variable to be overwritten each time we move through the loop. There needs to be a distinct group created for each transition/path.
// Creating the planes and flight paths programmatically.*************************************
for (i = 0; i < destPoi.length; i++) {
var g2 = map_svg.append("g").attr("class", "fp");
//creating flight path data with line generator
pathData[i] = lineGenerator([originPoint, t_dest_poi[i]]);
//continue with loop
Finally, since there are multiple elements in this case, "fp" should be the class of var g2, not the ID. Remember to update your accessors accordingly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.