D3,在 zoom/pan 时更新绘图数据

D3, update plotted data upon zoom/pan

我用一些 json 数据绘制了一堆点到 D3 地形 json 地图,我正在努力让它放大。我有一个非常简单的缩放工作,但是我绘制的点不是 moving/updating 缩放。

看这里 - http://jsfiddle.net/o3dxgfuu/6/

这是基本设置:

 var svg = d3.select("#map").append("svg")
.attr("preserveAspectRatio", "xMidYMid")
.attr("viewBox", "0 0 " + width + " " + height)
.attr("width", m_width)
.attr("height", m_width * height / width);

 svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)

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

 d3.json("scripts/world-110m2.json", function(error, us) {
  g.append("g")
.attr("id", "countries")
.selectAll("path")
.data(topojson.feature(us, us.objects.countries).features)
.enter()
.append("path")
.attr("id", function(d) { return d.id; })
.attr("d", path)

});

然后这些点被绘制在一个函数中,所以我可以根据需要交换它们(这可能是问题的一部分,我不太确定)-

 function plotPoints(data){
 svg.selectAll("circle")
 .transition()
 .delay(function(d, i) { return i * 2; })
 .attr("r", 0 )
 .remove()

svg.selectAll(".pin")
.data(data.earthquakes)
.enter().append("circle", ".pin")
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
 .attr("transform", function(d) {
 return "translate(" + projection([
  d.lon,
  d.lat
 ]) + ")"

 })
.attr("r", 0 )
.transition()
.duration(500)
.delay(function(d, i) { return i * 5; })
.attr("r",function(d){
   return d.magnitude/2;
 })

我正在使用缩放方法,我发现了一些很好的例子 -

 var zoom = d3.behavior.zoom()
.on("zoom",function() {
    g.attr("transform","translate("+ 
        d3.event.translate.join(",")+")scale("+d3.event.scale+")");
    g.selectAll(".pin")
        .attr("d", path.projection(projection));

});

svg.call(zoom)

所以,缩放和平移效果很好,当我缩放和平移时,我无法尝试让我的标绘点更新,看起来它们在地图右侧的 sheet 玻璃上现在,当我移动地图时不要移动。谢谢!

编辑:我在这里做了一个例子 -

http://jsfiddle.net/o3dxgfuu/6/

你看当你放大的时候绘制的点是不动的。仍然坚持这个:(。谢谢!

这是更新后的 fiddle,它可以正常工作:http://jsfiddle.net/o3dxgfuu/12/

我所做的更改是:

  1. 添加了一个新的 g 元素来容纳 circle.pin 元素:

    var g = svg.append("g");
    var gPins = svg.append("g"); //new g element
    
  2. circle 元素添加到新的 g 元素:

    // svg.selectAll(".pin")
    gPins.selectAll(".pin") // add circles to new g element
      .data(data.earthquakes)
    .enter().append("circle", ".pin")
      .attr("transform", function(d) {
        return "translate(" + projection([
          d.lon,
          d.lat
          ]) + ")"
    
        })
    
  3. 转换缩放处理程序中的新 g 元素

    var zoom = d3.behavior.zoom()
        .on("zoom",function() {
            g.attr("transform","translate("+ 
              d3.event.translate.join(",")+")scale("+d3.event.scale+")");
            gPins.attr("transform","translate("+ 
             d3.event.translate.join(",")+")scale("+d3.event.scale+")"); // transform new g element
    
      });
    

基本上,您应该将 circle 元素添加到一个组中,然后将 transform 应用于该组元素。