javascript - D3 map - 标记缩放

标签 javascript d3.js topojson

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

这是我第一次尝试 D3 map ,如果我在代码中搞砸了,我深表歉意。如果我做了或错过了什么,我将非常感谢解释。 如果有人可以提供帮助,我将非常感激。

enter image description here enter image description here

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>

最佳答案

问题是您将圈子直接附加到 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()
      ...

关于javascript - D3 map - 标记缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42380523/

相关文章:

php - 我的 jQuery 和 PHP 对同一件事给出不同的结果?

javascript - d3 工具提示删除了我的轴(并且不起作用)

javascript - 如何嵌套 GeoJSON/TopoJSON 几何图形或使用 D3 嵌套生成的路径?

json - 如何向 topojson 文件添加属性?

svg - 使用 D3.js 制作自定义的虚构 map

javascript - 如何解决 eslint(vue/html-closing-bracket-newline) 冲突

javascript - 如何实现与元素交互的功能?

javascript - Ajax 架构 - MVC?其他?

javascript - D3.js - 如何在上一步中使用结果

html - 调整 SVG foreignObject 元素的大小以适合 HTML 元素