在d3.js中将对象从一个区域移动到另一个区域

时间:2017-06-20 00:24:42

标签: javascript d3.js

目前我有一张topojson格式的地图,我希望一个物体从A点移动到B点。在这张地图上有部门和市政当局。现在两个部门之间,我只想移动一个元素,它可以是一个圆圈,例如从A点到B点生成一个过渡。

enter image description here

enter image description here

在附图中,我想要实现的结构和示例。例如,我想从“ANTIOQUIA”中移动一个元素直到“BOYACA”。如果我能从部门的质心转到部门B的质心那将是很好的。我怎样才能做到这一点?

    var width = 900,
        height = 900;

    var div = d3.select("body").append("div")   
      .attr("class", "tooltip")             
      .style("opacity", 0);

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

    d3.json("https://cdn.rawgit.com/finiterank/mapa-colombia-js/9ae3e4e6/colombia-municipios.json", function(error, co) {
      console.log(co)
      var subunits = topojson.feature(co, co.objects.mpios);
      var projection = d3.geo.mercator()
        .scale(2000)
        .translate([width / 2, height / 2])
        .center([-61,43])
        .rotate([2,3,2]);

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




    var zoom = d3.behavior.zoom()
        .translate([0, 0])
        .scale(1)
        .scaleExtent([1, 8])
        .on("zoom", zoomed);


    var g = svg.append("g");

    svg
        .call(zoom) // delete this line to disable free zooming
        .call(zoom.event);

      g.append("path")
        .datum(subunits)
        .attr("d", path);

    function zoomed() {
        console.log("zoom")
      g.style("stroke-width", 1.5 / d3.event.scale + "px");
      g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }

     //departments
      g.selectAll(".dpto")
        .data(topojson.feature(co, co.objects.depts).features)
        .enter().append("path")
        .attr("class", function(d) { return "depts " + "_" + d.id; })
        .attr("d", path)



     //municipalities
      g.selectAll(".mpio")
        .data(topojson.feature(co, co.objects.mpios).features)
        .enter().append("path")
        .on('mouseover', mouseoverMun )
        .on('mouseout',mouseoutMun)
        .attr("class", function(d) { return "mpio " + "_" + d.id + " " + d.properties.dpt})
        .attr("d", path)
    })

    function mouseoverMun(d){
      // Turn the department blue
      d3.selectAll("."+d.properties.dpt)
         .style("fill","steelblue")

      // Turn the municipality orange
      //d3.select(this).style("fill","orange");

      // Show a tooltip  
      div.style("opacity", .9)  
         .html(d.properties.name)   
         .style("left", (d3.event.pageX) + "px")        
         .style("top", (d3.event.pageY - 28) + "px"); 
         document.getElementById("department").innerHTML=d.properties.dpt

    }

    function mouseoutMun() {
      d3.selectAll(".mpio").style("fill","none");
      div.style("opacity",0);
      document.getElementById("department").innerHTML='';

    }

这就是我想要做的。

http://jsfiddle.net/0yLfzowy/

1 个答案:

答案 0 :(得分:2)

有几种方法可以获得这些质心。

在这个解决方案中,我有一个centroids对象,当你实际绘制路径时会填充这个对象:

var centroids = {};

g.selectAll(".dpto")
    //etc
    .attr("d", function(d) {
        if (d.properties.dpt === "ANTIOQUIA" || d.properties.dpt === "BOYACA") {
            centroids[d.properties.dpt] = path.centroid(d)
        }
        return path(d);
    });

然后,只需要附加元素(这里是一个圆圈)并移动它:

var circle = svg.append("circle")
    .attr("fill", "blue")
    .attr("r", 4)
    .attr("cx", centroids.ANTIOQUIA[0])
    .attr("cy", centroids.ANTIOQUIA[1]);

circle.transition()
    .delay(1000)
    .duration(2000)
    .attr("cx", centroids.BOYACA[0])
    .attr("cy", centroids.BOYACA[1]);

这是更新的小提琴:http://jsfiddle.net/bzfs55bg/