如何在D3地图中重绘标签?

时间:2015-12-15 12:30:30

标签: javascript d3.js topojson

我正在按照两个教程在TOPOJson中制作地图:

  1. 显示国家/地区,边界和城市(点和标签)。 Tutorial here
  2. 移动并缩放地图。 Tutorial here
  3. 我可以显示平移,平移,缩放,但不会重绘城市的名称。

           var path = d3.geo.path()
          .projection(projection)
          .pointRadius(2);
    
      /* What's hapenning here ? */
      var svg = d3.select("#vis").append("svg:svg")
          .attr("width", width)
          .attr("height", height)
          .call(d3.behavior.zoom().on("zoom", redraw));
    
      /* Format projected 2D geometry appropriately for SVG or Canvas. */
      d3.json("uk.json", function(error, uk) {
        svg.selectAll(".subunit")
            .data(topojson.feature(uk, uk.objects.subunits).features)
          .enter().append("path")
            .attr("class", function(d) { return "subunit " + d.id; })
            .attr("d", path);
    
        svg.append("path")
            .datum(topojson.mesh(uk, uk.objects.subunits, function(a, b) { return a !== b && a.id !== "IRL"; }))
            .attr("d", path)
            .attr("class", "subunit-boundary");
    
        svg.append("path")
            .datum(topojson.mesh(uk, uk.objects.subunits, function(a, b) { return a === b && a.id === "IRL"; }))
            .attr("d", path)
            .attr("class", "subunit-boundary IRL");
    
        svg.append("path")
          .datum(topojson.feature(uk, uk.objects.places))
          .attr("d", path)
          .attr("class", "place");
    
        svg.selectAll(".place-label")
            .data(topojson.feature(uk, uk.objects.places).features)
          .enter().append("text")
            .attr("class", "place-label")
            .attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
            .attr("x", function(d) { return d.geometry.coordinates[0] > -1 ? 6 : -6; })
            .attr("dy", ".35em")
            .style("text-anchor", function(d) { return d.geometry.coordinates[0] > -1 ? "start" : "end"; })
            .text(function(d) { return d.properties.name; });
    
        svg.selectAll(".subunit-label")
          .data(topojson.feature(uk, uk.objects.subunits).features)
        .enter().append("text")
          .attr("class", function(d) { return "subunit-label " + d.id; })
          .attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
          .attr("dy", ".35em")
          .text(function(d) { return d.properties.name; });
      });
    
      function redraw() {
        // d3.event.translate (an array) stores the current translation from the parent SVG element
        // t (an array) stores the projection's default translation
        // we add the x and y vales in each array to determine the projection's new translation
        var tx = t[0] * d3.event.scale + d3.event.translate[0];
        var ty = t[1] * d3.event.scale + d3.event.translate[1];
        projection.translate([tx, ty]);
    
        // now we determine the projection's new scale, but there's a problem:
        // the map doesn't 'zoom onto the mouse point'
        projection.scale(s * d3.event.scale);
    
        // redraw the map
        svg.selectAll("path").attr("d", path);
    
        // redraw the labels
        svg.selectAll(".place-label");
    
        // redraw the x axis
        xAxis.attr("x1", tx).attr("x2", tx);
    
        // redraw the y axis
        yAxis.attr("y1", ty).attr("y2", ty);
      }
    

    我试图添加这一行:

    svg.selectAll(".place-label").attr("d", path);
    

    在重绘功能中,但没有用。

    你能否告诉我应该添加哪一行来刷新他们的位置?

    这是我的实时代码:Plunker live example & code

1 个答案:

答案 0 :(得分:0)

要使标签与地图一起移动,您需要执行以下操作: 在redraw function

  svg.selectAll(".place-label")[0].forEach( function(d){
    var data = d3.select(d).data()[0];//this will give you the text location data
    d3.select(d).attr("transform", "translate("+projection(data.geometry.coordinates)+")" )//pass the location data here to get the new translated value.
  });

对于子单元:

svg.selectAll(".subunit-label")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })

工作示例here

希望这有效!