【问题标题】:D3 Map - Marks ZoomingD3 地图 - 标记缩放
【发布时间】:2017-07-11 20:31:15
【问题描述】:

我的 D3 地图上的标记有问题。当我为每个州设置缩放时,标记不会在地图内缩放..

这是我第一次尝试 D3 地图,如果我在代码中搞砸了,请见谅。如果我做了或错过了什么,我会非常感谢解释。 如果有人能提供帮助,我将不胜感激。

var width = 960,
    height = 500,
    centered;

var projection = d3.geo.albersUsa()
    .scale(1070)
    .translate([width / 2, height / 2]);

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

var svg = d3.select("body")
    .append("svg")
    .attr("viewBox", "0 0 " + width + " " + height )
    .attr("preserveAspectRatio", "xMinYMin");

svg.append("rect")
    .attr("class", "background")
    .attr("width", width)
    .attr("height", height)
    .on("click", clicked);

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

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

d3.json("https://bl.ocks.org/mbostock/raw/4090846/us.json", function(error, us) {
  if (error) throw error;

  g.append("g")
      .attr("id", "states")
    .selectAll("path")
      .data(topojson.feature(us, us.objects.states).features)
    .enter().append("path")
      .attr("d", path)
      .style("fill", "#26404b")
      .on("click", clicked);

  g.append("path")
      .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
      .attr("id", "state-borders")
      .attr("d", path);

  // CITIES
  d3.json("https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json", function(data) {
    svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return projection([d.longitude, d.latitude])[0];
      })
      .attr("cy", function(d) {
        return projection([d.longitude, d.latitude])[1];
      })
      .attr("r", function(d) {
        if(d.population >= 1 && d.population < 10000){
          return 1;
        }
        else if(d.population >= 10000 && d.population < 100000){
          return 2;
        }
        else if(d.population >= 100000 && d.population < 500000){
          return 3;
        }
        else if(d.population >= 500000 && d.population < 1000000){
          return 4;
        }
        else if(d.population >= 1000000 && d.population < 5000000){
          return 5;
        }
        else if(d.population < 5000000){
          return 10;
        }
        else {
          return 0;
        };
      })
        .style("fill", "rgba(26, 188, 156,0.8)")  

        // HOVER
        .on("mouseover", function(d) {
          d3.select(this)
            .transition()
            .duration(200)
            .style('fill', 'rgba(26, 188, 156, 0.3)')
            .style('stroke', '#1abc9c')
            .style('stroke-width', 4);      
            div.transition()        
                 .duration(200)      
                 .style("opacity", .9);      
                 div.html('<span id="place">City: ' + d.city + '</span><br><span id="people">Calls: ' + d.population + '</span>')
                 .style("left", (d3.event.pageX) + 35 + "px")     
                 .style("top", (d3.event.pageY - 28) + "px");    
        })   
          .on("mouseout", function(d) { 
            d3.select(this)
            .transition()
            .duration(200)
            .style('fill', 'rgba(26, 188, 156, 0.8)')
            .style('stroke-width', 0);        
              div.transition()        
                 .duration(200)      
                 .style("opacity", 0);   
          });
    }); 
});

function clicked(d) {
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  g.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  g.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}
.background {
  fill: #435863;
  pointer-events: all;
}

path:hover {
  fill-opacity: .9;
}

#states .active {
  fill-opacity: .9;
}

#state-borders {
  fill: none;
  stroke: rgba(22, 160, 133, .1);
  stroke-width: 1px;
}

/* Style for Custom Tooltip */
div.tooltip {   
  position: absolute;             
  height: 28px;                 
  padding: 5px 10px;              
  font: 12px sans-serif;        
  background: white;   
  border: 0px;      
  border-radius: 5px;           
  pointer-events: none;         
}
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>

【问题讨论】:

    标签: javascript d3.js topojson


    【解决方案1】:

    问题是您将圈子直接附加到svg,但您的美国州被附加到g 元素。您的缩放转换仅应用于g,这意味着圆圈不会受到影响:

    g.transition()
          .duration(750)
          .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
          .style("stroke-width", 1.5 / k + "px");
    

    您应该能够通过简单地将您的圈子附加到相同的g 元素本身而不是svg 来纠正此问题:

      d3.json("cities.json", function(data) {
        g.selectAll("circle")
          .data(data)
          .enter()
          ...
    

    【讨论】:

    • 哦.. 非常感谢,我为此苦苦挣扎了几个小时.. 哈哈
    • 我去过那里,没有什么比失去理智更令人沮丧的了,释放出一连串的脏话,为了一两个角色而愤怒地在屏幕上做手势。
    猜你喜欢
    • 2011-03-31
    • 2016-03-23
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2014-03-06
    • 2014-07-10
    • 1970-01-01
    相关资源
    最近更新 更多